Files
sics/statemon.c
Ferdi Franceschini ef7c2a6f87 histmem.c
sicvar.c
SICS-93 Save histogram data and instrument state during an acquisition

hipadaba_configuration_common.tcl
SICS-185 Preserve case on hdb node names

hmm_configuration_common_1.tcl
nxscripts_common_1.tcl
sicvar.c
SICS-174 Allow saving of histmem data and instrument status during a count operation.

wombat_configuration.tcl
echidna_configuration.tcl
platypus_configuration.tcl
kowari_configuration.tcl
quokka_configuration.tcl
SICS-153 Move setup of statemon to new server_init function for the new sics_uid state variable

server_config.tcl
SICS-153 set attributes on the sics_suid var which is now created by MakeStateMon
SICS-187 Add cold source info (TODO move to platypus,quokka and pelican configs)

utility.tcl
SICS-185 Added normalgetatt to preserve case on hdb node names etc.

sans/config/optics/aperture_configuration.tcl
New file, Provides lookup tables for attenuation and entrance apertures. (SICS-157)

sans/config/optics/optics.tcl
Load the new aperture_configuration.tcl

sans/config/parameters/parameters.tcl
SICS-157 Add instrument parameters section with derived parameters and their dependencies

statemon.c
SICS-153 Create sics_suid sicsvariable when loading statemon and increment it on each status change.

r2635 | ffr | 2008-06-23 12:41:12 +1000 (Mon, 23 Jun 2008) | 38 lines
2012-11-15 13:39:42 +11:00

358 lines
11 KiB
C

