Fixed indentation in epicsadapater.c

Corrected a header file include in zebraswap.c
This commit is contained in:
2016-12-21 08:53:31 +01:00
parent 8362096223
commit 116ee50ce3
2 changed files with 372 additions and 372 deletions

View File

@ -1,12 +1,12 @@
/** /**
* This is a general purpose adapter between SICS and EPICS. It provides callbacks * This is a general purpose adapter between SICS and EPICS. It provides callbacks
* which allows Hipadaba nodes to be connected to EPICS PV's for both reading and * which allows Hipadaba nodes to be connected to EPICS PV's for both reading and
* writing. * writing.
* *
* copyright: see file COPYRIGHT * copyright: see file COPYRIGHT
* *
* Mark Koennecke, October - November 2014 * Mark Koennecke, October - November 2014
*/ */
#include <assert.h> #include <assert.h>
#include <sics.h> #include <sics.h>
#include <sicshipadaba.h> #include <sicshipadaba.h>
@ -16,31 +16,31 @@
#include <messagepipe.h> #include <messagepipe.h>
/* /*
One of those: alarmString.h cannot be doubly included into the One of those: alarmString.h cannot be doubly included into the
same application same application
*/ */
#include <alarmString.h> #include <alarmString.h>
/* extern char *epicsAlarmConditionStrings[]; */ /* extern char *epicsAlarmConditionStrings[]; */
/* /*
* we have a SICS tasks which polls EPICS regularly. * we have a SICS tasks which polls EPICS regularly.
*/ */
static long epicsTaskID = -1L; static long epicsTaskID = -1L;
static pMP readPipe = NULL; static pMP readPipe = NULL;
static epicsMessageQueueId writeQueue; static epicsMessageQueueId writeQueue;
typedef struct { typedef struct {
char pvname[64]; char pvname[64];
int connected; int connected;
pHdb node; pHdb node;
chid pvchid; chid pvchid;
chtype pvtype; chtype pvtype;
}EpicsPriv, *pEpicsPriv; }EpicsPriv, *pEpicsPriv;
typedef struct { typedef struct {
SConnection *pCon; SConnection *pCon;
char message[512]; char message[512];
} WriteMessage, *pWriteMessage; } WriteMessage, *pWriteMessage;
/*====================================================================================== /*======================================================================================
@ -48,448 +48,448 @@ typedef struct {
======================================================================================*/ ======================================================================================*/
static int EpicsTask(void *userData) static int EpicsTask(void *userData)
{ {
pWriteMessage mes; pWriteMessage mes;
/* /*
drive the main EPICS loop for subscriptions drive the main EPICS loop for subscriptions
*/ */
ca_poll(); ca_poll();
/* /*
process possible messages from the writing threads process possible messages from the writing threads
*/ */
if(epicsMessageQueueTryReceive(writeQueue,&mes,sizeof(mes)) > 0){ if(epicsMessageQueueTryReceive(writeQueue,&mes,sizeof(mes)) > 0){
if(mes->pCon == NULL){ if(mes->pCon == NULL){
traceIO("epics",mes->message); traceIO("epics",mes->message);
} else { } else {
SCWrite(mes->pCon,mes->message,eError); SCWrite(mes->pCon,mes->message,eError);
SCDeleteConnection(mes->pCon); SCDeleteConnection(mes->pCon);
} }
free(mes); free(mes);
} }
return 1; return 1;
} }
/*---------------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------------*/
static int makeEPICSContext(void *message, void *userData) static int makeEPICSContext(void *message, void *userData)
{ {
int status; int status;
pEpicsPriv priv = NULL; pEpicsPriv priv = NULL;
if(epicsTaskID < 0){ if(epicsTaskID < 0){
status = ca_context_create(ca_disable_preemptive_callback); status = ca_context_create(ca_disable_preemptive_callback);
if(status != ECA_NORMAL){ if(status != ECA_NORMAL){
priv = (pEpicsPriv)message; priv = (pEpicsPriv)message;
SetHdbProperty(priv->node,"geterror", "Failed to create EPICS context"); SetHdbProperty(priv->node,"geterror", "Failed to create EPICS context");
return MPSTOP; return MPSTOP;
} }
epicsTaskID = TaskRegisterN(pServ->pTasker, epicsTaskID = TaskRegisterN(pServ->pTasker,
"epics", "epics",
EpicsTask, EpicsTask,
NULL,NULL,NULL,1 NULL,NULL,NULL,1
); );
} }
return MPCONTINUE; return MPCONTINUE;
} }
/*--------------------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------------------*/
static int epicsConnectPV(void *message, void *userData) static int epicsConnectPV(void *message, void *userData)
{ {
pEpicsPriv priv = NULL; pEpicsPriv priv = NULL;
int status; int status;
priv = (pEpicsPriv)message; priv = (pEpicsPriv)message;
status = ca_create_channel(priv->pvname,NULL,NULL,10,&priv->pvchid); status = ca_create_channel(priv->pvname,NULL,NULL,10,&priv->pvchid);
if(status != ECA_NORMAL){ if(status != ECA_NORMAL){
SetHdbProperty(priv->node,"geterror", "Failed to connect to PV"); SetHdbProperty(priv->node,"geterror", "Failed to connect to PV");
return MPSTOP; return MPSTOP;
} }
status = ca_pend_io(0.2); status = ca_pend_io(0.2);
if(status != ECA_NORMAL){ if(status != ECA_NORMAL){
SetHdbProperty(priv->node,"geterror", "Timeout connecting to PV"); SetHdbProperty(priv->node,"geterror", "Timeout connecting to PV");
return MPSTOP; return MPSTOP;
} }
return MPCONTINUE; return MPCONTINUE;
} }
/*--------------------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------------------*/
static void epicsDataCallback(struct event_handler_args args) static void epicsDataCallback(struct event_handler_args args)
{ {
pEpicsPriv priv = NULL; pEpicsPriv priv = NULL;
hdbValue v; hdbValue v;
char error[256]; char error[256];
priv = (pEpicsPriv)args.usr; priv = (pEpicsPriv)args.usr;
if(args.status == ECA_NORMAL){ if(args.status == ECA_NORMAL){
switch(priv->node->value.dataType){ switch(priv->node->value.dataType){
case HIPTEXT: case HIPTEXT:
free(priv->node->value.v.text); free(priv->node->value.v.text);
priv->node->value.v.text = strdup((char *)args.dbr); priv->node->value.v.text = strdup((char *)args.dbr);
break; break;
case HIPINT: case HIPINT:
priv->node->value.v.intValue = *(int *)args.dbr; priv->node->value.v.intValue = *(int *)args.dbr;
break; break;
case HIPFLOAT: case HIPFLOAT:
priv->node->value.v.doubleValue = *(double *)args.dbr; priv->node->value.v.doubleValue = *(double *)args.dbr;
break; break;
case HIPINTAR: case HIPINTAR:
case HIPINTVARAR: case HIPINTVARAR:
v = MakeHdbIntArray(args.count,(int *)args.dbr); v = MakeHdbIntArray(args.count,(int *)args.dbr);
copyHdbValue(&v,&priv->node->value); copyHdbValue(&v,&priv->node->value);
break; break;
case HIPFLOATAR: case HIPFLOATAR:
case HIPFLOATVARAR: case HIPFLOATVARAR:
v = MakeHdbFloatArray(args.count,(double *)args.dbr); v = MakeHdbFloatArray(args.count,(double *)args.dbr);
copyHdbValue(&v,&priv->node->value); copyHdbValue(&v,&priv->node->value);
break; break;
} }
SetHdbProperty(priv->node,"geterror",NULL); SetHdbProperty(priv->node,"geterror",NULL);
traceIO("epics","Received data for %s", priv->node->name); traceIO("epics","Received data for %s", priv->node->name);
NotifyHipadabaPar(priv->node,NULL); NotifyHipadabaPar(priv->node,NULL);
} else { } else {
snprintf(error,sizeof(error),"ERROR: %s for node %s", ca_message(args.status), priv->node->name); snprintf(error,sizeof(error),"ERROR: %s for node %s", ca_message(args.status), priv->node->name);
traceIO("epics",error); traceIO("epics",error);
SetHdbProperty(priv->node,"geterror",error); SetHdbProperty(priv->node,"geterror",error);
} }
} }
/*--------------------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------------------*/
static int epicsSubscribePV(void *message, void *userData) static int epicsSubscribePV(void *message, void *userData)
{ {
pEpicsPriv priv = NULL; pEpicsPriv priv = NULL;
int status; int status;
chtype subType = DBR_STRING; chtype subType = DBR_STRING;
evid eid; evid eid;
priv = (pEpicsPriv)message; priv = (pEpicsPriv)message;
switch(priv->node->value.dataType){ switch(priv->node->value.dataType){
case HIPTEXT: case HIPTEXT:
subType = DBR_STRING; subType = DBR_STRING;
break; break;
case HIPINT: case HIPINT:
case HIPINTAR: case HIPINTAR:
case HIPINTVARAR: case HIPINTVARAR:
subType = DBR_LONG; subType = DBR_LONG;
break; break;
case HIPFLOAT: case HIPFLOAT:
case HIPFLOATAR: case HIPFLOATAR:
case HIPFLOATVARAR: case HIPFLOATVARAR:
subType = DBR_DOUBLE; subType = DBR_DOUBLE;
break; break;
} }
status = ca_create_subscription(subType,0,priv->pvchid, status = ca_create_subscription(subType,0,priv->pvchid,
DBE_VALUE|DBE_ALARM,epicsDataCallback,priv,&eid); DBE_VALUE|DBE_ALARM,epicsDataCallback,priv,&eid);
if(status != ECA_NORMAL){ if(status != ECA_NORMAL){
SetHdbProperty(priv->node,"geterror", "Failed to subscribe to PV"); SetHdbProperty(priv->node,"geterror", "Failed to subscribe to PV");
return MPSTOP; return MPSTOP;
} }
return MPCONTINUE; return MPCONTINUE;
} }
/*--------------------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------------------*/
static void createEPICSReadPipe() static void createEPICSReadPipe()
{ {
readPipe = MakeMP(); readPipe = MakeMP();
AppendMPFilter(readPipe,makeEPICSContext,NULL,NULL); AppendMPFilter(readPipe,makeEPICSContext,NULL,NULL);
AppendMPFilter(readPipe,epicsConnectPV,NULL,NULL); AppendMPFilter(readPipe,epicsConnectPV,NULL,NULL);
AppendMPFilter(readPipe,epicsSubscribePV,NULL,NULL); AppendMPFilter(readPipe,epicsSubscribePV,NULL,NULL);
} }
/*--------------------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------------------*/
static void connectPV(pHdb node, pEpicsPriv priv) static void connectPV(pHdb node, pEpicsPriv priv)
{ {
int status; int status;
SetHdbProperty(node,"geterror", NULL); SetHdbProperty(node,"geterror", NULL);
priv->node = node; priv->node = node;
status = MPprocess(readPipe, priv); status = MPprocess(readPipe, priv);
if(status == MPCONTINUE){ if(status == MPCONTINUE){
priv->connected = 1; priv->connected = 1;
} }
} }
/*-------------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------------
This is the Hipadaba callback function This is the Hipadaba callback function
--------------------------------------------------------------------------------------*/ --------------------------------------------------------------------------------------*/
static hdbCallbackReturn EPICSReadCallback(pHdb currentNode, static hdbCallbackReturn EPICSReadCallback(pHdb currentNode,
void *userData, void *userData,
pHdbMessage message) pHdbMessage message)
{ {
pEpicsPriv priv = (pEpicsPriv)userData; pEpicsPriv priv = (pEpicsPriv)userData;
hdbDataMessage *mm = NULL; hdbDataMessage *mm = NULL;
SConnection *con = NULL; SConnection *con = NULL;
char *geterror; char *geterror;
char error[256]; char error[256];
enum channel_state cs; enum channel_state cs;
assert(priv != NULL); assert(priv != NULL);
mm = GetHdbGetMessage(message); mm = GetHdbGetMessage(message);
if (mm != NULL) { if (mm != NULL) {
con = mm->callData; con = mm->callData;
if(priv->connected != 1){ if(priv->connected != 1){
connectPV(currentNode, priv); connectPV(currentNode, priv);
} }
cs = ca_state(priv->pvchid); cs = ca_state(priv->pvchid);
if(cs != cs_conn){ if(cs != cs_conn){
SCWrite(con,"ERROR: epics disconnected", eError); SCWrite(con,"ERROR: epics disconnected", eError);
return hdbAbort; return hdbAbort;
} }
geterror = GetHdbProp(currentNode, "geterror"); geterror = GetHdbProp(currentNode, "geterror");
if (geterror != NULL) { if (geterror != NULL) {
snprintf(error,sizeof(error),"ERROR: %s", geterror); snprintf(error,sizeof(error),"ERROR: %s", geterror);
SCWrite(con, error, eError); SCWrite(con, error, eError);
if (mm->v->dataType == HIPTEXT) { if (mm->v->dataType == HIPTEXT) {
if (mm->v->v.text != NULL) { if (mm->v->v.text != NULL) {
free(mm->v->v.text); free(mm->v->v.text);
}
mm->v->v.text = strdup(error);
}
return hdbAbort;
}
return hdbContinue;
}
return hdbContinue;
}
/*------------------------------------------------------------------------------------*/
static int EpicsConnectRead(pSICSOBJ ccmd, SConnection * con,
Hdb * cmdNode, Hdb * par[], int nPar)
{
pHdb node = NULL;
pEpicsPriv priv = NULL;
if(nPar < 2){
SCWrite(con,"ERROR: need node and PV-name arguments to connectread", eError);
return 0;
}
node = FindHdbNode(NULL,par[0]->value.v.text,con);
if(node == NULL){
SCPrintf(con,eError,"ERROR: failed to locate node %s", par[0]->value.v.text);
return 0;
}
priv = calloc(1,sizeof(EpicsPriv));
priv->node = node;
strncpy(priv->pvname,par[1]->value.v.text,sizeof(priv->pvname));
SetHdbProperty(node,"readpv", par[1]->value.v.text);
AppendHipadabaCallback(node,MakeHipadabaCallback(EPICSReadCallback, priv,free));
connectPV(node,priv);
SCSendOK(con);
return 1;
} }
/*============================================================================================== mm->v->v.text = strdup(error);
Writing Things. Writing can block, thus it has to run in its own thread. This raises the }
question how to propagate error messages. The solution is a EPICS message queue to which return hdbAbort;
writing threads post. The epics task will read this queue and do the actual printing in the }
SICS main thread. A convention: NULL means to print to trace. return hdbContinue;
}
================================================================================================*/ return hdbContinue;
}
/*------------------------------------------------------------------------------------*/
static int EpicsConnectRead(pSICSOBJ ccmd, SConnection * con,
Hdb * cmdNode, Hdb * par[], int nPar)
{
pHdb node = NULL;
pEpicsPriv priv = NULL;
if(nPar < 2){
SCWrite(con,"ERROR: need node and PV-name arguments to connectread", eError);
return 0;
}
node = FindHdbNode(NULL,par[0]->value.v.text,con);
if(node == NULL){
SCPrintf(con,eError,"ERROR: failed to locate node %s", par[0]->value.v.text);
return 0;
}
priv = calloc(1,sizeof(EpicsPriv));
priv->node = node;
strncpy(priv->pvname,par[1]->value.v.text,sizeof(priv->pvname));
SetHdbProperty(node,"readpv", par[1]->value.v.text);
AppendHipadabaCallback(node,MakeHipadabaCallback(EPICSReadCallback, priv,free));
connectPV(node,priv);
SCSendOK(con);
return 1;
}
/*==============================================================================================
Writing Things. Writing can block, thus it has to run in its own thread. This raises the
question how to propagate error messages. The solution is a EPICS message queue to which
writing threads post. The epics task will read this queue and do the actual printing in the
SICS main thread. A convention: NULL means to print to trace.
================================================================================================*/
typedef struct { typedef struct {
SConnection *pCon; SConnection *pCon;
hdbValue v; hdbValue v;
char pvName[64]; char pvName[64];
} WritePar, *pWritePar; } WritePar, *pWritePar;
/*----------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------*/
static void writeEpicsMessage(void *target, char *txt) static void writeEpicsMessage(void *target, char *txt)
{ {
pWriteMessage wm = NULL; pWriteMessage wm = NULL;
wm = calloc(1,sizeof(WriteMessage)); wm = calloc(1,sizeof(WriteMessage));
if(wm != NULL){ if(wm != NULL){
if(target != NULL){ if(target != NULL){
wm->pCon = SCCopyConnection(target); wm->pCon = SCCopyConnection(target);
} }
strncpy(wm->message,txt,sizeof(wm->message)); strncpy(wm->message,txt,sizeof(wm->message));
epicsMessageQueueSend(writeQueue,&wm,sizeof(pWriteMessage)); epicsMessageQueueSend(writeQueue,&wm,sizeof(pWriteMessage));
} }
} }
/*---------------------------------------------------------------------------------------------- /*----------------------------------------------------------------------------------------------
To my surprise this is never called. May be, when the thread terminates anyway, To my surprise this is never called. May be, when the thread terminates anyway,
epics does not know anymore that the callback existed or how to call it. epics does not know anymore that the callback existed or how to call it.
------------------------------------------------------------------------------------------------*/ ------------------------------------------------------------------------------------------------*/
static void epicsEndCallback(struct event_handler_args args) static void epicsEndCallback(struct event_handler_args args)
{ {
char message[512]; char message[512];
snprintf(message,sizeof(message),"%s finished with %s", (char *)args.usr, snprintf(message,sizeof(message),"%s finished with %s", (char *)args.usr,
ca_message(args.status)); ca_message(args.status));
writeEpicsMessage(NULL,message); writeEpicsMessage(NULL,message);
free(args.usr); free(args.usr);
} }
/*----------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------*/
static void EpicsWriteFunc(void *param) static void EpicsWriteFunc(void *param)
{ {
pWritePar wp = (pWritePar)param; pWritePar wp = (pWritePar)param;
pWriteMessage wm = NULL; pWriteMessage wm = NULL;
int status; int status;
chid cid; chid cid;
char error[512]; char error[512];
char *pv; char *pv;
status = ca_context_create(ca_disable_preemptive_callback); status = ca_context_create(ca_disable_preemptive_callback);
if(status != ECA_NORMAL){ if(status != ECA_NORMAL){
writeEpicsMessage(wp->pCon,"ERROR: failed to create EPICS context for write"); writeEpicsMessage(wp->pCon,"ERROR: failed to create EPICS context for write");
goto cleanup; goto cleanup;
} }
status = ca_create_channel(wp->pvName,NULL,NULL,10,&cid); status = ca_create_channel(wp->pvName,NULL,NULL,10,&cid);
if(status != ECA_NORMAL){ if(status != ECA_NORMAL){
snprintf(error,sizeof(error),"ERROR: failed to create EPICS channel for %s", wp->pvName); snprintf(error,sizeof(error),"ERROR: failed to create EPICS channel for %s", wp->pvName);
writeEpicsMessage(wp->pCon,error); writeEpicsMessage(wp->pCon,error);
goto cleanup; goto cleanup;
} }
status = ca_pend_io(0.5); status = ca_pend_io(0.5);
if(status != ECA_NORMAL){ if(status != ECA_NORMAL){
snprintf(error,sizeof(error),"ERROR: failed to connect EPICS channel for %s", wp->pvName); snprintf(error,sizeof(error),"ERROR: failed to connect EPICS channel for %s", wp->pvName);
writeEpicsMessage(wp->pCon,error); writeEpicsMessage(wp->pCon,error);
goto cleanup; goto cleanup;
} }
pv = strdup(wp->pvName); pv = strdup(wp->pvName);
switch(wp->v.dataType){ switch(wp->v.dataType){
case HIPINT: case HIPINT:
status = ca_put_callback(DBR_LONG,cid,&wp->v.v.intValue,epicsEndCallback,pv); status = ca_put_callback(DBR_LONG,cid,&wp->v.v.intValue,epicsEndCallback,pv);
break; break;
case HIPFLOAT: case HIPFLOAT:
status = ca_put_callback(DBR_DOUBLE,cid,&wp->v.v.doubleValue,epicsEndCallback,pv); status = ca_put_callback(DBR_DOUBLE,cid,&wp->v.v.doubleValue,epicsEndCallback,pv);
break; break;
case HIPTEXT: case HIPTEXT:
status = ca_put_callback(DBR_STRING,cid,wp->v.v.text,epicsEndCallback, pv); status = ca_put_callback(DBR_STRING,cid,wp->v.v.text,epicsEndCallback, pv);
break; break;
case HIPINTVARAR: case HIPINTVARAR:
case HIPINTAR: case HIPINTAR:
status = ca_array_put_callback(DBR_LONG,wp->v.arrayLength, status = ca_array_put_callback(DBR_LONG,wp->v.arrayLength,
cid, wp->v.v.intArray,epicsEndCallback,pv); cid, wp->v.v.intArray,epicsEndCallback,pv);
break; break;
case HIPFLOATVARAR: case HIPFLOATVARAR:
case HIPFLOATAR: case HIPFLOATAR:
status = ca_array_put_callback(DBR_DOUBLE,wp->v.arrayLength, status = ca_array_put_callback(DBR_DOUBLE,wp->v.arrayLength,
cid, wp->v.v.floatArray,epicsEndCallback,pv); cid, wp->v.v.floatArray,epicsEndCallback,pv);
break; break;
} }
if(status != ECA_NORMAL){ if(status != ECA_NORMAL){
snprintf(error,sizeof(error),"ERROR: failed to write to EPICS channel for %s with %d", wp->pvName, status); snprintf(error,sizeof(error),"ERROR: failed to write to EPICS channel for %s with %d", wp->pvName, status);
writeEpicsMessage(wp->pCon,error); writeEpicsMessage(wp->pCon,error);
goto cleanup; goto cleanup;
} }
writeEpicsMessage(wp->pCon,"OK"); writeEpicsMessage(wp->pCon,"OK");
snprintf(error,sizeof(error),"Writing data for PV %s", wp->pvName); snprintf(error,sizeof(error),"Writing data for PV %s", wp->pvName);
writeEpicsMessage(NULL,error); writeEpicsMessage(NULL,error);
ca_pend_io(0); ca_pend_io(0);
goto cleanup; goto cleanup;
cleanup: cleanup:
SCDeleteConnection(wp->pCon); SCDeleteConnection(wp->pCon);
ReleaseHdbValue(&wp->v); ReleaseHdbValue(&wp->v);
free(wp); free(wp);
free(pv); free(pv);
ca_clear_channel(cid); ca_clear_channel(cid);
ca_context_destroy(); /* ca_context_destroy(); */
} }
/*----------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------*/
static hdbCallbackReturn EPICSWriteCallback(pHdb currentNode, static hdbCallbackReturn EPICSWriteCallback(pHdb currentNode,
void *userData, void *userData,
pHdbMessage message) pHdbMessage message)
{ {
hdbDataMessage *mm = NULL; hdbDataMessage *mm = NULL;
pWritePar par = NULL; pWritePar par = NULL;
mm = GetHdbSetMessage(message); mm = GetHdbSetMessage(message);
if(mm != NULL){ if(mm != NULL){
par = calloc(1,sizeof(WritePar)); par = calloc(1,sizeof(WritePar));
if(par == NULL){ if(par == NULL){
SCWrite(mm->callData,"ERROR: out of memory in EPICSWriteCallback", eError); SCWrite(mm->callData,"ERROR: out of memory in EPICSWriteCallback", eError);
return hdbAbort; return hdbAbort;
} }
if(mm->callData != NULL){ if(mm->callData != NULL){
par->pCon = SCCopyConnection(mm->callData); par->pCon = SCCopyConnection(mm->callData);
} }
cloneHdbValue(mm->v,&par->v); cloneHdbValue(mm->v,&par->v);
strncpy(par->pvName,(char *)userData,sizeof(par->pvName)); strncpy(par->pvName,(char *)userData,sizeof(par->pvName));
epicsThreadCreate("Write", epicsThreadCreate("Write",
epicsThreadPriorityHigh, epicsThreadPriorityHigh,
epicsThreadStackSmall, epicsThreadStackMedium,
EpicsWriteFunc, EpicsWriteFunc,
par); par);
} }
return hdbContinue; return hdbContinue;
} }
/*------------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------------*/
static int EpicsConnectWrite(pSICSOBJ ccmd, SConnection * con, static int EpicsConnectWrite(pSICSOBJ ccmd, SConnection * con,
Hdb * cmdNode, Hdb * par[], int nPar) Hdb * cmdNode, Hdb * par[], int nPar)
{ {
pHdb node = NULL; pHdb node = NULL;
pEpicsPriv priv = NULL; pEpicsPriv priv = NULL;
if(nPar < 2){ if(nPar < 2){
SCWrite(con,"ERROR: need node and PV-name arguments to connectread", eError); SCWrite(con,"ERROR: need node and PV-name arguments to connectread", eError);
return 0; return 0;
} }
node = FindHdbNode(NULL,par[0]->value.v.text,con); node = FindHdbNode(NULL,par[0]->value.v.text,con);
if(node == NULL){ if(node == NULL){
SCPrintf(con,eError,"ERROR: failed to locate node %s", par[0]->value.v.text); SCPrintf(con,eError,"ERROR: failed to locate node %s", par[0]->value.v.text);
return 0; return 0;
} }
SetHdbProperty(node,"writepv", par[1]->value.v.text); SetHdbProperty(node,"writepv", par[1]->value.v.text);
RemoveSetUpdateCallback(node); RemoveSetUpdateCallback(node);
AppendHipadabaCallback(node,MakeHipadabaCallback(EPICSWriteCallback, AppendHipadabaCallback(node,MakeHipadabaCallback(EPICSWriteCallback,
strdup(par[1]->value.v.text),free)); strdup(par[1]->value.v.text),free));
SCSendOK(con); SCSendOK(con);
return 1; return 1;
} }
/*============================================================================================== /*==============================================================================================
SICS Hydraulics SICS Hydraulics
================================================================================================*/ ================================================================================================*/
static int EpicsConvertAlarm(pSICSOBJ ccmd, SConnection * con, static int EpicsConvertAlarm(pSICSOBJ ccmd, SConnection * con,
Hdb * cmdNode, Hdb * par[], int nPar) Hdb * cmdNode, Hdb * par[], int nPar)
{ {
pHdb node = NULL; pHdb node = NULL;
char value[256]; char value[256];
if(nPar < 1){ if(nPar < 1){
SCWrite(con,"ERROR: need alarm code to convert", eError); SCWrite(con,"ERROR: need alarm code to convert", eError);
return 0; return 0;
} }
snprintf(value,sizeof(value),"%s", epicsAlarmConditionStrings[par[0]->value.v.intValue]); snprintf(value,sizeof(value),"%s", epicsAlarmConditionStrings[par[0]->value.v.intValue]);
SCWrite(con,value,eValue); SCWrite(con,value,eValue);
return 1; return 1;
} }
/*----------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------*/
int MakeEpicsAdapter(SConnection * con, SicsInterp * sics, int MakeEpicsAdapter(SConnection * con, SicsInterp * sics,
void *object, int argc, char *argv[]) void *object, int argc, char *argv[])
{ {
pSICSOBJ self = NULL; pSICSOBJ self = NULL;
pHdb child, par; pHdb child, par;
self = MakeSICSOBJv("epicsadapter", "EpicsAdapter", HIPNONE, usMugger); self = MakeSICSOBJv("epicsadapter", "EpicsAdapter", HIPNONE, usMugger);
createEPICSReadPipe(); createEPICSReadPipe();
writeQueue = epicsMessageQueueCreate(64,sizeof(pWriteMessage)); writeQueue = epicsMessageQueueCreate(64,sizeof(pWriteMessage));
child = AddSICSHdbPar(self->objectNode, child = AddSICSHdbPar(self->objectNode,
"connectread", usMugger, MakeSICSFunc(EpicsConnectRead)); "connectread", usMugger, MakeSICSFunc(EpicsConnectRead));
AddSICSHdbPar(child, "node", usMugger, MakeHdbText("")); AddSICSHdbPar(child, "node", usMugger, MakeHdbText(""));
AddSICSHdbPar(child, "pvname", usMugger, MakeHdbText("")); AddSICSHdbPar(child, "pvname", usMugger, MakeHdbText(""));
child = AddSICSHdbPar(self->objectNode, child = AddSICSHdbPar(self->objectNode,
"connectwrite", usMugger, MakeSICSFunc(EpicsConnectWrite)); "connectwrite", usMugger, MakeSICSFunc(EpicsConnectWrite));
AddSICSHdbPar(child, "node", usMugger, MakeHdbText("")); AddSICSHdbPar(child, "node", usMugger, MakeHdbText(""));
AddSICSHdbPar(child, "pvname", usMugger, MakeHdbText("")); AddSICSHdbPar(child, "pvname", usMugger, MakeHdbText(""));
child = AddSICSHdbPar(self->objectNode, child = AddSICSHdbPar(self->objectNode,
"convertalarm", usSpy, MakeSICSFunc(EpicsConvertAlarm)); "convertalarm", usSpy, MakeSICSFunc(EpicsConvertAlarm));
AddSICSHdbPar(child, "stat", usSpy, MakeHdbInt(1.)); AddSICSHdbPar(child, "stat", usSpy, MakeHdbInt(1.));
AddCommand(pServ->pSics, "epicsadapter", InterInvokeSICSOBJ, KillSICSOBJ, self); AddCommand(pServ->pSics, "epicsadapter", InterInvokeSICSOBJ, KillSICSOBJ, self);
return 1; return 1;
} }

View File

@ -12,7 +12,7 @@ Mark Koennecke, December 2016
*/ */
#include <sics.h> #include <sics.h>
#include <histmem.h> #include <HistMem.h>
#include <sicshipadaba.h> #include <sicshipadaba.h>
/*---------------------------------------------------------------*/ /*---------------------------------------------------------------*/