- unified the 2 script context commands
- minor changes in hipadaba and ascon/devser
This commit is contained in:
10
ascon.c
10
ascon.c
@ -75,9 +75,9 @@ static void AsconError(Ascon *a, char *msg, int errorno) {
|
|||||||
state = stateText[a->state];
|
state = stateText[a->state];
|
||||||
}
|
}
|
||||||
if (errorno != 0) {
|
if (errorno != 0) {
|
||||||
ErrPutMsg(&a->errList, NULL, "%s %s (during %s)", msg, strerror(errorno), state);
|
ErrPutMsg(a->errList, "%s %s (during %s)", msg, strerror(errorno), state);
|
||||||
} else {
|
} else {
|
||||||
ErrPutMsg(&a->errList, NULL, "%s (during %s)", msg, state);
|
ErrPutMsg(a->errList, "%s (during %s)", msg, state);
|
||||||
}
|
}
|
||||||
a->state |= AsconFailed;
|
a->state |= AsconFailed;
|
||||||
}
|
}
|
||||||
@ -400,7 +400,7 @@ Ascon *AsconMake(SConnection *con, int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
a->rdBuffer = CreateDynString(60, 63);
|
a->rdBuffer = CreateDynString(60, 63);
|
||||||
a->wrBuffer = CreateDynString(60, 63);
|
a->wrBuffer = CreateDynString(60, 63);
|
||||||
a->errList.head = NULL;
|
a->errList = NULL;
|
||||||
a->responseValid = 0;
|
a->responseValid = 0;
|
||||||
a->timeout = 2.0;
|
a->timeout = 2.0;
|
||||||
a->reconnectInterval = 10;
|
a->reconnectInterval = 10;
|
||||||
@ -500,6 +500,6 @@ char *AsconRead(Ascon *a) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrMsgList *AsconGetErrList(Ascon *a) {
|
ErrMsg *AsconGetErrList(Ascon *a) {
|
||||||
return &a->errList;
|
return a->errList;
|
||||||
}
|
}
|
||||||
|
2
ascon.h
2
ascon.h
@ -64,7 +64,7 @@ char *AsconRead(Ascon *a);
|
|||||||
/** \brief get the connections error list
|
/** \brief get the connections error list
|
||||||
* \return the error list
|
* \return the error list
|
||||||
*/
|
*/
|
||||||
ErrMsgList *AsconGetErrList(Ascon *a);
|
ErrMsg *AsconGetErrList(Ascon *a);
|
||||||
|
|
||||||
/** \brief a helper function
|
/** \brief a helper function
|
||||||
* \param argc the number of args
|
* \param argc the number of args
|
||||||
|
2
ascon.i
2
ascon.i
@ -64,7 +64,7 @@ struct Ascon {
|
|||||||
int wrPos; /**< write buffer position */
|
int wrPos; /**< write buffer position */
|
||||||
double timeout; /**< read timeout (sec) */
|
double timeout; /**< read timeout (sec) */
|
||||||
char *hostport; /**< host:port to connect */
|
char *hostport; /**< host:port to connect */
|
||||||
ErrMsgList errList; /**< error message list */
|
ErrMsg *errList; /**< error message list */
|
||||||
double start; /**< unix time when read was started */
|
double start; /**< unix time when read was started */
|
||||||
void *private; /**< private data of protocol */
|
void *private; /**< private data of protocol */
|
||||||
int noResponse; /**< no response expected */
|
int noResponse; /**< no response expected */
|
||||||
|
3
devser.c
3
devser.c
@ -117,7 +117,8 @@ int DevQueueTask(void *ds) {
|
|||||||
while (action != NULL) {
|
while (action != NULL) {
|
||||||
status = AsconTask(devser->asyncConn);
|
status = AsconTask(devser->asyncConn);
|
||||||
if (status == AsconFailure) {
|
if (status == AsconFailure) {
|
||||||
/* TODO: error handling */
|
devser->errmsg = AsconGetErrList(devser->asyncConn);
|
||||||
|
return 1;
|
||||||
} else if (status != AsconReady) {
|
} else if (status != AsconReady) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
54
errormsg.c
54
errormsg.c
@ -4,13 +4,30 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "errormsg.h"
|
#include "errormsg.h"
|
||||||
|
|
||||||
/* ErrMsgList implementation */
|
/* compare two strings for euqality, ignoring text within square brackets */
|
||||||
#define MC_NAME(T) ErrMsg##T
|
int ErrEqual(char *str1, char *str2) {
|
||||||
#define MC_IMPLEMENTATION
|
char *p;
|
||||||
#include "mclist.c"
|
|
||||||
|
|
||||||
ErrMsg *ErrPutMsg(ErrMsgList *dump, char *data, char *fmt, ...) {
|
while (*str1 != '\0' || *str2 != '\0') {
|
||||||
ErrMsg *m, *p;
|
if (*str1 != *str2) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (*str1 == '[') {
|
||||||
|
str1 = strchr(str1, ']');
|
||||||
|
str2 = strchr(str2, ']');
|
||||||
|
if (str1 == NULL || str2 == NULL) {
|
||||||
|
return str1 == str2;
|
||||||
|
}
|
||||||
|
str1++;
|
||||||
|
str2++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrMsg *ErrPutMsg(ErrMsg *dump, char *fmt, ...) {
|
||||||
|
ErrMsg *m;
|
||||||
|
ErrMsg **last;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
char buf[256];
|
char buf[256];
|
||||||
char *text;
|
char *text;
|
||||||
@ -28,36 +45,23 @@ ErrMsg *ErrPutMsg(ErrMsgList *dump, char *data, char *fmt, ...) {
|
|||||||
vsnprintf(text, l, fmt, ap);
|
vsnprintf(text, l, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
for (last = &dump; *last != NULL; last = &m->next) {
|
||||||
m = NULL;
|
m = *last;
|
||||||
for (p = ErrMsgFirst(dump); p!= NULL; p = ErrMsgNext(dump)) {
|
if (ErrEqual(text, m->text)) {
|
||||||
if (strcmp(text, p->text) == 0) {
|
*last = m->next;
|
||||||
m = ErrMsgTake(dump);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m == NULL) {
|
if (m == NULL) {
|
||||||
|
if (text == buf) text = strdup(buf);
|
||||||
m = calloc(1, sizeof(*m));
|
m = calloc(1, sizeof(*m));
|
||||||
if (text == buf) {
|
|
||||||
m->text = strdup(text);
|
|
||||||
} else {
|
|
||||||
m->text = text;
|
m->text = text;
|
||||||
}
|
|
||||||
m->data = NULL;
|
|
||||||
m->cnt = 1;
|
m->cnt = 1;
|
||||||
} else {
|
} else {
|
||||||
if (text != buf) free(text);
|
if (text != buf) free(text);
|
||||||
m->cnt++;
|
m->cnt++;
|
||||||
}
|
}
|
||||||
if (m->data) {
|
m->next = dump;
|
||||||
free(m->data);
|
|
||||||
m->data = NULL;
|
|
||||||
}
|
|
||||||
if (data) {
|
|
||||||
m->data = strdup(data);
|
|
||||||
}
|
|
||||||
ErrMsgFirst(dump);
|
|
||||||
ErrMsgInsert(dump, m);
|
|
||||||
time(&m->last);
|
time(&m->last);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
16
errormsg.h
16
errormsg.h
@ -11,20 +11,22 @@
|
|||||||
typedef struct ErrMsg {
|
typedef struct ErrMsg {
|
||||||
struct ErrMsg *next;
|
struct ErrMsg *next;
|
||||||
char *text; /**< the message text */
|
char *text; /**< the message text */
|
||||||
char *data; /**< additional text which may be different for the same message */
|
char *cmpr; /**< compressed message text */
|
||||||
int cnt; /**< count */
|
int cnt; /**< count */
|
||||||
time_t last; /**< time of last message */
|
time_t last; /**< time of last message */
|
||||||
} ErrMsg;
|
} ErrMsg;
|
||||||
|
|
||||||
/* define type ErrMsgList and functions ErrMsgAdd etc. */
|
|
||||||
#define MC_NAME(T) ErrMsg##T
|
|
||||||
#include "mclist.h"
|
|
||||||
|
|
||||||
/** \brief Put a formatted message to the error message list
|
/** \brief Put a formatted message to the error message list
|
||||||
|
*
|
||||||
|
* The error message list contains only one entry for all messages
|
||||||
|
* with the same text, storing only the count and the last used time.
|
||||||
|
* Characters within sqaure brackets are not taken into account
|
||||||
|
* when comparing messages.
|
||||||
|
*
|
||||||
* \param dump the error message list
|
* \param dump the error message list
|
||||||
* \param data some additional text (may be NULL)
|
|
||||||
* \param fmt the format for the message
|
* \param fmt the format for the message
|
||||||
|
* \return the new error message list head
|
||||||
*/
|
*/
|
||||||
ErrMsg *ErrPutMsg(ErrMsgList *dump, char *data, char *fmt, ...);
|
ErrMsg *ErrPutMsg(ErrMsg *dump, char *fmt, ...);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -914,7 +914,9 @@ static int calcDataLength(pHdb node, int testLength){
|
|||||||
/*============================= Property Functions ==========================*/
|
/*============================= Property Functions ==========================*/
|
||||||
void SetHdbProperty(pHdb node, char *key, char *value){
|
void SetHdbProperty(pHdb node, char *key, char *value){
|
||||||
if(node != NULL && key != NULL && node->properties != NULL){
|
if(node != NULL && key != NULL && node->properties != NULL){
|
||||||
if(StringDictExists(node->properties, key)){
|
if (value == NULL) {
|
||||||
|
StringDictDelete(node->properties, key);
|
||||||
|
} else if(StringDictExists(node->properties, key)){
|
||||||
StringDictUpdate(node->properties,key,value);
|
StringDictUpdate(node->properties,key,value);
|
||||||
} else {
|
} else {
|
||||||
StringDictAddPair(node->properties,key,value);
|
StringDictAddPair(node->properties,key,value);
|
||||||
|
214
scriptcontext.c
214
scriptcontext.c
@ -17,16 +17,19 @@
|
|||||||
|
|
||||||
#define MAX_HDB_PATH 1024
|
#define MAX_HDB_PATH 1024
|
||||||
|
|
||||||
|
typedef struct ContextItem {
|
||||||
|
struct ContextItem *next;
|
||||||
|
Hdb *node;
|
||||||
|
Hdb *controllerNode;
|
||||||
|
} ContextItem;
|
||||||
|
|
||||||
typedef struct ScriptContext {
|
typedef struct ScriptContext {
|
||||||
ObjectDescriptor *desc;
|
ObjectDescriptor *desc;
|
||||||
Hdb *node;
|
ContextItem *nodes;
|
||||||
|
ContextItem *trash;
|
||||||
|
ContextItem *base;
|
||||||
} ScriptContext;
|
} ScriptContext;
|
||||||
|
|
||||||
typedef struct ContextStack {
|
|
||||||
struct ContextStack *next;
|
|
||||||
Hdb *node;
|
|
||||||
} ContextStack;
|
|
||||||
|
|
||||||
typedef struct SctController {
|
typedef struct SctController {
|
||||||
DevSer *devser;
|
DevSer *devser;
|
||||||
Hdb *node; /* the controller node */
|
Hdb *node; /* the controller node */
|
||||||
@ -43,9 +46,7 @@ typedef struct SctData {
|
|||||||
Hdb *node; /* back link used by SctMatchWrite/SctMatchPoll */
|
Hdb *node; /* back link used by SctMatchWrite/SctMatchPoll */
|
||||||
} SctData;
|
} SctData;
|
||||||
|
|
||||||
static ScriptContext *nctx = NULL; /* the node context */
|
static ScriptContext *sct = NULL;
|
||||||
static ScriptContext *cctx = NULL; /* the controller context */
|
|
||||||
static ContextStack *stack, *stackTrash;
|
|
||||||
static SCStore *currentCon = NULL;
|
static SCStore *currentCon = NULL;
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
@ -54,31 +55,60 @@ static struct {
|
|||||||
|
|
||||||
static char *mainCallback = "main callback";
|
static char *mainCallback = "main callback";
|
||||||
|
|
||||||
void PushContext(Hdb *node) {
|
void PushContext(Hdb *node, Hdb *controllerNode) {
|
||||||
ContextStack *new;
|
ContextItem *new;
|
||||||
|
|
||||||
if (stackTrash == NULL) {
|
if (sct->trash == NULL) {
|
||||||
new = calloc(1, sizeof(*new));
|
new = calloc(1, sizeof(*new));
|
||||||
} else {
|
} else {
|
||||||
new = stackTrash;
|
new = sct->trash;
|
||||||
stackTrash = stackTrash->next;
|
sct->trash = sct->trash->next;
|
||||||
}
|
}
|
||||||
new->next = stack;
|
new->next = sct->nodes;
|
||||||
|
sct->nodes = new;
|
||||||
new->node = node;
|
new->node = node;
|
||||||
stack = new;
|
new->controllerNode = controllerNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
Hdb *PopContext(void) {
|
void PopContext(void) {
|
||||||
ContextStack *c;
|
ContextItem *c;
|
||||||
|
|
||||||
c = stack;
|
c = sct->nodes;
|
||||||
stack = stack->next;
|
assert(c);
|
||||||
c->next = stackTrash;
|
sct->nodes = c->next;
|
||||||
stackTrash = c;
|
c->next = sct->trash;
|
||||||
return c->node;
|
sct->trash = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetProp(Hdb *node, char *key, char *value) {
|
void CleanStack(Hdb *node) {
|
||||||
|
ContextItem *s;
|
||||||
|
|
||||||
|
/* clean context from killed nodes */
|
||||||
|
for (s = sct->nodes; s != NULL; s = s->next) {
|
||||||
|
if (s->node == node) {
|
||||||
|
s->node = NULL;
|
||||||
|
}
|
||||||
|
if (s->controllerNode == node) {
|
||||||
|
s->controllerNode = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetProp(Hdb *node, Hdb *cNode, char *key, char *value) {
|
||||||
|
char *val;
|
||||||
|
|
||||||
|
if (node == NULL) {
|
||||||
|
if (cNode == NULL) return;
|
||||||
|
node = cNode;
|
||||||
|
} else {
|
||||||
|
val = GetHdbProp(node, key);
|
||||||
|
if (val == NULL && cNode != NULL) {
|
||||||
|
val = GetHdbProp(cNode, key);
|
||||||
|
if (val != NULL) {
|
||||||
|
node = cNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (value == NULL) {
|
if (value == NULL) {
|
||||||
if (GetHdbProperty(node, key, NULL, 0) > 0) {
|
if (GetHdbProperty(node, key, NULL, 0) > 0) {
|
||||||
SetHdbProperty(node, key, "");
|
SetHdbProperty(node, key, "");
|
||||||
@ -88,14 +118,28 @@ static void SetProp(Hdb *node, char *key, char *value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *GetProp(Hdb *node, Hdb *cNode, char *key) {
|
||||||
|
char *val;
|
||||||
|
|
||||||
|
if (node != NULL) {
|
||||||
|
val = GetHdbProp(node, key);
|
||||||
|
if (val != NULL) return val;
|
||||||
|
}
|
||||||
|
if (cNode != NULL) {
|
||||||
|
val = GetHdbProp(node, key);
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
int SctCommand(SConnection *con, SicsInterp *sics, void *object,
|
int SctCommand(SConnection *con, SicsInterp *sics, void *object,
|
||||||
int argc, char *argv[]) {
|
int argc, char *argv[]) {
|
||||||
ScriptContext *ctx = object;
|
|
||||||
static char value[1024];
|
static char value[1024];
|
||||||
char *val;
|
char *val;
|
||||||
Hdb *node = ctx->node;
|
Hdb *node = sct->nodes->node;
|
||||||
|
Hdb *cNode = sct->nodes->controllerNode;
|
||||||
|
|
||||||
if (node == NULL) {
|
assert(sct == object);
|
||||||
|
if (node == NULL && cNode == NULL) {
|
||||||
SCPrintf(con, eError, "ERROR: %s may be called only in proper context",
|
SCPrintf(con, eError, "ERROR: %s may be called only in proper context",
|
||||||
argv[0]);
|
argv[0]);
|
||||||
return 0;
|
return 0;
|
||||||
@ -106,7 +150,7 @@ int SctCommand(SConnection *con, SicsInterp *sics, void *object,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (argc == 2) { /* get case */
|
if (argc == 2) { /* get case */
|
||||||
val = GetHdbProp(node, argv[1]);
|
val = GetProp(node, cNode, argv[1]);
|
||||||
if (val == NULL) {
|
if (val == NULL) {
|
||||||
SCPrintf(con, eError, "ERROR: %s %s not found", argv[0], argv[1]);
|
SCPrintf(con, eError, "ERROR: %s %s not found", argv[0], argv[1]);
|
||||||
return 0;
|
return 0;
|
||||||
@ -114,10 +158,8 @@ int SctCommand(SConnection *con, SicsInterp *sics, void *object,
|
|||||||
SCWrite(con, val, eValue);
|
SCWrite(con, val, eValue);
|
||||||
} else { /* set case */
|
} else { /* set case */
|
||||||
val = Arg2Tcl(argc-2, argv+2, value, sizeof value);
|
val = Arg2Tcl(argc-2, argv+2, value, sizeof value);
|
||||||
if (val != NULL) {
|
SetProp(node, cNode, argv[1], val);
|
||||||
SetHdbProperty(node, argv[1], val);
|
if (val != NULL && val != value) free(val);
|
||||||
if (val != value) free(val);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -130,10 +172,7 @@ int SctCallInContext(SConnection *con, char *script, Hdb *node,
|
|||||||
int iRet = 1;
|
int iRet = 1;
|
||||||
int verbose = controller->verbose;
|
int verbose = controller->verbose;
|
||||||
|
|
||||||
PushContext(nctx->node);
|
PushContext(node, controller->node);
|
||||||
PushContext(cctx->node);
|
|
||||||
nctx->node = node;
|
|
||||||
cctx->node = controller->node;
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
SCPrintf(con, eInError, "\nscript: %s\n", script);
|
SCPrintf(con, eInError, "\nscript: %s\n", script);
|
||||||
}
|
}
|
||||||
@ -149,32 +188,11 @@ int SctCallInContext(SConnection *con, char *script, Hdb *node,
|
|||||||
}
|
}
|
||||||
*resPtr = result;
|
*resPtr = result;
|
||||||
|
|
||||||
cctx->node = PopContext();
|
PopContext();
|
||||||
nctx->node = PopContext();
|
PopContext();
|
||||||
return iRet;
|
return iRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SctKill(void *object) {
|
|
||||||
ScriptContext *ctx = object;
|
|
||||||
if (ctx == nctx) nctx = NULL;
|
|
||||||
if (ctx == cctx) cctx = NULL;
|
|
||||||
if (ctx->desc != NULL) {
|
|
||||||
DeleteDescriptor(ctx->desc);
|
|
||||||
}
|
|
||||||
free(object);
|
|
||||||
}
|
|
||||||
|
|
||||||
ScriptContext *SctMake(char *name) {
|
|
||||||
ScriptContext *ctx;
|
|
||||||
|
|
||||||
ctx = calloc(1, sizeof(*ctx));
|
|
||||||
assert(ctx);
|
|
||||||
ctx->desc = CreateDescriptor("ScriptContext");
|
|
||||||
ctx->node = NULL;
|
|
||||||
AddCommand(pServ->pSics, name, SctCommand, SctKill, ctx);
|
|
||||||
return ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int SctMatch(void *data1, void *data2) {
|
static int SctMatch(void *data1, void *data2) {
|
||||||
SctData *a = data1;
|
SctData *a = data1;
|
||||||
SctData *b = data2;
|
SctData *b = data2;
|
||||||
@ -198,18 +216,18 @@ static char *SctActionHandler(void *actionData, char *lastReply) {
|
|||||||
} else {
|
} else {
|
||||||
con = SCStorePush(controller->conn);
|
con = SCStorePush(controller->conn);
|
||||||
}
|
}
|
||||||
SetProp(controller->node, "result", lastReply);
|
SetProp(node, controller->node, "result", lastReply);
|
||||||
if (controller->verbose && lastReply != NULL && *lastReply != '\0') {
|
if (controller->verbose && lastReply != NULL && *lastReply != '\0') {
|
||||||
SCPrintf(con, eWarning, "reply : %s", lastReply);
|
SCPrintf(con, eWarning, "reply : %s", lastReply);
|
||||||
}
|
}
|
||||||
state = GetHdbProp(controller->node, "state");
|
state = GetProp(node, controller->node, "state");
|
||||||
if (state == NULL || state[0] == '\0') {
|
if (state == NULL || strcasecmp(state, "idle") == 0) {
|
||||||
state = data->name;
|
state = data->name;
|
||||||
SetProp(controller->node, "state", state);
|
SetProp(node, controller->node, "state", state);
|
||||||
}
|
}
|
||||||
for (i = 0; i < 10; i++) {
|
for (i = 0; i < 10; i++) {
|
||||||
SetProp(controller->node, "send", NULL);
|
SetProp(node, controller->node, "send", NULL);
|
||||||
script = GetHdbProp(node, state);
|
script = GetProp(node, controller->node, state);
|
||||||
if (script == NULL) script = state;
|
if (script == NULL) script = state;
|
||||||
|
|
||||||
if (! SctCallInContext(con, script, node, data->controller, &result)) {
|
if (! SctCallInContext(con, script, node, data->controller, &result)) {
|
||||||
@ -227,8 +245,8 @@ static char *SctActionHandler(void *actionData, char *lastReply) {
|
|||||||
}
|
}
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
SetProp(controller->node, "state", state);
|
SetProp(node, controller->node, "state", state);
|
||||||
send = GetHdbProp(controller->node, "send");
|
send = GetProp(node, controller->node, "send");
|
||||||
if (send != NULL && send[0] != '\0') {
|
if (send != NULL && send[0] != '\0') {
|
||||||
if (controller->verbose) {
|
if (controller->verbose) {
|
||||||
SCPrintf(con, eWarning, "send : %s", send);
|
SCPrintf(con, eWarning, "send : %s", send);
|
||||||
@ -238,7 +256,7 @@ static char *SctActionHandler(void *actionData, char *lastReply) {
|
|||||||
}
|
}
|
||||||
SCPrintf(con, eError, "ERROR: too many quick scripts chained");
|
SCPrintf(con, eError, "ERROR: too many quick scripts chained");
|
||||||
finish:
|
finish:
|
||||||
SetProp(controller->node, "state", "");
|
SetProp(node, controller->node, "state", "idle");
|
||||||
quit:
|
quit:
|
||||||
if (currentCon) {
|
if (currentCon) {
|
||||||
SCStorePop(currentCon);
|
SCStorePop(currentCon);
|
||||||
@ -267,7 +285,7 @@ static hdbCallbackReturn SctMainCallback(Hdb *node, void *userData,
|
|||||||
hdbDataMessage *mm;
|
hdbDataMessage *mm;
|
||||||
hdbPtrMessage *pm;
|
hdbPtrMessage *pm;
|
||||||
hdbMessage *km;
|
hdbMessage *km;
|
||||||
ContextStack *s;
|
ContextItem *s;
|
||||||
SConnection *con;
|
SConnection *con;
|
||||||
char *geterror;
|
char *geterror;
|
||||||
|
|
||||||
@ -288,14 +306,7 @@ static hdbCallbackReturn SctMainCallback(Hdb *node, void *userData,
|
|||||||
}
|
}
|
||||||
km = GetHdbKillNodeMessage(msg);
|
km = GetHdbKillNodeMessage(msg);
|
||||||
if (km != NULL) {
|
if (km != NULL) {
|
||||||
/* clean context from killed nodes */
|
CleanStack(node);
|
||||||
for (s = stack; s != NULL; s = s->next) {
|
|
||||||
if (s->node == node) {
|
|
||||||
s->node = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (cctx->node == node) cctx->node = NULL;
|
|
||||||
if (nctx->node == node) nctx->node = NULL;
|
|
||||||
return hdbContinue;
|
return hdbContinue;
|
||||||
}
|
}
|
||||||
mm = GetHdbGetMessage(msg);
|
mm = GetHdbGetMessage(msg);
|
||||||
@ -353,7 +364,7 @@ static hdbCallbackReturn SctActionCallback(Hdb *node, void *userData,
|
|||||||
con = mm->callData;
|
con = mm->callData;
|
||||||
|
|
||||||
/* call check script, if available */
|
/* call check script, if available */
|
||||||
script = GetHdbProp(node, "check");
|
script = GetProp(node, data->controller->node, "check");
|
||||||
if (script != NULL) {
|
if (script != NULL) {
|
||||||
if (SctCallInContext(con, script, node, data->controller, &error) == 0) {
|
if (SctCallInContext(con, script, node, data->controller, &error) == 0) {
|
||||||
SCPrintf(con, eError, "ERROR: %s", error);
|
SCPrintf(con, eError, "ERROR: %s", error);
|
||||||
@ -366,7 +377,7 @@ static hdbCallbackReturn SctActionCallback(Hdb *node, void *userData,
|
|||||||
SetHdbProperty(node, "target", GetCharArray(text));
|
SetHdbProperty(node, "target", GetCharArray(text));
|
||||||
|
|
||||||
/* enqueue write action */
|
/* enqueue write action */
|
||||||
writeprio = GetHdbProp(node, "writeprio");
|
writeprio = GetProp(node, data->controller->node, "writeprio");
|
||||||
if (writeprio != NULL) {
|
if (writeprio != NULL) {
|
||||||
prio = DevText2Prio(writeprio);
|
prio = DevText2Prio(writeprio);
|
||||||
if (prio < 0) prio = WritePRIO;
|
if (prio < 0) prio = WritePRIO;
|
||||||
@ -492,9 +503,7 @@ static int SctPollCmd(pSICSOBJ ccmd, SConnection *con,
|
|||||||
|
|
||||||
SctAddPollNode(controller, node, interval, prio, action);
|
SctAddPollNode(controller, node, interval, prio, action);
|
||||||
|
|
||||||
if (stack == NULL) {
|
sct->base->node = node;
|
||||||
nctx->node = node;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -555,9 +564,7 @@ static int SctWriteCmd(pSICSOBJ ccmd, SConnection *con,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stack == NULL) {
|
sct->base->node = node;
|
||||||
nctx->node = node;
|
|
||||||
}
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -642,6 +649,7 @@ static hdbCallbackReturn SctDebugCallback(Hdb *node, void *userData,
|
|||||||
static void SctKillController(void *c) {
|
static void SctKillController(void *c) {
|
||||||
SctController *controller = c;
|
SctController *controller = c;
|
||||||
|
|
||||||
|
CleanStack(controller->node);
|
||||||
RemoveSICSInternalCallback(controller);
|
RemoveSICSInternalCallback(controller);
|
||||||
DevKill(controller->devser);
|
DevKill(controller->devser);
|
||||||
}
|
}
|
||||||
@ -680,8 +688,6 @@ static int SctMakeController(SConnection *con, SicsInterp *sics,
|
|||||||
AddCommand(pServ->pSics, nodeName, InvokeSICSOBJ, KillSICSOBJ, ccmd);
|
AddCommand(pServ->pSics, nodeName, InvokeSICSOBJ, KillSICSOBJ, ccmd);
|
||||||
SetDescriptorKey(ccmd->pDes, "creationCommand", "0");
|
SetDescriptorKey(ccmd->pDes, "creationCommand", "0");
|
||||||
|
|
||||||
SetProp(controller->node, "state", "");
|
|
||||||
|
|
||||||
AddHipadabaChild(parent, controller->node, con);
|
AddHipadabaChild(parent, controller->node, con);
|
||||||
|
|
||||||
controller->devser = DevMake(con, argc - 2, argv + 2);
|
controller->devser = DevMake(con, argc - 2, argv + 2);
|
||||||
@ -710,16 +716,38 @@ static int SctMakeController(SConnection *con, SicsInterp *sics,
|
|||||||
cb = MakeHipadabaCallback(SctDebugCallback, controller, NULL);
|
cb = MakeHipadabaCallback(SctDebugCallback, controller, NULL);
|
||||||
if (cb) AppendHipadabaCallback(par, cb);
|
if (cb) AppendHipadabaCallback(par, cb);
|
||||||
|
|
||||||
if (stack == NULL) {
|
sct->base->controllerNode = controller->node;
|
||||||
cctx->node = controller->node;
|
sct->base->node = NULL;
|
||||||
nctx->node = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SctKill(void *object) {
|
||||||
|
assert(sct == object);
|
||||||
|
ContextItem *p, *q;
|
||||||
|
|
||||||
|
for (p = sct->nodes; p != NULL; p = q) {
|
||||||
|
q = p->next;
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
for (p = sct->trash; p != NULL; p = q) {
|
||||||
|
q = p->next;
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
if (sct->desc != NULL) {
|
||||||
|
DeleteDescriptor(sct->desc);
|
||||||
|
}
|
||||||
|
free(sct);
|
||||||
|
sct = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void SctInit(void) {
|
void SctInit(void) {
|
||||||
nctx = SctMake("nctx");
|
if (sct) return;
|
||||||
cctx = SctMake("cctx");
|
sct = calloc(1, sizeof(*sct));
|
||||||
|
assert(sct);
|
||||||
|
sct->desc = CreateDescriptor("ScriptContext");
|
||||||
|
PushContext(NULL, NULL);
|
||||||
|
sct->base = sct->nodes;
|
||||||
|
AddCommand(pServ->pSics, "sct", SctCommand, SctKill, sct);
|
||||||
AddCmd("makesctcontroller", SctMakeController);
|
AddCmd("makesctcontroller", SctMakeController);
|
||||||
}
|
}
|
||||||
|
@ -2932,6 +2932,7 @@ static int SetSICSHdbProperty(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|||||||
int argc, char *argv[]){
|
int argc, char *argv[]){
|
||||||
pHdb targetNode = NULL;
|
pHdb targetNode = NULL;
|
||||||
char buffer[512];
|
char buffer[512];
|
||||||
|
char *val;
|
||||||
|
|
||||||
if(argc < 4) {
|
if(argc < 4) {
|
||||||
SCWrite(pCon,"ERROR: need path key value as parameters",eError);
|
SCWrite(pCon,"ERROR: need path key value as parameters",eError);
|
||||||
@ -2942,8 +2943,11 @@ static int SetSICSHdbProperty(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|||||||
SCWrite(pCon,"ERROR: node not found",eError);
|
SCWrite(pCon,"ERROR: node not found",eError);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Arg2Tcl(argc-3, &argv[3], buffer,512);
|
val = Arg2Tcl(argc-3, &argv[3], buffer, sizeof buffer);
|
||||||
SetHdbProperty(targetNode,argv[2], buffer);
|
if (val) {
|
||||||
|
SetHdbProperty(targetNode,argv[2], val);
|
||||||
|
if (val != buffer) free(val);
|
||||||
|
}
|
||||||
SCSendOK(pCon);
|
SCSendOK(pCon);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user