- Improvements to Hipadaba
- New chopper driver for MARS Juelich chopper system - New docbook based SANS manual SKIPPED: psi/amorcomp.c psi/amordrive.h psi/amorset.c psi/amorset.h psi/amorset.tex psi/amorset.w psi/julcho.c psi/libpsi.a psi/make_gen psi/psi.c
This commit is contained in:
4
choco.c
4
choco.c
@ -99,7 +99,7 @@
|
|||||||
|
|
||||||
if(argc < 2)
|
if(argc < 2)
|
||||||
{
|
{
|
||||||
sprintf(pMessage, "ERROR: Ragument required for %s",argv[0]);
|
sprintf(pMessage, "ERROR: argument required for %s",argv[0]);
|
||||||
SCWrite(pCon,pMessage,eError);
|
SCWrite(pCon,pMessage,eError);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -149,7 +149,7 @@
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*----------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------*/
|
||||||
static void KillChoco(void *pData)
|
void KillChoco(void *pData)
|
||||||
{
|
{
|
||||||
pChoco self = NULL;
|
pChoco self = NULL;
|
||||||
|
|
||||||
|
1
choco.h
1
choco.h
@ -19,6 +19,7 @@
|
|||||||
pCodri CHGetDriver(pChoco self);
|
pCodri CHGetDriver(pChoco self);
|
||||||
int CHList(pChoco self, SConnection *pCon, char *name);
|
int CHList(pChoco self, SConnection *pCon, char *name);
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
|
void KillChoco(void *pData);
|
||||||
int ChocoAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
int ChocoAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
int argc, char *argv[]);
|
int argc, char *argv[]);
|
||||||
int ChocoFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
|
int ChocoFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
@ -85,7 +85,7 @@ controller driver.
|
|||||||
\item[SetPar] tries to set the parameter parname to the value
|
\item[SetPar] tries to set the parameter parname to the value
|
||||||
fValue. The last is floating point which covers the frequent
|
fValue. The last is floating point which covers the frequent
|
||||||
occurence of numeric values.
|
occurence of numeric values.
|
||||||
\item[SetPar2] The same as SetPar but uses test string as input for
|
\item[SetPar2] The same as SetPar but uses text string as input for
|
||||||
parameter setting.
|
parameter setting.
|
||||||
\item[GetPar] retrieves the parameter parname formatted as text. The
|
\item[GetPar] retrieves the parameter parname formatted as text. The
|
||||||
value is put into the buffer pBuffer. iBufLen is the maximum number of
|
value is put into the buffer pBuffer. iBufLen is the maximum number of
|
||||||
@ -129,6 +129,7 @@ $\langle$chocoint {\footnotesize ?}$\rangle\equiv$
|
|||||||
\mbox{}\verb@ pCodri CHGetDriver(pChoco self);@\\
|
\mbox{}\verb@ pCodri CHGetDriver(pChoco self);@\\
|
||||||
\mbox{}\verb@ int CHList(pChoco self, SConnection *pCon, char *name);@\\
|
\mbox{}\verb@ int CHList(pChoco self, SConnection *pCon, char *name);@\\
|
||||||
\mbox{}\verb@/*------------------------------------------------------------------------*/@\\
|
\mbox{}\verb@/*------------------------------------------------------------------------*/@\\
|
||||||
|
\mbox{}\verb@ void KillChoco(void *pData);@\\
|
||||||
\mbox{}\verb@ int ChocoAction(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
\mbox{}\verb@ int ChocoAction(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||||
\mbox{}\verb@ int argc, char *argv[]);@\\
|
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||||
\mbox{}\verb@ int ChocoFactory(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
\mbox{}\verb@ int ChocoFactory(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||||
@ -366,8 +367,7 @@ $\langle$evada {\footnotesize ?}$\rangle\equiv$
|
|||||||
\subsubsection{To Do}
|
\subsubsection{To Do}
|
||||||
This scheme seems to be quite promising for handling many SICS
|
This scheme seems to be quite promising for handling many SICS
|
||||||
objects. The following enhancements could be considered. Allow to set
|
objects. The following enhancements could be considered. Allow to set
|
||||||
certain primitive parameters without a drivable interface. And add an
|
certain primitive parameters without a drivable interface.
|
||||||
adapter for an environment variable in the controller.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
6
choco.w
6
choco.w
@ -72,7 +72,7 @@ controller driver.
|
|||||||
\item[SetPar] tries to set the parameter parname to the value
|
\item[SetPar] tries to set the parameter parname to the value
|
||||||
fValue. The last is floating point which covers the frequent
|
fValue. The last is floating point which covers the frequent
|
||||||
occurence of numeric values.
|
occurence of numeric values.
|
||||||
\item[SetPar2] The same as SetPar but uses test string as input for
|
\item[SetPar2] The same as SetPar but uses text string as input for
|
||||||
parameter setting.
|
parameter setting.
|
||||||
\item[GetPar] retrieves the parameter parname formatted as text. The
|
\item[GetPar] retrieves the parameter parname formatted as text. The
|
||||||
value is put into the buffer pBuffer. iBufLen is the maximum number of
|
value is put into the buffer pBuffer. iBufLen is the maximum number of
|
||||||
@ -111,6 +111,7 @@ includes:
|
|||||||
pCodri CHGetDriver(pChoco self);
|
pCodri CHGetDriver(pChoco self);
|
||||||
int CHList(pChoco self, SConnection *pCon, char *name);
|
int CHList(pChoco self, SConnection *pCon, char *name);
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
|
void KillChoco(void *pData);
|
||||||
int ChocoAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
int ChocoAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
int argc, char *argv[]);
|
int argc, char *argv[]);
|
||||||
int ChocoFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
|
int ChocoFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
@ -267,8 +268,7 @@ controller driver:
|
|||||||
\subsubsection{To Do}
|
\subsubsection{To Do}
|
||||||
This scheme seems to be quite promising for handling many SICS
|
This scheme seems to be quite promising for handling many SICS
|
||||||
objects. The following enhancements could be considered. Allow to set
|
objects. The following enhancements could be considered. Allow to set
|
||||||
certain primitive parameters without a drivable interface. And add an
|
certain primitive parameters without a drivable interface.
|
||||||
adapter for an environment variable in the controller.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
18
devexec.c
18
devexec.c
@ -9,6 +9,9 @@
|
|||||||
revised for use with tasker: Mark Koennecke, September 1997
|
revised for use with tasker: Mark Koennecke, September 1997
|
||||||
Locking added: Mark Koennecke, August 2002
|
Locking added: Mark Koennecke, August 2002
|
||||||
|
|
||||||
|
Refactored and instrumentation for instrument staticstics added.
|
||||||
|
Mark Koennecke, July 2006
|
||||||
|
|
||||||
Copyright:
|
Copyright:
|
||||||
|
|
||||||
Labor fuer Neutronenstreuung
|
Labor fuer Neutronenstreuung
|
||||||
@ -52,6 +55,7 @@
|
|||||||
#include "devexec.h"
|
#include "devexec.h"
|
||||||
#include "status.h"
|
#include "status.h"
|
||||||
#include "lld.h"
|
#include "lld.h"
|
||||||
|
#include "commandlog.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#define DEBUG 1
|
#define DEBUG 1
|
||||||
@ -64,6 +68,13 @@
|
|||||||
char *name;
|
char *name;
|
||||||
commandContext comCon;
|
commandContext comCon;
|
||||||
} DevEntry, *pDevEntry;
|
} DevEntry, *pDevEntry;
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
typedef struct {
|
||||||
|
pExeList self;
|
||||||
|
pDevEntry pDev;
|
||||||
|
pICountable pCountInt;
|
||||||
|
pIDrivable pDrivInt;
|
||||||
|
}checkContext, *pCheckContext;
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
static pDevEntry CreateDevEntry(pObjectDescriptor pDes, void *pData,
|
static pDevEntry CreateDevEntry(pObjectDescriptor pDes, void *pData,
|
||||||
float fVal, char *name)
|
float fVal, char *name)
|
||||||
@ -402,7 +413,7 @@
|
|||||||
|
|
||||||
/* Sometimes this gets called, though nothing is running. There are
|
/* Sometimes this gets called, though nothing is running. There are
|
||||||
cases where this is feasible for maintainance, but in some cases it
|
cases where this is feasible for maintainance, but in some cases it
|
||||||
is pure rubbish, because nothing runs. This will ne checkd here.
|
is pure rubbish, because nothing runs. This will be checked here.
|
||||||
*/
|
*/
|
||||||
if((self->pOwner == NULL) || (LLDcheck(self->iList) == LIST_EMPTY))
|
if((self->pOwner == NULL) || (LLDcheck(self->iList) == LIST_EMPTY))
|
||||||
{
|
{
|
||||||
@ -421,10 +432,7 @@
|
|||||||
LLDnodeDataTo(self->iList,&pDev);
|
LLDnodeDataTo(self->iList,&pDev);
|
||||||
if(pDev)
|
if(pDev)
|
||||||
{
|
{
|
||||||
/*
|
SCPushContext(self->pOwner, pDev->comCon.transID, pDev->comCon.deviceID);
|
||||||
SCSetContext(self->pOwner,pDev->cmdID,pDev->name);
|
|
||||||
*/
|
|
||||||
SCPushContext(self->pOwner, pDev->comCon.transID, pDev->comCon.deviceID);
|
|
||||||
|
|
||||||
pDrivInt = pDev->pDescriptor->GetInterface(pDev->pData,DRIVEID);
|
pDrivInt = pDev->pDescriptor->GetInterface(pDev->pData,DRIVEID);
|
||||||
pCountInt = pDev->pDescriptor->GetInterface(pDev->pData,COUNTID);
|
pCountInt = pDev->pDescriptor->GetInterface(pDev->pData,COUNTID);
|
||||||
|
5284
doc/user/sansdocbook.xml
Normal file
5284
doc/user/sansdocbook.xml
Normal file
File diff suppressed because it is too large
Load Diff
35
hipadaba.c
35
hipadaba.c
@ -268,6 +268,7 @@ hdbValue makeHdbValue(int datatype, int length){
|
|||||||
|
|
||||||
switch(datatype){
|
switch(datatype){
|
||||||
case HIPINTAR:
|
case HIPINTAR:
|
||||||
|
case HIPINTVARAR:
|
||||||
val.arrayLength = length;
|
val.arrayLength = length;
|
||||||
val.v.intArray = malloc(length*sizeof(long));
|
val.v.intArray = malloc(length*sizeof(long));
|
||||||
if(val.v.intArray != NULL){
|
if(val.v.intArray != NULL){
|
||||||
@ -275,6 +276,7 @@ hdbValue makeHdbValue(int datatype, int length){
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case HIPFLOATAR:
|
case HIPFLOATAR:
|
||||||
|
case HIPFLOATVARAR:
|
||||||
val.arrayLength = length;
|
val.arrayLength = length;
|
||||||
val.v.floatArray = malloc(length*sizeof(double));
|
val.v.floatArray = malloc(length*sizeof(double));
|
||||||
if(val.v.floatArray != NULL){
|
if(val.v.floatArray != NULL){
|
||||||
@ -312,7 +314,7 @@ hdbValue MakeHdbText(char *initText){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
hdbValue MakeHdbIntArrray(int length, long *data){
|
hdbValue MakeHdbIntArray(int length, long *data){
|
||||||
hdbValue result;
|
hdbValue result;
|
||||||
|
|
||||||
result.dataType = HIPINTAR;
|
result.dataType = HIPINTAR;
|
||||||
@ -338,11 +340,13 @@ void ReleaseHdbValue(hdbValue *v){
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case HIPINTAR:
|
case HIPINTAR:
|
||||||
|
case HIPINTVARAR:
|
||||||
if(v->v.intArray != NULL){
|
if(v->v.intArray != NULL){
|
||||||
free(v->v.intArray);
|
free(v->v.intArray);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case HIPFLOATAR:
|
case HIPFLOATAR:
|
||||||
|
case HIPFLOATVARAR:
|
||||||
if(v->v.floatArray != NULL){
|
if(v->v.floatArray != NULL){
|
||||||
free(v->v.floatArray);
|
free(v->v.floatArray);
|
||||||
}
|
}
|
||||||
@ -382,6 +386,7 @@ int compareHdbValue(hdbValue v1, hdbValue v2){
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case HIPINTAR:
|
case HIPINTAR:
|
||||||
|
case HIPINTVARAR:
|
||||||
if(v1.arrayLength != v2.arrayLength){
|
if(v1.arrayLength != v2.arrayLength){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -393,6 +398,7 @@ int compareHdbValue(hdbValue v1, hdbValue v2){
|
|||||||
return 1;
|
return 1;
|
||||||
break;
|
break;
|
||||||
case HIPFLOATAR:
|
case HIPFLOATAR:
|
||||||
|
case HIPFLOATVARAR:
|
||||||
if(v1.arrayLength != v2.arrayLength){
|
if(v1.arrayLength != v2.arrayLength){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -430,6 +436,7 @@ pHdb MakeHipadabaNode(char *name, int datatype, int length){
|
|||||||
pNew->value.dataType = datatype;
|
pNew->value.dataType = datatype;
|
||||||
switch(datatype){
|
switch(datatype){
|
||||||
case HIPINTAR:
|
case HIPINTAR:
|
||||||
|
case HIPINTVARAR:
|
||||||
pNew->value.arrayLength = length;
|
pNew->value.arrayLength = length;
|
||||||
pNew->value.v.intArray = malloc(length*sizeof(long));
|
pNew->value.v.intArray = malloc(length*sizeof(long));
|
||||||
if(pNew->value.v.intArray == NULL){
|
if(pNew->value.v.intArray == NULL){
|
||||||
@ -438,6 +445,7 @@ pHdb MakeHipadabaNode(char *name, int datatype, int length){
|
|||||||
memset(pNew->value.v.intArray,0,length*sizeof(long));
|
memset(pNew->value.v.intArray,0,length*sizeof(long));
|
||||||
break;
|
break;
|
||||||
case HIPFLOATAR:
|
case HIPFLOATAR:
|
||||||
|
case HIPFLOATVARAR:
|
||||||
pNew->value.arrayLength = length;
|
pNew->value.arrayLength = length;
|
||||||
pNew->value.v.floatArray = malloc(length*sizeof(double));
|
pNew->value.v.floatArray = malloc(length*sizeof(double));
|
||||||
if(pNew->value.v.floatArray == NULL){
|
if(pNew->value.v.floatArray == NULL){
|
||||||
@ -498,13 +506,25 @@ int isHdbNodeValid(pHdb node){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
pHdb GetHipadabaNode(pHdb root, char *path){
|
pHdb GetHipadabaNode(pHdb root, char *puth){
|
||||||
pHdb resultNode = NULL;
|
pHdb resultNode = NULL;
|
||||||
char *separator = NULL;
|
char *separator = NULL;
|
||||||
|
char *path = NULL, *pathData;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* I need to make a copy in order to get the path in writable memory.
|
||||||
|
* Otherwise we SEGFAULT in hdbTrim when this function is called with
|
||||||
|
* a string constant in puth
|
||||||
|
*/
|
||||||
|
pathData = strdup(puth);
|
||||||
|
path = pathData;
|
||||||
|
if(path == NULL){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
path = hdbTrim(path);
|
path = hdbTrim(path);
|
||||||
|
|
||||||
if(strcmp(path,"/") == 0 || strlen(path) == 0){
|
if(strcmp(path,"/") == 0 || strlen(path) == 0){
|
||||||
|
free(pathData);
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -514,15 +534,20 @@ pHdb GetHipadabaNode(pHdb root, char *path){
|
|||||||
|
|
||||||
separator = strchr(path,'/');
|
separator = strchr(path,'/');
|
||||||
if(separator == NULL){
|
if(separator == NULL){
|
||||||
return locateChild(root,path);
|
resultNode = locateChild(root,path);
|
||||||
|
free(pathData);
|
||||||
|
return resultNode;
|
||||||
} else {
|
} else {
|
||||||
*separator = '\0';
|
*separator = '\0';
|
||||||
resultNode = locateChild(root, path);
|
resultNode = locateChild(root, path);
|
||||||
if(resultNode == NULL){
|
if(resultNode == NULL){
|
||||||
|
free(pathData);
|
||||||
return NULL;
|
return NULL;
|
||||||
} else {
|
} else {
|
||||||
separator++;
|
separator++;
|
||||||
return GetHipadabaNode(resultNode,separator);
|
resultNode = GetHipadabaNode(resultNode,separator);
|
||||||
|
free(pathData);
|
||||||
|
return resultNode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -715,6 +740,7 @@ int copyHdbValue(hdbValue *source, hdbValue *target){
|
|||||||
target->v.text = strdup(source->v.text);
|
target->v.text = strdup(source->v.text);
|
||||||
break;
|
break;
|
||||||
case HIPINTAR:
|
case HIPINTAR:
|
||||||
|
case HIPINTVARAR:
|
||||||
if(target->arrayLength != source->arrayLength){
|
if(target->arrayLength != source->arrayLength){
|
||||||
if(target->v.intArray != NULL){
|
if(target->v.intArray != NULL){
|
||||||
free(target->v.intArray);
|
free(target->v.intArray);
|
||||||
@ -731,6 +757,7 @@ int copyHdbValue(hdbValue *source, hdbValue *target){
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case HIPFLOATAR:
|
case HIPFLOATAR:
|
||||||
|
case HIPFLOATVARAR:
|
||||||
if(target->arrayLength != source->arrayLength){
|
if(target->arrayLength != source->arrayLength){
|
||||||
if(target->v.floatArray != NULL){
|
if(target->v.floatArray != NULL){
|
||||||
free(target->v.floatArray);
|
free(target->v.floatArray);
|
||||||
|
44
hipadaba.h
44
hipadaba.h
@ -1,19 +1,21 @@
|
|||||||
/**
|
/**
|
||||||
* Hipadaba is a hierarchical database of parameters. Parameters can be of various types.
|
* Hipadaba is a hierarchical database of parameters. Parameters can be of
|
||||||
* What happens when a parameter is being set, updated or read is largely determined
|
* various types. What happens when a parameter is being set, updated or read
|
||||||
* through callbacks which can be registered on parameters. This can implement permission
|
* is largely determined through callbacks which can be registered on
|
||||||
* checking, range checking, automatic notifications and whatever comes up.
|
* parameters. This can implement permission checking, range checking,
|
||||||
|
* automatic notifications and whatever comes up.
|
||||||
*
|
*
|
||||||
* There is some subtlety here between updating and setting a parameter. The issue is
|
* There is some subtlety here between updating and setting a parameter. The
|
||||||
* that in instrument control there are two types of parameters: Instant program parameters
|
* issue is that in instrument control there are two types of parameters:
|
||||||
* and external parameters like motors which are dependent on some possibly slow and
|
* Instant program parameters and external parameters like motors which are
|
||||||
* inaccurate hardware. Let us consider the latter: Setting the parameter should do all
|
* dependent on some possibly slow and inaccurate hardware. Let us consider
|
||||||
* necessary checks on the parameter and tell the hardware where to go. Some internal code
|
* the latter: Setting the parameter should do all necessary checks on the
|
||||||
* may be watching the hardware; that code should use Update which justs sets a new value
|
* parameter and tell the hardware where to go. Some internal code may be
|
||||||
* and invokes callbacks which notify interested parties about the new parameter value.
|
* watching the hardware; that code should use Update which justs sets a new value
|
||||||
* For program parameters, a callback shall be installed which calls update directly
|
* and invokes callbacks which notify interested parties about the new parameter
|
||||||
* after setting the parameter. Thus notification callbacks shall always be connected to the
|
* value. For program parameters, a callback shall be installed which calls update
|
||||||
* update chain.
|
* directly after setting the parameter. Thus notification callbacks shall always be
|
||||||
|
* connected to the update chain.
|
||||||
*
|
*
|
||||||
* copyright: GPL
|
* copyright: GPL
|
||||||
*
|
*
|
||||||
@ -23,12 +25,14 @@
|
|||||||
#define HIPADABA
|
#define HIPADABA
|
||||||
|
|
||||||
/*------- datatypes */
|
/*------- datatypes */
|
||||||
#define HIPNONE -1
|
#define HIPNONE -1
|
||||||
#define HIPINT 0
|
#define HIPINT 0
|
||||||
#define HIPFLOAT 1
|
#define HIPFLOAT 1
|
||||||
#define HIPTEXT 2
|
#define HIPTEXT 2
|
||||||
#define HIPINTAR 3
|
#define HIPINTAR 3
|
||||||
#define HIPFLOATAR 4
|
#define HIPFLOATAR 4
|
||||||
|
#define HIPINTVARAR 5
|
||||||
|
#define HIPFLOATVARAR 6
|
||||||
/* -------- callback types */
|
/* -------- callback types */
|
||||||
#define HCBSET 0
|
#define HCBSET 0
|
||||||
#define HCBUPDATE 1
|
#define HCBUPDATE 1
|
||||||
|
4
lld.c
4
lld.c
@ -208,6 +208,10 @@ void LLDdelete( int List )
|
|||||||
|
|
||||||
assert( (unsigned) List < ListCount );
|
assert( (unsigned) List < ListCount );
|
||||||
|
|
||||||
|
if(ListControl == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
Tmp = ListControl[ List ].first ; /* dummies are also deleted !!! */
|
Tmp = ListControl[ List ].first ; /* dummies are also deleted !!! */
|
||||||
while( NULL != Tmp ) /* still assuming last node has */
|
while( NULL != Tmp ) /* still assuming last node has */
|
||||||
{ /* a NULL next pointer ... */
|
{ /* a NULL next pointer ... */
|
||||||
|
2
motor.c
2
motor.c
@ -492,7 +492,7 @@ extern void KillPiPiezo(void *pData);
|
|||||||
|
|
||||||
pM = (pMotor)self;
|
pM = (pMotor)self;
|
||||||
|
|
||||||
MotorHalt(pM);
|
/* MotorHalt(pM); */
|
||||||
|
|
||||||
if(pM->name)
|
if(pM->name)
|
||||||
free(pM->name);
|
free(pM->name);
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#include "site.h"
|
#include "site.h"
|
||||||
#include "tcldrivable.h"
|
#include "tcldrivable.h"
|
||||||
#include "nserver.h"
|
#include "nserver.h"
|
||||||
|
#include "sicshipadaba.h"
|
||||||
|
|
||||||
int ServerSetupInterrupt(int iPort, pNetRead pNet, pTaskMan pTasker);
|
int ServerSetupInterrupt(int iPort, pNetRead pNet, pTaskMan pTasker);
|
||||||
/*
|
/*
|
||||||
@ -396,6 +397,7 @@
|
|||||||
|
|
||||||
KillFreeConnections();
|
KillFreeConnections();
|
||||||
|
|
||||||
|
killSICSHipadaba();
|
||||||
|
|
||||||
/* make fortify print his findings */
|
/* make fortify print his findings */
|
||||||
Fortify_DumpAllMemory(iFortifyScope);
|
Fortify_DumpAllMemory(iFortifyScope);
|
||||||
|
10
obdes.c
10
obdes.c
@ -44,6 +44,7 @@
|
|||||||
#include "obdes.h"
|
#include "obdes.h"
|
||||||
#include "conman.h"
|
#include "conman.h"
|
||||||
#include "servlog.h"
|
#include "servlog.h"
|
||||||
|
#include "hipadaba.h"
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
static void *DefaultGetInterface(void *pData,int iID)
|
static void *DefaultGetInterface(void *pData,int iID)
|
||||||
@ -67,6 +68,7 @@
|
|||||||
}
|
}
|
||||||
pRes->name = strdup(name);
|
pRes->name = strdup(name);
|
||||||
pRes->pKeys = NULL;
|
pRes->pKeys = NULL;
|
||||||
|
pRes->parNode = NULL;
|
||||||
pRes->SaveStatus = DefaultSave;
|
pRes->SaveStatus = DefaultSave;
|
||||||
pRes->GetInterface = DefaultGetInterface;
|
pRes->GetInterface = DefaultGetInterface;
|
||||||
return pRes;
|
return pRes;
|
||||||
@ -77,6 +79,14 @@
|
|||||||
assert(self);
|
assert(self);
|
||||||
if(self->name) free(self->name);
|
if(self->name) free(self->name);
|
||||||
if(self->pKeys) IFDeleteOptions(self->pKeys);
|
if(self->pKeys) IFDeleteOptions(self->pKeys);
|
||||||
|
/*
|
||||||
|
* delate a parameter node only when not linked elsewhere
|
||||||
|
*/
|
||||||
|
if(self->parNode != NULL){
|
||||||
|
if(self->parNode->mama == NULL){
|
||||||
|
DeleteHipadabaNode(self->parNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
free(self);
|
free(self);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
2
obdes.h
2
obdes.h
@ -23,12 +23,14 @@
|
|||||||
#define SICSDESCRIPTOR
|
#define SICSDESCRIPTOR
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <ifile.h>
|
#include <ifile.h>
|
||||||
|
#include <hipadaba.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *name;
|
char *name;
|
||||||
int (*SaveStatus)(void *self, char *name,FILE *fd);
|
int (*SaveStatus)(void *self, char *name,FILE *fd);
|
||||||
void *(*GetInterface)(void *self, int iInterfaceID);
|
void *(*GetInterface)(void *self, int iInterfaceID);
|
||||||
IPair *pKeys;
|
IPair *pKeys;
|
||||||
|
pHdb parNode;
|
||||||
} ObjectDescriptor, *pObjectDescriptor;
|
} ObjectDescriptor, *pObjectDescriptor;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
2
ofac.c
2
ofac.c
@ -376,7 +376,7 @@
|
|||||||
RemoveCommand(pSics,"MakeLin2Ang");
|
RemoveCommand(pSics,"MakeLin2Ang");
|
||||||
RemoveCommand(pSics,"MakeSync");
|
RemoveCommand(pSics,"MakeSync");
|
||||||
RemoveCommand(pSics,"MakeHMControl");
|
RemoveCommand(pSics,"MakeHMControl");
|
||||||
/* RemoveCommand(pSics,"MakeRS232Controller"); */
|
RemoveCommand(pSics,"MakeRS232Controller");
|
||||||
RemoveCommand(pSics,"MakeMaxDetector");
|
RemoveCommand(pSics,"MakeMaxDetector");
|
||||||
RemoveCommand(pSics,"AntiColliderInstall");
|
RemoveCommand(pSics,"AntiColliderInstall");
|
||||||
RemoveCommand(pSics,"MakeGPIB");
|
RemoveCommand(pSics,"MakeGPIB");
|
||||||
|
336
sicshipadaba.c
336
sicshipadaba.c
@ -13,6 +13,7 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <sicshipadaba.h>
|
#include <sicshipadaba.h>
|
||||||
#include <lld.h>
|
#include <lld.h>
|
||||||
|
#include <stptok.h>
|
||||||
|
|
||||||
/*== there can be only hipadaba in SICS, some globals to care for that == */
|
/*== there can be only hipadaba in SICS, some globals to care for that == */
|
||||||
static pHdb root = NULL;
|
static pHdb root = NULL;
|
||||||
@ -27,12 +28,22 @@ static int SICSCheckPermissionCallback(void *userData, void *callData, pHdb node
|
|||||||
pCon = (SConnection *)callData;
|
pCon = (SConnection *)callData;
|
||||||
testPriv = (int *)userData;
|
testPriv = (int *)userData;
|
||||||
|
|
||||||
assert(pCon != NULL && testPriv != NULL);
|
/*
|
||||||
|
* If pCon is NULL, then this is an internal call from some driver
|
||||||
|
* code where no permission check is necessary. However, when called
|
||||||
|
* through the hipadaba tree commands and other upper level code, the
|
||||||
|
* check will be honoured.
|
||||||
|
*/
|
||||||
|
if(pCon == NULL){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(testPriv != NULL);
|
||||||
|
|
||||||
if(SCMatchRights(pCon,*testPriv) == 1){
|
if(SCMatchRights(pCon,*testPriv) == 1){
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return SICSCBPERM;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*--------------------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------------------*/
|
||||||
@ -60,10 +71,11 @@ static int SICSReadOnlyCallback(void *userData, void *callData, pHdb node,
|
|||||||
SConnection *pCon = NULL;
|
SConnection *pCon = NULL;
|
||||||
|
|
||||||
pCon = (SConnection *)callData;
|
pCon = (SConnection *)callData;
|
||||||
assert(pCon != NULL);
|
|
||||||
|
|
||||||
SCWrite(pCon,"ERROR: parameter is READ-ONLY", eError);
|
if(pCon != NULL){
|
||||||
return 0;
|
SCWrite(pCon,"ERROR: parameter is READ-ONLY", eError);
|
||||||
|
}
|
||||||
|
return SICSCBRO;
|
||||||
}
|
}
|
||||||
/*-------------------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------------------*/
|
||||||
static pHdbCallback MakeReadOnlyCallback(){
|
static pHdbCallback MakeReadOnlyCallback(){
|
||||||
@ -86,6 +98,31 @@ pHdbCallback MakeSICSDriveCallback(void *sicsObject){
|
|||||||
return MakeHipadabaCallback(SICSDriveCallback, sicsObject,NULL,-1,-1);
|
return MakeHipadabaCallback(SICSDriveCallback, sicsObject,NULL,-1,-1);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------------*/
|
||||||
|
static int SICSReadDriveCallback(void *userData, void *callData, pHdb node,
|
||||||
|
hdbValue v){
|
||||||
|
SConnection *pCon = NULL;
|
||||||
|
pDummy dum = NULL;
|
||||||
|
pIDrivable pDriv = NULL;
|
||||||
|
float value;
|
||||||
|
|
||||||
|
pCon = (SConnection *)callData;
|
||||||
|
dum = (pDummy)userData;
|
||||||
|
assert(pCon != NULL && dum != NULL);
|
||||||
|
|
||||||
|
pDriv = dum->pDescriptor->GetInterface(dum,DRIVEID);
|
||||||
|
assert(pDriv != NULL);
|
||||||
|
if(pCon != NULL){
|
||||||
|
value = pDriv->GetValue(dum,pCon);
|
||||||
|
node->value.v.doubleValue = (double)value;
|
||||||
|
v.v.doubleValue = (double)value;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------------------------*/
|
||||||
|
pHdbCallback MakeSICSReadDriveCallback(void *sicsObject){
|
||||||
|
return MakeHipadabaCallback(SICSReadDriveCallback, sicsObject,NULL,-1,-1);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------------------*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
SConnection *pCon;
|
SConnection *pCon;
|
||||||
commandContext context;
|
commandContext context;
|
||||||
@ -228,11 +265,144 @@ static int SICSScriptReadCallback(void *userData, void *callData, pHdb node,
|
|||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
/*----------------------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
static pHdbCallback MakeSICSReadScriptCallback(char *script){
|
static pHdbCallback MakeSICSReadScriptCallback(char *script){
|
||||||
return MakeHipadabaCallback(SICSScriptReadCallback, strdup(script),free,-1,-1);
|
return MakeHipadabaCallback(SICSScriptReadCallback, strdup(script),
|
||||||
|
free,-1,-1);
|
||||||
}
|
}
|
||||||
/*============= Parameter Creation =======================================================*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
typedef struct {
|
||||||
|
int min;
|
||||||
|
int max;
|
||||||
|
}hdbIntRange, *pHdbIntRange;
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static int SICSIntRangeCallback(void *userData, void *callData, pHdb node,
|
||||||
|
hdbValue v){
|
||||||
|
char buffer[256];
|
||||||
|
pHdbIntRange range = NULL;
|
||||||
|
SConnection *pCon = NULL;
|
||||||
|
int status = 1;
|
||||||
|
|
||||||
|
range = (pHdbIntRange)userData;
|
||||||
|
pCon = (SConnection *)callData;
|
||||||
|
|
||||||
|
assert(range != NULL);
|
||||||
|
|
||||||
|
if(v.v.intValue > range->max || v.v.intValue < range->min) {
|
||||||
|
status = SICSCBRANGE;
|
||||||
|
if(pCon != NULL){
|
||||||
|
snprintf(buffer,255,"ERROR: %d is not within permitted range: %d to %d",
|
||||||
|
(int)v.v.intValue, range->min, range->max);
|
||||||
|
SCWrite(pCon,buffer,eError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
pHdbCallback MakeIntRangeCallback(int min, int max){
|
||||||
|
pHdbIntRange range = NULL;
|
||||||
|
|
||||||
|
range = malloc(sizeof(hdbIntRange));
|
||||||
|
if(range == NULL){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
range->min = min;
|
||||||
|
range->max = max;
|
||||||
|
return MakeHipadabaCallback(SICSIntRangeCallback, range,
|
||||||
|
free,-1,-1);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
typedef struct {
|
||||||
|
double min;
|
||||||
|
double max;
|
||||||
|
}hdbFloatRange, *pHdbFloatRange;
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static int SICSFloatRangeCallback(void *userData, void *callData, pHdb node,
|
||||||
|
hdbValue v){
|
||||||
|
char buffer[256];
|
||||||
|
pHdbFloatRange range = NULL;
|
||||||
|
SConnection *pCon = NULL;
|
||||||
|
int status = 1;
|
||||||
|
|
||||||
|
range = (pHdbFloatRange)userData;
|
||||||
|
pCon = (SConnection *)callData;
|
||||||
|
|
||||||
|
assert(range != NULL);
|
||||||
|
|
||||||
|
if(v.v.doubleValue > range->max || v.v.doubleValue < range->min) {
|
||||||
|
status = SICSCBRANGE;
|
||||||
|
if(pCon != NULL){
|
||||||
|
snprintf(buffer,255,"ERROR: %lf is not within permitted range: %lf to %lf",
|
||||||
|
v.v.doubleValue, range->min, range->max);
|
||||||
|
SCWrite(pCon,buffer,eError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
pHdbCallback MakeFloatRangeCallback(double min, double max){
|
||||||
|
pHdbFloatRange range = NULL;
|
||||||
|
|
||||||
|
range = malloc(sizeof(hdbFloatRange));
|
||||||
|
if(range == NULL){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
range->min = min;
|
||||||
|
range->max = max;
|
||||||
|
return MakeHipadabaCallback(SICSFloatRangeCallback, range,
|
||||||
|
free,-1,-1);
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
static void killHdbValue(void *pData){
|
||||||
|
hdbValue *v = NULL;
|
||||||
|
|
||||||
|
v = (hdbValue *)pData;
|
||||||
|
if(v == NULL){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ReleaseHdbValue(v);
|
||||||
|
free(v);
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
static int SICSIntFixedCallback(void *userData, void *callData, pHdb node,
|
||||||
|
hdbValue v){
|
||||||
|
hdbValue *allowed = NULL;
|
||||||
|
SConnection *pCon = NULL;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
allowed = (hdbValue *)userData;
|
||||||
|
pCon = (SConnection *)callData;
|
||||||
|
assert(allowed != NULL && allowed->dataType == HIPINTAR);
|
||||||
|
for(i = 0; i < allowed->arrayLength; i++){
|
||||||
|
if(v.v.intValue == allowed->v.intArray[i]){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(pCon != NULL){
|
||||||
|
SCWrite(pCon,"ERROR: value is not in the list of allowed values",eError);
|
||||||
|
}
|
||||||
|
return SICSCBBADFIXED;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
pHdbCallback MakeIntFixedCallback(long *data, int length){
|
||||||
|
pHdbCallback result = NULL;
|
||||||
|
hdbValue *v = NULL;
|
||||||
|
|
||||||
|
v = malloc(sizeof(hdbValue));
|
||||||
|
if(v == NULL){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
v->dataType = HIPINTAR;
|
||||||
|
v->arrayLength = length;
|
||||||
|
v->v.intArray = malloc(length*sizeof(long));
|
||||||
|
if(v->v.intArray == NULL){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memcpy(v->v.intArray,data,length*sizeof(long));
|
||||||
|
return MakeHipadabaCallback(SICSIntFixedCallback, v,
|
||||||
|
killHdbValue,-1,-1);
|
||||||
|
}
|
||||||
|
/*============= Parameter Creation ===========================================*/
|
||||||
pHdb MakeSICSHdbPar(char *name, int priv, hdbValue v){
|
pHdb MakeSICSHdbPar(char *name, int priv, hdbValue v){
|
||||||
pHdb result = NULL;
|
pHdb result = NULL;
|
||||||
pHdbCallback pHcb = NULL;
|
pHdbCallback pHcb = NULL;
|
||||||
@ -283,10 +453,17 @@ pHdb MakeSICSHdbDriv(char *name, int priv, void *sicsObject, int dataType){
|
|||||||
}
|
}
|
||||||
AppendHipadabaCallback(result,HCBSET,pHcb);
|
AppendHipadabaCallback(result,HCBSET,pHcb);
|
||||||
|
|
||||||
|
pHcb = MakeSICSReadDriveCallback(sicsObject);
|
||||||
|
if(pHcb == NULL){
|
||||||
|
DeleteHipadabaNode(result);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
AppendHipadabaCallback(result,HCBREAD,pHcb);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
pHdb MakeSICSHdbROPar(char *name, int priv, hdbValue v){
|
pHdb MakeSICSROPar(char *name, hdbValue v){
|
||||||
pHdb result = NULL;
|
pHdb result = NULL;
|
||||||
pHdbCallback pHcb = NULL;
|
pHdbCallback pHcb = NULL;
|
||||||
|
|
||||||
@ -296,7 +473,7 @@ pHdb MakeSICSHdbROPar(char *name, int priv, hdbValue v){
|
|||||||
}
|
}
|
||||||
copyHdbValue(&v,&result->value);
|
copyHdbValue(&v,&result->value);
|
||||||
|
|
||||||
pHcb = MakeReadOnlyCallback(priv);
|
pHcb = MakeReadOnlyCallback();
|
||||||
if(pHcb == NULL){
|
if(pHcb == NULL){
|
||||||
DeleteHipadabaNode(result);
|
DeleteHipadabaNode(result);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -498,6 +675,9 @@ int SICSHipadabaTask(void *pData){
|
|||||||
if(self->iEnd == 1){
|
if(self->iEnd == 1){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if(LLDcheck(self->updateList) == LIST_EMPTY){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
memset(&old,0,sizeof(hdbValue));
|
memset(&old,0,sizeof(hdbValue));
|
||||||
memset(&newValue,0,sizeof(hdbValue));
|
memset(&newValue,0,sizeof(hdbValue));
|
||||||
|
|
||||||
@ -561,12 +741,14 @@ pDynString formatValue(hdbValue v){
|
|||||||
DynStringCopy(result,v.v.text);
|
DynStringCopy(result,v.v.text);
|
||||||
break;
|
break;
|
||||||
case HIPINTAR:
|
case HIPINTAR:
|
||||||
|
case HIPINTVARAR:
|
||||||
for(i = 0; i < v.arrayLength; i++){
|
for(i = 0; i < v.arrayLength; i++){
|
||||||
snprintf(number,30," %ld", v.v.intArray[i]);
|
snprintf(number,30," %ld", v.v.intArray[i]);
|
||||||
DynStringConcat(result,number);
|
DynStringConcat(result,number);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case HIPFLOATAR:
|
case HIPFLOATAR:
|
||||||
|
case HIPFLOATVARAR:
|
||||||
for(i = 0; i < v.arrayLength; i++){
|
for(i = 0; i < v.arrayLength; i++){
|
||||||
snprintf(number,30," %12.4f", v.v.floatArray[i]);
|
snprintf(number,30," %12.4f", v.v.floatArray[i]);
|
||||||
DynStringConcat(result,number);
|
DynStringConcat(result,number);
|
||||||
@ -597,7 +779,39 @@ static char *getNextHdbNumber(char *pStart, char pNumber[80]){
|
|||||||
pNumber[charCount] = '\0';
|
pNumber[charCount] = '\0';
|
||||||
return pStart;
|
return pStart;
|
||||||
}
|
}
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
static int adjustDataLength(hdbValue *v, char *data){
|
||||||
|
char number[80];
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
while(getNextHdbNumber(data,number) != NULL){
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
if(count != v->arrayLength){
|
||||||
|
v->arrayLength = count;
|
||||||
|
if(v->dataType == HIPINTVARAR){
|
||||||
|
if(v->v.intArray != NULL){
|
||||||
|
free(v->v.intArray);
|
||||||
|
}
|
||||||
|
v->v.intArray = malloc(count*sizeof(long));
|
||||||
|
if(v->v.intArray == NULL){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
memset(v->v.intArray,0,count*sizeof(long));
|
||||||
|
}
|
||||||
|
if(v->dataType == HIPFLOATVARAR){
|
||||||
|
if(v->v.floatArray != NULL){
|
||||||
|
free(v->v.floatArray);
|
||||||
|
}
|
||||||
|
v->v.floatArray = malloc(count*sizeof(double));
|
||||||
|
if(v->v.floatArray == NULL){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
memset(v->v.floatArray,0,count*sizeof(double));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
int readHdbValue(hdbValue *v, char *data, char *error, int errlen){
|
int readHdbValue(hdbValue *v, char *data, char *error, int errlen){
|
||||||
int i, status;
|
int i, status;
|
||||||
@ -633,6 +847,11 @@ int readHdbValue(hdbValue *v, char *data, char *error, int errlen){
|
|||||||
}
|
}
|
||||||
v->v.text = strdup(data);
|
v->v.text = strdup(data);
|
||||||
break;
|
break;
|
||||||
|
case HIPINTVARAR:
|
||||||
|
if(!adjustDataLength(v,data)){
|
||||||
|
snprintf(error,errlen,"Out of memory allocating variable length data");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case HIPINTAR:
|
case HIPINTAR:
|
||||||
for(i = 0; i < v->arrayLength; i++){
|
for(i = 0; i < v->arrayLength; i++){
|
||||||
data = getNextHdbNumber(data,number);
|
data = getNextHdbNumber(data,number);
|
||||||
@ -650,6 +869,11 @@ int readHdbValue(hdbValue *v, char *data, char *error, int errlen){
|
|||||||
v->v.intArray[i] = lValue;
|
v->v.intArray[i] = lValue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case HIPFLOATVARAR:
|
||||||
|
if(!adjustDataLength(v,data)){
|
||||||
|
snprintf(error,errlen,"Out of memory allocating variable length data");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case HIPFLOATAR:
|
case HIPFLOATAR:
|
||||||
for(i = 0; i < v->arrayLength; i++){
|
for(i = 0; i < v->arrayLength; i++){
|
||||||
data = getNextHdbNumber(data,number);
|
data = getNextHdbNumber(data,number);
|
||||||
@ -684,6 +908,8 @@ static char *hdbTypes[] = {"none",
|
|||||||
"text",
|
"text",
|
||||||
"intar",
|
"intar",
|
||||||
"floatar",
|
"floatar",
|
||||||
|
"intvarar",
|
||||||
|
"floatvarar",
|
||||||
NULL};
|
NULL};
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
static int convertHdbType(char *text){
|
static int convertHdbType(char *text){
|
||||||
@ -729,9 +955,9 @@ static int MakeHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|||||||
*/
|
*/
|
||||||
strtolower(argv[3]);
|
strtolower(argv[3]);
|
||||||
type = convertHdbType(argv[3]);
|
type = convertHdbType(argv[3]);
|
||||||
if(type >= 5){
|
if(type >= 7){
|
||||||
SCWrite(pCon,
|
SCWrite(pCon,
|
||||||
"ERROR: invalid type requested: none, int, float, text, intar, floatar supported",
|
"ERROR: invalid type requested: none, int, float, text, intar, floatar, intvarar, floatvarar supported",
|
||||||
eError);
|
eError);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -800,9 +1026,9 @@ static int MakeHdbScriptNode(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|||||||
*/
|
*/
|
||||||
strtolower(argv[4]);
|
strtolower(argv[4]);
|
||||||
type = convertHdbType(argv[4]);
|
type = convertHdbType(argv[4]);
|
||||||
if(type >= 5){
|
if(type >= 7){
|
||||||
SCWrite(pCon,
|
SCWrite(pCon,
|
||||||
"ERROR: invalid type requested: none, int, float, text, intar, floatar supported",
|
"ERROR: invalid type requested: none, int, float, text, intar, floatar, intvarar, floatvarar supported",
|
||||||
eError);
|
eError);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -868,7 +1094,46 @@ static int DeleteHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|||||||
SCSendOK(pCon);
|
SCSendOK(pCon);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*------------------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static pHdb locateSICSNode(SicsInterp *pSics, SConnection *pCon, char *path){
|
||||||
|
pHdb result = NULL;
|
||||||
|
char *pPtr = NULL, sicsObj[128], error[256];
|
||||||
|
pDummy pDum = NULL;
|
||||||
|
CommandList *pCom = NULL;
|
||||||
|
|
||||||
|
if(strstr(path,"/sics/") != NULL){
|
||||||
|
pPtr = stptok(path,sicsObj,128,"/");
|
||||||
|
pPtr = stptok(pPtr,sicsObj,128,"/");
|
||||||
|
pPtr = stptok(pPtr,sicsObj,128,"/");
|
||||||
|
strtolower(sicsObj);
|
||||||
|
pCom = FindCommand(pSics,sicsObj);
|
||||||
|
if(pCom == NULL) {
|
||||||
|
snprintf(error,255,"ERROR: object %s not found",sicsObj);
|
||||||
|
SCWrite(pCon,error,eError);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
pDum = (pDummy)pCom->pData;
|
||||||
|
if(pDum == NULL){
|
||||||
|
snprintf(error,255,"ERROR: object %s has no data",sicsObj);
|
||||||
|
SCWrite(pCon,error,eError);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if(pDum->pDescriptor->parNode == NULL){
|
||||||
|
snprintf(error,255,"ERROR: object %s does not use Hipadaba",sicsObj);
|
||||||
|
SCWrite(pCon,error,eError);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
result = GetHipadabaNode(pDum->pDescriptor->parNode,pPtr);
|
||||||
|
} else {
|
||||||
|
result = GetHipadabaNode(root,path);
|
||||||
|
}
|
||||||
|
if(result == NULL){
|
||||||
|
snprintf(error,255,"ERROR: node %s NOT found",path);
|
||||||
|
SCWrite(pCon,error,eError);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
static int SetHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
|
static int SetHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
int argc, char *argv[]){
|
int argc, char *argv[]){
|
||||||
pHdb targetNode = NULL;
|
pHdb targetNode = NULL;
|
||||||
@ -887,10 +1152,8 @@ static int SetHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
targetNode = GetHipadabaNode(root,argv[1]);
|
targetNode = locateSICSNode(pSics,pCon,argv[1]);
|
||||||
if(targetNode == NULL){
|
if(targetNode == NULL){
|
||||||
SCWrite(pCon,"ERROR: node to set not found!",
|
|
||||||
eError);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(!cloneHdbValue(&targetNode->value,&newValue)){
|
if(!cloneHdbValue(&targetNode->value,&newValue)){
|
||||||
@ -936,10 +1199,8 @@ static int GetHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|||||||
}
|
}
|
||||||
|
|
||||||
strncpy(oriPath,argv[1], 511);
|
strncpy(oriPath,argv[1], 511);
|
||||||
targetNode = GetHipadabaNode(root,argv[1]);
|
targetNode = locateSICSNode(pSics,pCon,argv[1]);
|
||||||
if(targetNode == NULL){
|
if(targetNode == NULL){
|
||||||
SCWrite(pCon,"ERROR: node to read not found!",
|
|
||||||
eError);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
memset(&newValue,0,sizeof(hdbValue));
|
memset(&newValue,0,sizeof(hdbValue));
|
||||||
@ -1057,6 +1318,7 @@ static pDynString formatClientList(pHdb node){
|
|||||||
DynStringConcat(result,current->value.v.text);
|
DynStringConcat(result,current->value.v.text);
|
||||||
break;
|
break;
|
||||||
case HIPINTAR:
|
case HIPINTAR:
|
||||||
|
case HIPINTVARAR:
|
||||||
for(i = 0; i < length; i++){
|
for(i = 0; i < length; i++){
|
||||||
snprintf(number,50,"%ld",current->value.v.intArray[i]);
|
snprintf(number,50,"%ld",current->value.v.intArray[i]);
|
||||||
DynStringConcat(result,number);
|
DynStringConcat(result,number);
|
||||||
@ -1066,6 +1328,7 @@ static pDynString formatClientList(pHdb node){
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case HIPFLOATAR:
|
case HIPFLOATAR:
|
||||||
|
case HIPFLOATVARAR:
|
||||||
for(i = 0; i < length; i++){
|
for(i = 0; i < length; i++){
|
||||||
snprintf(number,50,"%lf",current->value.v.floatArray[i]);
|
snprintf(number,50,"%lf",current->value.v.floatArray[i]);
|
||||||
DynStringConcat(result,number);
|
DynStringConcat(result,number);
|
||||||
@ -1100,10 +1363,8 @@ static int ListHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
node = GetHipadabaNode(root,argv[pathArg]);
|
node = locateSICSNode(pSics,pCon,argv[pathArg]);
|
||||||
if(node == NULL){
|
if(node == NULL){
|
||||||
SCWrite(pCon,"ERROR: node to list not found!",
|
|
||||||
eError);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1136,10 +1397,8 @@ static int AutoNotifyHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
node = GetHipadabaNode(root,argv[1]);
|
node = locateSICSNode(pSics,pCon,argv[1]);
|
||||||
if(node == NULL){
|
if(node == NULL){
|
||||||
SCWrite(pCon,"ERROR: node to add notify found!",
|
|
||||||
eError);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1168,15 +1427,18 @@ static int RemoveHdbCallback(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void killSICSHipadaba(void *pData){
|
void killSICSHipadaba(){
|
||||||
DeleteHipadabaNode(root);
|
if(root != NULL){
|
||||||
|
DeleteHipadabaNode(root);
|
||||||
|
}
|
||||||
root = NULL;
|
root = NULL;
|
||||||
/**
|
/**
|
||||||
* children have already been removed when killing the
|
* children have already been removed when killing the
|
||||||
* main tree
|
* main tree
|
||||||
*/
|
*/
|
||||||
|
if(scriptUpdate > 0 && LLDcheck(scriptUpdate) != LIST_EMPTY){
|
||||||
LLDdelete(scriptUpdate);
|
LLDdelete(scriptUpdate);
|
||||||
SCDeleteConnection(taskData.pCon);
|
}
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
int InstallSICSHipadaba(SConnection *pCon, SicsInterp *pSics, void *pData,
|
int InstallSICSHipadaba(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
@ -1194,10 +1456,10 @@ int InstallSICSHipadaba(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|||||||
TaskRegister(pServ->pTasker,
|
TaskRegister(pServ->pTasker,
|
||||||
SICSHipadabaTask,
|
SICSHipadabaTask,
|
||||||
SICSHipadabaSignal,
|
SICSHipadabaSignal,
|
||||||
killSICSHipadaba,
|
NULL,
|
||||||
&taskData,1);
|
&taskData,1);
|
||||||
|
|
||||||
AddCommand(pSics,"hmake", MakeHdbNode, killSICSHipadaba, NULL);
|
AddCommand(pSics,"hmake", MakeHdbNode, NULL, NULL);
|
||||||
AddCommand(pSics,"hmakescript", MakeHdbScriptNode, NULL, NULL);
|
AddCommand(pSics,"hmakescript", MakeHdbScriptNode, NULL, NULL);
|
||||||
AddCommand(pSics,"hdel", DeleteHdbNode, NULL, NULL);
|
AddCommand(pSics,"hdel", DeleteHdbNode, NULL, NULL);
|
||||||
AddCommand(pSics,"hset", SetHdbNode, NULL, NULL);
|
AddCommand(pSics,"hset", SetHdbNode, NULL, NULL);
|
||||||
|
@ -12,6 +12,11 @@
|
|||||||
#include <hipadaba.h>
|
#include <hipadaba.h>
|
||||||
#include <sics.h>
|
#include <sics.h>
|
||||||
#include <dynstring.h>
|
#include <dynstring.h>
|
||||||
|
/*======================== callback error codes ===============================*/
|
||||||
|
#define SICSCBRO -607
|
||||||
|
#define SICSCBPERM -608
|
||||||
|
#define SICSCBRANGE -609
|
||||||
|
#define SICSCBBADFIXED -610
|
||||||
/*======================== data structure for automatic parameter update =======*/
|
/*======================== data structure for automatic parameter update =======*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
SConnection *pCon;
|
SConnection *pCon;
|
||||||
@ -40,6 +45,13 @@ pHdbCallback MakeSetUpdateCallback();
|
|||||||
* starting a parameter driving.
|
* starting a parameter driving.
|
||||||
*/
|
*/
|
||||||
pHdbCallback MakeSICSDriveCallback(void *sicsObject);
|
pHdbCallback MakeSICSDriveCallback(void *sicsObject);
|
||||||
|
/**
|
||||||
|
* make a callback which reads a SICS drivable object
|
||||||
|
* @param sicsObject The SICS drivable object to read.
|
||||||
|
* @return a suitably initialized callback structure for
|
||||||
|
* reading a drivable parameter
|
||||||
|
*/
|
||||||
|
pHdbCallback MakeSICSReadDriveCallback(void *sicsObject);
|
||||||
/**
|
/**
|
||||||
* make a callback which enables automatically
|
* make a callback which enables automatically
|
||||||
* notification of pCon on parameter updates.
|
* notification of pCon on parameter updates.
|
||||||
@ -51,6 +63,33 @@ pHdbCallback MakeSICSDriveCallback(void *sicsObject);
|
|||||||
* automatic notification.
|
* automatic notification.
|
||||||
*/
|
*/
|
||||||
pHdbCallback MakeNotifyCallback(SConnection *pCon, int id);
|
pHdbCallback MakeNotifyCallback(SConnection *pCon, int id);
|
||||||
|
/**
|
||||||
|
* make a callback for checking if a parameter is within a given
|
||||||
|
* range of integers
|
||||||
|
* @param min The minimum value of the range
|
||||||
|
* @param max The maximum value of the range
|
||||||
|
* @return a suitably configured callback or NULL
|
||||||
|
* when out of memory
|
||||||
|
*/
|
||||||
|
pHdbCallback MakeIntRangeCallback(int min, int max);
|
||||||
|
/**
|
||||||
|
* make a callback for checking if a parameter is one out
|
||||||
|
* of a series of permitted integers
|
||||||
|
* @param data An array of permitted integers
|
||||||
|
* @param length The length of the data array.
|
||||||
|
* @return a suitably configured callback or NULL
|
||||||
|
* when out of memory
|
||||||
|
*/
|
||||||
|
pHdbCallback MakeIntFixedCallback(long *data, int length);
|
||||||
|
/**
|
||||||
|
* make a callback for checking if a parameter is within a given
|
||||||
|
* range of floats
|
||||||
|
* @param min The minimum value of the range
|
||||||
|
* @param max The maximum value of the range
|
||||||
|
* @return a suitably configured callback or NULL
|
||||||
|
* when out of memory
|
||||||
|
*/
|
||||||
|
pHdbCallback MakeFloatRangeCallback(double min, double max);
|
||||||
/*======================== parameter creation ===================================*/
|
/*======================== parameter creation ===================================*/
|
||||||
/**
|
/**
|
||||||
* make a simple SICS hdb parameter. Setting it will call update immediately. Use
|
* make a simple SICS hdb parameter. Setting it will call update immediately. Use
|
||||||
@ -171,5 +210,9 @@ int InstallSICSHipadaba(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|||||||
* @return The root node of the hipdaba
|
* @return The root node of the hipdaba
|
||||||
*/
|
*/
|
||||||
pHdb GetHipadabaRoot();
|
pHdb GetHipadabaRoot();
|
||||||
|
/**
|
||||||
|
* kill the SICS hierarchical database
|
||||||
|
* Only to be called when shutting down the SICServer
|
||||||
|
*/
|
||||||
|
void killSICSHipadaba(void);
|
||||||
#endif /*SICSHIPADABA_H_*/
|
#endif /*SICSHIPADABA_H_*/
|
||||||
|
Reference in New Issue
Block a user