Largely comments and splint conformance

r1070 | dcl | 2006-08-21 09:47:25 +1000 (Mon, 21 Aug 2006) | 2 lines
This commit is contained in:
Douglas Clowes
2006-08-21 09:47:25 +10:00
parent 7660b67290
commit b2ce43d554

View File

@@ -13,6 +13,7 @@
#include <assert.h>
#include <math.h>
#include <time.h>
#include <sys/time.h>
#include "fortify.h"
#include <string.h>
#include <sics.h>
@@ -20,17 +21,28 @@
#include <countdriv.h>
#include "anstoutil.h"
#define FAILURE 0
#define SUCCESS 1
#ifdef SPLINT
/*@-incondefs@*/
int gettimeofday(/*@out@*/ struct timeval *restrict tp,
/*@null@*/ void *restrict tzp);
char *strdup(const char *s);
int strcasecmp(const char *s1, const char *s2);
int strncasecmp(const char *s1, const char *s2, size_t n);
unsigned long long int
strtoull(const char *nptr, /*@null@*/ char **endptr, int base);
/*@+incondefs@*/
#endif
/*@-incondefs@*/
/*@observer@*//*@dependent@*/ Tcl_Interp *InterpGetTcl(SicsInterp *pSics);
int readRS232(prs232 self, /*@out@*/void *data, /*@out@*/int *dataLen);
int readRS232TillTerm(prs232 self, /*@out@*/void *data, /*@out@*/int *dataLen);
void getRS232Error(int iCode, /*@out@*/ char *errorBuffer, int errorBufferLen);
/*@observer@*//*@dependent@*/ pCounterDriver CreateCounterDriver(char *name, char *type);
void KillRS232(/*@only@ frees pData */ void *pData);
/*@+incondefs@*/
typedef unsigned long long int uint64;
typedef struct {
int length;
@@ -46,17 +58,22 @@ typedef struct {
int iPort;
float dummy_threshold;
BUFFER buffer;
unsigned long long counter_value;
uint64 counter_value;
} BeamMon, *pBeamMon;
static int MonSend(CounterDriver *cntrData, char *pText, char *pReply, int iReplyLen);
/** \brief file logging
*
* Logs text to a debug file. The file is opened and closed for each call.
*
* \param flag character used to distinguish calls
* \param pText pointer to text to be logged
*/
static void flog(char flag, char* pText) {
FILE* file;
file = fopen("flog.txt", "a");
if (file) {
struct timeval tv;
gettimeofday(&tv, NULL);
(void) gettimeofday(&tv, NULL);
fprintf(file, "%02d:%02d:%02d:%06d::%c::%s",
tv.tv_sec % (24 * 3600) / 3600,
tv.tv_sec % (3600) / 60,
@@ -65,8 +82,8 @@ static void flog(char flag, char* pText) {
flag,
pText);
if (strchr(pText, '\n') == NULL)
fputc('\n', file);
fclose(file);
(void) fputc('\n', file);
(void) fclose(file);
}
}
@@ -75,19 +92,17 @@ static void flog(char flag, char* pText) {
*
* \param *cntrData provides access to a monitor's data
* \param *text pointer to NULL terminated text to send.
* \return
* - SUCCESS
* - FAILURE
* \return SUCCESS or FAILURE
*/
static int MonWrite(pBeamMon self, char* text) {
int len;
size_t len;
int status;
len = strlen(text);
if (len > 0)
flog('>', text);
status = writeRS232(self->controller, text, len);
status = writeRS232(self->controller, text, (int) len);
if (status != 1) {
self->errorCode = status;
return FAILURE;
@@ -101,13 +116,12 @@ static int MonWrite(pBeamMon self, char* text) {
* \param *cntrData provides access to a monitor's data
* \param *text pointer to NULL terminated text to receive.
* \param *pLen inout pointer to length of text to receive.
* \return
* - SUCCESS
* - FAILURE
* \return SUCCESS or FAILURE
*/
static int MonRead(pBeamMon self, char* text, int *pLen) {
static int MonRead(pBeamMon self, /*@out@*/ char* text, int *pLen) {
int i, status, retries=20;
*text = '\0';
for (i=0; i<retries; i++) {
status = readRS232TillTerm(self->controller, text, pLen);
switch (status) {
@@ -129,16 +143,86 @@ static int MonRead(pBeamMon self, char* text, int *pLen) {
return FAILURE;
}
/** \brief drains any pending input on the RS232 channel
*
* \param *cntrData provides access to a monitor's data
*/
static void MonDrainInput(CounterDriver *cntrData) {
int iRet;
int len;
char reply[1024];
BeamMon* self = NULL;
self = (BeamMon *) cntrData->pData;
while (availableRS232(self->controller) != 0) {
len = (int) sizeof(reply);
iRet = MonRead(self, reply, &len);
if (iRet == FAILURE) {
return;
}
}
}
/** \brief sends a command to the monitor and gets the reply
*
* \param cntrData provides access to a monitor's data
* \param pText command to send
* \param pReply space for reply
* \param iReplyLen length of space for reply
* \return SUCCESS or FAILURE
*/
static int MonSend(CounterDriver *cntrData, char *pText, char *pReply, int iReplyLen) {
BeamMon *self = NULL;
int status;
self = (BeamMon *) cntrData->pData;
MonDrainInput(cntrData);
status = MonWrite(self, pText);
if (status != SUCCESS)
return status;
if ((status = MonRead(self, pReply, &iReplyLen)) == SUCCESS)
{
pReply[iReplyLen] = '\0';
return SUCCESS;
}
return status;
}
/** \brief sends a command to the monitor and gets the reply
*
* \param cntrData provides access to a monitor's data
* \param pText command to send
* \param buffer space for reply
* \return SUCCESS or FAILURE
*/
static int MonSendBuffer(CounterDriver *cntrData, char *pText, BUFFER* buffer) {
int status;
buffer->length = 0;
status = MonSend(cntrData, pText, buffer->body, (int) sizeof(buffer->body));
if (status == SUCCESS) {
buffer->length = (int) strlen(buffer->body);
}
return status;
}
/** \brief parses and acts upon the READ line
*
* \param *cntrData provides access to a monitor's data
* \param bp pointer to buffer containing the text line
*
* This function sets the state of the counter based on state flags reported by
* the monitor.
*/
static void HandleReport(CounterDriver *cntrData, BUFFER* bp)
{
//READ xxxx 00:00:00.000000 0.000000 0 0.00
//0123456789012345678901234567890
BeamMon* self = NULL;
char *cp = NULL;
char *ep = NULL;
char str[100];
self = (BeamMon *) cntrData->pData;
/* TODO better than this */
char* cp = &bp->body[26];
char* ep;
cntrData->fTime = strtod(cp, &ep);
cp = &bp->body[26];
cntrData->fTime = (float) strtod(cp, &ep);
cp = ep;
switch (toupper(bp->body[5])) {
case 'I': /* idle */
@@ -151,16 +235,16 @@ static void HandleReport(CounterDriver *cntrData, BUFFER* bp)
case 'P': /* paused */
self->state = HWPause;
break;
default:
default: /* should not happen */
self->state = HWFault;
break;
}
if (toupper(bp->body[8] == 'G')) /* Gated */
if ((self->state == HWBusy || self->state == HWPause)
&& (toupper(bp->body[8]) == (int) 'G')) /* Gated */
self->state = HWNoBeam;
self->counter_value = strtoull(cp, &ep, 10);
cntrData->fLastCurrent = self->counter_value;
char str[100];
snprintf(str, sizeof(str), "READ %s, %f, %f, %f\n",
cntrData->fLastCurrent = (float) self->counter_value;
(void) snprintf(str, sizeof(str), "READ %s, %f, %f, %f\n",
cntrData->eMode == eTimer ? "eTimer" :
cntrData->eMode == ePreset ? "ePreset" : "Unknown",
cntrData->fPreset,
@@ -169,70 +253,60 @@ static void HandleReport(CounterDriver *cntrData, BUFFER* bp)
flog('.', str);
}
static int MonDrainInput(CounterDriver *cntrData) {
int iRet, len;
char reply[1024];
/** \brief handles an input line received on the RS232 channel
*
* \param cntrData provides access to a monitor's data
* \param bp pointer to buffer containing the line of input
*
* This function sets the state of the counter based on events reported by
* the monitor.
*/
static void MonHandleInput(CounterDriver *cntrData, BUFFER* bp) {
BeamMon* self = NULL;
self = (BeamMon *) cntrData->pData;
while (availableRS232(self->controller)) {
len = sizeof(reply);
iRet = MonRead(self, reply, &len);
if (iRet == FAILURE) {
return iRet;
}
}
return SUCCESS;
}
static int MonHandleInput(CounterDriver *cntrData, BUFFER* bp) {
BeamMon* self = NULL;
int iRet, len;
int iLen = 0;
int jLen = 0;
char reply[1024];
char* pTerm;
const char et[] = "EVENT TERMINAL";
const char eri[] = "EVENT RANGE IN";
const char ero[] = "EVENT RANGE OUT";
const char rpt[] = "READ";
self = (BeamMon *) cntrData->pData;
/* TODO handle the line */
flog('<', bp->body);
const char et[] = "EVENT TERMINAL";
flog('=', bp->body);
if (strncasecmp(bp->body, et, sizeof(et) - 1) == 0) {
if (self->state == HWBusy)
self->state = HWIdle;
}
const char eri[] = "EVENT RANGE IN";
if (strncasecmp(bp->body, eri, sizeof(eri) - 1) == 0)
if (self->state == HWPause)
self->state = HWBusy;
const char ero[] = "EVENT RANGE OUT";
if (strncasecmp(bp->body, ero, sizeof(ero) - 1) == 0)
if (self->state == HWBusy)
self->state = HWPause;
const char rpt[] = "READ";
if (strncasecmp(bp->body, rpt, sizeof(rpt) - 1) == 0) {
if (self->state == HWBusy) {
HandleReport(cntrData, &self->buffer);
MonWrite(self, "SICS READ");
}
}
bp->length = 0;
return 1;
}
static int MonLookForInput(CounterDriver *cntrData, int timeout) {
/** \brief look for input on the socket
*
* breaks input into lines terminated by <CR><LF> pairs and passes complete lines to MonHandleInput for processing.
*
* \param cntrData provides access to a monitor's data
* \param timeout upper limit on time to wait for data to arrive
*/
static void MonLookForInput(CounterDriver *cntrData, /*@unused@*/ int timeout) {
BeamMon* self = NULL;
int iRet, len;
int iLen = 0;
int jLen = 0;
char reply[1024];
char* pTerm;
self = (BeamMon *) cntrData->pData;
while (availableRS232(self->controller)) {
len = sizeof(reply);
while (availableRS232(self->controller) != 0) {
len = (int) sizeof(reply);
iRet = MonRead(self, reply, &len);
if (iRet == FAILURE) {
return iRet;
return;
}
iLen = 0;
while (iLen < len) {
@@ -243,7 +317,7 @@ static int MonLookForInput(CounterDriver *cntrData, int timeout) {
jLen = len - iLen;
strncpy(&self->buffer.body[self->buffer.length],
&reply[iLen],
jLen);
(size_t) jLen);
self->buffer.length += jLen;
self->buffer.body[self->buffer.length] = '\0';
iLen += jLen;
@@ -254,7 +328,6 @@ static int MonLookForInput(CounterDriver *cntrData, int timeout) {
self->buffer.length = 0;
}
}
return 1;
}
/** \brief Returns the counter status,
@@ -275,7 +348,7 @@ static int MonGetStatus(CounterDriver *cntrData, float *fControl) {
self = (BeamMon *) cntrData->pData;
MonLookForInput(cntrData, 0);
status = MonSend(cntrData, "SICS READ", self->buffer.body, sizeof(self->buffer.body));
status = MonSendBuffer(cntrData, "SICS READ", &self->buffer);
if (status == SUCCESS) {
/* TODO */
MonHandleInput(cntrData, &self->buffer);
@@ -302,11 +375,18 @@ static int MonGetStatus(CounterDriver *cntrData, float *fControl) {
/** \brief Starts counting in the current mode and with the current preset
*
* \param *cntrData provides access to a monitor's data
* \return SUCCESS or FAILURE
*
* This function also sets some of the parameters in the monitor for mode and
* preset.
*
* TODO: check the return from the monitor
*/
static int MonStart(CounterDriver *cntrData) {
BeamMon *self = NULL;
int status;
char str[100];
snprintf(str, sizeof(str), "START %s, %f, %f, %f\n",
(void) snprintf(str, sizeof(str), "START %s, %f, %f, %f\n",
cntrData->eMode == eTimer ? "eTimer" :
cntrData->eMode == ePreset ? "ePreset" : "Unknown",
cntrData->fPreset,
@@ -316,32 +396,53 @@ static int MonStart(CounterDriver *cntrData) {
self = (BeamMon *) cntrData->pData;
MonDrainInput(cntrData);
if (cntrData->eMode == eTimer) {
MonSend(cntrData, "SICS SET TE_CHECK=TIMER",
self->buffer.body, sizeof(self->buffer.body));
status = MonSendBuffer(cntrData, "SICS SET TE_CHECK=TIMER", &self->buffer);
if (status != SUCCESS || strcasecmp(self->buffer.body, "OK") != 0) {
self->errorCode = /* TODO */ 0;
return FAILURE;
}
} else {
MonSend(cntrData, "SICS SET TE_CHECK=COUNTER",
self->buffer.body, sizeof(self->buffer.body));
status = MonSendBuffer(cntrData, "SICS SET TE_CHECK=COUNTER", &self->buffer);
if (status != SUCCESS || strcasecmp(self->buffer.body, "OK") != 0) {
self->errorCode = /* TODO */ 0;
return FAILURE;
}
}
/*@-duplicatequals@ for uint64 */
/*@-formattype@ for uint64 */
(void) snprintf(str, sizeof(str), "SICS SET TERMINAL=%llu",
(uint64) cntrData->fPreset);
/*@+formattype@*/
/*@+duplicatequals@*/
status = MonSendBuffer(cntrData, str, &self->buffer);
if (status != SUCCESS || strcasecmp(self->buffer.body, "OK") != 0) {
self->errorCode = /* TODO */ 0;
return FAILURE;
}
status = MonSendBuffer(cntrData, "SICS START", &self->buffer);
if (status != SUCCESS || strcasecmp(self->buffer.body, "OK") != 0) {
self->errorCode = /* TODO */ 0;
return FAILURE;
}
snprintf(str, sizeof(str), "SICS SET TERMINAL=%llu",
(unsigned long long) cntrData->fPreset);
MonSend(cntrData, str,
self->buffer.body, sizeof(self->buffer.body));
MonSend(cntrData, "SICS START",
self->buffer.body, sizeof(self->buffer.body));
self->state = HWBusy;
return SUCCESS;
}
}
/** \brief Pauses a counting operation
*
* \param *cntrData provides access to a monitor's data
* \return SUCCESS or FAILURE
*
* TODO: check if we should set the state to HWPause or just leave it till we
* get it back from the monitor.
*/
static int MonPause(CounterDriver *cntrData) {
BeamMon *self = NULL;
int status;
self = (BeamMon *) cntrData->pData;
if (MonSend(cntrData, "SICS PAUSE",
self->buffer.body, sizeof(self->buffer.body)) == SUCCESS) {
status = MonSendBuffer(cntrData, "SICS PAUSE", &self->buffer);
if (status == SUCCESS) {
self->state = HWPause;
return SUCCESS;
}
@@ -351,13 +452,18 @@ static int MonPause(CounterDriver *cntrData) {
/* \brief Continues a paused counting operation.
*
* \param *cntrData provides access to a monitor's data
* \return SUCCESS or FAILURE
*
* TODO: check if we should set the sate to HWBusy or just leave it till we
* get it back from the monitor.
*/
static int MonContinue(CounterDriver *cntrData) {
BeamMon *self = NULL;
int status;
self = (BeamMon *) cntrData->pData;
if (MonSend(cntrData, "SICS CONTINUE",
self->buffer.body, sizeof(self->buffer.body)) == SUCCESS) {
status = MonSendBuffer(cntrData, "SICS CONTINUE", &self->buffer);
if (status == SUCCESS) {
self->state = HWBusy;
return SUCCESS;
}
@@ -366,14 +472,19 @@ static int MonContinue(CounterDriver *cntrData) {
/** \brief Cancels a counting operation. This is an emergency stop used when interrupting an operation.
* \param *cntrData provides access to a monitor's data
* \return SUCCESS or FAILURE
*
* TODO: check if we should set the sate to HWIdle or just leave it till we
* get it back from the monitor.
*/
static int MonHalt(CounterDriver *cntrData) {
BeamMon *self = NULL;
int status;
self = (BeamMon *) cntrData->pData;
if (MonSend(cntrData, "SICS STOP",
self->buffer.body, sizeof(self->buffer.body)) == SUCCESS) {
self->state = HWBusy;
status = MonSendBuffer(cntrData, "SICS STOP", &self->buffer);
if (status == SUCCESS) {
self->state = HWIdle;
return SUCCESS;
}
return FAILURE;
@@ -382,18 +493,21 @@ static int MonHalt(CounterDriver *cntrData) {
/** \brief Reads the counter and the monitors in the lCounts array.
*
* \param *cntrData provides access to a monitor's data
* \return SUCCESS or FAILURE
*/
static int MonReadValues(CounterDriver *cntrData) {
BeamMon *self = NULL;
int status;
flog('.', "MonReadValues");
self = (BeamMon *) cntrData->pData;
if (MonSend(cntrData, "SICS READ",
self->buffer.body, sizeof(self->buffer.body)) == SUCCESS) {
status = MonSendBuffer(cntrData, "SICS READ", &self->buffer);
if (status == SUCCESS) {
HandleReport(cntrData, &self->buffer);
lCounts[0] = self->counter_value;
cntrData->lCounts[0] = (long) self->counter_value; /* NOTE: truncation */
return SUCCESS;
}
return SUCCESS;
return FAILURE;
}
/* \brief Called when an error condition is reported by a counter operation.
@@ -411,7 +525,7 @@ static int MonGetError(CounterDriver *cntrData, int *iCode, char *error, int iEr
self = (BeamMon *) cntrData->pData;
/* Allocate iErrLen bytes for error messages */
if (self->errorMsg == NULL) {
self->errorMsg = (char *) malloc(iErrLen);
self->errorMsg = (char *) malloc((size_t) iErrLen);
if (self->errorMsg == NULL) {
return FAILURE;
}
@@ -420,7 +534,9 @@ static int MonGetError(CounterDriver *cntrData, int *iCode, char *error, int iEr
*iCode = self->errorCode;
switch (*iCode) {
case 0:
strncpy(error, "UNKNOWN ERROR: counterdriv did not set an errorcode.", iErrLen);
strncpy(error,
"UNKNOWN ERROR: counterdriv did not set an errorcode.",
(size_t) iErrLen);
break;
case NOTCONNECTED:
case TIMEOUT:
@@ -430,7 +546,9 @@ static int MonGetError(CounterDriver *cntrData, int *iCode, char *error, int iEr
getRS232Error(*iCode, error, iErrLen);
break;
default:
snprintf(error, iErrLen, "Unknown error code: %d, returned from counterdriv", *iCode);
(void) snprintf(error, (size_t) iErrLen,
"Unknown error code: %d, returned from counterdriv",
*iCode);
}
self->errorCode = 0;
return SUCCESS;
@@ -453,8 +571,9 @@ static int MonTryAndFixIt(CounterDriver *cntrData, int iCode) {
switch(iCode){
case NOTCONNECTED:
initRS232(self->controller);
return COREDO;
if (initRS232(self->controller) == 1)
return COREDO;
return COTERM;
case BADSEND:
case TIMEOUT:
case BADMEMORY: /* Won't happen if MonConnect sets the send terminator */
@@ -473,7 +592,7 @@ static int MonTryAndFixIt(CounterDriver *cntrData, int iCode) {
static int MonSet(CounterDriver *cntrData, char *name, int iCter, float fVal) {
BeamMon *self = NULL;
char str[100];
snprintf(str, 100, "MonSet(%s, %d, %f)", name, iCter, fVal);
(void) snprintf(str, 100, "MonSet(%s, %d, %f)", name, iCter, fVal);
flog('.', str);
self = (BeamMon *) cntrData->pData;
@@ -487,6 +606,7 @@ static int MonSet(CounterDriver *cntrData, char *name, int iCter, float fVal) {
static int MonGet(CounterDriver *cntrData, char *name, int iCter, float *fVal) {
BeamMon *self = NULL;
char str[100];
self = (BeamMon *) cntrData->pData;
if(strcasecmp(name,"threshold") == 0){
@@ -495,35 +615,28 @@ static int MonGet(CounterDriver *cntrData, char *name, int iCter, float *fVal) {
}
/* TODO*/
char str[100];
snprintf(str, 100, "MonGet(%s, %d, %f)", name, iCter, *fVal);
(void) snprintf(str, 100, "MonGet(%s, %d, %f)", name, iCter, *fVal);
flog('.', str);
return SUCCESS;
}
static int MonSend(CounterDriver *cntrData, char *pText, char *pReply, int iReplyLen) {
BeamMon *self = NULL;
int status;
self = (BeamMon *) cntrData->pData;
MonDrainInput(cntrData);
MonWrite(self, pText);
if ((status = MonRead(self, pReply, &iReplyLen)) == SUCCESS)
{
pReply[iReplyLen] = '\0';
return SUCCESS;
}
return status;
}
static void KillMon(pCounterDriver cntrData) {
pBeamMon self = NULL;
self = (pBeamMon) cntrData->pData;
if (self) {
if (self->host)
free(self->host);
if (self->errorMsg)
free(self->errorMsg);
static void KillMon(/*@null@*/ pCounterDriver cntrData) {
if (cntrData != NULL) {
if (cntrData->pData != NULL) {
pBeamMon self = (pBeamMon) cntrData->pData;
if (self->host) {
free(self->host);
self->host = NULL;
}
if (self->errorMsg) {
free(self->errorMsg);
self->errorMsg = NULL;
}
KillRS232(self->controller);
free(cntrData->pData);
cntrData->pData = NULL;
}
/* TODO free(cntrData); */
}
}
@@ -541,17 +654,17 @@ static void KillMon(pCounterDriver cntrData) {
controller=createRS232(host,port);
if (controller==NULL) {
snprintf(pError, ERRLEN,
(void) snprintf(pError, ERRLEN,
"ERROR: failed to create controller for %s at port %d",
host, port);
SCWrite(pCon,pError,eError);
(void) SCWrite(pCon,pError,eError);
return NULL;
}
if ( initRS232(controller) != 1) {
snprintf(pError, ERRLEN,
(void) snprintf(pError, ERRLEN,
"ERROR: failed to connect to %s at port %d",
host, port);
SCWrite(pCon,pError,eError);
(void) SCWrite(pCon,pError,eError);
KillRS232(controller);
return NULL;
}
@@ -614,13 +727,19 @@ static void KillMon(pCounterDriver cntrData) {
KillMon(pCntDriv);
return NULL;
}
sscanf(pPtr,"%d", &newCtr->iPort);
(void) sscanf(pPtr,"%d", &newCtr->iPort);
if ((pPtr=getParam(pCon, interp, params,"host",1)) == NULL) {
KillMon(pCntDriv);
return NULL;
}
/*@-mustfreeonly@ host = NULL after BeamMon is created */
newCtr->host = strdup(pPtr);
/*@+mustfreeonly@*/
/*@-mustfreeonly@ controller = NULL after BeamMon is created */
newCtr->controller = MonConnect(pCon, newCtr->host, newCtr->iPort);
/*@+mustfreeonly@*/
newCtr->dummy_threshold = 1.7e6;
return pCntDriv;