/**
* This is a state monitor. It collects all the start and stop messages
* from the device executor and from scan and batch commands. Clients can
* listen to this in order to figure out what is actually going on in a
* given SICS installation. This might in the end supersede the status code
* management in status.c
*
* copyright: see file COPYRIGHT
*
* Mark Koennecke, January 2007
*/
#include <sics.h>
#include "exeman.h"
#include "scan.h"
#include "scan.i"
#include "stptok.h"
#include "statemon.h"
#include "sicshipadaba.h"
#include "sicsvar.h"
#define SICS_SUID "sics_suid"
/*==========================================================================*/
typedef struct __STATEMON {
pObjectDescriptor pDes;
pICallBack pCall;
}StateMon;
SConnection *pStateMonDummyCon = NULL;
/*============================ Callbacks =================================*/
static int DevexecCallback(int iEvent, void *text, void *pData,
commandContext cc){
char pDevice[132];
int eventCode;
pStateMon self = (pStateMon)pData;
memset(pDevice,0,132);
if(iEvent == DRIVSTAT){
stptok(text,pDevice,131," ");
if(strstr(text,"started") != NULL){
eventCode = STSTART;
} else if(strstr(text,"finished") != NULL) {
eventCode = STEND;
} else {
printf("Unrecognized event text from devexec in statemon.c: %s\n",
(char *)text);
return 0;
}
if(self != NULL){
InvokeCallBack(self->pCall,eventCode,pDevice);
}
}
return 1;
}
/*---------------------------------------------------------------------------*/
static int StateMonScanInterest(int iEvent, void *pEventData, void *pUser,
commandContext cc){
pScanData pScan = NULL;
pStateMon self = (pStateMon)pUser;
pScan = (pScanData)pEventData;
if(pScan == NULL || self == NULL){
printf("Bad StateMonScanInterst in statemon\n");
return 0;
}
if(iEvent == SCANSTART){
InvokeCallBack(self->pCall,STSTART,pScan->objectName);
return 1;
}else if(iEvent == SCANEND){
InvokeCallBack(self->pCall,STEND,pScan->objectName);
return 1;
}
return 1;
}
/*--------------------------------------------------------------------------*/
static int ExeCallback(int iEvent, void *pEvent, void *pUser,
commandContext cc){
pStateMon self = (pStateMon)pUser;
char *name = (char *)pEvent;
char pBueffel[131];
if(self == NULL || name == NULL){
printf("Bad ExeCallback in statemon\n");
return 0;
}
if(iEvent == BATCHSTART){
snprintf(pBueffel,131,"exe %s",name);
InvokeCallBack(self->pCall,STSTART,pBueffel);
return 1;
}
if(iEvent == BATCHEND){
snprintf(pBueffel,131,"exe %s",name);
InvokeCallBack(self->pCall,STEND,pBueffel);
return 1;
}
return 0;
}
/*=============== user callbacks ============================================*/
static int StateInterest(int iEvent, void *pEvent, void *pUser,
commandContext cc){
SConnection *pCon = (SConnection *)pUser;
char *device = (char *)pEvent;
char buffer[256];
pSicsVariable pVar = NULL;
if( pCon == NULL || device == NULL) {
printf("Bad StateInterest in statemon\n");
return 0;
} else if (pCon == pStateMonDummyCon) {
if(iEvent == STSTART){
snprintf(buffer,255,"SUID MSG STARTED = %s", device);
SCWrite(pStateMonDummyCon,buffer,eError);
}
if(iEvent == STEND){
snprintf(buffer,255,"SUID MSG FINISH = %s", device);
SCWrite(pStateMonDummyCon,buffer,eError);
}
pVar = (pSicsVariable)FindCommandData(pServ->pSics,SICS_SUID,"SicsVariable");
if (pVar == NULL) {
SCWrite(pStateMonDummyCon,"ERROR: StateMon.c: Could not find SUID SicsVariable",eError);
return 0;
}
(pVar->iVal)++;
InvokeCallBack(pVar->pCall, VALUECHANGE, pVar);
} else {
if(iEvent == STSTART){
snprintf(buffer,255,"STARTED = %s", device);
SCWriteInContext(pCon,buffer,eWarning,cc);
}
if(iEvent == STEND){
snprintf(buffer,255,"FINISH = %s", device);
SCWriteInContext(pCon,buffer,eWarning,cc);
}
}
return 1;
}
/*--------------------------------------------------------------------------*/
static pHdb recurseInterestNode(pHdb current, char *pDevice){
char pSicsdev[131], pAlias[132];
pHdb result = NULL;
char *alias = NULL, *pPtr = NULL;
memset(pSicsdev,0,132);
memset(pAlias,0,132);
if(current != NULL){
if(GetHdbProperty(current,"sicsdev",pSicsdev,131) != 0){
strtolower(pSicsdev);
if(strcmp(pSicsdev,pDevice) == 0){
return current;
}
/*
* try to look for aliases, too
*/
alias = FindAliases(pServ->pSics,pSicsdev);
pPtr = alias;
while((pPtr = stptok(pPtr,pAlias,131,",")) != NULL){
if(strcmp(pAlias,pDevice) == 0){
return current;
}
}
if(alias != NULL){
free(alias);
}
}
current = current->child;
while(current != NULL){
result = recurseInterestNode(current, pDevice);
if(result != NULL){
return result;
}
current = current->next;
}
}
return NULL;
}
/*--------------------------------------------------------------------------*/
static pHdb locateInterestNode(char *device){
char pDevice[132], pSicsdev[132];
pHdb current = NULL, result = NULL;
memset(pDevice,0,132);
memset(pSicsdev,0,132);
/*
* this is to strip off exes batch file name
*/
stptok(device,pDevice,131," ");
strtolower(pDevice);
current = GetHipadabaRoot();
return recurseInterestNode(current,pDevice);
}
/*--------------------------------------------------------------------------*/
static int StateHdbInterest(int iEvent, void *pEvent, void *pUser,
commandContext cc){
SConnection *pCon = (SConnection *)pUser;
char *device = (char *)pEvent, *path = NULL;
char buffer[1024];
pHdb node = NULL;
if(pCon == NULL || device == NULL){
printf("Bad StateHdbInterest in statemon\n");
return 0;
}
node = locateInterestNode(device);
if(node != NULL){
path = GetHipadabaPath(node);
if(iEvent == STSTART){
snprintf(buffer,1024,"%s STARTED", path);
SCWriteInContext(pCon,buffer,eWarning,cc);
}
if(iEvent == STEND){
snprintf(buffer,1024,"%s FINISH", path);
SCWriteInContext(pCon,buffer,eWarning,cc);
}
}
return 1;
}
/*====================== interpreter interface ==============================*/
static void killStateMon(void *pData){
pStateMon self = NULL;
self = (pStateMon)pData;
if(self != NULL){
if(self->pDes != NULL){
DeleteDescriptor(self->pDes);
}
if(self->pCall != NULL){
DeleteCallBackInterface(self->pCall);
}
if(pStateMonDummyCon != NULL) {
SCDeleteConnection(pStateMonDummyCon);
}
free(self);
}
}
/*---------------------------------------------------------------------------*/
int StateMonFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){
long lID;
pStateMon pNew = NULL;
commandContext cc;
pICallBack target = NULL;
void *pPtr = NULL, *exe = NULL, *pDevexec = NULL;
pSicsVariable pRes = NULL;
exe = FindCommandData(pSics,"exe", "ExeManager");
pDevexec = FindCommandData(pSics,"stopexe","DeviceExecutor");
if(exe == NULL || pDevexec == NULL){
SCWrite(pCon,
"ERROR: both the device executor and the batch file module must be installed before initialising statemon",
eError);
return 0;
}
/*
* generate data structures
*/
strcpy(cc.deviceID,"statemon");
cc.transID = -120;
pNew = (pStateMon)malloc(sizeof(StateMon));
if(pNew == NULL){
SCWrite(pCon,"ERROR: out of memory creating StateMon",eError);
return 0;
}
memset(pNew,0,sizeof(StateMon));
pNew->pDes = CreateDescriptor("statemon");
pNew->pCall = CreateCallBackInterface();
if(pNew->pDes == NULL || pNew->pCall == NULL){
SCWrite(pCon,"ERROR: out of memory creating StateMon",eError);
return 0;
}
/*
* register callbacks
*/
target = GetCallbackInterface(pDevexec);
assert(target != NULL);
RegisterCallback(target,cc,DRIVSTAT,DevexecCallback,pNew,NULL);
target = GetCallbackInterface(exe);
assert(target != NULL);
RegisterCallback(target,cc,BATCHSTART,ExeCallback,pNew,NULL);
RegisterCallback(target,cc,BATCHEND,ExeCallback,pNew,NULL);
if(argc > 1) {
pPtr = FindCommandData(pSics,argv[1],"ScanObject");
if(pPtr == NULL){
SCWrite(pCon,"ERROR: failed to locate scan object",eError);
} else {
target = GetCallbackInterface(pPtr);
assert(target != NULL);
RegisterCallback(target,cc,SCANSTART,StateMonScanInterest,pNew,NULL);
RegisterCallback(target,cc,SCANEND,StateMonScanInterest,pNew,NULL);
}
}
/* Make dummy connection for SUID (instrument state id) */
pStateMonDummyCon = SCCreateDummyConnection(pSics);
lID = RegisterCallback(pNew->pCall, SCGetContext(pStateMonDummyCon),STSTART, StateInterest, pStateMonDummyCon, NULL);
SCRegister(pStateMonDummyCon,pSics, pNew->pCall,lID);
lID = RegisterCallback(pNew->pCall, SCGetContext(pStateMonDummyCon),STEND, StateInterest, pStateMonDummyCon, NULL);
SCRegister(pStateMonDummyCon,pSics, pNew->pCall,lID);
pRes = VarCreate(usInternal,veInt,SICS_SUID);
AddCommand(pSics,SICS_SUID,VarWrapper,(KillFunc)VarKill,pRes);
/*
* TODO: add kill functions
*/
AddCommand(pSics,"statemon",StateMonAction,killStateMon,pNew);
return 1;
}
/*---------------------------------------------------------------------------*/
int StateMonAction(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){
long lID;
int i;
pStateMon self = NULL;
self = (pStateMon)pData;
assert(self != NULL);
if(argc < 2){
SCWrite(pCon,"ERROR: not enough arguments to statemon",eError);
return 0;
}
strtolower(argv[1]);
if(strcmp(argv[1],"interest") == 0){
lID = RegisterCallback(self->pCall, SCGetContext(pCon),STSTART, StateInterest,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
lID = RegisterCallback(self->pCall, SCGetContext(pCon),STEND, StateInterest,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
SCSendOK(pCon);
return 1;
} else if(strcmp(argv[1],"uninterest") == 0) {
for(i = 0; i < 2; i++){
lID = SCgetCallbackID(pCon,self->pCall);
if(lID >= 0){
RemoveCallback(self->pCall,lID);
SCUnregisterID(pCon,lID);
}
}
SCSendOK(pCon);
return 1;
} else if(strcmp(argv[1],"hdbinterest") == 0){
lID = RegisterCallback(self->pCall, SCGetContext(pCon),STSTART, StateHdbInterest,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
lID = RegisterCallback(self->pCall, SCGetContext(pCon),STEND, StateHdbInterest,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
SCSendOK(pCon);
return 1;
}
SCWrite(pCon,"ERROR: keyword not recognized",eError);
return 0;
}