Files
sics/serialwait.c
koennecke 86e246416b - Added bridge functions to histmemsec to make it look more like histmem
- Modifed many modules using histmem to work also with histmemsec
- Extended tasker with task names and task groups
- There is a new taskobj which allows to list tasks and to interact with them.
- Task now supports running Tcl functions as tasks
- There is a new experimental sctcomtask module which allows to define communication
  tasks against a scriptcontext. This is a new feature which should facilitate
  writing sequential scripts using asynchronous communication.
- A fix to make spss7 work when there are no switches
- ORION support for single X. TRICS measures crystals hanging down, ORION
  standing up


SKIPPED:
	psi/ease.c
	psi/faverage.c
	psi/jvlprot.c
	psi/make_gen
	psi/pardef.c
	psi/polterwrite.c
	psi/psi.c
	psi/sinq.c
	psi/spss7.c
2012-12-20 11:32:33 +00:00

219 lines
5.2 KiB
C

/*--------------------------------------------------------------------------
S E R I A L W A I T
wait for an command to execute in a serial device by polling with
null messages in SICS.
copyright: see copyright.h
Mark Koennecke, June 1998
This code is defunct and not used at the time being. It is left in the
source tree for documentation purposes. Mark Koennecke, June 2003
---------------------------------------------------------------------------*/
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <assert.h>
#include "fortify.h"
#include "serialwait.h"
#include "dynstring.h"
/*
#define SDEBUG 1
*/
/*--------------- The wait data structure --------------------------------*/
typedef struct {
int iEnd; /* end signal flag */
int iError; /* error returns */
int iFirst; /* first call, receive only */
time_t tEnd; /* not more then a minute! */
pDynString data; /* reply data read */
void **pData; /* the serial IO data structure */
} SW, *pSW;
/*---------------- The signal function --------------------------------*/
static void SWSignal(void *pUser, int iSignal, void *pSigData)
{
pSW self = NULL;
int *iInt;
self = (pSW) pUser;
iInt = (int *) pSigData;
if (iSignal == SICSINT) {
if (*iInt > eContinue) {
self->iEnd = 2;
}
}
}
/*---------------------- The task function ------------------------------*/
static int SWTask(void *pData)
{
pSW self = NULL;
char pReply[1024];
int iRet, iCount;
char *pPtr;
self = (pSW) pData;
assert(self);
/* check for interrupt end */
if (self->iEnd > 0) {
return 0;
}
/* check for timeout */
if (time(NULL) >= self->tEnd) {
self->iError = TIMEOUT;
self->iEnd = 3;
return 0;
}
/* wait for a second */
SicsWait(1);
/* send a null command and read reply */
if (!self->iFirst) {
iRet = SerialSend(self->pData, "");
} else {
self->iFirst = 0;
}
pReply[0] = '\0';
iRet = SerialReceive(self->pData, pReply, 1023);
#ifdef SDEBUG
printf("Primary answer: %s\n", pReply);
#endif
if ((iRet == TIMEOUT) || (iRet == SELECTFAIL)) {
#ifdef SDEBUG
printf("Return 1 on timeout\n");
#endif
return 1;
} else if (iRet < 0) {
self->iError = iRet;
self->iEnd = 3;
#ifdef SDEBUG
printf("Error %d return Receive 0\n", iRet);
#endif
return 0;
}
/* is there data ? */
iCount = strlen(pReply);
if (iCount <= 0) {
#ifdef SDEBUG
printf("No data in Reply, return 1\n");
#endif
return 1;
}
/* do we have a tmo message ? */
if (strncmp("?TMO", pReply, 4) == 0) {
/* is there additional data appended ? */
if (iCount > 4) {
/* store what we have */
pPtr = pReply + 4;
DynStringConcat(self->data, pPtr);
/* set tmo high, read rest of reply */
SerialConfig(self->pData, 90000);
pReply[0] = '\0';
iRet = SerialWriteRead(self->pData, "", pReply, 1023);
#ifdef SDEBUG
printf(" sec rep: %s\n", pReply);
#endif
if (iRet != 1) {
self->iError = iRet;
self->iEnd = 3;
#ifdef SDEBUG
printf("return 0, on secondary read error\n");
#endif
return 0;
}
DynStringConcat(self->data, pReply);
self->iEnd = 1;
#ifdef SDEBUG
printf("Complete read on second try, return 0\n");
#endif
return 0;
} else { /* schnuuuueeeeeffffff! no data, poll again */
#ifdef SDEBUG
printf("Do agaian, got a TMO \n");
#endif
return 1;
}
} else { /* we obtained all the data right away */
DynStringConcat(self->data, pReply);
self->iEnd = 1;
#ifdef SDEBUG
printf("Return 0, received all data in one go \n");
#endif
return 0;
}
/* should not get here */
#ifdef SDEBUG
printf("Should not get here return 1\n");
#endif
return 1;
}
/*-------------------------- The actual working function ------------------*/
int SerialSicsExecute(void **pData, char *pCommand,
char *pReply, int iBufLen)
{
int iOldTmo, iRet, iResult;
long lTask;
SW control;
char *pPtr;
/* set timeout to 0 */
iOldTmo = SerialGetTmo(pData);
SerialConfig(pData, 200);
/* send the command to execute */
iRet = SerialSend(pData, pCommand);
if (iRet != 1) {
SerialConfig(pData, iOldTmo);
return iRet;
}
/* initialize task data structure */
control.iEnd = 0;
control.iError = 0;
control.iFirst = 1;
control.pData = pData;
/* do a timeout after a minute without a reply */
control.tEnd = time(NULL) + 60;
control.data = CreateDynString(1024, 1024);
/* start task */
lTask = TaskRegisterN(pServ->pTasker,"serialwait",
SWTask, SWSignal, NULL, &control, 1);
/* wait for it to end */
TaskWait(pServ->pTasker, lTask);
/* analyse what we have got, success first */
if (control.iEnd == 1) {
iResult = 1;
pPtr = GetCharArray(control.data);
strlcpy(pReply, pPtr, iBufLen);
} else if (control.iEnd == 2) { /* interrupted */
iResult = INTERRUPTED;
} else {
iResult = control.iError;
}
control.iEnd = 10;
/* clear up and go */
DeleteDynString(control.data);
SerialConfig(pData, iOldTmo);
return iResult;
}