PSI sics-cvs-psi-2008-10-02
This commit is contained in:
476
proxy.c
Normal file
476
proxy.c
Normal file
@@ -0,0 +1,476 @@
|
||||
/**
|
||||
* This is the implementation of a SICS object which really is a placeholder
|
||||
* for another one. It shall be used in Hipadaba for sample enviornment
|
||||
* devices. This is also the reason why the objectNode is supposed to be
|
||||
* double.
|
||||
*
|
||||
* copyright: see file COPYRIGHT
|
||||
*
|
||||
* Mark Koennecke, March 2008
|
||||
*
|
||||
*/
|
||||
#include <sics.h>
|
||||
#include <sicsobj.h>
|
||||
#include <sicshipadaba.h>
|
||||
/*-----------------------------------------------------------------------*/
|
||||
typedef struct {
|
||||
pIDrivable pDriv;
|
||||
pEVInterface pEnv;
|
||||
pIDrivable pSlaveDriv;
|
||||
void *slaveData;
|
||||
pEVInterface pEnvSlave;
|
||||
} ProxyInt, *pProxyInt;
|
||||
/*------------------------------------------------------------------------*/
|
||||
static void KillProxyInt(void *data){
|
||||
pProxyInt proxy = (pProxyInt)data;
|
||||
|
||||
if(proxy == NULL){
|
||||
return;
|
||||
}
|
||||
if(proxy->pDriv != NULL){
|
||||
free(proxy->pDriv);
|
||||
}
|
||||
if(proxy->pEnv != NULL){
|
||||
free(proxy->pEnv);
|
||||
}
|
||||
free(proxy);
|
||||
}
|
||||
/*===================== Drivable Interfaces ================================*/
|
||||
static int testDrivProxy(pSICSOBJ self){
|
||||
pProxyInt proxy = self->pPrivate;
|
||||
|
||||
if(proxy->pSlaveDriv != NULL && proxy->slaveData != NULL){
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
static int ProxyHalt(void *data){
|
||||
pSICSOBJ self = (pSICSOBJ)data;
|
||||
pProxyInt proxy = NULL;
|
||||
|
||||
assert(self != NULL);
|
||||
proxy = self->pPrivate;
|
||||
assert(self != NULL);
|
||||
|
||||
if(testDrivProxy(self)){
|
||||
return proxy->pSlaveDriv->Halt(proxy->slaveData);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
static int ProxyLimits(void *data, float fval,
|
||||
char *error, int iErrLen){
|
||||
pSICSOBJ self = (pSICSOBJ)data;
|
||||
pProxyInt proxy = NULL;
|
||||
|
||||
assert(self != NULL);
|
||||
proxy = self->pPrivate;
|
||||
assert(self != NULL);
|
||||
|
||||
if(testDrivProxy(self)){
|
||||
return proxy->pSlaveDriv->CheckLimits(proxy->slaveData, fval,
|
||||
error, iErrLen);
|
||||
} else {
|
||||
strncpy(error,"ERROR: device not configured",iErrLen);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
static long ProxySet(void *data, SConnection *pCon, float fVal){
|
||||
pSICSOBJ self = (pSICSOBJ)data;
|
||||
pProxyInt proxy = NULL;
|
||||
|
||||
assert(self != NULL);
|
||||
proxy = self->pPrivate;
|
||||
assert(self != NULL);
|
||||
|
||||
if(testDrivProxy(self)){
|
||||
return proxy->pSlaveDriv->SetValue(proxy->slaveData,
|
||||
pCon, fVal);
|
||||
} else {
|
||||
SCWrite(pCon,"ERROR: device not configured", eError);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
static int ProxyStatus(void *data, SConnection *pCon){
|
||||
pSICSOBJ self = (pSICSOBJ)data;
|
||||
pProxyInt proxy = NULL;
|
||||
|
||||
assert(self != NULL);
|
||||
proxy = self->pPrivate;
|
||||
assert(self != NULL);
|
||||
|
||||
if(testDrivProxy(self)){
|
||||
return proxy->pSlaveDriv->CheckStatus(proxy->slaveData,
|
||||
pCon);
|
||||
} else {
|
||||
SCWrite(pCon,"ERROR: device not configured", eError);
|
||||
return HWFault;
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
static float ProxyGet(void *data, SConnection *pCon){
|
||||
pSICSOBJ self = (pSICSOBJ)data;
|
||||
pProxyInt proxy = NULL;
|
||||
|
||||
assert(self != NULL);
|
||||
proxy = self->pPrivate;
|
||||
assert(self != NULL);
|
||||
|
||||
if(testDrivProxy(self)){
|
||||
return proxy->pSlaveDriv->GetValue(proxy->slaveData, pCon);
|
||||
} else {
|
||||
SCWrite(pCon,"ERROR: device not configured", eError);
|
||||
return HWFault;
|
||||
}
|
||||
}
|
||||
/*===================== environment interface ==========================*/
|
||||
static int testEnvProxy(pSICSOBJ self){
|
||||
pProxyInt proxy = self->pPrivate;
|
||||
|
||||
if(proxy->pEnvSlave != NULL && proxy->slaveData != NULL){
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
static EVMode ProxyMode(void *data){
|
||||
pSICSOBJ self = (pSICSOBJ)data;
|
||||
pProxyInt proxy = NULL;
|
||||
|
||||
assert(self != NULL);
|
||||
proxy = self->pPrivate;
|
||||
assert(self != NULL);
|
||||
|
||||
if(testEnvProxy(self)){
|
||||
return proxy->pEnvSlave->GetMode(proxy->slaveData);
|
||||
} else {
|
||||
return EVError;
|
||||
}
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
static int ProxyTolerance(void *data){
|
||||
pSICSOBJ self = (pSICSOBJ)data;
|
||||
pProxyInt proxy = NULL;
|
||||
|
||||
assert(self != NULL);
|
||||
proxy = self->pPrivate;
|
||||
assert(self != NULL);
|
||||
|
||||
if(testEnvProxy(self)){
|
||||
return proxy->pEnvSlave->IsInTolerance(proxy->slaveData);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static int ProxyError(void *data){
|
||||
pSICSOBJ self = (pSICSOBJ)data;
|
||||
pProxyInt proxy = NULL;
|
||||
|
||||
assert(self != NULL);
|
||||
proxy = self->pPrivate;
|
||||
assert(self != NULL);
|
||||
|
||||
if(testEnvProxy(self)){
|
||||
return proxy->pEnvSlave->HandleError(proxy->slaveData);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
static void *findRealDev(pHdb node){
|
||||
char realDevice[80];
|
||||
CommandList *pCom = NULL;
|
||||
|
||||
GetHdbProperty(node,"proxy",realDevice,80);
|
||||
pCom = FindCommand(pServ->pSics,realDevice);
|
||||
if(pCom != NULL){
|
||||
return pCom->pData;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
static void *ProxyGetInterface(void *pData, int iID){
|
||||
pSICSOBJ self = (pSICSOBJ)pData;
|
||||
pDummy other = NULL;
|
||||
void *inter = NULL;
|
||||
pProxyInt proxy = NULL;
|
||||
|
||||
assert(self != NULL);
|
||||
proxy = self->pPrivate;
|
||||
|
||||
if(self != NULL){
|
||||
other = (pDummy)findRealDev(self->objectNode);
|
||||
if(other != NULL){
|
||||
inter = other->pDescriptor->GetInterface(other, iID);
|
||||
if(inter == NULL &&
|
||||
(iID == DRIVEID || iID == ENVIRINTERFACE) ){
|
||||
proxy->pEnvSlave = NULL;
|
||||
proxy->pSlaveDriv = NULL;
|
||||
proxy->slaveData = NULL;
|
||||
return NULL;
|
||||
} else {
|
||||
if(iID == DRIVEID){
|
||||
proxy->pSlaveDriv = inter;
|
||||
proxy->slaveData = other;
|
||||
return proxy->pDriv;
|
||||
} else if(iID == ENVIRINTERFACE){
|
||||
proxy->pEnvSlave = inter;
|
||||
proxy->slaveData = other;
|
||||
return proxy->pEnv;
|
||||
}
|
||||
}
|
||||
return inter;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
static hdbCallbackReturn ProxyCallback(pHdb node, void *userData,
|
||||
pHdbMessage message){
|
||||
pHdbDataMessage get = NULL, set = NULL;
|
||||
pDummy other = NULL;
|
||||
pIDrivable pDriv = NULL;
|
||||
float fval;
|
||||
int status;
|
||||
SConnection *pCon = NULL;
|
||||
pSICSOBJ self = (pSICSOBJ)userData;
|
||||
char proxyDev[80];
|
||||
|
||||
get = GetHdbGetMessage(message);
|
||||
if(get != NULL){
|
||||
pCon = (SConnection *)get->callData;
|
||||
other = (pDummy)findRealDev(node);
|
||||
if(other != NULL){
|
||||
pDriv = other->pDescriptor->GetInterface(other,DRIVEID);
|
||||
if(pDriv != NULL && pCon != NULL){
|
||||
fval = pDriv->GetValue(other, pCon);
|
||||
get->v->v.doubleValue = (double)fval;
|
||||
node->value.v.doubleValue = (double)fval;
|
||||
return hdbContinue;
|
||||
}
|
||||
}
|
||||
get->v->v.doubleValue = .0;
|
||||
}
|
||||
|
||||
set = GetHdbSetMessage(message);
|
||||
if(set != NULL){
|
||||
pCon = (SConnection *)set->callData;
|
||||
other = (pDummy)findRealDev(node);
|
||||
if(other == NULL){
|
||||
if(pCon != NULL){
|
||||
SCWrite(pCon,"ERROR: device not configured", eError);
|
||||
return hdbAbort;
|
||||
}
|
||||
}
|
||||
GetHdbProperty(node,"proxy", proxyDev,80);
|
||||
status = StartDevice(pServ->pExecutor, proxyDev,
|
||||
self->pDes, self, pCon, (float)set->v->v.doubleValue);
|
||||
if(status == 1){
|
||||
return hdbContinue;
|
||||
} else {
|
||||
return hdbAbort;
|
||||
}
|
||||
}
|
||||
|
||||
return hdbContinue;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static hdbCallbackReturn MapParCallback(pHdb node, void *userData,
|
||||
pHdbMessage message){
|
||||
pHdbDataMessage get = NULL, set = NULL;
|
||||
CommandList *pCom = NULL;
|
||||
SConnection *pCon = NULL;
|
||||
char mapPar[80], proxyDev[80], *pData = NULL;
|
||||
char command[1024];
|
||||
pDynString data = NULL;
|
||||
|
||||
if(GetHdbKillNodeMessage(message) != NULL ){
|
||||
return hdbContinue;
|
||||
}
|
||||
|
||||
GetHdbProperty(node->mama, "proxy", proxyDev,80);
|
||||
pCom = FindCommand(pServ->pSics, proxyDev);
|
||||
if(pCom == NULL){
|
||||
if(pCon != NULL){
|
||||
SCWrite(pCon,"ERROR: device not configured", eError);
|
||||
}
|
||||
return hdbContinue;
|
||||
}
|
||||
GetHdbProperty(node,"mappar", mapPar, 80);
|
||||
|
||||
get = GetHdbGetMessage(message);
|
||||
if(get != NULL){
|
||||
pCon = (SConnection *)get->callData; snprintf(command,1024,"%s %s", proxyDev, mapPar);
|
||||
if(pCon != NULL){
|
||||
SCStartBuffering(pCon);
|
||||
InterpExecute(pServ->pSics, pCon,command);
|
||||
data = SCEndBuffering(pCon);
|
||||
if(data != NULL){
|
||||
pData = GetCharArray(data);
|
||||
if(strstr(pData,"ERROR") != NULL){
|
||||
SCWrite(pCon,pData,eError);
|
||||
} else {
|
||||
pData = strchr(pData,(int)'=');
|
||||
if(pData != NULL){
|
||||
pData++;
|
||||
if(!readHdbValue(get->v, pData, command, 1024)){
|
||||
SCWrite(pCon, command, eError);
|
||||
}
|
||||
copyHdbValue(get->v, &node->value);
|
||||
return hdbContinue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set = GetHdbSetMessage(message);
|
||||
if(set != NULL){
|
||||
pCon = (SConnection *)set->callData;
|
||||
data = formatValue(*(set->v), node);
|
||||
if(data != NULL){
|
||||
snprintf(command,1024,"%s %s %s", proxyDev, mapPar,
|
||||
GetCharArray(data));
|
||||
DeleteDynString(data);
|
||||
InterpExecute(pServ->pSics, pCon, command);
|
||||
}
|
||||
}
|
||||
|
||||
return hdbContinue;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static int MapFunc(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
|
||||
pHdb par[], int nPar){
|
||||
pHdb node = NULL;
|
||||
int type;
|
||||
|
||||
if(nPar < 4){
|
||||
SCWrite(pCon,"ERROR: not enough arguments to MapFunc", eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
type = convertHdbType(par[2]->value.v.text);
|
||||
node = MakeHipadabaNode(par[0]->value.v.text, type, 1);
|
||||
if(node == NULL){
|
||||
SCWrite(pCon,"ERROR: out of memory in MapFunc", eError);
|
||||
return 0;
|
||||
}
|
||||
SetHdbProperty(node,"mappar", par[1]->value.v.text);
|
||||
SetHdbProperty(node,"priv", par[3]->value.v.text);
|
||||
AppendHipadabaCallback(node,
|
||||
MakeHipadabaCallback(MapParCallback, NULL, NULL));
|
||||
AddHipadabaChild(self->objectNode, node, pCon);
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int ProxyAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]){
|
||||
int status;
|
||||
pSICSOBJ self = (pSICSOBJ)pData;
|
||||
CommandList *pCom = NULL;
|
||||
char proxyObj[80];
|
||||
|
||||
assert(self != NULL);
|
||||
|
||||
/*
|
||||
* do parameters and object functions
|
||||
*/
|
||||
if(argc > 1){
|
||||
status = InvokeSICSOBJ(pCon, pSics, pData, argc, argv);
|
||||
if(status != -1 ){
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* try the interpreter function of the proxy object
|
||||
*/
|
||||
GetHdbProperty(self->objectNode,"proxy", proxyObj, 80);
|
||||
pCom = FindCommand(pSics, proxyObj);
|
||||
if(pCom != NULL){
|
||||
return pCom->OFunc(pCon,pSics,pCom->pData, argc, argv);
|
||||
} else {
|
||||
SCWrite(pCon,"ERROR: device not configured", eError);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int ProxyFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]){
|
||||
int type;
|
||||
pSICSOBJ pNew = NULL;
|
||||
pHdb mapFunc = NULL;
|
||||
hdbValue v;
|
||||
pProxyInt proxy = NULL;
|
||||
|
||||
if(argc < 4){
|
||||
SCWrite(pCon,"ERROR: not enough arguments for ProxyFactory",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
type = convertHdbType(argv[3]);
|
||||
pNew = MakeSICSOBJv(argv[1], "ProxyObject", type, usSpy);
|
||||
if(pNew == NULL){
|
||||
SCWrite(pCon,"ERROR: out of memory in ProxyFactory",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
proxy = malloc(sizeof(ProxyInt));
|
||||
if(proxy == NULL){
|
||||
SCWrite(pCon,"ERROR: out of memory in ProxyFactory",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
memset(proxy,0,sizeof(ProxyInt));
|
||||
proxy->pDriv = CreateDrivableInterface();
|
||||
proxy->pEnv = CreateEVInterface();
|
||||
if(proxy->pDriv == NULL && proxy->pEnv == NULL){
|
||||
SCWrite(pCon,"ERROR: out of memory in ProxyFactory",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
proxy->pDriv->CheckLimits = ProxyLimits;
|
||||
proxy->pDriv->CheckStatus = ProxyStatus;
|
||||
proxy->pDriv->GetValue = ProxyGet;
|
||||
proxy->pDriv->Halt = ProxyHalt;
|
||||
proxy->pDriv->SetValue = ProxySet;
|
||||
|
||||
proxy->pEnv->GetMode = ProxyMode;
|
||||
proxy->pEnv->HandleError = ProxyError;
|
||||
proxy->pEnv->IsInTolerance = ProxyTolerance;
|
||||
|
||||
pNew->KillPrivate = KillProxyInt;
|
||||
pNew->pPrivate = proxy;
|
||||
|
||||
pNew->pDes->GetInterface = ProxyGetInterface;
|
||||
SetHdbProperty(pNew->objectNode, "proxy", argv[2]);
|
||||
AppendHipadabaCallback(pNew->objectNode,
|
||||
MakeHipadabaCallback(ProxyCallback, pNew,NULL));
|
||||
|
||||
v = MakeSICSFunc(MapFunc);
|
||||
mapFunc = MakeSICSHdbPar("map", usMugger, v);
|
||||
SetHdbProperty(mapFunc,"visible","false");
|
||||
v = MakeHdbText("Undefined");
|
||||
AddSICSHdbPar(mapFunc,"name",usMugger,v);
|
||||
AddSICSHdbPar(mapFunc,"target",usMugger,v);
|
||||
AddSICSHdbPar(mapFunc,"type",usMugger,v);
|
||||
AddSICSHdbPar(mapFunc,"priv",usMugger,v);
|
||||
AddHipadabaChild(pNew->objectNode, mapFunc, pCon);
|
||||
|
||||
AddCommand(pSics,argv[1],
|
||||
ProxyAction,
|
||||
KillSICSOBJ,
|
||||
pNew);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user