- Added a SICS to Hipadaba adapter

- Added a separate polling module to SICS
This commit is contained in:
koennecke
2006-12-07 14:04:17 +00:00
parent 5b727dc784
commit 78fce0127d
32 changed files with 1899 additions and 183 deletions

View File

@@ -6,19 +6,22 @@
* copyright: GPL
*
* Mark Koennecke, June 2006
*
* Introduced notification on tree changes, Mark Koennecke, November 2006
*/
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <ctype.h>
#include <sicshipadaba.h>
#include <sicshdbadapter.h>
#include "sicspoll.h"
#include <lld.h>
#include <stptok.h>
/*== there can be only hipadaba in SICS, some globals to care for that == */
static pHdb root = NULL;
static int scriptUpdate = -1;
static hdbUpdateTask taskData;
static pSicsPoll poller = NULL;
/*=============== common callback functions used for SICS ===========================*/
static int SICSCheckPermissionCallback(void *userData, void *callData, pHdb node,
hdbValue v){
@@ -79,7 +82,7 @@ static int SICSReadOnlyCallback(void *userData, void *callData, pHdb node,
return SICSCBRO;
}
/*-------------------------------------------------------------------------------------*/
static pHdbCallback MakeReadOnlyCallback(){
pHdbCallback MakeReadOnlyCallback(){
return MakeHipadabaCallback(SICSReadOnlyCallback, NULL,NULL,-1,-1);
}
/*-------------------------------------------------------------------------------------*/
@@ -101,6 +104,7 @@ pHdbCallback MakeSICSDriveCallback(void *sicsObject){
/*---------------------------------------------------------------------------------------*/
static int SICSReadDriveCallback(void *userData, void *callData, pHdb node,
hdbValue v){
static SConnection *defCon = NULL;
SConnection *pCon = NULL;
pDummy dum = NULL;
pIDrivable pDriv = NULL;
@@ -108,7 +112,11 @@ static int SICSReadDriveCallback(void *userData, void *callData, pHdb node,
pCon = (SConnection *)callData;
dum = (pDummy)userData;
assert(pCon != NULL && dum != NULL);
assert(dum != NULL);
if(defCon == NULL){
defCon = SCCreateDummyConnection(pServ->pSics);
}
pDriv = dum->pDescriptor->GetInterface(dum,DRIVEID);
assert(pDriv != NULL);
@@ -116,6 +124,12 @@ static int SICSReadDriveCallback(void *userData, void *callData, pHdb node,
value = pDriv->GetValue(dum,pCon);
node->value.v.doubleValue = (double)value;
v.v.doubleValue = (double)value;
} else {
if(defCon != NULL){
value = pDriv->GetValue(dum,defCon);
node->value.v.doubleValue = (double)value;
v.v.doubleValue = (double)value;
}
}
return 1;
}
@@ -172,6 +186,33 @@ pHdbCallback MakeNotifyCallback(SConnection *pCon, int id){
cbInfo->context = SCGetContext(pCon);
return MakeHipadabaCallback(SICSNotifyCallback, cbInfo,free,id,pCon->ident);
}
/*-------------------------------------------------------------------------*/
static int TreeChangeCallback(void *userData, void *callData, pHdb node,
hdbValue v){
char *path = NULL;
char buffer[1024];
HdbCBInfo *cbInfo = (HdbCBInfo *)userData;
if(cbInfo != NULL && cbInfo->pCon != NULL){
path = GetHipadabaPath(node);
snprintf(buffer,1023,"treechange = %s", path);
SCWriteInContext(cbInfo->pCon,buffer,eEvent,cbInfo->context);
free(path);
}
return 1;
}
/*-------------------------------------------------------------------------*/
pHdbCallback MakeTreeChangeCallback(SConnection *pCon, int id){
HdbCBInfo *cbInfo = NULL;
cbInfo = malloc(sizeof(HdbCBInfo));
if(cbInfo == NULL){
return NULL;
}
cbInfo->pCon = pCon;
cbInfo->context = SCGetContext(pCon);
return MakeHipadabaCallback(TreeChangeCallback, cbInfo,free,id,pCon->ident);
}
/*----------------------------------------------------------------------------------------*/
static int SICSScriptWriteCallback(void *userData, void *callData, pHdb node,
hdbValue v){
@@ -527,14 +568,14 @@ pHdb MakeSICSHdbPar(char *name, int priv, hdbValue v){
pHcb = MakeCheckPermissionCallback(priv);
if(pHcb == NULL){
DeleteHipadabaNode(result);
DeleteHipadabaNode(result,NULL);
return NULL;
}
AppendHipadabaCallback(result,HCBSET,pHcb);
pHcb = MakeSetUpdateCallback();
if(pHcb == NULL){
DeleteHipadabaNode(result);
DeleteHipadabaNode(result,NULL);
return NULL;
}
AppendHipadabaCallback(result,HCBSET,pHcb);
@@ -559,21 +600,21 @@ pHdb MakeSICSHdbDriv(char *name, int priv, void *sicsObject, int dataType){
pHcb = MakeCheckPermissionCallback(priv);
if(pHcb == NULL){
DeleteHipadabaNode(result);
DeleteHipadabaNode(result,NULL);
return NULL;
}
AppendHipadabaCallback(result,HCBSET,pHcb);
pHcb = MakeSICSDriveCallback(sicsObject);
if(pHcb == NULL){
DeleteHipadabaNode(result);
DeleteHipadabaNode(result,NULL);
return NULL;
}
AppendHipadabaCallback(result,HCBSET,pHcb);
pHcb = MakeSICSReadDriveCallback(sicsObject);
if(pHcb == NULL){
DeleteHipadabaNode(result);
DeleteHipadabaNode(result,NULL);
return NULL;
}
AppendHipadabaCallback(result,HCBREAD,pHcb);
@@ -592,21 +633,21 @@ pHdb MakeSICSMemPar(char *name, int priv, float *address){
pHcb = MakeCheckPermissionCallback(priv);
if(pHcb == NULL){
DeleteHipadabaNode(result);
DeleteHipadabaNode(result,NULL);
return NULL;
}
AppendHipadabaCallback(result,HCBSET,pHcb);
pHcb = MakeMemSetCallback(address);
if(pHcb == NULL){
DeleteHipadabaNode(result);
DeleteHipadabaNode(result,NULL);
return NULL;
}
AppendHipadabaCallback(result,HCBSET,pHcb);
pHcb = MakeMemReadCallback(address);
if(pHcb == NULL){
DeleteHipadabaNode(result);
DeleteHipadabaNode(result,NULL);
return NULL;
}
AppendHipadabaCallback(result,HCBREAD,pHcb);
@@ -626,7 +667,7 @@ pHdb MakeSICSROPar(char *name, hdbValue v){
pHcb = MakeReadOnlyCallback();
if(pHcb == NULL){
DeleteHipadabaNode(result);
DeleteHipadabaNode(result,NULL);
return NULL;
}
AppendHipadabaCallback(result,HCBSET,pHcb);
@@ -647,22 +688,22 @@ pHdb MakeSICSScriptPar(char *name, char *setScript, char *readScript,
pHcb = MakeSICSWriteScriptCallback(setScript);
if(pHcb == NULL){
DeleteHipadabaNode(result);
DeleteHipadabaNode(result,NULL);
return NULL;
}
AppendHipadabaCallback(result,HCBSET,pHcb);
pHcb = MakeSICSReadScriptCallback(readScript);
if(pHcb == NULL){
DeleteHipadabaNode(result);
DeleteHipadabaNode(result,NULL);
return NULL;
}
AppendHipadabaCallback(result,HCBREAD,pHcb);
/**
* put into the list of nodes to check with the update task
*/
LLDnodeAppend(scriptUpdate,&result);
/* LLDnodeAppend(scriptUpdate,&result); */
return result;
}
/*-------------------------------------------------------------------------*/
@@ -675,24 +716,28 @@ pHdb CreateSICSScriptPar(char *name, char *setScript, char *readScript,
static void removeNodeFromUpdateList(pHdb node){
pHdb current = NULL;
int status;
char *objName = NULL;
status = LLDnodePtr2First(scriptUpdate);
while(status != 0){
current = LLDnodePtr(scriptUpdate);
if(current == node){
LLDnodeDelete(scriptUpdate);
return;
}
status = LLDnodePtr2Next(scriptUpdate);
objName = GetHipadabaPath(node);
if(objName != NULL){
removePollObject(poller, objName);
free(objName);
}
}
/*-----------------------------------------------------------------------*/
static void SICSDeleteNodeData(pHdb node){
pHdb tmp = NULL;
if(node == NULL){
return;
}
removeNodeFromUpdateList(node);
while(node->child != NULL){
tmp = node->child;
node->child = node->child->next;
SICSDeleteNodeData(tmp);
}
DeleteCallbackChain(node->writeCallbacks);
DeleteCallbackChain(node->updateCallbacks);
DeleteCallbackChain(node->readCallbacks);
@@ -703,23 +748,17 @@ static void SICSDeleteNodeData(pHdb node){
ReleaseHdbValue(&node->value);
node->magic = 000000;
while(node->child != NULL){
tmp = node->child;
node->child = node->child->next;
SICSDeleteNodeData(tmp);
}
removeNodeFromUpdateList(node);
free(node);
}
/*--------------------------------------------------------------------------*/
void RemoveSICSPar(pHdb node){
void RemoveSICSPar(pHdb node, void *callData){
pHdb current = NULL, tmp = NULL;
if(node == NULL){
return;
}
RemoveHdbNodeFromParent(node);
RemoveHdbNodeFromParent(node,NULL);
SICSDeleteNodeData(node);
}
@@ -731,7 +770,7 @@ int AddSICSHdbPar(pHdb node, char *name, int priv, hdbValue v){
if(child == NULL){
return 0;
}
AddHipadabaChild(node,child);
AddHipadabaChild(node,child,NULL);
return 1;
}
/*---------------------------------------------------------------------------*/
@@ -742,7 +781,7 @@ int AddSICSHdbROPar(pHdb node, char *name, hdbValue v){
if(child == NULL){
return 0;
}
AddHipadabaChild(node,child);
AddHipadabaChild(node,child,NULL);
return 1;
}
/*--------------------------------------------------------------------------*/
@@ -763,25 +802,25 @@ int AddSICSHdbMemPar(pHdb node, char *name, int priv,
pHcb = MakeCheckPermissionCallback(priv);
if(pHcb == NULL){
DeleteHipadabaNode(child);
DeleteHipadabaNode(child,NULL);
return 0;
}
AppendHipadabaCallback(child,HCBSET,pHcb);
pHcb = MakeMemGenSetCallback(data);
if(pHcb == NULL){
DeleteHipadabaNode(child);
DeleteHipadabaNode(child,NULL);
return 0;
}
AppendHipadabaCallback(child,HCBSET,pHcb);
pHcb = MakeMemGenReadCallback(data);
if(pHcb == NULL){
DeleteHipadabaNode(child);
DeleteHipadabaNode(child,NULL);
return 0;
}
AppendHipadabaCallback(child,HCBREAD,pHcb);
AddHipadabaChild(node,child);
AddHipadabaChild(node,child,NULL);
return 1;
}
@@ -887,13 +926,16 @@ int SICSHdbSetPar(void *obj, SConnection *pCon,
int InstallSICSNotify(pHdb node, SConnection *pCon, int id, int recurse){
pHdb currentChild = NULL;
pHdbCallback noty = NULL;
pHdbCallback treeChange = NULL;
treeChange = MakeTreeChangeCallback(pCon,id);
noty = MakeNotifyCallback(pCon,id);
if(noty == NULL){
if(noty == NULL || treeChange == NULL){
SCWrite(pCon,"ERROR: out of memory installing callback", eError);
return 0;
}
AppendHipadabaCallback(node, HCBUPDATE, noty);
AppendHipadabaCallback(node, HCBTREE, treeChange);
if(recurse == 1){
currentChild = node->child;
@@ -1041,60 +1083,6 @@ void SaveSICSHipadaba(FILE *fd, pHdb node, char *prefix){
currentChild = currentChild->next;
}
}
/*---------------------------------------------------------------------------*/
int SICSHipadabaTask(void *pData){
pHdbUpdateTask self = NULL;
hdbValue old, newValue;
pHdb currentNode = NULL;
int status;
self = (pHdbUpdateTask)pData;
assert(self != NULL);
if(self->iEnd == 1){
return 0;
}
if(LLDcheck(self->updateList) == LIST_EMPTY){
return 1;
}
memset(&old,0,sizeof(hdbValue));
memset(&newValue,0,sizeof(hdbValue));
currentNode = (pHdb)LLDnodePtr(self->updateList);
if(currentNode != NULL){
old.dataType = currentNode->value.dataType;
copyHdbValue(&currentNode->value,&old);
if(GetHipadabaPar(currentNode,&newValue, self->pCon) == 1){
if(!compareHdbValue(old,newValue)){
UpdateHipadabaPar(currentNode,newValue,self->pCon);
}
}
ReleaseHdbValue(&old);
ReleaseHdbValue(&newValue);
}
status = LLDnodePtr2Next(self->updateList);
if(status == 0){
LLDnodePtr2First(self->updateList);
}
return 1;
}
/*---------------------------------------------------------------------------*/
void SICSHipadabaSignal(void *pData, int iSignal, void *pSigData){
pHdbUpdateTask self = NULL;
int *iInt;
self = (pHdbUpdateTask)pData;
if(iSignal == SICSINT){
iInt = (int *)pSigData;
if(*iInt == eEndServer){
self->iEnd = 1;
}
}
}
/*================ value helpers ============================================*/
pDynString formatValue(hdbValue v){
pDynString result = NULL;
@@ -1162,8 +1150,10 @@ static char *getNextHdbNumber(char *pStart, char pNumber[80]){
static int adjustDataLength(hdbValue *v, char *data){
char number[80];
int count = 0;
char *pPtr = NULL;
while(getNextHdbNumber(data,number) != NULL){
pPtr = data;
while((pPtr = getNextHdbNumber(pPtr,number)) != NULL){
count++;
}
if(count != v->arrayLength){
@@ -1315,6 +1305,7 @@ static int MakeHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
char *pPtr = NULL;
pHdb parent = NULL;
pHdb child = NULL;
char buffer[512], buffer2[512];
if(!SCMatchRights(pCon,usMugger)){
return 0;
@@ -1351,7 +1342,8 @@ static int MakeHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
}
/* split off last path element */
pPtr = strrchr(argv[1],'/');
strncpy(buffer,argv[1],511);
pPtr = strrchr(buffer,'/');
if(pPtr == NULL){
SCWrite(pCon,"ERROR: invalid path specification",
eError);
@@ -1362,10 +1354,12 @@ static int MakeHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
if(strlen(pPtr) < 1) {
parent = root;
} else {
parent = GetHipadabaNode(root,argv[1]);
parent = GetHipadabaNode(root,buffer);
}
if(parent == NULL){
SCWrite(pCon,"ERROR: parent for new node does not exist",eError);
snprintf(buffer2,512,"ERROR: parent %s for new node does not exist",
buffer);
SCWrite(pCon,buffer2,eError);
return 0;
}
if(type != HIPNONE){
@@ -1378,7 +1372,7 @@ static int MakeHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
return 0;
}
AddHipadabaChild(parent,child);
AddHipadabaChild(parent,child,pCon);
SCSendOK(pCon);
return 1;
}
@@ -1390,6 +1384,10 @@ static int MakeHdbScriptNode(SConnection *pCon, SicsInterp *pSics, void *pData,
pHdb parent = NULL;
pHdb child = NULL;
pHdb current = NULL;
char *urgv[] = {"5", NULL};
char driver[] = {"hdb"};
char buffer[512], buffer2[512];
if(!SCMatchRights(pCon,usMugger)){
return 0;
@@ -1422,7 +1420,8 @@ static int MakeHdbScriptNode(SConnection *pCon, SicsInterp *pSics, void *pData,
}
/* split off last path element */
pPtr = strrchr(argv[1],'/');
strncpy(buffer,argv[1],511);
pPtr = strrchr(buffer,'/');
if(pPtr == NULL){
SCWrite(pCon,"ERROR: invalid path specification",
eError);
@@ -1433,10 +1432,12 @@ static int MakeHdbScriptNode(SConnection *pCon, SicsInterp *pSics, void *pData,
if(strlen(pPtr) < 1) {
parent = root;
} else {
parent = GetHipadabaNode(root,argv[1]);
parent = GetHipadabaNode(root,buffer);
}
if(parent == NULL){
SCWrite(pCon,"ERROR: parent for new node does not exist",eError);
snprintf(buffer2,512,"ERROR: parent %s for new node does not exist",
buffer);
SCWrite(pCon,buffer2,eError);
return 0;
}
child = MakeSICSScriptPar(pPtr, argv[3], argv[2],
@@ -1446,11 +1447,32 @@ static int MakeHdbScriptNode(SConnection *pCon, SicsInterp *pSics, void *pData,
return 0;
}
AddHipadabaChild(parent,child);
AddHipadabaChild(parent,child,pCon);
/*
* have it polled automatically
*/
addPollObject(poller,pCon, GetHipadabaPath(child),driver,1,urgv);
SCSendOK(pCon);
return 1;
}
/*------------------------------------------------------------------------------*/
static int isNodeProtected(pHdb node){
pHdb current = NULL;
if(node->protected == 1){
return 1;
}
current = node->child;
while(current != NULL){
if(isNodeProtected(current)){
return 1;
}
current = current->next;
}
return 0;
}
/*-----------------------------------------------------------------------------------------*/
static int DeleteHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){
@@ -1469,7 +1491,13 @@ static int DeleteHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
SCWrite(pCon,"ERROR: node to delete not found",eError);
return 0;
}
RemoveSICSPar(killNode);
if(isNodeProtected(killNode)){
SCWrite(pCon,"ERROR: this node or one of its children is protected",
eError);
return 0;
}
RemoveSICSPar(killNode, pCon);
SCSendOK(pCon);
return 1;
}
@@ -1927,7 +1955,7 @@ static int LinkHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
return 0;
}
AddHipadabaChild(node,pDum->pDescriptor->parNode);
AddHipadabaChild(node,pDum->pDescriptor->parNode,pCon);
if(argc > 3){
if(pDum->pDescriptor->parNode->name != NULL){
@@ -1939,41 +1967,75 @@ static int LinkHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
SCSendOK(pCon);
return 1;
}
/*-------------------------------------------------------------------------*/
static int ChainCallback(void *userData, void *callData, pHdb node,
hdbValue v){
pHdb slave = (pHdb)userData;
hdbValue vv, old;
if(slave != NULL){
old = slave->value;
memset(&vv,0,sizeof(hdbValue));
GetHipadabaPar(slave,&vv,callData);
if(!compareHdbValue(old,vv)){
UpdateHipadabaPar(slave, vv, callData);
}
}
return 1;
}
/*--------------------------------------------------------------------------*/
static int ChainHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){
pHdb master = NULL, slave = NULL;
char buffer[512];
pHdbCallback kalle = NULL;
if(argc < 3) {
SCWrite(pCon,"ERROR: insufficent number of arguments to hchain",
eError);
}
if(!SCMatchRights(pCon,usMugger)){
return 0;
}
slave = GetHipadabaNode(root,argv[1]);
if(slave == NULL){
snprintf(buffer,511,"ERROR: slave %s not found",argv[1]);
SCWrite(pCon,buffer,eError);
return 0;
}
master = GetHipadabaNode(root,argv[2]);
if(master == NULL){
snprintf(buffer,511,"ERROR: master %s not found",argv[1]);
SCWrite(pCon,buffer,eError);
return 0;
}
kalle = MakeHipadabaCallback(ChainCallback,slave, NULL, -1,-1);
if(kalle == NULL){
SCWrite(pCon,"ERROR: out of memory creating callback",eError);
return 0;
}
AppendHipadabaCallback(master,HCBUPDATE, kalle);
SCSendOK(pCon);
return 1;
}
/*---------------------------------------------------------------------------*/
void killSICSHipadaba(){
if(root != NULL){
DeleteHipadabaNode(root);
DeleteHipadabaNode(root,NULL);
}
root = NULL;
/**
* children have already been removed when killing the
* main tree
*/
if(scriptUpdate > 0 && LLDcheck(scriptUpdate) != LIST_EMPTY){
LLDdelete(scriptUpdate);
}
}
/*---------------------------------------------------------------------------*/
int InstallSICSHipadaba(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){
root = MakeHipadabaNode("/",HIPNONE,0);
scriptUpdate = LLDcreate(sizeof(void *));
taskData.updateList = scriptUpdate;
taskData.iEnd = 0;
taskData.pCon = SCCreateDummyConnection(pSics);
if(taskData.pCon == NULL){
SCWrite(pCon,"ERROR: out of memory creating Hipadaba",eError);
return 0;
}
TaskRegister(pServ->pTasker,
SICSHipadabaTask,
SICSHipadabaSignal,
NULL,
&taskData,1);
AddCommand(pSics,"hmake", MakeHdbNode, NULL, NULL);
AddCommand(pSics,"hmakescript", MakeHdbScriptNode, NULL, NULL);
AddCommand(pSics,"hattach", SICSHdbAdapter, NULL, NULL);
AddCommand(pSics,"hdel", DeleteHdbNode, NULL, NULL);
AddCommand(pSics,"hset", SetHdbNode, NULL, NULL);
AddCommand(pSics,"hget", GetHdbNode, NULL, NULL);
@@ -1983,6 +2045,10 @@ int InstallSICSHipadaba(SConnection *pCon, SicsInterp *pSics, void *pData,
AddCommand(pSics,"hlink", LinkHdbNode, NULL, NULL);
AddCommand(pSics,"hinfo", HdbNodeInfo, NULL, NULL);
AddCommand(pSics,"hval", HdbNodeVal, NULL, NULL);
AddCommand(pSics,"hchain", ChainHdbNode, NULL, NULL);
InstallSICSPoll(pCon,pSics,pData,argc,argv);
poller = (pSicsPoll)FindCommandData(pSics,"sicspoll","SicsPoll");
return 1;
}