diff --git a/site_ansto/counterdriv.c b/site_ansto/counterdriv.c index eedfed9c..59effb81 100644 --- a/site_ansto/counterdriv.c +++ b/site_ansto/counterdriv.c @@ -20,6 +20,9 @@ #include #include "anstoutil.h" +#define FAILURE 0 +#define SUCCESS 1 + /*@-incondefs@*/ /*@observer@*//*@dependent@*/ Tcl_Interp *InterpGetTcl(SicsInterp *pSics); /*@observer@*//*@dependent@*/ pCounterDriver CreateCounterDriver(char *name, char *type); @@ -61,10 +64,74 @@ typedef struct __COUNTDRIV { typedef struct { prs232 controller; + int state; + int errorCode; char *host; int iPort; float dummy_threshold; -} BeamMon; + struct { int length; char body[8192]; } buffer; +} BeamMon, *pBeamMon; + +/** \brief Writes a line to the Monitor + * used for sending commands. + * + * \param *cntrData provides access to a monitor's data + * \param *text pointer to NULL terminated text to send. + * \return + * - SUCCESS + * - FAILURE + */ +static int MonWrite(pBeamMon self, char* text) { + int len; + int status; + + len = strlen(text); + + /*@+matchanyintegral@ let size_t from strlen match int */ + status = writeRS232(self->controller, text, len); + /*@-matchanyintegral@*/ + if (status != 1) { + self->errorCode = status; + return FAILURE; + } + return SUCCESS; +} + +static int MonHandleInput(pBeamMon self, int timeout) { + int iRet, len; + int iLen = 0; + int jLen = 0; + char reply[1024]; + char* pTerm; + while (availableRS232(self->controller)) { + len = sizeof(reply); + iRet = readRS232(self->controller, reply, &len); + if (iRet < 0) { + return iRet; + } + iLen = 0; + while (iLen < len) { + char* pTerm = strstr(&reply[iLen], "\r\n"); + if (pTerm) + jLen = &pTerm[2] - &reply[iLen]; + else + jLen = len - iLen; + strncpy(&self->buffer.body[self->buffer.length], + &reply[iLen], + jLen); + self->buffer.length += jLen; + self->buffer.body[self->buffer.length] = '\0'; + iLen += jLen; + if (pTerm) + { + /* TODO handle the line */ + fputs(self->buffer.body, stderr); + self->buffer.length = 0; + } + } + } + return 1; +} /** \brief Returns the counter status, * implements the GetStatus method in the MotorDriver interface. @@ -82,7 +149,20 @@ static int MonGetStatus(CounterDriver *cntrData, float *fControl) { BeamMon *self = NULL; self = (BeamMon *) cntrData->pData; - return HWIdle; + MonHandleInput(self, 0); + switch (self->state) { + case HWIdle: + return HWIdle; + case HWNoBeam: + return HWNoBeam; + case HWPause: + return HWPause; + case HWBusy: + return HWBusy; + case HWFault: + default: + return HWFault; + } } /** \brief Starts counting in the current mode and with the current preset @@ -211,7 +291,13 @@ static int MonSend(CounterDriver *cntrData, char *pText, char *pReply, int iRepl return SUCCESS; } -static void KillMon(pCounterDriver self) { +static void KillMon(pCounterDriver cntrData) { + pBeamMon self = NULL; + self = (pBeamMon) cntrData->pData; + if (self) { + if (self->host) + free(self->host); + } } /*@only@*/ prs232 createRS232(char *host, int iPort); @@ -237,7 +323,7 @@ static void KillMon(pCounterDriver self) { if ( initRS232(controller) != 1) { snprintf(pError, ERRLEN, "ERROR: failed to connect to %s at port %d", - controller->pHost, controller->iPort); + host, port); SCWrite(pCon,pError,eError); KillRS232(controller); return NULL; @@ -252,8 +338,6 @@ static void KillMon(pCounterDriver self) { BeamMon *newCtr = NULL; pCounterDriver pCntDriv = NULL; char *pPtr = NULL; - char buffer[132]; - int port; Tcl_Interp *interp; interp = InterpGetTcl(pServ->pSics); @@ -286,6 +370,10 @@ static void KillMon(pCounterDriver self) { pCntDriv->Get = MonGet; pCntDriv->iNoOfMonitors = 1; + + memset(newCtr, 0, sizeof(BeamMon)); + newCtr->state = HWIdle; + /*@-mustfreeonly@ pData = NULL after CreateCounterDriver is called */ pCntDriv->pData = newCtr; /*@+mustfreeonly@*/ @@ -295,13 +383,13 @@ static void KillMon(pCounterDriver self) { KillMon(pCntDriv); return NULL; } - sscanf(pPtr,"%d",&port); + sscanf(pPtr,"%d", &newCtr->iPort); if ((pPtr=getParam(pCon, interp, params,"host",1)) == NULL) { KillMon(pCntDriv); return NULL; } - strncpy(buffer,pPtr, 131); - newCtr->controller = MonConnect(pCon, buffer, port); + newCtr->host = strdup(pPtr); + newCtr->controller = MonConnect(pCon, newCtr->host, newCtr->iPort); newCtr->dummy_threshold = 1.7e6; return pCntDriv;