- Added messagepipe.c
- Added initial version of sicsget. This is a more generalised way of reading and writing SICS data wherever it is. The thing is extendable if reading something the current way is to slow. This has both a C interface and an interpreter interface.
This commit is contained in:
3
make_gen
3
make_gen
@ -44,7 +44,8 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \
|
|||||||
singlenb.o simindex.o simidx.o uselect.o singletas.o motorsec.o \
|
singlenb.o simindex.o simidx.o uselect.o singletas.o motorsec.o \
|
||||||
rwpuffer.o asynnet.o background.o countersec.o hdbtable.o velosec.o \
|
rwpuffer.o asynnet.o background.o countersec.o hdbtable.o velosec.o \
|
||||||
histmemsec.o sansbc.o sicsutil.o strlutil.o genbinprot.o trace.o\
|
histmemsec.o sansbc.o sicsutil.o strlutil.o genbinprot.o trace.o\
|
||||||
singlebinb.o taskobj.o sctcomtask.o tasmono.o multicountersec.o
|
singlebinb.o taskobj.o sctcomtask.o tasmono.o multicountersec.o \
|
||||||
|
messagepipe.o sicsget.o
|
||||||
|
|
||||||
MOTOROBJ = motor.o simdriv.o
|
MOTOROBJ = motor.o simdriv.o
|
||||||
COUNTEROBJ = countdriv.o simcter.o counter.o
|
COUNTEROBJ = countdriv.o simcter.o counter.o
|
||||||
|
118
messagepipe.c
Normal file
118
messagepipe.c
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
/**
|
||||||
|
* An implementation for a message pipe system as described in
|
||||||
|
*
|
||||||
|
* http://eventuallyconsistent.net/2013/08/14/messaging-as-a-programming-model-part-2/
|
||||||
|
*
|
||||||
|
* A message is passed through a series of filter routines which do things.
|
||||||
|
*
|
||||||
|
* Rather then loops I try using recursion here.
|
||||||
|
*
|
||||||
|
* copyright: GPL Copyleft
|
||||||
|
*
|
||||||
|
* Mark Koennecke, November 2013
|
||||||
|
*/
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <messagepipe.h>
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------*/
|
||||||
|
typedef struct __MessagePipe {
|
||||||
|
void *userData;
|
||||||
|
mpUserKill killFunc;
|
||||||
|
mpFilterFunc filterFunc;
|
||||||
|
struct __MessagePipe *next;
|
||||||
|
struct __MessagePipe *previous;
|
||||||
|
} MessagePipe;
|
||||||
|
/*--------------------------------------------------------------------------------*/
|
||||||
|
static int EmptyFunc(void *message, void *userData)
|
||||||
|
{
|
||||||
|
return MPCONTINUE;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
pMP MakeMP()
|
||||||
|
{
|
||||||
|
pMP result = NULL;
|
||||||
|
|
||||||
|
result = malloc(sizeof(MessagePipe));
|
||||||
|
if(result != NULL){
|
||||||
|
memset(result,0,sizeof(MessagePipe));
|
||||||
|
result->filterFunc = EmptyFunc;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
void KillMP(pMP self)
|
||||||
|
{
|
||||||
|
if(self == NULL){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pMP next = self->next;
|
||||||
|
if(self->userData != NULL && self->killFunc != NULL){
|
||||||
|
self->killFunc(self->userData);
|
||||||
|
}
|
||||||
|
free(self);
|
||||||
|
KillMP(next);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
int AppendMPFilter(pMP self, mpFilterFunc func, void *userData, mpUserKill usKill)
|
||||||
|
{
|
||||||
|
assert(self != NULL);
|
||||||
|
assert(func != NULL);
|
||||||
|
|
||||||
|
if(self->next == NULL){
|
||||||
|
self->next = malloc(sizeof(MessagePipe));
|
||||||
|
if(self->next != NULL){
|
||||||
|
self->next->previous = self;
|
||||||
|
self->next->next = NULL;
|
||||||
|
self->next->userData = userData;
|
||||||
|
self->next->killFunc = usKill;
|
||||||
|
self->next->filterFunc = func;
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return AppendMPFilter(self->next, func, userData, usKill);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
pMP PrependMPFilter(pMP self, mpFilterFunc func, void *userData, mpUserKill usKill)
|
||||||
|
{
|
||||||
|
pMP result = NULL;
|
||||||
|
|
||||||
|
assert(func != NULL);
|
||||||
|
|
||||||
|
result = malloc(sizeof(MessagePipe));
|
||||||
|
if(result != NULL){
|
||||||
|
result->userData = userData;
|
||||||
|
result->killFunc = usKill;
|
||||||
|
result->filterFunc = func;
|
||||||
|
result->next = self;
|
||||||
|
result->previous = NULL;
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
we are ignoring an error here.........
|
||||||
|
*/
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
int MPprocess(pMP self, void *message)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
|
||||||
|
if(self == NULL || self->filterFunc == NULL){
|
||||||
|
return MPCONTINUE;
|
||||||
|
} else {
|
||||||
|
status = self->filterFunc(message, self->userData);
|
||||||
|
if(status == MPSTOP){
|
||||||
|
return status;
|
||||||
|
} else {
|
||||||
|
return MPprocess(self->next, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
82
messagepipe.h
Normal file
82
messagepipe.h
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
/**
|
||||||
|
* An implementation for a message pipe system as described in
|
||||||
|
*
|
||||||
|
* http://eventuallyconsistent.net/2013/08/14/messaging-as-a-programming-model-part-2/
|
||||||
|
*
|
||||||
|
* A message is passed through a series of filter routines which do things.
|
||||||
|
*
|
||||||
|
* copyright: GPL Copyleft
|
||||||
|
*
|
||||||
|
* Mark Koennecke, November 2013
|
||||||
|
*/
|
||||||
|
#ifndef __MESSAGEPIPE
|
||||||
|
#define __MESSAGEPIPE
|
||||||
|
|
||||||
|
#define MPCONTINUE 1
|
||||||
|
#define MPSTOP 0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The messagePipe data structure defined in messagepipe.c
|
||||||
|
*/
|
||||||
|
typedef struct __MessagePipe *pMP;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protoype of the message filter function.
|
||||||
|
* @param message The message to process
|
||||||
|
* @param Optional private data for this message filter function
|
||||||
|
* @return MPSTOP for stopping further processing of the filter pipe
|
||||||
|
* or MPCONTINUE to continue processing
|
||||||
|
*/
|
||||||
|
typedef int (*mpFilterFunc)(void *message, void *userData);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A function to free the userData when it is used
|
||||||
|
* @param userData The data structure passed in for userData to a filter function.
|
||||||
|
*/
|
||||||
|
typedef void (*mpUserKill)(void *userData);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an empty message pipe
|
||||||
|
* @return A message pipe structure or NULL when out of memory
|
||||||
|
*/
|
||||||
|
pMP MakeMP();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a message pipe
|
||||||
|
* @param self The message pipe to delete
|
||||||
|
*/
|
||||||
|
void KillMP(pMP self);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append a filter function to the list of message filters to process
|
||||||
|
* @param self The message queue to append too
|
||||||
|
* @param func The filter function to append
|
||||||
|
* @param Optional userData to pass through to the filter function
|
||||||
|
* @param usKill An optional function to free the userData when the message pipe gets deleted
|
||||||
|
* @return 0 on success, 1 when out of memory
|
||||||
|
*/
|
||||||
|
int AppendMPFilter(pMP self, mpFilterFunc func, void *userData, mpUserKill usKill);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Preppend a filter function to the list of message filters to process
|
||||||
|
* @param self The message queue to append too
|
||||||
|
* @param func The filter function to append
|
||||||
|
* @param Optional userData to pass through to the filter function
|
||||||
|
* @param usKill An optional function to free the userData when the message pipe gets deleted
|
||||||
|
* @return An updated pointer to the message pipe.
|
||||||
|
*/
|
||||||
|
pMP PrependMPFilter(pMP self, mpFilterFunc func, void *userData, mpUserKill usKill);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process the message pipe with the given message
|
||||||
|
* @param self The messae pipe to process
|
||||||
|
* @param message The message to process.
|
||||||
|
* @return MPCONTINUE on successfull completion, MPABORT when the chain was
|
||||||
|
* aborted for some reason.
|
||||||
|
*/
|
||||||
|
int MPprocess(pMP self, void *message);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
1
ofac.c
1
ofac.c
@ -35,6 +35,7 @@ static void InitGeneral(void)
|
|||||||
INIT(SctDriveAdapterInit);
|
INIT(SctDriveAdapterInit);
|
||||||
INIT(SctDriveObjInit);
|
INIT(SctDriveObjInit);
|
||||||
INIT(SctDriveAdapterInit);
|
INIT(SctDriveAdapterInit);
|
||||||
|
INIT(SICSGetInit);
|
||||||
INIT(LogReaderInit);
|
INIT(LogReaderInit);
|
||||||
INIT(LogSetupInit);
|
INIT(LogSetupInit);
|
||||||
INIT(InstallBackground);
|
INIT(InstallBackground);
|
||||||
|
548
sicsget.c
Normal file
548
sicsget.c
Normal file
@ -0,0 +1,548 @@
|
|||||||
|
/**
|
||||||
|
* This is a generalized SICS get/put routine. It tries to hard to match a name
|
||||||
|
* with the data.
|
||||||
|
*
|
||||||
|
* The other difference is that this uses the message pipe system for implementation.
|
||||||
|
* See messsagepipe.c for a pointer to documentation.
|
||||||
|
*
|
||||||
|
* copyright: see file COPYRIGHT
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <sics.h>
|
||||||
|
#include <sicsget.h>
|
||||||
|
#include <messagepipe.h>
|
||||||
|
#include <sicshipadaba.h>
|
||||||
|
#include <splitter.h>
|
||||||
|
#include <stptok.h>
|
||||||
|
#include <sicsdata.h>
|
||||||
|
|
||||||
|
static pMP getPipe, setPipe, sicsPipe, tclPipe;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int success;
|
||||||
|
char *name;
|
||||||
|
hdbValue *v;
|
||||||
|
} SSGMessage, *pSSGMessage;
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
typedef struct {
|
||||||
|
int success;
|
||||||
|
char *command;
|
||||||
|
char *response;
|
||||||
|
hdbValue *v;
|
||||||
|
} ParseMessage, *pParseMessage;
|
||||||
|
|
||||||
|
extern char *trim(char *txt);
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
int sget(char *name, hdbValue *v)
|
||||||
|
{
|
||||||
|
SSGMessage ssg;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
ssg.success = 0;
|
||||||
|
ssg.name = strdup(name);
|
||||||
|
ssg.v = v;
|
||||||
|
|
||||||
|
MPprocess(getPipe,&ssg);
|
||||||
|
free(ssg.name);
|
||||||
|
|
||||||
|
return ssg.success;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
int sput(char *name, hdbValue v)
|
||||||
|
{
|
||||||
|
SSGMessage ssg;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
ssg.success = 0;
|
||||||
|
ssg.name = strdup(name);
|
||||||
|
ssg.v = &v;
|
||||||
|
|
||||||
|
MPprocess(setPipe,&ssg);
|
||||||
|
free(ssg.name);
|
||||||
|
|
||||||
|
return ssg.success;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static int SICSGetCommand(SConnection * pCon, SicsInterp * pSics, void *pData,
|
||||||
|
int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
hdbValue v;
|
||||||
|
pDynString data;
|
||||||
|
|
||||||
|
if(argc < 2) {
|
||||||
|
SCWrite(pCon,"ERROR: need at least address for sicsget",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = sget(argv[1], &v);
|
||||||
|
if(status){
|
||||||
|
data = formatValue(v,NULL);
|
||||||
|
if(data != NULL){
|
||||||
|
SCPrintf(pCon,eValue,"%s",GetCharArray(data));
|
||||||
|
DeleteDynString(data);
|
||||||
|
} else {
|
||||||
|
SCPrintf(pCon,eError,"ERROR: formatting value for %s failed", argv[1]);
|
||||||
|
ReleaseHdbValue(&v);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SCPrintf(pCon,eError,"ERROR: value for %s not found", argv[1]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ReleaseHdbValue(&v);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static int SICSPutCommand(SConnection * pCon, SicsInterp * pSics, void *pData,
|
||||||
|
int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
hdbValue v;
|
||||||
|
char buffer[2048];
|
||||||
|
char error[132];
|
||||||
|
|
||||||
|
if(argc < 2) {
|
||||||
|
SCWrite(pCon,"ERROR: need at least address for sicsget",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = sget(argv[1],&v);
|
||||||
|
if(!status){
|
||||||
|
SCPrintf(pCon,eError,"ERROR: %s not found",argv[1]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Arg2Text(argc-2, &argv[2], buffer,sizeof(buffer));
|
||||||
|
status = readHdbValue(&v,buffer,error,sizeof(error));
|
||||||
|
if(status == 0){
|
||||||
|
SCPrintf(pCon,eError,"ERROR: failed to parse data for %s, error %s",
|
||||||
|
argv[1], error);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = sput(argv[1],v);
|
||||||
|
if(status == 0){
|
||||||
|
SCPrintf(pCon,eError,"ERROR: error setting %s, value invalid?",
|
||||||
|
argv[1]);
|
||||||
|
} else {
|
||||||
|
SCSendOK(pCon);
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static int InvokeSICSFunc(void *ms, void *userData)
|
||||||
|
{
|
||||||
|
pParseMessage self = (pParseMessage)ms;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
SCsetMacro(pServ->dummyCon,1);
|
||||||
|
status = InterpExecute(pServ->pSics, pServ->dummyCon, self->command);
|
||||||
|
SCsetMacro(pServ->dummyCon,0);
|
||||||
|
if(!status){
|
||||||
|
self->success = 0;
|
||||||
|
return MPSTOP;
|
||||||
|
}
|
||||||
|
self->response = strdup(Tcl_GetStringResult(InterpGetTcl(pServ->pSics)));
|
||||||
|
return MPCONTINUE;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int CheckSICSError(void *ms, void *userData)
|
||||||
|
{
|
||||||
|
pParseMessage self = (pParseMessage)ms;
|
||||||
|
|
||||||
|
if(strstr(self->response,"ERROR") != NULL){
|
||||||
|
self->success = 0;
|
||||||
|
return MPSTOP;
|
||||||
|
}
|
||||||
|
return MPCONTINUE;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int SplitOffEqual(void *ms, void *userData)
|
||||||
|
{
|
||||||
|
pParseMessage self = (pParseMessage)ms;
|
||||||
|
char *pPtr, *pEQ;
|
||||||
|
|
||||||
|
pPtr = self->response;
|
||||||
|
if((pEQ = strstr(pPtr, "=")) != NULL){
|
||||||
|
self->response = strdup(trim(pEQ+1));
|
||||||
|
free(pPtr);
|
||||||
|
}
|
||||||
|
return MPCONTINUE;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static int isNumber(char *txt)
|
||||||
|
{
|
||||||
|
if(*txt == '\0'){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(isalpha(*txt)){
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return isNumber(txt+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static int countWords(char *txt)
|
||||||
|
{
|
||||||
|
char number[80];
|
||||||
|
|
||||||
|
if(txt == NULL){
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return 1 + countWords(stptok(txt,number,sizeof(number)," "));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static hdbValue makeArray(char *txt, int type, int count)
|
||||||
|
{
|
||||||
|
hdbValue ar;
|
||||||
|
char *pPtr;
|
||||||
|
char number[80];
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
if(type == HIPINT){
|
||||||
|
ar = makeHdbValue(HIPINTAR,count);
|
||||||
|
} else {
|
||||||
|
ar = makeHdbValue(HIPFLOATAR,count);
|
||||||
|
}
|
||||||
|
pPtr = txt;
|
||||||
|
while((pPtr = stptok(pPtr,number,sizeof(number)," ")) != NULL){
|
||||||
|
if(type == HIPINT){
|
||||||
|
ar.v.intArray[i] = atoi(number);
|
||||||
|
} else {
|
||||||
|
ar.v.floatArray[i] = atof(number);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ar;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static int ReturnAsNumber(void *ms, void *userData)
|
||||||
|
{
|
||||||
|
pParseMessage self = (pParseMessage)ms;
|
||||||
|
int type, count;
|
||||||
|
hdbValue v;
|
||||||
|
|
||||||
|
if(isNumber(self->response)){
|
||||||
|
if(strstr(self->response,".") != NULL){
|
||||||
|
type = HIPFLOAT;
|
||||||
|
} else {
|
||||||
|
type = HIPINT;
|
||||||
|
}
|
||||||
|
count = countWords(self->response);
|
||||||
|
if(count > 1) {
|
||||||
|
v = makeArray(self->response, type, count);
|
||||||
|
} else {
|
||||||
|
if(type == HIPINT){
|
||||||
|
v = MakeHdbInt(atoi(self->response));
|
||||||
|
} else {
|
||||||
|
v = MakeHdbFloat(atof(self->response));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cloneHdbValue(&v,self->v);
|
||||||
|
ReleaseHdbValue(&v);
|
||||||
|
self->success = 1;
|
||||||
|
return MPSTOP;
|
||||||
|
} else {
|
||||||
|
return MPCONTINUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static int ReturnAsText(void *ms, void *userData)
|
||||||
|
{
|
||||||
|
hdbValue v;
|
||||||
|
|
||||||
|
pParseMessage self = (pParseMessage)ms;
|
||||||
|
self->success = 1;
|
||||||
|
v = MakeHdbText(strdup(self->response));
|
||||||
|
cloneHdbValue(&v,self->v);
|
||||||
|
ReleaseHdbValue(&v);
|
||||||
|
return MPCONTINUE;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static void configureSICSPipe()
|
||||||
|
{
|
||||||
|
sicsPipe = MakeMP();
|
||||||
|
AppendMPFilter(sicsPipe, InvokeSICSFunc, NULL, NULL);
|
||||||
|
AppendMPFilter(sicsPipe, CheckSICSError, NULL, NULL);
|
||||||
|
AppendMPFilter(sicsPipe, SplitOffEqual, NULL, NULL);
|
||||||
|
AppendMPFilter(sicsPipe, ReturnAsNumber, NULL, NULL);
|
||||||
|
AppendMPFilter(sicsPipe, ReturnAsText, NULL, NULL);
|
||||||
|
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int FindTclVar(void *ms, void *userData)
|
||||||
|
{
|
||||||
|
pParseMessage self = (pParseMessage)ms;
|
||||||
|
|
||||||
|
self->response = Tcl_GetVar(InterpGetTcl(pServ->pSics),self->command, TCL_GLOBAL_ONLY);
|
||||||
|
if(self->response == NULL){
|
||||||
|
return MPSTOP;
|
||||||
|
}
|
||||||
|
return MPCONTINUE;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static void configureTclPipe()
|
||||||
|
{
|
||||||
|
tclPipe = MakeMP();
|
||||||
|
AppendMPFilter(tclPipe, FindTclVar, NULL, NULL);
|
||||||
|
AppendMPFilter(tclPipe, SplitOffEqual, NULL, NULL);
|
||||||
|
AppendMPFilter(tclPipe, ReturnAsNumber, NULL, NULL);
|
||||||
|
AppendMPFilter(tclPipe, ReturnAsText, NULL, NULL);
|
||||||
|
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int GetHdbFunc(void *ms, void *userData)
|
||||||
|
{
|
||||||
|
pSSGMessage self = (pSSGMessage)ms;
|
||||||
|
pHdb node = NULL;
|
||||||
|
|
||||||
|
node = FindHdbNode(NULL,self->name,NULL);
|
||||||
|
if(node != NULL){
|
||||||
|
cloneHdbValue(&node->value, self->v);
|
||||||
|
self->success = 1;
|
||||||
|
return MPSTOP;
|
||||||
|
} else {
|
||||||
|
return MPCONTINUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static int GetSICSFunc(void *ms, void *userData)
|
||||||
|
{
|
||||||
|
pSSGMessage self = (pSSGMessage)ms;
|
||||||
|
ParseMessage ps;
|
||||||
|
|
||||||
|
memset(&ps,0,sizeof(ParseMessage));
|
||||||
|
ps.command = strdup(self->name);
|
||||||
|
ps.v = self->v;
|
||||||
|
MPprocess(sicsPipe,&ps);
|
||||||
|
self->success = ps.success;
|
||||||
|
free(ps.command);
|
||||||
|
if(ps.response != NULL){
|
||||||
|
free(ps.response);
|
||||||
|
}
|
||||||
|
if(self->success){
|
||||||
|
return MPSTOP;
|
||||||
|
}
|
||||||
|
return MPCONTINUE;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static int GetTclFunc(void *ms, void *userData)
|
||||||
|
{
|
||||||
|
pSSGMessage self = (pSSGMessage)ms;
|
||||||
|
ParseMessage ps;
|
||||||
|
|
||||||
|
memset(&ps,0,sizeof(ParseMessage));
|
||||||
|
ps.command = strdup(self->name);
|
||||||
|
ps.v = self->v;
|
||||||
|
MPprocess(tclPipe,&ps);
|
||||||
|
self->success = ps.success;
|
||||||
|
free(ps.command);
|
||||||
|
if(self->success){
|
||||||
|
return MPSTOP;
|
||||||
|
}
|
||||||
|
return MPCONTINUE;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int GetDrivableFunc(void *ms, void *userData)
|
||||||
|
{
|
||||||
|
pSSGMessage self = (pSSGMessage)ms;
|
||||||
|
void *data = NULL;
|
||||||
|
pIDrivable pDriv = NULL;
|
||||||
|
float fVal;
|
||||||
|
hdbValue v;
|
||||||
|
|
||||||
|
data = FindCommandData(pServ->pSics, self->name,NULL);
|
||||||
|
if(data != NULL){
|
||||||
|
pDriv = GetDrivableInterface(data);
|
||||||
|
if(pDriv != NULL){
|
||||||
|
fVal = pDriv->GetValue(data,pServ->dummyCon);
|
||||||
|
v = MakeHdbFloat(fVal);
|
||||||
|
self->success = 1;
|
||||||
|
cloneHdbValue(&v,self->v);
|
||||||
|
return MPSTOP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return MPCONTINUE;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int GetSicsdataFunc(void *ms, void *userData)
|
||||||
|
{
|
||||||
|
pSSGMessage self = (pSSGMessage)ms;
|
||||||
|
pSICSData data = NULL;
|
||||||
|
hdbValue v;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
data = FindCommandData(pServ->pSics,self->name, "SICSData");
|
||||||
|
if(data != NULL){
|
||||||
|
if(data->dataType[0] == INTTYPE){
|
||||||
|
v = makeHdbValue(HIPINTVARAR, data->dataUsed);
|
||||||
|
for(i = 0; i < data->dataUsed; i++){
|
||||||
|
v.v.intArray[i] = data->data[i];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
v = makeHdbValue(HIPFLOATVARAR, data->dataUsed);
|
||||||
|
for(i = 0; i < data->dataUsed; i++){
|
||||||
|
v.v.floatArray[i] = (double)data->data[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cloneHdbValue(&v, self->v);
|
||||||
|
ReleaseHdbValue(&v);
|
||||||
|
self->success = 1;
|
||||||
|
return MPSTOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MPCONTINUE;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static void configureGetPipe()
|
||||||
|
{
|
||||||
|
getPipe = MakeMP();
|
||||||
|
AppendMPFilter(getPipe, GetHdbFunc, NULL, NULL);
|
||||||
|
AppendMPFilter(getPipe, GetDrivableFunc, NULL, NULL);
|
||||||
|
AppendMPFilter(getPipe, GetSicsdataFunc, NULL, NULL);
|
||||||
|
AppendMPFilter(getPipe, GetSICSFunc, NULL, NULL);
|
||||||
|
AppendMPFilter(getPipe, GetTclFunc, NULL, NULL);
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int PutHdbFunc(void *ms, void *userData)
|
||||||
|
{
|
||||||
|
pSSGMessage self = (pSSGMessage)ms;
|
||||||
|
pHdb node = NULL;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
node = FindHdbNode(NULL,self->name,NULL);
|
||||||
|
if(node != NULL){
|
||||||
|
status = UpdateHipadabaPar(node,*(self->v),NULL);
|
||||||
|
self->success = status;
|
||||||
|
if(status == 1){
|
||||||
|
return MPSTOP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return MPCONTINUE;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int PutSICSFunc(void *ms, void *userData)
|
||||||
|
{
|
||||||
|
pSSGMessage self = (pSSGMessage)ms;
|
||||||
|
pDynString data = NULL;
|
||||||
|
int status;
|
||||||
|
char sicsobj[80];
|
||||||
|
void *cdata;
|
||||||
|
|
||||||
|
|
||||||
|
data = formatValue(*(self->v),NULL);
|
||||||
|
if(data != NULL){
|
||||||
|
DynStringInsert(data," ", 0);
|
||||||
|
DynStringInsert(data,self->name, 0);
|
||||||
|
status = InterpExecute(pServ->pSics, pServ->dummyCon, GetCharArray(data));
|
||||||
|
DeleteDynString(data);
|
||||||
|
if(status == 1) {
|
||||||
|
self->success = 1;
|
||||||
|
return MPSTOP;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
Without this test bad sets on SICS commands may fall
|
||||||
|
through to Tcl where they succedd
|
||||||
|
*/
|
||||||
|
stptok(self->name,sicsobj,sizeof(sicsobj)," ");
|
||||||
|
cdata = FindCommandData(pServ->pSics,sicsobj,NULL);
|
||||||
|
if(cdata != NULL){
|
||||||
|
self->success = 0;
|
||||||
|
return MPSTOP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return MPCONTINUE;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int PutTclFunc(void *ms, void *userData)
|
||||||
|
{
|
||||||
|
pSSGMessage self = (pSSGMessage)ms;
|
||||||
|
pDynString data = NULL;
|
||||||
|
int status;
|
||||||
|
char *pPtr = NULL;
|
||||||
|
|
||||||
|
data = formatValue(*(self->v),NULL);
|
||||||
|
if(data != NULL){
|
||||||
|
pPtr = Tcl_SetVar(InterpGetTcl(pServ->pSics),self->name,GetCharArray(data),TCL_GLOBAL_ONLY);
|
||||||
|
DeleteDynString(data);
|
||||||
|
if(pPtr != NULL) {
|
||||||
|
self->success = 1;
|
||||||
|
return MPSTOP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return MPCONTINUE;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int PutDrivableFunc(void *ms, void *userData)
|
||||||
|
{
|
||||||
|
pSSGMessage self = (pSSGMessage)ms;
|
||||||
|
void *data = NULL;
|
||||||
|
pIDrivable pDriv = NULL;
|
||||||
|
float fVal;
|
||||||
|
hdbValue v;
|
||||||
|
|
||||||
|
data = FindCommandData(pServ->pSics, self->name,NULL);
|
||||||
|
if(data != NULL){
|
||||||
|
pDriv = GetDrivableInterface(data);
|
||||||
|
if(pDriv != NULL){
|
||||||
|
StartMotor(pServ->pExecutor,pServ->pSics, pServ->dummyCon,
|
||||||
|
self->name, RUNRUN, (float)self->v->v.doubleValue);
|
||||||
|
self->success = 1;
|
||||||
|
return MPSTOP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return MPCONTINUE;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int PutSicsdataFunc(void *ms, void *userData)
|
||||||
|
{
|
||||||
|
pSSGMessage self = (pSSGMessage)ms;
|
||||||
|
pSICSData data = NULL;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
data = FindCommandData(pServ->pSics,self->name, "SICSData");
|
||||||
|
if(data != NULL){
|
||||||
|
if(self->v->dataType == HIPINTAR || self->v->dataType == HIPINTVARAR){
|
||||||
|
for(i = 0; i < self->v->arrayLength; i++){
|
||||||
|
setSICSDataInt(data,i,self->v->v.intArray[i]);
|
||||||
|
}
|
||||||
|
} else if(self->v->dataType == HIPFLOATAR || self->v->dataType == HIPFLOATVARAR){
|
||||||
|
for(i = 0; i < self->v->arrayLength; i++){
|
||||||
|
setSICSDataFloat(data,i,(float)self->v->v.floatArray[i]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return MPSTOP;
|
||||||
|
}
|
||||||
|
self->success = 1;
|
||||||
|
return MPSTOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MPCONTINUE;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static void configureSetPipe()
|
||||||
|
{
|
||||||
|
setPipe = MakeMP();
|
||||||
|
AppendMPFilter(setPipe, PutHdbFunc, NULL, NULL);
|
||||||
|
AppendMPFilter(setPipe, PutDrivableFunc, NULL, NULL);
|
||||||
|
AppendMPFilter(setPipe, PutSicsdataFunc, NULL, NULL);
|
||||||
|
AppendMPFilter(setPipe, PutSICSFunc, NULL, NULL);
|
||||||
|
AppendMPFilter(setPipe, PutTclFunc, NULL, NULL);
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
void SICSGetInit(void)
|
||||||
|
{
|
||||||
|
if (getPipe == NULL) {
|
||||||
|
configureGetPipe();
|
||||||
|
configureSetPipe();
|
||||||
|
configureSICSPipe();
|
||||||
|
configureTclPipe();
|
||||||
|
AddCmd("sget", SICSGetCommand);
|
||||||
|
AddCmd("sput", SICSPutCommand);
|
||||||
|
}
|
||||||
|
}
|
30
sicsget.h
Normal file
30
sicsget.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* This is a generalized SICS get/put routine. It tries to hard to match a name
|
||||||
|
* with the data.
|
||||||
|
*
|
||||||
|
* copyright: see file COPYRIGHT
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef __SICSGET
|
||||||
|
#define __SICSGET
|
||||||
|
#include <hipadaba.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a SICS value
|
||||||
|
* @param name The name of the value to get
|
||||||
|
* @param v The output hdbValue
|
||||||
|
* @return 1 on success, 0 on failure
|
||||||
|
*/
|
||||||
|
int sget(char *name, hdbValue *v);
|
||||||
|
/**
|
||||||
|
* Put a SICS value
|
||||||
|
* @param name The name of the value to write to
|
||||||
|
* @param v The hdbValue to write
|
||||||
|
* @return 1 on success, 0 on failure
|
||||||
|
*/
|
||||||
|
int sput(char *name, hdbValue v);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
Reference in New Issue
Block a user