- added scriptcontext.h
- killing a node using sct should now be safe - sctdrive adapter object might be dynamic - default for the checkstatus script: returning the status property - introduced <sctcon> unpoll - changed <sctcon> queuecon to <sctcon> send - some more improvements in sct
This commit is contained in:
@ -3,7 +3,7 @@
|
||||
* scriptcontext generic device model. This is a wrapper around
|
||||
* such a node which implements the drivable interface.
|
||||
*
|
||||
* Soem cooperation from the node is required: It has to provide
|
||||
* Some cooperation from the node is required: It has to provide
|
||||
* certain properties the value of which define scripts which
|
||||
* have to be called at various stages. These are:
|
||||
*
|
||||
@ -21,13 +21,7 @@
|
||||
#include <tcl.h>
|
||||
#include <macro.h>
|
||||
#include <sicsobj.h>
|
||||
/*------------- Some things from scriptcontext.c ----------------*/
|
||||
typedef struct SctController SctController;
|
||||
typedef struct SctData SctData;
|
||||
SctData *SctQueueNode(SctController *controller, pHdb node,
|
||||
DevPrio prio, char *action);
|
||||
int SctCallInContext(SConnection *con, char *script, Hdb *node,
|
||||
SctController *controller, char **resPtr);
|
||||
#include "scriptcontext.h"
|
||||
/*---------------------------------------------------------------*/
|
||||
typedef struct {
|
||||
pObjectDescriptor pDes;
|
||||
@ -41,6 +35,7 @@ static void *SCTDRIVGetInterface(void *data, int iD){
|
||||
|
||||
self = (pSctDrive)data;
|
||||
if(self != NULL && iD == DRIVEID){
|
||||
if (self->node == NULL) return NULL;
|
||||
return self->pDriv;
|
||||
} else {
|
||||
return NULL;
|
||||
@ -53,14 +48,14 @@ static void *SCTDRIVGetInterface(void *data, int iD){
|
||||
------------------------------------------------------------------*/
|
||||
static int SCTDRIVHalt(void *data) {
|
||||
pSctDrive self = NULL;
|
||||
|
||||
char dummy[16];
|
||||
|
||||
self = (pSctDrive)data;
|
||||
SctQueueNode(self->c, self->node, HaltPRIO, "halt");
|
||||
/*
|
||||
* SctQueueNode returns a dynamically allocated SctData
|
||||
* structure. I am not sure if this is not really a memory
|
||||
* leak
|
||||
*/
|
||||
if (GetHdbProperty(self->node,"halt", dummy, sizeof dummy)) {
|
||||
SctQueueNode(self->c, self->node, HaltPRIO, "halt", NULL);
|
||||
} else if (GetHdbProperty(self->node, "status", dummy, sizeof dummy)) {
|
||||
SetHdbProperty(self->node, "status", "idle");
|
||||
}
|
||||
return OKOK;
|
||||
}
|
||||
/*----------------------------------------------------------------
|
||||
@ -85,6 +80,7 @@ static int SCTDRIVCheckLimits(void *data, float val,
|
||||
self->node, self->c, &result);
|
||||
if(status == 0){
|
||||
strncpy(error,result,errlen);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
@ -132,31 +128,34 @@ static int SCTDRIVCheckStatus(void *data, SConnection *pCon){
|
||||
|
||||
self = (pSctDrive)data;
|
||||
|
||||
if(GetHdbProperty(self->node,"checkstatus",script,1024)){
|
||||
status = SctCallInContext(pCon,script, self->node,
|
||||
self->c, &result);
|
||||
if(status == 1){
|
||||
if(strstr(result,"busy") != NULL){
|
||||
return HWBusy;
|
||||
} else if(strstr(result,"posfault") != NULL){
|
||||
return HWPosFault;
|
||||
} else if(strstr(result,"fault") != NULL){
|
||||
return HWFault;
|
||||
} else if(strstr(result,"idle") != NULL){
|
||||
return HWIdle;
|
||||
} else {
|
||||
SCPrintf(pCon,eError,"ERROR: invalid status code %s returned from checkstatus script",
|
||||
result);
|
||||
return HWFault;
|
||||
}
|
||||
} else {
|
||||
SCWrite(pCon,result, eError);
|
||||
return HWFault;
|
||||
}
|
||||
if(!GetHdbProperty(self->node,"checkstatus",script,1024)){
|
||||
if (!GetHdbProperty(self->node,"status",script,1024)){
|
||||
SCWrite(pCon,
|
||||
"ERROR: configuration problem: no checkstatus script!", eError);
|
||||
return HWFault;
|
||||
}
|
||||
result = script;
|
||||
} else {
|
||||
SCWrite(pCon,
|
||||
"ERROR: configuration problem: no checkstatus script!", eError);
|
||||
return HWFault;
|
||||
status = SctCallInContext(pCon,script, self->node,
|
||||
self->c, &result);
|
||||
if (status == 0) {
|
||||
SCWrite(pCon,result, eError);
|
||||
return HWFault;
|
||||
}
|
||||
}
|
||||
if(strstr(result,"busy") != NULL){
|
||||
return HWBusy;
|
||||
} else if(strstr(result,"posfault") != NULL){
|
||||
return HWPosFault;
|
||||
} else if(strstr(result,"fault") != NULL){
|
||||
return HWFault;
|
||||
} else if(strstr(result,"idle") != NULL){
|
||||
return HWIdle;
|
||||
} else {
|
||||
SCPrintf(pCon,eError,
|
||||
"ERROR: invalid status code %s returned from checkstatus script",
|
||||
result);
|
||||
return HWFault;
|
||||
}
|
||||
return HWFault;
|
||||
}
|
||||
@ -212,6 +211,10 @@ static int SctDriveCommand(SConnection *pCon, SicsInterp *sics, void *object,
|
||||
|
||||
assert(self != NULL);
|
||||
|
||||
if (self->node == NULL) {
|
||||
SCWrite(pCon, "ERROR: defunct object", eError);
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* only action: print value
|
||||
*/
|
||||
@ -234,15 +237,26 @@ static void SctDriveKill(void *data){
|
||||
}
|
||||
free(self);
|
||||
}
|
||||
/*----------------------------------------------------------------*/
|
||||
static hdbCallbackReturn SctDummyCallback(Hdb *node, void *userData,
|
||||
hdbMessage *msg) {
|
||||
return hdbContinue;
|
||||
}
|
||||
/*----------------------------------------------------------------*/
|
||||
static void SctDriveDeleteNode(void *data) {
|
||||
pSctDrive self = (pSctDrive)data;
|
||||
self->node = NULL;
|
||||
}
|
||||
/*---------------------------------------------------------------*/
|
||||
int SctMakeDriveAdapter(SConnection *pCon, SicsInterp *pSics, void *object,
|
||||
int argc, char *argv[]) {
|
||||
pSctDrive pNew = NULL;
|
||||
pSICSOBJ obj = NULL;
|
||||
hdbCallback *cb;
|
||||
|
||||
pNew = SCTDRIVMakeObject();
|
||||
if(pNew == NULL){
|
||||
SCWrite(pCon,"ERROR: out of memory in SctmakeDriveAdapter",
|
||||
SCWrite(pCon,"ERROR: out of memory in SctMakeDriveAdapter",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
@ -260,7 +274,22 @@ int SctMakeDriveAdapter(SConnection *pCon, SicsInterp *pSics, void *object,
|
||||
return 0;
|
||||
}
|
||||
pNew->c =(SctController *)obj->pPrivate;
|
||||
|
||||
if (strcasecmp(argv[0],"dynsctdrive") == 0) {
|
||||
/* make object dynamic by defining a descriptor command */
|
||||
SetDescriptorKey(pNew->pDes, "creationCommand", "0");
|
||||
}
|
||||
AddCommand(pSics, argv[1], SctDriveCommand, SctDriveKill, pNew);
|
||||
SetHdbProperty(pNew->node,"sicsdev",argv[1]);
|
||||
|
||||
cb = MakeHipadabaCallback(SctDummyCallback, pNew, SctDriveDeleteNode);
|
||||
assert(cb);
|
||||
AppendHipadabaCallback(pNew->node, cb);
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------*/
|
||||
void SctDriveInit(void) {
|
||||
AddCmd("makesctdrive", SctMakeDriveAdapter);
|
||||
AddCmd("dynsctdrive", SctMakeDriveAdapter);
|
||||
}
|
||||
|
Reference in New Issue
Block a user