/*--------------------------------------------------------------------------- eve.c extended environment controller utilities Markus Zolliker, Sept 2004 ---------------------------------------------------------------------------- */ #include #include #include #include #include #include #include "sics.h" #include "rs232controller.h" #include "obpar.h" #include "evcontroller.h" #include "evcontroller.i" #include "evdriver.i" #include "eve.h" #include "fsm.h" #include "logger.h" #define ILLNUM -1456 #define ILLARGC -1457 #define AMBIGUOS -1458 #define ILLPRIV -1460 #define BADLOG -1461 #define BUSY -1462 typedef enum { cntAction, iniAction, parAction, listAction, logAction, logSwitchAction, saveAction } EveAction; typedef enum { noOp, fmtOp, setOp } ArgOp; struct EveParArg { EveAction action; int argc; char **argv; int ret; /* return value */ SConnection *pCon; pEVControl evc; time_t now; int period; int idx; FILE *fil; }; struct EvePar { char *name; Logger *log; }; /*--------------------------------------------------------------------------*/ char *EveArg2Text(int argc, char *argv[], char *res, int maxsize) { int i, l; char *p; if (res == NULL) { maxsize = 0; for (i=0; ierrMsg[0] = '\0'; if (eve->evc != NULL) { pCon = SCLoad(&eve->evc->conn); if (pCon != NULL) { if (iOut < 0) { if (-iOut > eve->verbose) return 0; iOut=eStatus; } return SCWrite(pCon, buf, iOut); } } if (iOut == eError) { snprintf(eve->errMsg, sizeof eve->errMsg, "%s", buf); } return 1; } /*--------------------------------------------------------------------------*/ int EveText2Int(char *list[], char *text) { int num = 0; char *endp; while (list[num] != NULL) { if (strcasecmp(list[num],text) == 0) { return num; } num++; } num = strtol(text, &endp, 0); if (endp == text) return -1; return num; } /*--------------------------------------------------------------------------*/ char *EveInt2Text(char *list[], int num) { int i; static char buf[12]; for (i = 0; i <= num; i++) { if (list[i] == NULL) { snprintf(buf, sizeof buf, "%d", num); return buf; } } return list[num]; } /*----------------------------------------------------------------------------*/ int EveCheckRights(EveParArg *arg, int access) { if (SCMatchRights(arg->pCon,access)) { return 1; } else { arg->ret = ILLPRIV; } return 0; } /*--------------------------------------------------------------------------*/ void EveMakePar(Eve *eve) { EveParArg arg; int i; if (eve->par == NULL) { arg.action = cntAction; arg.pCon = NULL; arg.evc = eve->evc; arg.idx = 0; eve->pardef(eve, &arg); /* first time: count */ eve->npar = arg.idx; eve->par = calloc(arg.idx, sizeof *eve->par); for (i=0; ipar[i].log = NULL; eve->par[i].name = NULL; } arg.action = iniAction; arg.idx = 0; eve->pardef(eve, &arg); /* second time: start default loggers */ } } /*--------------------------------------------------------------------------*/ EvePar *EveThisPar(EveParArg *arg, char *name, int flags) { Eve *eve = arg->evc->pDriv->pPrivate; EvePar *par; if (!eve->par) return NULL; assert(arg->idx < eve->npar); par = eve->par + arg->idx; if (par->name == NULL) { par->name = name; if (flags & EVE_LOGPAR) { /* first time: default logger */ EveSwitchLog(eve, par, 1); } } else { assert(par->name == name); } return par; } /*--------------------------------------------------------------------------*/ void EveLog(Eve *eve) { EveParArg arg; if (!eve->par) { EveMakePar(eve); } arg.now = time(NULL); if (arg.now >= (eve->logtime / eve->period + 1) * eve->period) { arg.action = logAction; arg.pCon = NULL; arg.evc = eve->evc; arg.argc = 0; arg.idx = 0; arg.period = eve->period; eve->pardef(eve, &arg); eve->logtime = arg.now; } } /*----------------------------------------------------------------------------*/ int EveSwitchLog(Eve *eve, EvePar *par, int on) { char buf[80]; if (on) { if (par->log == NULL) { if (par->name[0] == '\0') { par->log = LoggerMake(eve->evc->pName, eve->period); } else { snprintf(buf, sizeof buf, "%s.%s", eve->evc->pName, par->name); par->log = LoggerMake(buf, eve->period); } if (par->log == NULL) { return BADLOG; } } } else { if (par->log != NULL) { LoggerKill(par->log); par->log = NULL; } } return 1; } /*----------------------------------------------------------------------------*/ ArgOp EveOp(EveParArg *arg, char *name, char **fmt, int access, int flags) { static char buf[80]; char *sp; int l; EvePar *par; ArgOp op; switch (arg->action) { case cntAction: arg->idx ++; return noOp; case iniAction: EveThisPar(arg, name, flags); arg->idx ++; return noOp; case listAction: if (flags & EVE_ACTPAR) { return fmtOp; } return noOp; case logAction: if (flags & EVE_ACTPAR) { op = fmtOp; break; /* reduce fmt */ } arg->idx++; return noOp; case logSwitchAction: if (arg->argc > 2) { arg->ret = ILLARGC; return noOp; } if (0==strcasecmp(name, arg->argv[1])) { if (arg->ret) { arg->ret = AMBIGUOS; return noOp; } par = EveThisPar(arg, name, 0); EveSwitchLog(arg->evc->pDriv->pPrivate, par, toupper(arg->argv[0][0]) == 'L'); } arg->idx ++; return noOp; case parAction: if (0==strcasecmp(name, arg->argv[0])) { if (arg->ret) { arg->ret = AMBIGUOS; return noOp; } arg->ret = 1; if (arg->argc == 1) { op = fmtOp; break; /* reduce fmt */ } if (!EveCheckRights(arg, access)) return noOp; op = setOp; break; } return noOp; case saveAction: if (flags & EVE_SAVEPAR) { op = fmtOp; break; /* reduce fmt */ } return noOp; default: return noOp; } if (fmt != NULL) { /* skip fmt after tab */ sp = strchr(*fmt, '\t'); if (sp != NULL) { l = sp - *fmt; if (l >= sizeof buf) l = sizeof buf - 1; strncpy(buf, *fmt, l); buf[l]='\0'; *fmt = buf; } } return op; } /*----------------------------------------------------------------------------*/ void EveOut(EveParArg *arg, char *name, char *buf) { EvePar *par; int l, i, j, m, ln, lp, iret; char *p, *q, *tab; char buffer[256]; char *dot; switch (arg->action) { case listAction: p = buf; while (*p == ' ') p++; /* skip blanks */ i = 0; if (p[i] == '-') i++; j = i; while (p[i] >= '0' && p[i] <='9') i++; tab = strchr(p, '\t'); if (tab) { l = tab - p; *tab = ' '; } else { l = strlen(p); } ln = strlen(name); if (i != j && (buf[i] == '.' || buf[i] <= ' ')) { l += 16 - i - ln; /* decimal point or end of number at least 16 chars after object name */ if (tab) { *tab = '\0'; q = tab + 1; } else { q = ""; } lp = strlen(p); if (l < lp) l = lp; m = 22 - l - ln; /* unit/comment at least 22 chars after object name */ if (m < 1) m = 1; m += strlen(q); } else { l = 16 - ln; q = ""; m = 0; } if (l <= 0) l = 1; SCPrintf(arg->pCon, eStatus, "%s %s %*s%*s", arg->evc->pName, name, l, p, m, q); break; case parAction: SCPrintf(arg->pCon, eValue, "%s %s = %s", arg->evc->pName, name, buf); break; case logAction: par = EveThisPar(arg, name, 0); arg->idx ++; if (par->log) { iret = LoggerWrite(par->log, arg->now, arg->period, buf); if (iret) { if (*name) { dot = "."; } else { dot = ""; } snprintf(buffer, sizeof buffer, "%s%s%s = %s", arg->evc->pName, dot, name, buf); InvokeCallBack(arg->evc->pCall, VALUECHANGE, buffer); } } break; case saveAction: fprintf(arg->fil, "%s %s %s\n", arg->evc->pName, name, buf); break; } } /*----------------------------------------------------------------------------*/ void EveFloatPar(EveParArg *arg, char *name, float *value, char *fmt, int access, int flags) { char *endp; float f; char buf[132]; switch (EveOp(arg, name, &fmt, access, flags)) { case setOp: if (arg->argc > 2) { arg->ret = ILLARGC; return; } f = strtod(arg->argv[1], &endp); if (endp == arg->argv[1]) { arg->ret = ILLNUM; break; } *value = f; SCparChange(arg->pCon); /* fall through */ case fmtOp: snprintf(buf, sizeof buf, fmt, *value); EveOut(arg, name, buf); break; } } /*----------------------------------------------------------------------------*/ void EveIntPar(EveParArg *arg, char *name, int *value, int access, int flags) { char *endp; int i; char buf[132]; switch (EveOp(arg, name, NULL, access, flags)) { case setOp: if (arg->argc > 2) { arg->ret = ILLARGC; return; } i = strtol(arg->argv[1], &endp, 0); if (endp == arg->argv[1]) { arg->ret = ILLNUM; break; } *value = i; SCparChange(arg->pCon); /* fall through */ case fmtOp: snprintf(buf, sizeof buf, "%d", *value); EveOut(arg, name, buf); break; } } /*----------------------------------------------------------------------------*/ void EveStrPar(EveParArg *arg, char *name, char **value, int maxsize, int access, int flags) { static char *empty=""; switch (EveOp(arg, name, NULL, access, flags)) { case setOp: if (maxsize == 0) { /* dynamic string */ if (*value != NULL) free(*value); *value = EveArg2Text(arg->argc-1, arg->argv+1, NULL, 0); } else { /* fixed string */ EveArg2Text(arg->argc, arg->argv, *value, maxsize); } SCparChange(arg->pCon); /* fall through */ case fmtOp: if (*value == NULL) value = ∅ EveOut(arg, name, *value); break; } } /*----------------------------------------------------------------------------*/ void EveObPar(EveParArg *arg, int index, char *fmt, int flags) { char *name; char *endp; char buf[132]; float f; name = arg->evc->pParam[index].name; switch (EveOp(arg, name, &fmt, arg->evc->pParam[index].iCode, flags)) { case setOp: if (arg->argc > 2) { arg->ret = ILLARGC; return; } f = strtod(arg->argv[1], &endp); if (endp == arg->argv[1]) { arg->ret = ILLNUM; } else { arg->evc->pParam[index].fVal = f; } SCparChange(arg->pCon); /* fall through */ case fmtOp: snprintf(buf, sizeof buf, fmt, arg->evc->pParam[index].fVal); EveOut(arg, name, buf); break; } } /*----------------------------------------------------------------------------*/ void EveObParEnum(EveParArg *arg, int index, char *list[], int flags) { char *name; int i; char buf[132]; char *fmt="%d\t(%s)"; name=arg->evc->pParam[index].name; switch (EveOp(arg, name, &fmt, arg->evc->pParam[index].iCode, flags)) { case setOp: if (arg->argc > 2) { arg->ret = ILLARGC; return; } i = EveText2Int(list, arg->argv[1]); if (i<0) { arg->ret = ILLNUM; } else { arg->evc->pParam[index].fVal = i; } SCparChange(arg->pCon); /* fall through */ case fmtOp: i = (int)ObVal(arg->evc->pParam, index); snprintf(buf, sizeof buf, fmt, i, EveInt2Text(list, i)); EveOut(arg, name, buf); break; } } /*----------------------------------------------------------------------------*/ void EveEnumPar(EveParArg *arg, char *name, int *value, char *list[], int access, int flags) { int i; char buf[132]; char *fmt="%d\t(%s)"; switch (EveOp(arg, name, &fmt, access, flags)) { case setOp: if (arg->argc > 2) { arg->ret = ILLARGC; return; } i = EveText2Int(list, arg->argv[1]); if (i<0) { arg->ret = ILLNUM; } else { *value = i; SCparChange(arg->pCon); } /* fall through */ case fmtOp: snprintf(buf, sizeof buf, fmt, *value, EveInt2Text(list, *value)); EveOut(arg, name, buf); break; } } /*----------------------------------------------------------------------------*/ void EveCmd(EveParArg *arg, char *name, EveSubCmd subcmd, int access) { if (arg->action == parAction) { if (0==strcasecmp(name, arg->argv[0])) { if (arg->ret) { arg->ret = AMBIGUOS; return; } if (!EveCheckRights(arg, access)) return; arg->ret=subcmd(arg->pCon, arg->evc, arg->argc, arg->argv); } } } /*----------------------------------------------------------------------------*/ void EveFloatCmd(EveParArg *arg, char *name, float *value, char *fmt, FsmFunc fsmFunc, int access, int flags) { Eve *eve; EveFloatPar(arg, name, value, fmt, access, flags); if (arg->action == parAction && arg->argc == 2 && 0==strcasecmp(name, arg->argv[0])) { eve = (Eve *)arg->evc->pDriv->pPrivate; if (eve->todo) { arg->ret = BUSY; } else { eve->todo = fsmFunc; } } } /*----------------------------------------------------------------------------*/ #define A EVE_ACTPAR #define L EVE_LOGPAR #define S EVE_SAVEPAR void EveStdPar(EveParArg *arg) { static char *errList[]={"noop", "pause", "interrupt", "safeValue", "script", NULL }; static char *intList[]={"continue", "abortOp", "abortScan", "abortBatch", NULL }; float value; int eh; EveObPar(arg, UPLIMIT, "%.5g\tK", A + S); EveObPar(arg, LOWLIMIT, "%.5g\tK", A + S); EveObPar(arg, TOLERANCE, "%.5g\tK", A + S); EveObParEnum(arg, ERRORHANDLER, errList, A + S); eh = (int)ObVal(arg->evc->pParam, ERRORHANDLER); EveObParEnum(arg, INTERRUPT, intList, (eh == 2) * A + S); EveObPar(arg, SAFEVALUE, "%.5g\tK", (eh == 3) * A + S); EveStrPar(arg, "errorScript", &arg->evc->errorScript, 0, usUser, (eh == 4) * A + S); EveObPar(arg, MAXWAIT, "%.0f\tsec", A + S); EveObPar(arg, SETTLE, "%.0f\tsec", A + S); } /*----------------------------------------------------------------------------*/ void EveStdParEnd(EveParArg *arg, char *fmt, int targetFlag) { static char *accessList[]={"internal", "manager", "user", "spy", NULL }; float value; pEVControl evc = arg->evc; Eve *eve = evc->pDriv->pPrivate; EveIntPar(arg, "verbose", &eve->verbose, usUser, S); EveIntPar(arg, "period", &eve->period, usUser, S); EveObParEnum(arg, ACCESS, accessList, A+S); EveStrPar(arg, "driver", &evc->driverName, 0, usInternal, A); EveFloatPar(arg, "targetValue", &evc->fTarget, fmt, usInternal, targetFlag); EveFloatPar(arg, "", &eve->value, fmt, usInternal, A+L); } /*----------------------------------------------------------------------------*/ SConnection *EveArgConn(EveParArg *arg) { return arg->pCon; } /*----------------------------------------------------------------------------*/ int EveUserAction(EveParArg *arg) { return (arg->action == parAction || arg->action == listAction); } /*----------------------------------------------------------------------------*/ int EveWrapper(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]) { pEVControl evc = pData; EveParArg arg; Eve *eve = evc->pDriv->pPrivate; if (eve->state == lostState) { SCPrintf(pCon, eError, "%s does not respond", evc->pDes->name); return -1; } arg.pCon = pCon; arg.evc = evc; arg.ret = 0; if (argc == 2 && 0==strcasecmp(argv[1], "list")) { arg.action = listAction; eve->pardef(evc->pDriv->pPrivate, &arg); return 1; } if (argc == 3 && (0 == strcasecmp(argv[1], "log") || 0 == strcasecmp(argv[1], "unlog"))) { if (!eve->par) EveMakePar(eve); arg.action = logSwitchAction; arg.argc = argc - 1; arg.argv = argv + 1; arg.idx = 0; eve->pardef(eve, &arg); } else { arg.action = parAction; arg.argc = argc - 1; arg.argv = argv + 1; if (argc > 1) eve->pardef(eve, &arg); if (arg.ret == 0) { /* forward to standard EVController */ return EVControlWrapper(pCon,pSics,pData,argc,argv); } } error: switch (arg.ret) { case AMBIGUOS: SCPrintf(pCon, eError, "ERROR: doubly defined parameter %s.%s", evc->pName, argv[1]); break; case ILLPRIV: SCPrintf(pCon, eError, "ERROR: Insufficient privilege to change %s.%s", evc->pName, argv[1]); break; case ILLNUM: SCPrintf(pCon, eError, "ERROR: illegal value", evc->pName, argv[2]); break; case ILLARGC: SCPrintf(pCon, eError, "ERROR: illegal number of arguments for %s %s", evc->pName, argv[1]); break; case BADLOG: SCPrintf(pCon, eError, "ERROR: can not create log directory for %s %s", evc->pName, argv[1]); break; case BUSY: SCPrintf(pCon, eError, "ERROR: %s busy", evc->pName); break; default: return arg.ret; } return -1; } /*----------------------------------------------------------------------------*/ void EveWriteError(Eve *eve) { switch (eve->errCode) { case NOTCONNECTED: EvePrintf(eve, eError, "terminalserver for %s not connected", eve->evc->pName); break; case FAILEDCONNECT: EvePrintf(eve, eError, "can not connect to %s:%d", eve->ser->pHost, eve->ser->iPort); break; case TIMEOUT: EvePrintf(eve, eError, "timeout on %s", eve->evc->pName); break; case INCOMPLETE: EvePrintf(eve, eError, "incomplete answer %s from %s", eve->ans, eve->evc->pName); break; case EVE_ILL_ANS: EvePrintf(eve, eError, "illegal answer %s from %s (cmd: %*s)", eve->ans, eve->evc->pName, strlen(eve->cmd)-1, eve->cmd); break; case EVE_DEV_CHANGED: EvePrintf(eve, eError, "controller was exchanged on %s", eve->evc->pName); break; case EVE_FAULT: EvePrintf(eve, eError, "error on %s", eve->evc->pName); break; default: EvePrintf(eve, eError, "error code %d on %s", eve->errCode, eve->evc->pName); break; } } /*----------------------------------------------------------------------------*/ void EveWrite(Eve *eve, char *cmd) { int iRet; char trash[64]; int l, iret; if (eve->errCode || eve->state == expectState) return; while (availableRS232(eve->ser) == 1) { l=sizeof(trash); iret = readRS232TillTerm(eve->ser, trash, &l); EvePrintf(eve, -2, "trash: %s\n", trash); } snprintf(eve->cmd, sizeof(eve->cmd), "%s\n", cmd); iRet = writeRS232(eve->ser, eve->cmd, strlen(eve->cmd)); EvePrintf(eve, -2, "cmd: %s", cmd); eve->state = expectState; eve->cmdtime = time(NULL); } /*----------------------------------------------------------------------------*/ void EveWaitRead(Eve *eve) { int cnt=0; FsmPause(eve->task, 1); while (eve->state == expectState) { TaskYield(pServ->pTasker); /* wait for handling the last message */ cnt++; } FsmPause(eve->task, 0); /* if (cnt>1) printf("TaskYield %d\n", cnt); */ } /*----------------------------------------------------------------------------*/ int EveHandler(Eve *eve) { if (eve->state == expectState) return 0; if (eve->errCode) { eve->hwstate = HWFault; EveWriteError(eve); eve->errCode = 0; FsmStop(eve->task, eve->run); return 0; } if (eve->state == lostState) { if (FsmStop(eve->task, eve->run)) { EvePrintf(eve, -1, "stop %s caused by timeout", eve->evc->pName); } return 0; } if (eve->evc->iStop && eve->hwstate == HWBusy) { if (FsmStop(eve->task, eve->run)) { EvePrintf(eve, -1, "%s stopped", eve->evc->pName); return 0; } } return 1; } /*----------------------------------------------------------------------------*/ int EveIdle(long pc, Eve *eve) { FsmFunc todo; struct timeval tm; FSM_BEGIN idle: if (!eve->todo) goto rd; doit: todo = eve->todo; eve->todo = NULL; FSM_CALL(todo); rd: if (eve->hwstate == HWBusy) eve->hwstate = HWIdle; FSM_CALL(eve->read); EveLog(eve); /* just for the case EveLog was not included in the read function */ if (eve->logtime == 0) eve->logtime = 1; if (eve->todo) goto doit; /* gettimeofday(&tm, NULL); printf("stop %s %f\n", eve->evc->pName, tm.tv_usec / 1e6); */ FSM_WAIT(1) /* gettimeofday(&tm, NULL); printf("start %s %f\n", eve->evc->pName, tm.tv_usec / 1e6); */ goto idle; /* never return */ FSM_END } /*----------------------------------------------------------------------------*/ static int EveGet(pEVDriver driver, float *fPos) { Eve *eve = driver->pPrivate; assert(driver); assert(eve); *fPos=eve->value; return 1; } /*----------------------------------------------------------------------------*/ int EveRun(pEVDriver driver, float fVal) { Eve *eve = driver->pPrivate; assert(driver && eve); if (! eve->run) { EvePrintf(eve, -1, "can not run %s", eve->evc->pName); return 0; } if (FsmStop(eve->task, eve->run)) { EvePrintf(eve, -1, "running %s cancelled", eve->evc->pName); } eve->todo = eve->run; eve->hwstate = HWBusy; return 1; } /*--------------------------------------------------------------------------*/ int EveSend(pEVDriver driver, char *pCommand, char *pReply, int iLen) { Eve *eve = driver->pPrivate; int iRet; assert(driver && eve); EveWaitRead(eve); if (eve->errCode) { EveWriteError(eve); return 0; } EvePrintf(eve, -2, "cmd: %s", pCommand); iRet = transactRS232(eve->ser, pCommand, strlen(pCommand), pReply, iLen); EvePrintf(eve, -2, "ans: %s", pReply); if(iRet < 0) { eve->errCode = iRet; EveWriteError(eve); return 0; } return 1; } /*-------------------------------------------------------------------------*/ int EveCheckStatus(void *evcVoid, SConnection *pCon) { pEVControl evc=evcVoid; pEVDriver driver; Eve *eve; SConnection *con; assert(evc); driver = evc->pDriv; assert(driver); eve = driver->pPrivate; con = SCLoad(&evc->conn); if (con != pCon) { /* not sure if this is the case in any situation */ if (con) { SCWrite(con, "no more infos", eWarning); } SCWrite(pCon, "infos now here", eWarning); SCSave(&evc->conn, pCon); } return eve->hwstate; } /*-------------------------------------------------------------------------*/ EVMode EveGetMode(void *data) { /* EveGetMode is called in the SICS task loop as long as evc lives and is not been explicitely unregistered */ pEVControl evc = data; pEVDriver driver; Eve *eve = evc->pDriv->pPrivate; if (eve->task != NULL) { FsmTaskHandler(eve->task); } return evc->eMode; } /*-------------------------------------------------------------------------*/ int EveClose(pEVDriver driver) { /* empty routine */ return 1; } /*-------------------------------------------------------------------------*/ int EveAlwaysOk(void *data) { return 1; } /*-------------------------------------------------------------------------*/ int EveDontFix(pEVDriver driver, int iError) { return(DEVFAULT); /* severe */ } /*-------------------------------------------------------------------------*/ int EveSavePars(pEVDriver driver, FILE *fil) { Eve *eve = driver->pPrivate; EveParArg arg; arg.action = saveAction; arg.pCon = NULL; arg.evc = eve->evc; arg.fil = fil; eve->pardef(eve, &arg); return 2; /* no (duplicate) save of standard parameters ! */ } /*-------------------------------------------------------------------------*/ void EveKill(void *pData) { Eve *eve = pData; EvePar *p; Logger *log; int i; assert(eve); KillRS232(eve->ser); for (i=0; inpar; i++) { if (eve->par[i].log) { LoggerKill(eve->par[i].log); } eve->par[i].log = NULL; } free(eve); } /*--------------------------------------------------------------------------*/ int EveGetError(pEVDriver driver, int *iCode, char *error, int iErrLen) { Eve *eve = driver->pPrivate; *iCode = 1; /* severe */ strncpy(error, eve->errMsg, iErrLen); error[iErrLen-1]='\0'; eve->errMsg[0]='\0'; return 1; } /*----------------------------------------------------------------------------*/ int EveInit(pEVDriver driver) { Eve *eve; int iRet; char *res, buf[128]; pExeList exe; assert(driver); eve = driver->pPrivate; eve->errCode = 0; eve->state = idleState; eve->version[0] = '\0'; eve->errMsg[0]='\0'; iRet = initRS232(eve->ser); if (iRet != 1) { eve->errCode = iRet; EveWriteError(eve); return -1; } setRS232ReplyTerminator(eve->ser,"\r"); setRS232SendTerminator(eve->ser,"\r"); setRS232Timeout(eve->ser,1000); /* milliseconds */ setRS232Debug(eve->ser,0); return 1; } /*----------------------------------------------------------------------------*/ pEVControl MakeEveEVC(int argc, char *argv[], Eve *eve, SConnection *pCon) { /* args: */ pEVDriver driver = NULL; int port; rs232 *ser; pEVControl evc; if (argc < 3 || argc > 4) { SCWrite(pCon, "illegal number of arguments", eError); goto error; } driver = CreateEVDriver(0,NULL); /* arguments obsolete */ if(!driver || !eve) { SCWrite(pCon, "ERROR: out of memory", eError); goto error; } driver->pPrivate = eve; driver->KillPrivate = EveKill; /* initalise IpsDriver */ eve->evc = NULL; eve->hwstate = HWIdle; eve->task = NULL; eve->run = NULL; eve->logtime = 0; eve->period = 5; eve->par = NULL; if (argc == 4) { port=atoi(argv[3]); if (port==0) { SCWrite(pCon, "ERROR: illegal port number", eError); goto error; } ser = createRS232(argv[2], port); if (ser == NULL) { SCWrite(pCon, "out of memory", eError); goto error; } } else { ser = FindCommandData(pServ->pSics, argv[2], "RS232 Controller"); if (ser == NULL) { SCWrite(pCon, "ERROR: rs232 not found", eError); goto error; } } eve->ser = ser; /* initialise function pointers */ driver->GetValue = EveGet; driver->SetValue = EveRun; driver->Send = EveSend; driver->GetError = EveGetError; driver->TryFixIt = EveDontFix; driver->SavePars = EveSavePars; driver->Init = EveInit; driver->Close = EveClose; evc = MakeEVController(driver, pCon, EveWrapper, argc, argv); if (!evc) return NULL; eve->evc=evc; eve->hwstate = HWIdle; eve->verbose = 1; SCSave(&eve->evc->conn, pCon); eve->checkStatus = evc->pDrivInt->CheckStatus; evc->pDrivInt->CheckStatus = EveCheckStatus; evc->pEnvir->GetMode = EveGetMode; return evc; error: if (driver) { free(driver); driver = NULL; } /* write out error message */ return MakeEVController(driver, pCon, EveWrapper, argc, argv); } /*----------------------------------------------------------------------------*/