- 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 \
|
||||
rwpuffer.o asynnet.o background.o countersec.o hdbtable.o velosec.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
|
||||
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(SctDriveObjInit);
|
||||
INIT(SctDriveAdapterInit);
|
||||
INIT(SICSGetInit);
|
||||
INIT(LogReaderInit);
|
||||
INIT(LogSetupInit);
|
||||
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