- Scriptcontext debugged to be working
- Added a drivable adapter to scriptcontext nodes - Added subsampling to simulated histograms (and as a general option) in order to support Gumtree testing.
This commit is contained in:
201
scriptcontext.c
201
scriptcontext.c
@@ -11,6 +11,9 @@
|
||||
#include "sicshipadaba.h"
|
||||
#include "dynstring.h"
|
||||
#include "devser.h"
|
||||
#include "ascon.h"
|
||||
#include "macro.h"
|
||||
|
||||
|
||||
#define MAX_HDB_PATH 1024
|
||||
|
||||
@@ -128,12 +131,18 @@ static char *GetProp(Hdb *node, Hdb *cNode, char *key) {
|
||||
return val;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the actual sct command available in scripts.
|
||||
*/
|
||||
int SctCommand(SConnection *con, SicsInterp *sics, void *object,
|
||||
int argc, char *argv[]) {
|
||||
static char value[1024];
|
||||
char *val;
|
||||
char error[512];
|
||||
Hdb *node = sct->nodes->node;
|
||||
Hdb *cNode = sct->nodes->controllerNode;
|
||||
hdbValue v;
|
||||
double dtime;
|
||||
|
||||
assert(sct == object);
|
||||
if (node == NULL && cNode == NULL) {
|
||||
@@ -146,6 +155,49 @@ int SctCommand(SConnection *con, SicsInterp *sics, void *object,
|
||||
SCWrite(con, value, eValue);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* update command
|
||||
*/
|
||||
if(strcmp(argv[1],"update") == 0){
|
||||
cloneHdbValue(&node->value, &v);
|
||||
Arg2Text(argc-2, argv+2, value, sizeof value);
|
||||
if(!readHdbValue(&v, value, error, 512)){
|
||||
SCWrite(con, error, eError);
|
||||
return 0;
|
||||
}
|
||||
UpdateHipadabaPar(node,v,con);
|
||||
SetHdbProperty(node,"geterror", NULL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* print
|
||||
*/
|
||||
if(strcmp(argv[1],"print") == 0){
|
||||
Arg2Text(argc-2, argv+2, value, sizeof value);
|
||||
SCWrite(con,value,eWarning);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* time stamping
|
||||
*/
|
||||
if(strcmp(argv[1],"utime") == 0){
|
||||
if(argc < 3){
|
||||
SCWrite(con,"ERROR: need property to write time stamp too",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
dtime = DoubleTime();
|
||||
snprintf(value,1024,"%ld",(long)dtime);
|
||||
SetHdbProperty(node,argv[2], value);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* property handling
|
||||
*/
|
||||
if (argc == 2) { /* get case */
|
||||
val = GetProp(node, cNode, argv[1]);
|
||||
if (val == NULL) {
|
||||
@@ -154,9 +206,9 @@ int SctCommand(SConnection *con, SicsInterp *sics, void *object,
|
||||
}
|
||||
SCWrite(con, val, eValue);
|
||||
} else { /* set case */
|
||||
val = Arg2Tcl(argc-2, argv+2, value, sizeof value);
|
||||
SetProp(node, cNode, argv[1], val);
|
||||
if (val != NULL && val != value) free(val);
|
||||
val = Arg2Tcl(argc-2, argv+2, value, sizeof value);
|
||||
SetProp(node, cNode, argv[1], val);
|
||||
if (val != NULL && val != value) free(val);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -174,6 +226,7 @@ int SctCallInContext(SConnection *con, char *script, Hdb *node,
|
||||
SCPrintf(con, eInError, "\nscript: %s\n", script);
|
||||
}
|
||||
|
||||
MacroPush(con);
|
||||
l = strlen(script);
|
||||
ret = Tcl_EvalEx(pTcl, script, l, 0);
|
||||
result = (char *)Tcl_GetStringResult(pTcl);
|
||||
@@ -185,7 +238,7 @@ int SctCallInContext(SConnection *con, char *script, Hdb *node,
|
||||
}
|
||||
*resPtr = result;
|
||||
|
||||
PopContext();
|
||||
MacroPop();
|
||||
PopContext();
|
||||
return iRet;
|
||||
}
|
||||
@@ -359,19 +412,21 @@ static hdbCallbackReturn SctActionCallback(Hdb *node, void *userData,
|
||||
mm = GetHdbSetMessage(msg);
|
||||
if (mm != NULL && data->writable) {
|
||||
con = mm->callData;
|
||||
|
||||
/* set target value */
|
||||
text = formatValue(*(mm->v), node);
|
||||
SetHdbProperty(node, "target", GetCharArray(text));
|
||||
|
||||
/* call check script, if available */
|
||||
script = GetProp(node, data->controller->node, "check");
|
||||
if (script != NULL) {
|
||||
if (SctCallInContext(con, script, node, data->controller, &error) == 0) {
|
||||
SCPrintf(con, eError, "ERROR: %s", error);
|
||||
SetHdbProperty(node,"target", NULL);
|
||||
return hdbAbort;
|
||||
}
|
||||
}
|
||||
|
||||
/* set target value */
|
||||
text = formatValue(*(mm->v), node);
|
||||
SetHdbProperty(node, "target", GetCharArray(text));
|
||||
|
||||
/* enqueue write action */
|
||||
writeprio = GetProp(node, data->controller->node, "writeprio");
|
||||
@@ -494,6 +549,7 @@ static int SctPollCmd(pSICSOBJ ccmd, SConnection *con,
|
||||
SCPrintf(con, eError, "ERROR: %s not found", path);
|
||||
return 0;
|
||||
}
|
||||
SetHdbProperty(node,"geterror","Not read yet");
|
||||
interval = ParValue(cmdNode, "interval");
|
||||
prio = DevText2Prio(ParText(cmdNode, "prio"));
|
||||
action = ParText(cmdNode, "action");
|
||||
@@ -505,6 +561,36 @@ static int SctPollCmd(pSICSOBJ ccmd, SConnection *con,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int SctConnectCmd(pSICSOBJ ccmd, SConnection *con,
|
||||
Hdb *cmdNode, Hdb *par[], int nPar) {
|
||||
Hdb *node;
|
||||
SctController *controller;
|
||||
char *path;
|
||||
hdbCallback *cb;
|
||||
|
||||
if(nPar < 1){
|
||||
SCPrintf(con,eError,
|
||||
"ERROR: should be: %s connect <node> ",
|
||||
ccmd->objectNode->name);
|
||||
return 0;
|
||||
}
|
||||
controller = ccmd->pPrivate;
|
||||
path = ParText(cmdNode, "node");
|
||||
node = FindHdbNode(NULL, path, con);
|
||||
if (node == NULL) {
|
||||
SCPrintf(con, eError, "ERROR: %s not found", path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (! FindHdbCallbackData(node, controller)) {
|
||||
cb = MakeHipadabaCallback(SctMainCallback, controller, NULL);
|
||||
assert(cb);
|
||||
AppendHipadabaCallback(node, cb);
|
||||
}
|
||||
SCSendOK(con);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SctAddWriteNode(SctController *controller, Hdb *node) {
|
||||
hdbCallback *cb;
|
||||
SctData *data;
|
||||
@@ -619,6 +705,87 @@ static int SctQueueCmd(pSICSOBJ ccmd, SConnection *con,
|
||||
return 1;
|
||||
}
|
||||
|
||||
typedef struct SctTransact {
|
||||
char *command;
|
||||
int sent;
|
||||
SConnection *con;
|
||||
}SctTransact, *pSctTransact;
|
||||
|
||||
static void KillSctTransact(void *data){
|
||||
pSctTransact self = (pSctTransact)data;
|
||||
if(self == NULL){
|
||||
return;
|
||||
}
|
||||
if(self->command){
|
||||
free(self->command);
|
||||
}
|
||||
free(self);
|
||||
}
|
||||
|
||||
static char *TransactionHandler(void *actionData, char *lastReply){
|
||||
pSctTransact st = (pSctTransact)actionData;
|
||||
|
||||
if(st->sent == 0){
|
||||
st->sent = 1;
|
||||
return st->command;
|
||||
} else {
|
||||
st->sent = 2;
|
||||
SCWrite(st->con,lastReply, eValue);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
static int SctTransactMatch(void *d1, void *d2){
|
||||
return d1 == d2;
|
||||
}
|
||||
|
||||
static int SctTransactCmd(pSICSOBJ ccmd, SConnection *con,
|
||||
Hdb *cmdNode, Hdb *par[], int nPar) {
|
||||
pSctTransact st = NULL;
|
||||
SctController *c;
|
||||
|
||||
c = (SctController *)ccmd->pPrivate;
|
||||
|
||||
st = calloc(sizeof(SctTransact),1);
|
||||
if(st == NULL){
|
||||
SCWrite(con,"ERROR: out of memory in SctTransactCommand", eError);
|
||||
return 0;
|
||||
}
|
||||
st->con = con;
|
||||
st->command = strdup(par[0]->value.v.text);
|
||||
|
||||
DevQueue(c->devser, st, WritePRIO,
|
||||
TransactionHandler, SctTransactMatch, NULL);
|
||||
while(st->sent != 2){
|
||||
TaskYield(pServ->pTasker);
|
||||
if(SCGetInterrupt(con) != eContinue){
|
||||
break;
|
||||
}
|
||||
}
|
||||
KillSctTransact(st);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int SctQueueComCmd(pSICSOBJ ccmd, SConnection *con,
|
||||
Hdb *cmdNode, Hdb *par[], int nPar) {
|
||||
pSctTransact st = NULL;
|
||||
SctController *c;
|
||||
|
||||
c = (SctController *)ccmd->pPrivate;
|
||||
|
||||
st = calloc(sizeof(SctTransact),1);
|
||||
if(st == NULL){
|
||||
SCWrite(con,"ERROR: out of memory in SctTransactCommand", eError);
|
||||
return 0;
|
||||
}
|
||||
st->con = con;
|
||||
st->command = strdup(par[0]->value.v.text);
|
||||
|
||||
DevQueue(c->devser, st, WritePRIO,
|
||||
TransactionHandler, SctTransactMatch, KillSctTransact);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static hdbCallbackReturn SctDebugCallback(Hdb *node, void *userData,
|
||||
hdbMessage *msg) {
|
||||
hdbDataMessage *mm;
|
||||
@@ -648,7 +815,7 @@ static void SctKillController(void *c) {
|
||||
|
||||
CleanStack(controller->node);
|
||||
RemoveSICSInternalCallback(controller);
|
||||
DevKill(controller->devser);
|
||||
/* devser is killed by task function */
|
||||
}
|
||||
|
||||
static int SctMakeController(SConnection *con, SicsInterp *sics,
|
||||
@@ -696,6 +863,10 @@ static int SctMakeController(SConnection *con, SicsInterp *sics,
|
||||
AddSICSHdbPar(cmd, "interval", usMugger, MakeHdbFloat(5.0));
|
||||
AddSICSHdbPar(cmd, "prio", usMugger, MakeHdbText("read"));
|
||||
AddSICSHdbPar(cmd, "action", usMugger, MakeHdbText("read"));
|
||||
|
||||
cmd = AddSICSHdbPar(controller->node,
|
||||
"connect", usMugger, MakeSICSFunc(SctConnectCmd));
|
||||
AddSICSHdbPar(cmd, "node", usMugger, MakeHdbText(""));
|
||||
|
||||
cmd = AddSICSHdbPar(controller->node,
|
||||
"write", usMugger, MakeSICSFunc(SctWriteCmd));
|
||||
@@ -708,6 +879,15 @@ static int SctMakeController(SConnection *con, SicsInterp *sics,
|
||||
AddSICSHdbPar(cmd, "prio", usMugger, MakeHdbText("write"));
|
||||
AddSICSHdbPar(cmd, "action", usMugger, MakeHdbText("write"));
|
||||
|
||||
cmd = AddSICSHdbPar(controller->node,
|
||||
"transact", usMugger, MakeSICSFunc(SctTransactCmd));
|
||||
AddSICSHdbPar(cmd, "data", usMugger, MakeHdbText(""));
|
||||
|
||||
cmd = AddSICSHdbPar(controller->node,
|
||||
"queuecom", usMugger, MakeSICSFunc(SctQueueComCmd));
|
||||
AddSICSHdbPar(cmd, "data", usMugger, MakeHdbText(""));
|
||||
|
||||
|
||||
par = AddSICSHdbPar(controller->node, "debug", usUser, MakeHdbInt(0));
|
||||
|
||||
cb = MakeHipadabaCallback(SctDebugCallback, controller, NULL);
|
||||
@@ -738,6 +918,10 @@ void SctKill(void *object) {
|
||||
sct = NULL;
|
||||
}
|
||||
|
||||
/* from sctdriveadapter.c */
|
||||
int SctMakeDriveAdapter(SConnection *pCon, SicsInterp *pSics, void *object,
|
||||
int argc, char *argv[]);
|
||||
|
||||
void SctInit(void) {
|
||||
if (sct) return;
|
||||
sct = calloc(1, sizeof(*sct));
|
||||
@@ -747,4 +931,5 @@ void SctInit(void) {
|
||||
sct->base = sct->nodes;
|
||||
AddCommand(pServ->pSics, "sct", SctCommand, SctKill, sct);
|
||||
AddCmd("makesctcontroller", SctMakeController);
|
||||
AddCmd("makesctdrive", SctMakeDriveAdapter);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user