Cleaned up ANSTO code to merge with sinqdev.sics

This is our new RELEASE-4_0 branch which was taken from ansto/93d9a7c
Conflicts:
	.gitignore
	SICSmain.c
	asynnet.c
	confvirtualmot.c
	counter.c
	devexec.c
	drive.c
	event.h
	exebuf.c
	exeman.c
	histmem.c
	interface.h
	motor.c
	motorlist.c
	motorsec.c
	multicounter.c
	napi.c
	napi.h
	napi4.c
	network.c
	nwatch.c
	nxscript.c
	nxxml.c
	nxxml.h
	ofac.c
	reflist.c
	scan.c
	sicshipadaba.c
	sicsobj.c
	site_ansto/docs/Copyright.txt
	site_ansto/instrument/lyrebird/config/tasmad/sicscommon/nxsupport.tcl
	site_ansto/instrument/lyrebird/config/tasmad/taspub_sics/tasscript.tcl
	statusfile.c
	tasdrive.c
	tasub.c
	tasub.h
	tasublib.c
	tasublib.h
This commit is contained in:
Ferdi Franceschini
2015-04-23 20:49:26 +10:00
parent c650788a2c
commit 10d29d597c
1336 changed files with 9430 additions and 226646 deletions

View File

@@ -19,6 +19,10 @@
* Refactored to new callback system, Markus Zolliker, Mark Koennecke, March 2008
*
* Added start and finished messages to commands. Mark Koennecke, November 2008
*
* Added SicsValueCheckCallback and implemented first version of haddcheck.
* Mark Koennecke, July 2013
*
*/
#include <stdlib.h>
#include <string.h>
@@ -36,6 +40,8 @@
#include <macro.h>
#include "commandlog.h"
#include "arrayutil.h"
#include "HistMem.h"
#include "asynnet.h"
#define MAX_HDB_PATH 1024
@@ -236,7 +242,55 @@ pHdbCallback MakeReadOnlyCallback()
{
return MakeHipadabaCallback(SICSReadOnlyCallback, NULL, NULL);
}
/*------------------------------------------------------------------------------------*/
hdbCallbackReturn SICSValueCheckCallback(pHdb node, void *userData,
pHdbMessage message)
{
SConnection *pCon = NULL;
pHdbDataMessage mm = NULL;
char values[1024], *pPtr, pToken[80], *pVal;
int status;
hdbValue v;
mm = GetHdbSetMessage(message);
if (mm == NULL) {
return hdbContinue;
}
pCon = (SConnection *) mm->callData;
v = *(mm->v);
status = GetHdbProperty(node,"values",values,sizeof(values));
if(status != 1 && pCon != NULL){
SCPrintf(pCon,eLogError,"ERROR: configuration error, no values on node %s",
node->name);
return hdbAbort;
}
if(v.dataType != HIPTEXT && pCon != NULL){
SCPrintf(pCon,eLogError,"ERROR: need text data for node %s",
node->name);
return hdbAbort;
}
pPtr = values;
pVal = strdup(v.v.text);
strtolower(pVal);
while((pPtr = stptok(pPtr,pToken,sizeof(pToken),",")) != NULL){
if(strcmp(pToken,pVal) == 0) {
free(pVal);
return hdbContinue;
}
}
free(pVal);
if(pCon != NULL){
SCPrintf(pCon,eLogError,"ERROR: %s not allowed as value for %s, allowed are: %s",
v.v.text, node->name, values);
}
return hdbAbort;
}
/*-------------------------------------------------------------------------------------*/
static hdbCallbackReturn SICSDriveCallback(pHdb node, void *userData,
pHdbMessage message)
@@ -541,6 +595,7 @@ static hdbCallbackReturn SICSNotifyCallback(pHdb node, void *userData,
pHdbPtrMessage cmm = NULL;
pHdbDataMessage mm = NULL;
SConnection *tstCon;
char updatePath[1024];
cbInfo = (HdbCBInfo *) userData;
@@ -602,7 +657,7 @@ static hdbCallbackReturn SICSNotifyCallback(pHdb node, void *userData,
return hdbContinue;
}
pPath = GetHipadabaPath(node);
GetHdbPath(node,updatePath,sizeof(updatePath));
result = CreateDynString(128, 128);
if ((protocol = isJSON(cbInfo->pCon, 1)) == 1)
outCode = eHdbEvent;
@@ -616,14 +671,13 @@ static hdbCallbackReturn SICSNotifyCallback(pHdb node, void *userData,
if (GetHdbProperty(node, "transfer", value, 80) == 1) {
if (strstr(value, "zip") != NULL || strstr(value,"bin") != NULL) {
status = sendZippedNodeData(node, *(mm->v), cbInfo->pCon);
free(pPath);
DeleteDynString(result);
return hdbContinue;
}
}
if (mm->v->arrayLength < 100) {
printedData = formatValue(*(mm->v), node);
if (pPath == NULL || printedData == NULL || result == NULL) {
if (printedData == NULL || result == NULL) {
SCWrite(cbInfo->pCon, "ERROR: out of memory formatting data",
eEvent);
/*
@@ -632,7 +686,7 @@ static hdbCallbackReturn SICSNotifyCallback(pHdb node, void *userData,
*/
return hdbContinue;
}
formatNameValue(protocol, pPath, GetCharArray(printedData), result,
formatNameValue(protocol, updatePath, GetCharArray(printedData), result,
mm->v->dataType);
#ifdef SITE_ANSTO
SCWrite(cbInfo->pCon, GetCharArray(result), outCode);
@@ -641,10 +695,9 @@ static hdbCallbackReturn SICSNotifyCallback(pHdb node, void *userData,
#endif
DeleteDynString(printedData);
} else {
formatNameValue(protocol, pPath, "!!datachange!!", result, HIPTEXT);
formatNameValue(protocol, updatePath, "!!datachange!!", result, HIPTEXT);
SCWrite(cbInfo->pCon, GetCharArray(result), outCode);
}
free(pPath);
DeleteDynString(result);
return hdbContinue;
@@ -2356,7 +2409,7 @@ static int isNodeProtected(pHdb node)
{
pHdb current = NULL;
if (node->protected == 1) {
if (node->iprotected == 1) {
return 1;
}
current = node->child;
@@ -2409,6 +2462,8 @@ static int SetHdbNode(SConnection * pCon, SicsInterp * pSics, void *pData,
pDynString parData = NULL;
char error[512], value[132];
int i, status, priv;
pIDrivable pDriv = NULL;
pDummy data = NULL;
if (argc < 3) {
@@ -2432,6 +2487,25 @@ static int SetHdbNode(SConnection * pCon, SicsInterp * pSics, void *pData,
return 0;
}
/**
* special code to handle certain types of motors right
**/
status = GetHdbProperty(targetNode,"sicsdev",value,sizeof(value));
if(status == 1){
data = (pDummy)FindCommandData(pSics,value,NULL);
if(data != NULL){
pDriv = GetDrivableInterface(data);
if(pDriv != NULL){
status = StartDevice(pServ->pExecutor,value, data->pDescriptor,
data, pCon,RUNRUN, atof(argv[2]));
if(status == 1){
SCSendOK(pCon);
}
return status;
}
}
}
if (!cloneHdbValue(&targetNode->value, &newValue)) {
SCWrite(pCon, "ERROR: out of memory cloning node", eError);
@@ -2517,7 +2591,7 @@ static int UpdateHdbNode(SConnection * pCon, SicsInterp * pSics,
}
status = UpdateHipadabaPar(targetNode, newValue, pCon);
ReleaseHdbValue(&newValue);
if (status == 1) {
if (status == 1 && SCinMacro(pCon) == 0) {
SCSendOK(pCon);
}
return status;
@@ -2571,6 +2645,106 @@ static int ZipGetHdbNode(SConnection * pCon, SicsInterp * pSics,
return status;
}
/*-----------------------------------------------------------------------------*/
static int ZipReadHdbNode(SConnection * pCon, SicsInterp * pSics,
void *pData, int argc, char *argv[])
{
pHdb targetNode = NULL;
char error[512], oriPath[512];
int status;
pDynString parData = NULL, result= NULL;
Protocol protocol = normal_protocol;
OutCode outCode;
if (argc < 2) {
SCWrite(pCon, "ERROR: need path to node", eError);
return 0;
}
strlcpy(oriPath, argv[1], 511);
targetNode = FindHdbNode(NULL, argv[1], pCon);
if (targetNode == NULL) {
return 0;
}
if(targetNode->value.dataType == HIPTEXT){
parData = formatValue(targetNode->value, targetNode);
if (parData == NULL) {
SCWrite(pCon, "ERROR: out of memory formatting data", eError);
return 0;
}
if ((protocol = isJSON(pCon)) == 1)
outCode = eHdbEvent;
else
outCode = eValue;
result = CreateDynString(128, 128);
formatNameValue(protocol, oriPath, GetCharArray(parData), result,
targetNode->value.dataType);
SCWrite(pCon, GetCharArray(result), outCode);
DeleteDynString(parData);
DeleteDynString(result);
} else {
status = sendZippedNodeData(targetNode, targetNode->value, pCon);
}
return status;
}
/*---------------------------------------------------------------------------*/
static int BinReadHdbNode(SConnection *pCon, SicsInterp *pSics,
void *pData, int argc, char *argv[])
{
static int binMagic = 7333;
pHdb targetNode = NULL;
char oriPath[512];
hdbValue val;
int *data = NULL, i;
if (argc < 2) {
SCWrite(pCon, "ERROR: need path to node", eError);
return 0;
}
strlcpy(oriPath, argv[1], 511);
targetNode = FindHdbNode(NULL, argv[1], pCon);
if (targetNode == NULL) {
return 0;
}
val = targetNode->value;
switch(val.dataType){
case HIPINTAR:
case HIPINTVARAR:
data = malloc(val.arrayLength+2*sizeof(int));
if(data == NULL){
SCWrite(pCon,"ERROR: out of memory in BinReadHdbNode",eError);
return 0;
}
data[0] = binMagic;
data[1] = val.arrayLength;
memcpy(data+2,val.v.intArray,val.arrayLength*sizeof(int));
break;
case HIPFLOATAR:
case HIPFLOATVARAR:
data = malloc(val.arrayLength+2*sizeof(int));
if(data == NULL){
SCWrite(pCon,"ERROR: out of memory in BinReadHdbNode",eError);
return 0;
}
data[0] = binMagic;
data[1] = val.arrayLength;
for(i = 0; i < val.arrayLength; i++){
data[i+2] = (int)(val.v.floatArray[i]*65536.);
}
break;
default:
SCWrite(pCon,"ERROR: cannot send binary data for this node type",eError);
return 0;
}
if(data != NULL){
ANETwrite(pCon->sockHandle,data,(val.arrayLength+2)*sizeof(int));
free(data);
}
return 1;
}
/*---------------------------------------------------------------------------*/
static int GetHdbNode(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[])
@@ -2601,10 +2775,10 @@ static int GetHdbNode(SConnection * pCon, SicsInterp * pSics, void *pData,
return 0;
}
/*
* if transfer = zip, redirect to zip
* if transfer = zip or bin, redirect to zip
*/
if (GetHdbProperty(targetNode, "transfer", value, 80) == 1) {
if (strstr(value, "zip") != NULL) {
if (strstr(value, "zip") != NULL || strstr(value,"bin") != NULL) {
return ZipGetHdbNode(pCon, pSics, pData, argc, argv);
}
}
@@ -3029,6 +3203,7 @@ static int RemoveHdbCallback(SConnection * pCon, SicsInterp * pSics,
{
int id;
hdbIDMessage m;
pObjectDescriptor pObj = NULL;
if (argc < 2) {
SCWrite(pCon, "ERROR: need callback id to remove", eError);
@@ -3037,7 +3212,14 @@ static int RemoveHdbCallback(SConnection * pCon, SicsInterp * pSics,
id = atoi(argv[1]);
m.type = killID;
m.ID = id;
RecurseCallbackChains(root, (pHdbMessage) & m);
if(argc < 3){
RecurseCallbackChains(root, (pHdbMessage) & m);
} else {
pObj = FindCommandDescriptor(pSics,argv[2]);
if(pObj != NULL && pObj->parNode != NULL){
RecurseCallbackChains(pObj->parNode,(pHdbMessage)&m);
}
}
SCSendOK(pCon);
return 1;
}
@@ -3113,6 +3295,171 @@ static int isArrayNode(pHdb node)
return 0;
}
/*-------------------------------------------------------------------------*/
static int ArrayCopyNode(pHdb to, SConnection *pCon, int argc, char *argv[])
{
pHdb from = NULL;
int iStart, iLength;
hdbValue fromData;
from = FindHdbNode(NULL,argv[3],pCon);
if(from == NULL){
SCPrintf(pCon,eError,"ERROR: source node %s not found", argv[3]);
return 0;
}
if(!isArrayNode(from)){
SCPrintf(pCon,eError,"ERROR: %s is no array data node", argv[3]);
return 0;
}
iStart = 0;
iLength = from->value.arrayLength;
if(argc > 4) {
iStart = atoi(argv[4]);
if(iStart < 0) {
iStart = 0;
}
}
if(argc > 5) {
iLength = atoi(argv[5]);
if(iStart + iLength > from->value.arrayLength){
iLength = from->value.arrayLength - iStart - 1;
}
}
switch(from->value.dataType){
case HIPINTAR:
case HIPINTVARAR:
fromData = MakeHdbIntArray(iLength, from->value.v.intArray+iStart);
break;
case HIPFLOATAR:
case HIPFLOATVARAR:
fromData = MakeHdbFloatArray(iLength, from->value.v.floatArray+iStart);
break;
default:
assert(0);
/* cannot really happen */
}
if(!copyHdbValue(&fromData, &to->value)) {
SCPrintf(pCon,eError,"ERROR: cannot copy data from %s to %s because of data type mismatch",
argv[3],argv[1]);
return 0;
}
SCSendOK(pCon);
return 1;
}
/*-------------------------------------------------------------------------*/
static int ArrayCopyOldHM(pHdb to, SConnection *pCon, int argc, char *argv[])
{
pHistMem hm = NULL;
int iStart, iLength;
int *data = NULL;
hdbValue copyData;
hm = (pHistMem)FindCommandData(pServ->pSics, argv[3],"HistMem");
if(hm == NULL){
SCPrintf(pCon,eError,"ERROR: cannot find HM %s", argv[3]);
return 0;
}
iStart = 0;
iLength = GetHistLength(hm);
if(argc > 4){
iStart = atoi(argv[4]);
iLength -= iStart;
}
if(argc > 5){
iLength = atoi(argv[5]);
}
if(iStart < 0){
iStart = 0;
}
if(iStart + iLength > GetHistLength(hm)){
iLength = GetHistLength(hm) - iStart - 1;
}
data = GetHistogramPointer(hm,pCon);
if(data == NULL){
SCPrintf(pCon,eError, "ERROR: failed to retrive HM data for %s", argv[3]);
return 0;
}
copyData = MakeHdbIntArray(iLength, data + iStart);
if(!copyHdbValue(&copyData, &to->value)) {
SCPrintf(pCon,eError,"ERROR: cannot copy data from %s to %s because of data type mismatch",
argv[3],argv[1]);
return 0;
}
SCSendOK(pCon);
return 1;
}
/*-------------------------------------------------------------------------*/
static int ArrayCopyOldTB(pHdb to, SConnection *pCon, int argc, char *argv[])
{
pHistMem hm = NULL;
int iStart, iLength, timeLength, i;
const float *data = NULL;
double *ddata = NULL;
hdbValue copyData;
hm = (pHistMem)FindCommandData(pServ->pSics, argv[3],"HistMem");
if(hm == NULL){
SCPrintf(pCon,eError,"ERROR: cannot find HM %s", argv[3]);
return 0;
}
iStart = 0;
data = GetHistTimeBin(hm,&timeLength);
if(data == NULL){
SCPrintf(pCon,eError, "ERROR: failed to retrive time binning for HM %s", argv[3]);
return 0;
}
iLength = timeLength;
if(argc > 4){
iStart = atoi(argv[4]);
iLength -= iStart;
}
if(argc > 5){
iLength = atoi(argv[5]);
}
if(iStart < 0){
iStart = 0;
}
if(iStart + iLength > timeLength){
iLength = timeLength - iStart - 1;
}
ddata = malloc(iLength*sizeof(double));
if(ddata == NULL){
SCPrintf(pCon,eError,"ERROR: out of memory copying %s time binning to %s",
argv[3],argv[1]);
return 0;
}
for(i = 0; i < iLength; i++){
ddata[i] = data[iStart+i];
}
copyData = MakeHdbFloatArray(iLength, ddata);
if(!copyHdbValue(&copyData, &to->value)) {
SCPrintf(pCon,eError,
"ERROR: cannot copy data from %s to %s because of data type mismatch",
argv[3],argv[1]);
return 0;
}
free(ddata);
SCSendOK(pCon);
return 1;
}
/*-------------------------------------------------------------------------*/
static int HdbArrayNode(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[])
{
@@ -3191,6 +3538,16 @@ static int HdbArrayNode(SConnection * pCon, SicsInterp * pSics, void *pData,
return 1;
}
if(strcmp(argv[2],"copynode") == 0){
return ArrayCopyNode(node, pCon, argc, argv);
}
if(strcmp(argv[2],"copyoldhm") == 0){
return ArrayCopyOldHM(node, pCon, argc, argv);
}
if(strcmp(argv[2],"copyoldtb") == 0){
return ArrayCopyOldTB(node, pCon, argc, argv);
}
idx = atoi(argv[2]);
if(idx < 0 || idx >= node->value.arrayLength ){
SCPrintf(pCon,eError,"ERROR: %d is out of range 0 - %d",
@@ -3207,7 +3564,6 @@ static int HdbArrayNode(SConnection * pCon, SicsInterp * pSics, void *pData,
node->value.v.floatArray[idx] = atof(argv[3]);
break;
}
NotifyHipadabaPar(node, pCon);
SCSendOK(pCon);
return 1;
}
@@ -3225,9 +3581,14 @@ static hdbCallbackReturn ChainCallback(pHdb node, void *userData,
if (slave != NULL) {
memset(&vv, 0, sizeof(hdbValue));
/*
The GetHipadabaPar here has to happen. Otherwise
necessary calculations to update the slave are not
performed.
*/
GetHipadabaPar(slave, &vv, mm->callData);
/* UpdateHipadabaPar(slave, *(mm->v), mm->callData); */
ReleaseHdbValue(&vv);
UpdateHipadabaPar(slave, vv, mm->callData);
ReleaseHdbValue(&vv);
}
return hdbContinue;
}
@@ -3683,6 +4044,27 @@ static int ANSTO_ListSICSHdbProperty(SConnection * pCon,
DeleteDynString(data);
return 1;
}
/*---------------------------------------------------------------------------*/
static int CallNotify(SConnection * pCon, SicsInterp * pSics,
void *pData, int argc, char *argv[])
{
pHdb node = NULL;
if(argc < 2) {
SCPrintf(pCon,eError, "ERROR: require path argument to %s", argv[0]);
return 0;
}
node = GetHipadabaNode(GetHipadabaRoot(), argv[1]);
if(node == NULL){
SCPrintf(pCon,eError,"ERROR: cannot find node %s to notify", argv[1]);
return 0;
}
NotifyHipadabaPar(node,pCon);
return 1;
}
/*---------------------------------------------------------------------------*/
static pHdb matchHdbProp(pHdb root, char *propname, char *buffer,
@@ -3730,7 +4112,6 @@ static pHdb matchHdbProp(pHdb root, char *propname, char *buffer,
return NULL;
}
/*---------------------------------------------------------------------------*/
static int MatchHdbProperty(SConnection * pCon, SicsInterp * pSics,
void *pData, int argc, char *argv[])
@@ -3772,7 +4153,95 @@ static int MatchHdbProperty(SConnection * pCon, SicsInterp * pSics,
DeleteDynString(matchList);
return 1;
}
/*---------------------------------------------------------------------------*/
static int AddCheck(SConnection * pCon, SicsInterp * pSics,
void *pData, int argc, char *argv[])
{
pHdb node = NULL;
if(argc < 3) {
SCPrintf(pCon,eLogError, "ERROR: need at least node and key argument for %s",
argv[0]);
return 0;
}
node = FindHdbNode(NULL, argv[1],pCon);
if (node == NULL) {
SCPrintf(pCon,eLogError, "ERROR: node %s to add check to not found", argv[1]);
return 0;
}
strtolower(argv[2]);
if(strcmp(argv[2],"values") == 0) {
PrependHipadabaCallback(node,MakeHipadabaCallback(SICSValueCheckCallback,
NULL,NULL));
SCSendOK(pCon);
return 1;
} else {
SCPrintf(pCon,eLogError,"ERROR: key %s for %s not recognized",
argv[2], argv[0]);
return 0;
}
return 1;
}
/*---------------------------------------------------------------------------*/
static hdbCallbackReturn SICSNotifyScriptCallback(pHdb node, void *userData,
pHdbMessage message)
{
char *pPath = NULL;
int macro, status;
pHdbDataMessage mm = NULL;
SConnection *tstCon;
char script[256];
/*
* Deal with update messages
*/
if ((mm = GetHdbUpdateMessage(message)) == NULL) {
return hdbContinue;
}
status = GetHdbProperty(node, "updatescript", script, sizeof(script));
if(status == 0){
tracePar(node->name,"ERROR: did not find updatescript property");
return hdbContinue;
}
copyHdbValue(mm->v, &node->value);
status = Tcl_Eval(InterpGetTcl(pServ->pSics), script);
if (status != TCL_OK) {
tracePar(node->name,"ERROR: %s while evaluating updatescript %s",
Tcl_GetStringResult(InterpGetTcl(pServ->pSics)), script);
}
return hdbContinue;
}
/*---------------------------------------------------------------------------*/
static int AddScriptNotify(SConnection * pCon, SicsInterp * pSics,
void *pData, int argc, char *argv[])
{
pHdb node = NULL;
if(argc < 3) {
SCWrite(pCon,"ERROR: Parameter missing, Usage: hscriptnotify node script",
eError);
return 0;
}
node = FindHdbNode(NULL,argv[1],pCon);
if (node == NULL) {
SCPrintf(pCon,eLogError, "ERROR: node %s to add script update not found",
argv[1]);
return 0;
}
SetHdbProperty(node,"updatescript",strdup(argv[2]));
AppendHipadabaCallback(node,MakeHipadabaCallback(SICSNotifyScriptCallback,
NULL,NULL));
SCSendOK(pCon);
return 1;
}
/*======================= Factory Functions =================================*/
void killSICSHipadaba()
{
@@ -3801,12 +4270,14 @@ int InstallSICSHipadaba(SConnection * pCon, SicsInterp * pSics,
AddCommand(pSics, "hget", GetHdbNode, NULL, NULL);
AddCommand(pSics, "hval", GetHdbVal, NULL, NULL);
AddCommand(pSics, "hzipget", ZipGetHdbNode, NULL, NULL);
AddCommand(pSics, "hzipread", ZipReadHdbNode, NULL, NULL);
AddCommand(pSics, "hbinread", BinReadHdbNode, NULL, NULL);
AddCommand(pSics, "hlist", ListHdbNode, NULL, NULL);
AddCommand(pSics, "hnotify", AutoNotifyHdbNode, NULL, NULL);
AddCommand(pSics, "hdelcb", RemoveHdbCallback, NULL, NULL);
AddCommand(pSics, "hlink", LinkHdbNode, NULL, NULL);
AddCommand(pSics, "hinfo", HdbNodeInfo, NULL, NULL);
AddCommand(pSics, "hval", HdbNodeVal, NULL, NULL);
/* AddCommand(pSics, "hval", HdbNodeVal, NULL, NULL);*/
AddCommand(pSics, "hchain", ChainHdbNode, NULL, NULL);
AddCommand(pSics, "hcommand", SicsCommandNode, NULL, NULL);
AddCommand(pSics, "harray", HdbArrayNode, NULL, NULL);
@@ -3818,6 +4289,9 @@ int InstallSICSHipadaba(SConnection * pCon, SicsInterp * pSics,
AddCommand(pSics, "hpropexists", HasSICSHdbProperty, NULL, NULL);
AddCommand(pSics, "hlistprop", ListSICSHdbProperty, NULL, NULL);
AddCommand(pSics, "hfindprop", ANSTO_ListSICSHdbProperty, NULL, NULL);
AddCommand(pSics, "hcallnotify",CallNotify, NULL, NULL);
AddCommand(pSics, "haddcheck",AddCheck, NULL, NULL);
AddCommand(pSics, "hscriptnotify",AddScriptNotify, NULL, NULL);
InstallSICSPoll(pCon, pSics, pData, argc, argv);
poller = (pSicsPoll) FindCommandData(pSics, "sicspoll", "SicsPoll");