PSI sics-cvs-psi-2008-10-02
This commit is contained in:
819
sicshdbadapter.c
Normal file
819
sicshdbadapter.c
Normal file
@@ -0,0 +1,819 @@
|
||||
/*
|
||||
* Experience has shown that integrating existing SICS objects into the
|
||||
* Hierarchical Parameter Database (Hdb) is a difficult task without reworking
|
||||
* the complete SICS object model. Rather, it seems easier to adapt some
|
||||
* critical objects to the Hdb with some glue code. Following the facade or
|
||||
* adapter design pattern. This is the purpose of this module. For the moment
|
||||
* the external interface is only an interpreter function which will be used to
|
||||
* install suitable SICS objects into the Hdb tree and generates the necessary
|
||||
* adapters internally. This code can be used to adapt to:
|
||||
* - motors
|
||||
* - the data segment of histogram memories
|
||||
*
|
||||
* copyright: see file COPYRIGHT
|
||||
*
|
||||
* Mark Koennecke, November 2006
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <sics.h>
|
||||
#include "stptok.h"
|
||||
#include "motor.h"
|
||||
#include "HistMem.h"
|
||||
#include "HistMem.i"
|
||||
#include "HistDriv.i"
|
||||
#include "sicsvar.h"
|
||||
#include "counter.h"
|
||||
#include "lld.h"
|
||||
#include "sicshipadaba.h"
|
||||
#include "sicshdbadapter.h"
|
||||
#include "sicsdata.h"
|
||||
|
||||
#define PRIVNAM "priv"
|
||||
/*==================== support code ====================================*/
|
||||
static void AddPrivProperty(pHdb node, int priv){
|
||||
char pPriv[80];
|
||||
switch(priv){
|
||||
case usInternal:
|
||||
strcpy(pPriv,"internal");
|
||||
break;
|
||||
case usMugger:
|
||||
strcpy(pPriv,"manager");
|
||||
break;
|
||||
case usUser:
|
||||
strcpy(pPriv,"user");
|
||||
break;
|
||||
case usSpy:
|
||||
strcpy(pPriv,"spy");
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
SetHdbProperty(node,PRIVNAM,pPriv);
|
||||
}
|
||||
/*=================== motor code =======================================*/
|
||||
static int MoveCallback(int iEvent, void *eventData, void *userData,
|
||||
commandContext cc){
|
||||
MotCallback *motData = (MotCallback *)eventData;
|
||||
pHdb motor = (pHdb)userData;
|
||||
pHdb pos = NULL;
|
||||
|
||||
if(iEvent == MOTDRIVE && motData != NULL && motor != NULL){
|
||||
UpdateHipadabaPar(motor,MakeHdbFloat((double)motData->fVal)
|
||||
,NULL);
|
||||
pos = GetHipadabaNode(motor,"position");
|
||||
if(pos != NULL){
|
||||
UpdateHipadabaPar(pos,MakeHdbFloat((double)motData->fVal)
|
||||
,NULL);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------*/
|
||||
static int MotorValueCallback(int iEvent, void *eventData, void *userData,
|
||||
commandContext cc){
|
||||
pHdb motor = (pHdb)userData;
|
||||
pMotor pMot = (pMotor)eventData;
|
||||
pHdb current = NULL;
|
||||
float fVal;
|
||||
|
||||
/*
|
||||
* as setting some motor parameters might cause other motor
|
||||
* parametes to change too, I opt for the cheap solution to check
|
||||
* them all.
|
||||
*/
|
||||
if(iEvent == HDBVAL && motor != NULL && pMot != NULL){
|
||||
current = motor->child;
|
||||
while(current != NULL){
|
||||
MotorGetPar(pMot,current->name,&fVal);
|
||||
if(fVal != current->value.v.doubleValue) {
|
||||
UpdateHipadabaPar(current,MakeHdbFloat((double)fVal),NULL);
|
||||
}
|
||||
current = current->next;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------*/
|
||||
static hdbCallbackReturn MotorParSetCallback(pHdb currentNode, void *userData,
|
||||
pHdbMessage message){
|
||||
pMotor pMot = (pMotor)userData;
|
||||
SConnection *pCon = NULL;
|
||||
int status;
|
||||
pHdbDataMessage mm = NULL;
|
||||
|
||||
if((mm = GetHdbSetMessage(message)) == NULL){
|
||||
return hdbContinue;
|
||||
}
|
||||
pCon = mm->callData;
|
||||
|
||||
assert(pMot != NULL && pCon != NULL);
|
||||
status = MotorSetPar(pMot,pCon,currentNode->name,
|
||||
(float)mm->v->v.doubleValue);
|
||||
if(status == 1){
|
||||
return hdbContinue;
|
||||
} else {
|
||||
return hdbAbort;
|
||||
}
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
static hdbCallbackReturn MotorParGetCallback(pHdb currentNode, void *userData,
|
||||
pHdbMessage message){
|
||||
pMotor pMot = (pMotor)userData;
|
||||
float fVal;
|
||||
int status;
|
||||
pHdbDataMessage mm = NULL;
|
||||
|
||||
if((mm = GetHdbGetMessage(message)) == NULL){
|
||||
return hdbContinue;
|
||||
}
|
||||
|
||||
assert(pMot != NULL);
|
||||
status = MotorGetPar(pMot,currentNode->name,&fVal);
|
||||
currentNode->value.v.doubleValue = fVal;
|
||||
if(status == 1){
|
||||
return hdbContinue;
|
||||
} else {
|
||||
return hdbAbort;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------*/
|
||||
static pHdb MakeMotParNode(char *name, pMotor pMot){
|
||||
pHdb node = NULL;
|
||||
pHdbCallback pCall = NULL;
|
||||
char command[1024];
|
||||
|
||||
node = MakeHipadabaNode(name, HIPFLOAT, 1);
|
||||
if(node != NULL) {
|
||||
pCall = MakeHipadabaCallback(MotorParSetCallback,pMot,NULL);
|
||||
if(pCall == NULL){
|
||||
return NULL;
|
||||
}
|
||||
AppendHipadabaCallback(node,pCall);
|
||||
pCall = MakeHipadabaCallback(MotorParGetCallback,pMot,NULL);
|
||||
if(pCall == NULL){
|
||||
return NULL;
|
||||
}
|
||||
AppendHipadabaCallback(node,pCall);
|
||||
snprintf(command,1023,"%s %s ", pMot->name, name);
|
||||
SetHdbProperty(node,"sicscommand", command);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
/*---------------------------------------------------------------------*/
|
||||
static int AddStdMotorPar(pHdb motorNode, pMotor pMot){
|
||||
int i;
|
||||
pHdb parNode = NULL;
|
||||
char *addPar[] = {"target",
|
||||
"hardlowerlim",
|
||||
"hardupperlim",
|
||||
NULL};
|
||||
|
||||
i = 0;
|
||||
while(addPar[i] != NULL){
|
||||
parNode = MakeMotParNode(addPar[i],pMot);
|
||||
SetHdbProperty(parNode,PRIVNAM,"internal");
|
||||
if(parNode == NULL){
|
||||
return 0;
|
||||
}
|
||||
AddHipadabaChild(motorNode,parNode, NULL);
|
||||
i++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add the parameters in the obpar array
|
||||
*/
|
||||
for(i = 0; i < MOTOBPARLENGTH; i++){
|
||||
parNode = MakeMotParNode(pMot->ParArray[i].name,pMot);
|
||||
if(parNode == NULL){
|
||||
return 0;
|
||||
}
|
||||
AddHipadabaChild(motorNode,parNode, NULL);
|
||||
AddPrivProperty(parNode,pMot->ParArray[i].iCode);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static char *getDriverParList(MotorDriver *pDriv){
|
||||
SConnection *pCon = NULL;
|
||||
pDynString list = NULL;
|
||||
char *listData = NULL;
|
||||
|
||||
if(pDriv->ListDriverPar != NULL){
|
||||
pCon = SCCreateDummyConnection(pServ->pSics);
|
||||
if(pCon == NULL){
|
||||
return NULL;
|
||||
}
|
||||
SCStartBuffering(pCon);
|
||||
pDriv->ListDriverPar(pDriv,"test.", pCon);
|
||||
list = SCEndBuffering(pCon);
|
||||
if(list != NULL){
|
||||
listData = strdup(GetCharArray(list));
|
||||
SCDeleteConnection(pCon);
|
||||
} else {
|
||||
listData = NULL;
|
||||
}
|
||||
return listData;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
extern char *trim(char *str);
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static char *extractName(char *line){
|
||||
char *name = NULL, *pEnd = NULL;
|
||||
|
||||
name = strchr(line,'.');
|
||||
assert(name != NULL);
|
||||
while(*name == '.'){
|
||||
name++;
|
||||
}
|
||||
pEnd = strchr(name,'=');
|
||||
assert(pEnd != NULL);
|
||||
*pEnd = '\0';
|
||||
return trim(name);
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
static int CreateDriverParameters(pMotor pM, pHdb parent){
|
||||
char *listPtr = NULL, line[80], *pPtr, *name;
|
||||
pHdb node = NULL;
|
||||
|
||||
listPtr = getDriverParList(pM->pDriver);
|
||||
if(listPtr == NULL){
|
||||
/*
|
||||
* no driver parameters
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
pPtr = listPtr;
|
||||
while((pPtr = stptok(pPtr,line,79,"\n")) != NULL){
|
||||
name = extractName(line);
|
||||
node = MakeMotParNode(name,pM);
|
||||
SetHdbProperty(node,PRIVNAM,"manager");
|
||||
if(node != NULL){
|
||||
AddHipadabaChild(parent,node,NULL);
|
||||
}
|
||||
}
|
||||
free(listPtr);
|
||||
return 1;
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
static pHdb CreateMotorAdapter(char *name, pMotor pMot){
|
||||
pHdb result = NULL;
|
||||
commandContext comCom;
|
||||
float access;
|
||||
|
||||
assert(pMot != NULL);
|
||||
|
||||
result = MakeSICSHdbDriv(name,usUser,pMot,HIPFLOAT);
|
||||
if(result == NULL){
|
||||
return NULL;
|
||||
}
|
||||
MotorGetPar(pMot,"accesscode",&access);
|
||||
AddPrivProperty(result,(int)access);
|
||||
SetHdbProperty(result,"type","drivable");
|
||||
SetHdbProperty(result,"sicsdev",pMot->name);
|
||||
/*
|
||||
* We want to be notified when this motor drives around. Or
|
||||
* its parameters change.
|
||||
*/
|
||||
strncpy(comCom.deviceID,name,255);
|
||||
comCom.transID = -77;
|
||||
RegisterCallback(pMot->pCall,comCom, MOTDRIVE, MoveCallback,
|
||||
result,NULL);
|
||||
RegisterCallback(pMot->pCall,comCom, HDBVAL, MotorValueCallback,
|
||||
result,NULL);
|
||||
|
||||
if(!AddStdMotorPar(result,pMot)){
|
||||
DeleteHipadabaNode(result,NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!CreateDriverParameters(pMot,result)){
|
||||
DeleteHipadabaNode(result,NULL);
|
||||
return NULL;
|
||||
}
|
||||
result->protected = 1;
|
||||
|
||||
return result;
|
||||
}
|
||||
/*============== histogram memory ======================================*/
|
||||
static long totalSum(int *data, int length){
|
||||
long result = 0l;
|
||||
int i;
|
||||
|
||||
if(data == NULL){
|
||||
return 0;
|
||||
}
|
||||
for(i = 0; i < length; i++){
|
||||
result += data[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
typedef struct {
|
||||
pHistMem pHM;
|
||||
long oldSum;
|
||||
} HMAdapter, *pHMAdapter;
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static hdbCallbackReturn HMDataGetCallback(pHdb currentNode, void *userData,
|
||||
pHdbMessage message){
|
||||
pHMAdapter pHMA = (pHMAdapter)userData;
|
||||
SConnection *pCon = NULL;
|
||||
long sum1;
|
||||
pHdbDataMessage mm = NULL;
|
||||
|
||||
if((mm = GetHdbGetMessage(message)) == NULL){
|
||||
return hdbContinue;
|
||||
}
|
||||
pCon = mm->callData;
|
||||
assert(pHMA != NULL && pHMA->pHM != NULL);
|
||||
if(pCon == NULL){
|
||||
return hdbAbort;
|
||||
}
|
||||
currentNode->value.arrayLength = GetHistLength(pHMA->pHM);
|
||||
currentNode->value.v.intArray = (int *)GetHistogramPointer(pHMA->pHM,pCon);
|
||||
sum1 = totalSum(currentNode->value.v.intArray, currentNode->value.arrayLength);
|
||||
if(sum1 != pHMA->oldSum){
|
||||
UpdateHipadabaPar(currentNode,currentNode->value,NULL);
|
||||
pHMA->oldSum = sum1;
|
||||
}
|
||||
return hdbContinue;
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
static pHdb MakeHMDataNode(pHistMem pHM, char *name){
|
||||
pHdb node = NULL;
|
||||
pHdbCallback pCall = NULL;
|
||||
pHMAdapter pHMA = NULL;
|
||||
|
||||
node = MakeHipadabaNode(name,HIPINTVARAR,2);
|
||||
pHMA = malloc(sizeof(HMAdapter));
|
||||
if(node == NULL || pHMA == NULL){
|
||||
return NULL;
|
||||
}
|
||||
pHMA->pHM = pHM;
|
||||
pHMA->oldSum = 0;
|
||||
node->value.doNotFree = 1;
|
||||
pCall = MakeHipadabaCallback(HMDataGetCallback,pHMA,free);
|
||||
if(pCall == NULL){
|
||||
return NULL;
|
||||
}
|
||||
AppendHipadabaCallback(node,pCall);
|
||||
AppendHipadabaCallback(node,MakeReadOnlyCallback());
|
||||
|
||||
return node;
|
||||
}
|
||||
/*================ SICS Variable ======================================*/
|
||||
static hdbCallbackReturn SicsVarSetCallback(pHdb currentNode, void *userData,
|
||||
pHdbMessage message){
|
||||
pSicsVariable pVar = (pSicsVariable)userData;
|
||||
SConnection *pCon = NULL;
|
||||
int userRights = usMugger;
|
||||
pHdbDataMessage mm = NULL;
|
||||
|
||||
if((mm = GetHdbSetMessage(message)) == NULL){
|
||||
return hdbContinue;
|
||||
}
|
||||
pCon = mm->callData;
|
||||
|
||||
assert(pVar != NULL);
|
||||
|
||||
if(pCon != NULL){
|
||||
userRights = SCGetRights(pCon);
|
||||
}
|
||||
switch(currentNode->value.dataType){
|
||||
case HIPINT:
|
||||
VarSetInt(pVar, mm->v->v.intValue, userRights);
|
||||
break;
|
||||
case HIPFLOAT:
|
||||
VarSetFloat(pVar, (float)mm->v->v.doubleValue, userRights);
|
||||
break;
|
||||
case HIPTEXT:
|
||||
VarSetText(pVar, mm->v->v.text, userRights);
|
||||
break;
|
||||
}
|
||||
return hdbContinue;
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
static int ValueCallback(int iEvent, void *eventData, void *userData,
|
||||
commandContext cc){
|
||||
pSicsVariable pVar = (pSicsVariable)eventData;
|
||||
pHdb node = (pHdb)userData;
|
||||
hdbValue v;
|
||||
|
||||
if(iEvent == VALUECHANGE && pVar != NULL && node != NULL){
|
||||
switch(pVar->eType){
|
||||
case veInt:
|
||||
v = MakeHdbInt(pVar->iVal);
|
||||
break;
|
||||
case veFloat:
|
||||
v = MakeHdbFloat((double)pVar->fVal);
|
||||
break;
|
||||
case veText:
|
||||
v = MakeHdbText(pVar->text);
|
||||
break;
|
||||
}
|
||||
UpdateHipadabaPar(node,v,NULL);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
static pHdb MakeSicsVarNode(pSicsVariable pVar, char *name){
|
||||
pHdb node = NULL;
|
||||
pHdbCallback pCall = NULL;
|
||||
commandContext comCom;
|
||||
int type;
|
||||
char command[1024];
|
||||
|
||||
switch(pVar->eType){
|
||||
case veInt:
|
||||
type = HIPINT;
|
||||
break;
|
||||
case veFloat:
|
||||
type = HIPFLOAT;
|
||||
break;
|
||||
case veText:
|
||||
type = HIPTEXT;
|
||||
break;
|
||||
}
|
||||
node = MakeHipadabaNode(name,type,1);
|
||||
if(node == NULL){
|
||||
return NULL;
|
||||
}
|
||||
if(pVar->iLock == 1) {
|
||||
AddPrivProperty(node,usInternal);
|
||||
} else {
|
||||
AddPrivProperty(node,pVar->iAccessCode);
|
||||
}
|
||||
pCall = MakeHipadabaCallback(SicsVarSetCallback,pVar,NULL);
|
||||
if(pCall == NULL){
|
||||
return NULL;
|
||||
}
|
||||
strncpy(comCom.deviceID,name,255);
|
||||
comCom.transID = -77;
|
||||
AppendHipadabaCallback(node,pCall);
|
||||
RegisterCallback(pVar->pCall,comCom, VALUECHANGE, ValueCallback,
|
||||
node,NULL);
|
||||
snprintf(command,1023,"%s ", pVar->name);
|
||||
SetHdbProperty(node,"sicscommand",command);
|
||||
|
||||
node->protected = 1;
|
||||
return node;
|
||||
}
|
||||
/*================ counter =============================================*/
|
||||
typedef struct {
|
||||
pHdb node;
|
||||
int monitor; /* -1 == time */
|
||||
pCounter counter;
|
||||
} CountEntry;
|
||||
static int countList = -10;
|
||||
/*---------------------------------------------------------------------*/
|
||||
static void updateCountList(){
|
||||
int status;
|
||||
hdbValue v;
|
||||
CountEntry hugo;
|
||||
long monitor;
|
||||
float time;
|
||||
SConnection *pDummy = NULL;
|
||||
|
||||
if(countList < 0){
|
||||
return;
|
||||
}
|
||||
pDummy = SCCreateDummyConnection(pServ->pSics);
|
||||
if(pDummy == NULL){
|
||||
return;
|
||||
}
|
||||
|
||||
status = LLDnodePtr2First(countList);
|
||||
while(status != 0){
|
||||
LLDnodeDataTo(countList,&hugo);
|
||||
if(hugo.monitor < 0){
|
||||
time = GetCountTime(hugo.counter,pDummy);
|
||||
v = MakeHdbFloat((double)time);
|
||||
UpdateHipadabaPar(hugo.node,v, NULL);
|
||||
} else {
|
||||
monitor = GetMonitor(hugo.counter, hugo.monitor, pDummy);
|
||||
v = MakeHdbInt((int)monitor);
|
||||
UpdateHipadabaPar(hugo.node,v, NULL);
|
||||
}
|
||||
status = LLDnodePtr2Next(countList);
|
||||
}
|
||||
SCDeleteConnection(pDummy);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int CounterCallback(int iEvent, void *eventData, void *userData,
|
||||
commandContext cc){
|
||||
if(iEvent == MONITOR || iEvent == COUNTEND){
|
||||
updateCountList();
|
||||
}
|
||||
return 1;
|
||||
}/*=================== SICSData ========================================*/
|
||||
static void copyIntSicsData(pHdb node, pSICSData data){
|
||||
if(node->value.arrayLength != data->dataUsed){
|
||||
if(node->value.v.intArray != NULL){
|
||||
free(node->value.v.intArray);
|
||||
}
|
||||
node->value.arrayLength = data->dataUsed;
|
||||
node->value.v.intArray = malloc(data->dataUsed*sizeof(int));
|
||||
if(node->value.v.intArray == NULL){
|
||||
node->value.arrayLength = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
memcpy(node->value.v.intArray, data->data,
|
||||
data->dataUsed*sizeof(int));
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
static void copyFloatSicsData(pHdb node, pSICSData data){
|
||||
int i;
|
||||
float val;
|
||||
|
||||
if(node->value.arrayLength != data->dataUsed){
|
||||
if(node->value.v.floatArray != NULL){
|
||||
free(node->value.v.floatArray);
|
||||
}
|
||||
node->value.arrayLength = data->dataUsed;
|
||||
node->value.v.floatArray = malloc(data->dataUsed*sizeof(double));
|
||||
if(node->value.v.floatArray == NULL){
|
||||
node->value.arrayLength = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
for(i = 0; i < data->dataUsed; i++){
|
||||
getSICSDataFloat(data,i,&val);
|
||||
node->value.v.floatArray[i] = val;
|
||||
}
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
static hdbCallbackReturn SICSDataCallback(pHdb node, void *userData,
|
||||
pHdbMessage message){
|
||||
pSICSData self = (pSICSData)userData;
|
||||
pHdbDataMessage mm = NULL;
|
||||
int i, status;
|
||||
char script[256], error[1024];
|
||||
|
||||
assert(self != NULL);
|
||||
|
||||
/*
|
||||
* I have to make copies because the floats in SICSData
|
||||
* are floats but doubles in Hipdaba. Siiiigggghhhh!
|
||||
* But it is cleaner in some way anyway.
|
||||
*/
|
||||
if((mm = GetHdbGetMessage(message)) != NULL){
|
||||
memset(script,0,256);
|
||||
if(GetHdbProperty(node,"readscript", script,256) == 1){
|
||||
status = Tcl_Eval(InterpGetTcl(pServ->pSics),script);
|
||||
if(status != TCL_OK){
|
||||
snprintf(error,1023,"ERROR: Tcl returned error: %s",
|
||||
Tcl_GetStringResult(InterpGetTcl(pServ->pSics)));
|
||||
if(mm->callData != NULL){
|
||||
SCWrite((SConnection *)mm->callData, error, eError);
|
||||
return hdbAbort;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(node->value.dataType == HIPINTVARAR){
|
||||
copyIntSicsData(node, self);
|
||||
} else if(node->value.dataType == HIPFLOATVARAR){
|
||||
copyFloatSicsData(node, self);
|
||||
}
|
||||
return hdbContinue;
|
||||
}
|
||||
|
||||
if((mm = GetHdbSetMessage(message)) != NULL){
|
||||
if(node->value.dataType == HIPINTVARAR){
|
||||
for(i = 0; i < mm->v->arrayLength; i++){
|
||||
setSICSDataInt(self,i,mm->v->v.intArray[i]);
|
||||
}
|
||||
} else if(node->value.dataType == HIPFLOATVARAR){
|
||||
for(i = 0; i < mm->v->arrayLength; i++){
|
||||
setSICSDataFloat(self,i,(float)mm->v->v.floatArray[i]);
|
||||
}
|
||||
}
|
||||
memset(script,0,256);
|
||||
if(GetHdbProperty(node,"writescript", script,256) == 1){
|
||||
status = Tcl_Eval(InterpGetTcl(pServ->pSics),script);
|
||||
if(status != TCL_OK){
|
||||
snprintf(error,1023,"ERROR: Tcl returned error: %s",
|
||||
Tcl_GetStringResult(InterpGetTcl(pServ->pSics)));
|
||||
if(mm->callData != NULL){
|
||||
SCWrite((SConnection *)mm->callData, error, eError);
|
||||
return hdbAbort;
|
||||
}
|
||||
}
|
||||
}
|
||||
return hdbContinue;
|
||||
}
|
||||
|
||||
return hdbContinue;
|
||||
}
|
||||
/*============== interpreter function ==================================*/
|
||||
int SICSHdbAdapter(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]){
|
||||
pHdb path = NULL;
|
||||
pHdb node = NULL;
|
||||
pMotor pMot = NULL;
|
||||
pHistMem pHM = NULL;
|
||||
CommandList *pCom = NULL;
|
||||
pIDrivable pDriv = NULL;
|
||||
pSicsVariable pVar = NULL;
|
||||
char buffer[512];
|
||||
pCounter pCount = NULL;
|
||||
CountEntry hugo;
|
||||
pSICSData data = NULL;
|
||||
int type;
|
||||
pHdbCallback pCall = NULL;
|
||||
|
||||
if(!SCMatchRights(pCon,usMugger)){
|
||||
return 0;
|
||||
}
|
||||
if(argc < 4) {
|
||||
SCWrite(pCon,"ERROR: Insufficient number of arguments",eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
path = FindHdbNode(NULL,argv[1],pCon);
|
||||
if(path == NULL){
|
||||
SCWrite(pCon,"ERROR: path to attach object too not found",eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* look for motors
|
||||
*/
|
||||
pMot = (pMotor)FindCommandData(pSics,argv[2],"Motor");
|
||||
if(pMot != NULL){
|
||||
node = CreateMotorAdapter(argv[3],pMot);
|
||||
if(node == NULL){
|
||||
SCWrite(pCon,"ERROR: out of memory creating motor node",eError);
|
||||
return 0;
|
||||
}
|
||||
AddHipadabaChild(path,node,pCon);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
* look for drivables
|
||||
*/
|
||||
pDriv = FindDrivable(pSics,argv[2]);
|
||||
pCom = FindCommand(pSics,argv[2]);
|
||||
if(pDriv != NULL && pCom != NULL && pCom->pData != NULL){
|
||||
node = MakeSICSHdbDriv(argv[3],usUser,pCom->pData,HIPFLOAT);
|
||||
if(node == NULL){
|
||||
SCWrite(pCon,"ERROR: out of memory creating drivable node",eError);
|
||||
return 0;
|
||||
}
|
||||
SetHdbProperty(node,PRIVNAM,"user");
|
||||
SetHdbProperty(node,"type","drivable");
|
||||
SetHdbProperty(node,"sicsdev",argv[2]);
|
||||
AddHipadabaChild(path,node,pCon);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* look for SICS Variables
|
||||
*/
|
||||
pVar = (pSicsVariable)FindCommandData(pSics,argv[2],"SicsVariable");
|
||||
if(pVar != NULL){
|
||||
node = MakeSicsVarNode(pVar,argv[3]);
|
||||
if(node == NULL){
|
||||
SCWrite(pCon,"ERROR: out of memory creating SICS variable node",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
AddHipadabaChild(path,node,pCon);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* look for histogram memories
|
||||
*/
|
||||
pHM = (pHistMem)FindCommandData(pSics,argv[2],"HistMem");
|
||||
if(pHM != NULL){
|
||||
node = MakeHMDataNode(pHM,argv[3]);
|
||||
if(node == NULL){
|
||||
SCWrite(pCon,"ERROR: out of memory creating HM node",eError);
|
||||
return 0;
|
||||
}
|
||||
AddHipadabaChild(path,node,pCon);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* look for counters
|
||||
*/
|
||||
pCount = (pCounter)FindCommandData(pSics,argv[2],"SingleCounter");
|
||||
if(pCount != NULL){
|
||||
hugo.monitor = atoi(argv[3]);
|
||||
hugo.counter = pCount;
|
||||
hugo.node = path;
|
||||
if(countList < 0){
|
||||
countList = LLDcreate(sizeof(CountEntry));
|
||||
RegisterCallback(pCount->pCall, SCGetContext(pCon),
|
||||
COUNTSTART, CounterCallback,
|
||||
NULL, NULL);
|
||||
RegisterCallback(pCount->pCall, SCGetContext(pCon),
|
||||
COUNTEND, CounterCallback,
|
||||
NULL, NULL);
|
||||
RegisterCallback(pCount->pCall, SCGetContext(pCon),
|
||||
MONITOR, CounterCallback,
|
||||
NULL, NULL);
|
||||
}
|
||||
LLDnodeAppendFrom(countList,&hugo);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* look for SICSData
|
||||
*/
|
||||
data = (pSICSData)FindCommandData(pSics,argv[2],"SICSData");
|
||||
if(data != NULL){
|
||||
if(argc < 5){
|
||||
SCWrite(pCon,"ERROR: need type and name to create SICSData adapter",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
type = convertHdbType(argv[3]);
|
||||
if(type != HIPINTVARAR && type != HIPFLOATVARAR ){
|
||||
SCWrite(pCon,
|
||||
"ERROR: need intvarar or floatvarar type for SICSData adapter",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
node = MakeHipadabaNode(argv[4],type,0);
|
||||
if(node == NULL){
|
||||
SCWrite(pCon,"ERROR: out of memory in SICSHdbAdapter", eError);
|
||||
return 0;
|
||||
}
|
||||
pCall = MakeHipadabaCallback(SICSDataCallback,data,NULL);
|
||||
if(pCall == NULL){
|
||||
SCWrite(pCon,"ERROR: out of memory in SICSHdbAdapter", eError);
|
||||
return 0;
|
||||
}
|
||||
AppendHipadabaCallback(node,pCall);
|
||||
AddHipadabaChild(path,node,pCon);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
|
||||
snprintf(buffer,511,
|
||||
"ERROR: attaching this type of object: %s at %s not implemented",
|
||||
argv[2], argv[1]);
|
||||
SCWrite(pCon,buffer,eError);
|
||||
return 0;
|
||||
}
|
||||
/*====================== SubSample =========================================*/
|
||||
int HdbSubSample(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]){
|
||||
pHistMem pHM = NULL;
|
||||
pHdb node = NULL;
|
||||
int bank = 0, length = -1, status;
|
||||
HistInt *data = NULL;
|
||||
char *pPtr = NULL;
|
||||
hdbValue v;
|
||||
|
||||
if(argc < 4){
|
||||
SCWrite(pCon,"ERROR: insufficient number of arguments to HdbSubSample",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pPtr = strchr(argv[1],':');
|
||||
if(pPtr != NULL){
|
||||
*pPtr = '\0';
|
||||
pPtr++;
|
||||
sscanf(pPtr,"%d",&bank);
|
||||
}
|
||||
pHM = (pHistMem)FindCommandData(pSics,argv[1],"HistMem");
|
||||
node = FindHdbNode(NULL,argv[2], pCon);
|
||||
if(pHM == NULL || node == NULL){
|
||||
SCWrite(pCon,"ERROR: either histogram memory or node not found!",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(pHM->pDriv->SubSample == NULL){
|
||||
SCWrite(pCon,"ERROR: hm does not support subsampling", eError);
|
||||
return 0;
|
||||
}
|
||||
data = pHM->pDriv->SubSample(pHM->pDriv, pCon, bank, argv[3]);
|
||||
if(data == NULL){
|
||||
SCWrite(pCon,"ERROR: sub sampling failed", eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
v.dataType = HIPINTVARAR;
|
||||
v.arrayLength = data[0];
|
||||
v.v.intArray = data+1;
|
||||
|
||||
UpdateHipadabaPar(node,v,pCon);
|
||||
free(data);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
Reference in New Issue
Block a user