From 6c7bb14fad9f8ac2334809b936841651fd901348 Mon Sep 17 00:00:00 2001 From: koennecke Date: Tue, 3 Feb 2009 08:07:30 +0000 Subject: [PATCH] - Major changes folling the rework of the connection object - Added support for galil controllers --- amorscan.c | 4 +- amorstat.c | 87 +++++++++++---------- arrobj.c | 2 +- el737hpdriv.c | 2 + euro2kdriv.c | 2 +- fowrite.c | 10 +-- haakedriv.c | 2 +- ighdriv.c | 2 +- ilmdriv.c | 2 +- ipsdriv.c | 2 +- itcdriv.c | 2 +- julprot.c | 5 +- lcdriv.c | 2 +- linadriv.c | 2 +- lmd200.c | 2 - lsc370driv.c | 2 +- make_gen | 3 +- nextrics.c | 22 +++--- pardef.c | 31 ++++---- pardef.h | 2 +- pmacprot.c | 204 +++++++++++++++++++++++++++++++++++++++++++++++++ polterwrite.c | 11 +-- psi.c | 3 + ptasdrive.c | 6 +- scontroller.c | 8 +- sinqhttpprot.c | 30 ++++++-- tasinit.c | 17 ++--- tasscan.c | 18 ++--- tricssupport.c | 18 +++-- 29 files changed, 364 insertions(+), 139 deletions(-) create mode 100644 pmacprot.c diff --git a/amorscan.c b/amorscan.c index d7d375e..d90e5f2 100644 --- a/amorscan.c +++ b/amorscan.c @@ -122,8 +122,8 @@ /* write progress */ strcat(pHead,"\n"); strcat(pStatus,"\n"); - SCWrite(self->pCon,pHead,eWarning); - SCWrite(self->pCon,pStatus,eWarning); + SCWrite(self->pCon,pHead,eLog); + SCWrite(self->pCon,pStatus,eLog); /* stow away */ DynarReplace(self->pCounts,self->iCounts,&sCount,sizeof(CountEntry)); diff --git a/amorstat.c b/amorstat.c index a97c524..c3d4851 100644 --- a/amorstat.c +++ b/amorstat.c @@ -54,15 +54,18 @@ static int iTOF = 0; static pHistMem pHMHM = NULL; /*-------------------------------------------------------------------------*/ - static int HMCountStartCallback(int iEvent, void *pEvent, void *pUser, - commandContext cc) + static int HMCountStartCallback(int iEvent, void *pEvent, void *pUser) { SConnection *pCon = (SConnection *)pUser; const float *fTime = NULL; int *iTime = NULL; int iLength, iRet, i; - assert(pCon); + /* check kill condition */ + if(pCon == NULL || !SCisConnected(pCon)) + { + return -1; + } if(iEvent == COUNTSTART) { @@ -80,18 +83,15 @@ iTime[i+1] = htonl((int)((fTime[i]/10.)*65536.)); } /* send new time binning to all clients */ - SCPushContext2(pCon,cc); SCWrite(pCon,"TOFClear",eError); SCWriteUUencoded(pCon,"arrowaxis_time",iTime, (iLength+1)*sizeof(int)); - SCPopContext(pCon); free(iTime); } return 1; } /*-------------------------------------------------------------------------*/ - static int ScanStartCallback(int iEvent, void *pEvent, void *pUser, - commandContext cc) + static int ScanStartCallback(int iEvent, void *pEvent, void *pUser) { float *fAxis = NULL; int *iAxis = NULL; @@ -100,9 +100,13 @@ SConnection *pCon = (SConnection *)pUser; pScanData pScan = (pScanData)pEvent; - assert(pCon); assert(pScan); - + + /* check kill conditions */ + if(pCon == NULL || !SCisConnected(pCon)) + { + return -1; + } if(iEvent == SCANSTART) { @@ -124,19 +128,16 @@ iAxis[i+1] = htonl((int)(fAxis[i]*65536.)); } /* send new axis to client */ - SCPushContext2(pCon,cc); SCWrite(pCon,"SCANClear",eError); SCWriteUUencoded(pCon,pBueffel,iAxis, (iLength+1)*sizeof(int)); - SCPopContext(pCon); free(iAxis); free(fAxis); } return 1; } /*------------------------------------------------------------------------*/ - static int ScanPointCallback(int iEvent, void *pEvent, void *pUser, - commandContext cc) + static int ScanPointCallback(int iEvent, void *pEvent, void *pUser) { long *lData = NULL; int *iData = NULL; @@ -144,9 +145,12 @@ SConnection *pCon = (SConnection *)pUser; pScanData pScan = (pScanData)pEvent; - assert(pCon); assert(pScan); - + + /* check kill conditions */ + if(pCon == NULL || !SCisConnected(pCon)){ + return -1; + } if( (iEvent == SCANPOINT) || (iEvent == SCANEND) ) { @@ -166,7 +170,6 @@ iData[i+1] = htonl((int)(lData[i])); } /* send counts to client */ - SCPushContext2(pCon,cc); SCWriteUUencoded(pCon,"arrow_spinupup",iData, (iLength+1)*sizeof(int)); /* send counts for other detector */ @@ -178,7 +181,6 @@ SCWriteUUencoded(pCon,"arrow_spinuplo",iData, (iLength+1)*sizeof(int)); /* to do: check for polarization and send spinlo */ - SCPopContext(pCon); free(iData); free(lData); } @@ -214,21 +216,25 @@ return 0; } /*------------------------------------------------------------------------*/ - static int LoadCallback(int iEvent, void *pEvent, void *pUser, - commandContext cc) + static int LoadCallback(int iEvent, void *pEvent, void *pUser) { pAmorStat pAS = NULL; SConnection *pCon = NULL; - + + pCon = (SConnection *)pUser; + + /* check kill conditions */ + if(pCon == NULL || !SCisConnected(pCon)) + { + return -1; + } + if(iEvent == FILELOADED) { pAS = (pAmorStat)pEvent; - pCon = (SConnection *)pUser; assert(pAS); assert(pCon); - SCPushContext2(pCon,cc); SendLoadedData(pAS,pCon); - SCPopContext(pCon); } return 1; } @@ -394,7 +400,6 @@ long lID; pDummy pDum = NULL; pICallBack pCall = NULL; - commandContext comCon; assert(self); assert(pCon); @@ -403,11 +408,9 @@ iTOF invoke the apropriate callbacks in order to force an initial update. */ - comCon = SCGetContext(pCon); /* file load callback */ - lID = RegisterCallback(self->pCall, comCon,FILELOADED, LoadCallback, - pCon, NULL); - SCRegister(pCon,pServ->pSics, self->pCall,lID); + lID = RegisterCallback(self->pCall,FILELOADED, LoadCallback, + SCCopyConnection(pCon), SCDeleteConnection); SendLoadedData(self,pCon); /* scan object */ @@ -415,19 +418,16 @@ pCall = pDum->pDescriptor->GetInterface(pDum,CALLBACKINTERFACE); if(pCall) { - lID = RegisterCallback(pCall,comCon,SCANSTART,ScanStartCallback, - pCon, NULL); - SCRegister(pCon,pServ->pSics,pCall,lID); - lID = RegisterCallback(pCall,comCon,SCANPOINT,ScanPointCallback, - pCon, NULL); - SCRegister(pCon,pServ->pSics,pCall,lID); - lID = RegisterCallback(pCall,comCon,SCANEND,ScanPointCallback, - pCon, NULL); - SCRegister(pCon,pServ->pSics,pCall,lID); + lID = RegisterCallback(pCall,SCANSTART,ScanStartCallback, + SCCopyConnection(pCon), SCDeleteConnection); + lID = RegisterCallback(pCall,SCANPOINT,ScanPointCallback, + SCCopyConnection(pCon), SCDeleteConnection); + lID = RegisterCallback(pCall,SCANEND,ScanPointCallback, + SCCopyConnection(pCon), SCDeleteConnection); if(iTOF == 0) { - ScanStartCallback(SCANSTART,pDum,pCon,SCGetContext(pCon)); - ScanPointCallback(SCANPOINT,pDum,pCon,SCGetContext(pCon)); + ScanStartCallback(SCANSTART,pDum,pCon); + ScanPointCallback(SCANPOINT,pDum,pCon); } } /* @@ -437,12 +437,11 @@ pCall = pDum->pDescriptor->GetInterface(pDum,CALLBACKINTERFACE); if(pCall) { - lID = RegisterCallback(pCall,comCon,COUNTSTART,HMCountStartCallback, - pCon, NULL); - SCRegister(pCon,pServ->pSics,pCall,lID); + lID = RegisterCallback(pCall,COUNTSTART,HMCountStartCallback, + SCCopyConnection(pCon), SCDeleteConnection); if(iTOF == 1) { - HMCountStartCallback(COUNTSTART,pDum,pCon,SCGetContext(pCon)); + HMCountStartCallback(COUNTSTART,pDum,pCon); } } return 1; @@ -1110,7 +1109,7 @@ } else if(strcmp(argv[1],"tofmode") == 0) { - HMCountStartCallback(COUNTSTART,NULL,pCon,SCGetContext(pCon)); + HMCountStartCallback(COUNTSTART,NULL,pCon); return 1; } else diff --git a/arrobj.c b/arrobj.c index 39dc7cb..358bd08 100644 --- a/arrobj.c +++ b/arrobj.c @@ -202,7 +202,7 @@ static int ArrayMakeItem(void *object, void *delete, int argc, char *argv[]) { if (item->unit) item->unit = strdup(item->unit); if (item->value) item->value = strdup(item->value); ParInitPar(object, item->name); - SCparChange(SCLoad(arr->p.conn)); + SCparChange(arr->p.conn); return 1; Usage: diff --git a/el737hpdriv.c b/el737hpdriv.c index 8d26b33..61d3edb 100644 --- a/el737hpdriv.c +++ b/el737hpdriv.c @@ -155,6 +155,7 @@ static int readRS(pEL737hp pPriv, int *RS){ pPriv->readErrorCount++; pPriv->errorCode = BADREPLY; setBadReply(pPriv,reply); + printf("Bad reply to EL737 RS command: %s\n", reply); return 0; } pPriv->readErrorCount = 0; @@ -668,6 +669,7 @@ pCounterDriver MakeEL737HP(SConnection *pCon, char *name, */ setRS232Debug(pPriv->controller,0); setRS232ReplyTerminator(pPriv->controller,"\r"); + setRS232Timeout(pPriv->controller, 4000); status = initRS232(pPriv->controller); status = EL737Command(pPriv,"RMT 1\r",pHost,131); status = EL737Command(pPriv,"RMT 1\r",pHost,131); diff --git a/euro2kdriv.c b/euro2kdriv.c index 0979973..41d4782 100644 --- a/euro2kdriv.c +++ b/euro2kdriv.c @@ -425,7 +425,7 @@ static long Euro2kStart(long pc, void *object) { ParPrintf(drv, eError, "bad or no response on ModBus"); goto quit; } - ParPrintf(drv, eStatus, "connected to euro2k"); + ParPrintf(drv, eLog, "connected to euro2k"); ModBusPutValue(eab, 111, modBusFloat, drv->d.upperLimit); return __LINE__; case __LINE__: /**********************************/ ModBusPutValue(eab, 112, modBusFloat, drv->d.lowerLimit); diff --git a/fowrite.c b/fowrite.c index 13a00c4..21188b8 100644 --- a/fowrite.c +++ b/fowrite.c @@ -67,8 +67,7 @@ /*------------------ The Countstart Callback Function ----------------------*/ - static int Countstartcallback(int iEvent, void *pEventData, void *pUser, - commandContext cc) + static int Countstartcallback(int iEvent, void *pEventData, void *pUser) { pFoWrite self = NULL; @@ -86,8 +85,7 @@ return 1; } /*------------------ The Countend Callback Function ----------------------*/ - static int Countendcallback(int iEvent, void *pEventData, void *pUser, - commandContext cc) + static int Countendcallback(int iEvent, void *pEventData, void *pUser) { pFoWrite self = NULL; @@ -1021,8 +1019,8 @@ comCon.transID = 0; strncpy(comCon.deviceID,"internal",SCDEVIDLEN); - RegisterCallback(pHMC->pCall,comCon,COUNTSTART,Countstartcallback,pNew,NULL); - RegisterCallback(pHMC->pCall,comCon,COUNTEND,Countendcallback,pNew,NULL); + RegisterCallback(pHMC->pCall,COUNTSTART,Countstartcallback,pNew,NULL); + RegisterCallback(pHMC->pCall,COUNTEND,Countendcallback,pNew,NULL); /* install command */ AddCommand(pSics,"StoreFocus",FoAction,KillFoWrite,pNew); diff --git a/haakedriv.c b/haakedriv.c index 547cf65..ec74e05 100644 --- a/haakedriv.c +++ b/haakedriv.c @@ -238,7 +238,7 @@ static long HaakeStart(long pc, void *object) { EaseStop(eab); goto quit; } - ParPrintf(drv, eStatus, "connected to haake thermostat %s", eab->version); + ParPrintf(drv, eLog, "connected to haake thermostat %s", eab->version); EaseWrite(eab, "W TE K"); return __LINE__; case __LINE__: /**********************************/ FsmCall(HaakeRead); diff --git a/ighdriv.c b/ighdriv.c index 73e1b54..e262ddc 100644 --- a/ighdriv.c +++ b/ighdriv.c @@ -479,7 +479,7 @@ static long IghStart(long pc, void *object) { } else { eab->syntax = 0; } - ParPrintf(drv, eStatus, "connected to %s", eab->version); + ParPrintf(drv, eLog, "connected to %s", eab->version); FsmCall(IghRead); return __LINE__; case __LINE__: /**********************************/ diff --git a/ilmdriv.c b/ilmdriv.c index 9af6ec7..9eb65d9 100644 --- a/ilmdriv.c +++ b/ilmdriv.c @@ -181,7 +181,7 @@ static long IlmStart(long pc, void *object) { EaseStop(eab); goto quit; } - ParPrintf(drv, eStatus, "connected to %s", eab->version); + ParPrintf(drv, eLog, "connected to %s", eab->version); eab->msg[0]='\0'; /* o.k. */ FsmCall(IlmRead); return __LINE__; case __LINE__: /**********************************/ diff --git a/ipsdriv.c b/ipsdriv.c index f0c19a0..5e3716c 100644 --- a/ipsdriv.c +++ b/ipsdriv.c @@ -282,7 +282,7 @@ static long IpsStart(long pc, void *object) { EaseStop(eab); goto quit; } - ParPrintf(drv, eStatus, "connected to %s", eab->version); + ParPrintf(drv, eLog, "connected to %s", eab->version); if (eab->syntax) { drv->fmt = "%.4f"; } else { diff --git a/itcdriv.c b/itcdriv.c index bb788ed..522c505 100644 --- a/itcdriv.c +++ b/itcdriv.c @@ -645,7 +645,7 @@ static long ItcStart(long pc, void *object) { goto quit; } } - ParPrintf(drv, eStatus, "connected to %s", eab->version); + ParPrintf(drv, eLog, "connected to %s", eab->version); FsmCall(ItcRead); return __LINE__; case __LINE__: /**********************************/ if (drv->controlChan == 0 && drv->h >= 1 && drv->h <= 3) { diff --git a/julprot.c b/julprot.c index 8d823a3..b9ce244 100644 --- a/julprot.c +++ b/julprot.c @@ -40,7 +40,10 @@ int JulchoHandler(Ascon *a){ case AsconReading: ret = AsconReadChar(a->fd, &chr); if(ret < 0){ - AsconError(a, "AsconReadChar failed:", errno); + /* EINTR means we must retry */ + if(errno != EINTR && errno != EAGAIN){ + AsconError(a, "AsconReadChar failed:", errno); + } return 1; } else if (ret > 0) { a->start = DoubleTime(); diff --git a/lcdriv.c b/lcdriv.c index b0494cd..e6ff677 100644 --- a/lcdriv.c +++ b/lcdriv.c @@ -159,7 +159,7 @@ static int LcStart(long pc, LcDriv *me) { EvePrintf(eve, eError, "unknown lambda controller version: %s", eve->version); goto quit; } - EvePrintf(eve, eStatus, "connected to %s", eve->version); + EvePrintf(eve, eLog, "connected to %s", eve->version); FSM_CALL(LcRead); quit: diff --git a/linadriv.c b/linadriv.c index 9e27098..bee566a 100644 --- a/linadriv.c +++ b/linadriv.c @@ -154,7 +154,7 @@ static long LinaStart(long pc, void *object) { EaseStop(eab); goto quit; } - ParPrintf(drv, eStatus, "connected to %s", eab->version); + ParPrintf(drv, eLog, "connected to %s", eab->version); FsmCall(LinaRead); return __LINE__; case __LINE__: /**********************************/ diff --git a/lmd200.c b/lmd200.c index bdb66da..344ae8e 100644 --- a/lmd200.c +++ b/lmd200.c @@ -63,7 +63,6 @@ static void setAlarm(pSICSOBJ self, char *text){ node = GetHipadabaNode(self->objectNode,"alarm"); assert(node != NULL); UpdateHipadabaPar(node,alarmVal, NULL); - ReleaseHdbValue(&alarmVal); } /*--------------------------------------------------------------------------*/ static void doAlarm(pSICSOBJ self, char *lineBuffer){ @@ -232,7 +231,6 @@ int MakeLMD200(SConnection *pCon, SicsInterp *pSics, void *pData, self->pPrivate = priv; self->KillPrivate = killLMD200; ReleaseHdbValue(&dataValue); - ReleaseHdbValue(&textValue); NetWatchRegisterCallback(&priv->watchContext, priv->pSock->sockid, LMD200Callback, self); diff --git a/lsc370driv.c b/lsc370driv.c index d0852e8..5b4ccdf 100644 --- a/lsc370driv.c +++ b/lsc370driv.c @@ -327,7 +327,7 @@ static long Lsc370Start(long pc, void *object) { EaseStop(eab); goto quit; } - ParPrintf(drv, eStatus, "connected to %s", eab->version); + ParPrintf(drv, eLog, "connected to %s", eab->version); FsmCall(Lsc370Read); return __LINE__; case __LINE__: /**********************************/ diff --git a/make_gen b/make_gen index 64ae129..a5a892c 100644 --- a/make_gen +++ b/make_gen @@ -22,7 +22,8 @@ OBJ=psi.o buffer.o ruli.o dmc.o nxsans.o nextrics.o sps.o pimotor.o \ $(MZOBJ) amordrive.o amorset.o tcpdornier.o sinqhttp.o\ dgrambroadcast.o sinq.o tabledrive.o tcpdocho.o julcho.o \ ritastorage.o poldizug.o audinelib.o delcam.o el737hpdrivsps.o \ - rebin.o sanslirebin.o lmd200.o slsvme.o julprot.o sinqhttpprot.o + rebin.o sanslirebin.o lmd200.o slsvme.o julprot.o sinqhttpprot.o \ + pmacprot.o .SECONDARY.: sanslirebin.c diff --git a/nextrics.c b/nextrics.c index d0c51fe..7c9b922 100644 --- a/nextrics.c +++ b/nextrics.c @@ -486,7 +486,7 @@ name of hkl object holding crystallographic information /* close and done */ sprintf(pBueffel,"Frame %d succesfully written",iFrameNum-1); - SCWrite(pCon,pBueffel,eStatus); + SCWrite(pCon,pBueffel,eLog); return 1; } @@ -1339,24 +1339,28 @@ name of hkl object holding crystallographic information return iRet; } /*-------------------------------------------------------------------------*/ - static int FrameInterest(int iEvent, void *pEvent, void *pUser, commandContext cc) + static int FrameInterest(int iEvent, void *pEvent, void *pUser) { SConnection *pCon = NULL; int *iFrame; char pBueffel[512]; + pCon = (SConnection *)pUser; - if(iEvent != NEWFRAME) + /* kill condition check */ + if(pCon == NULL || !SCisConnected(pCon)) + { + return -1; + } + + if(iEvent != NEWFRAME ) { return 0; } - pCon = (SConnection *)pUser; iFrame = (int *)pEvent; assert(pCon); sprintf(pBueffel,"framenumber = %d",*iFrame); - SCPushContext2(pCon,cc); SCWrite(pCon,pBueffel,eWarning); - SCPopContext(pCon); return 1; } /*------------------------------------------------------------------------- @@ -1509,9 +1513,9 @@ name of hkl object holding crystallographic information } else if(strcmp(argv[1],"interest") == 0) { - lID = RegisterCallback(self->pCall, comCon, NEWFRAME, FrameInterest, - pCon, NULL); - SCRegister(pCon,pSics, self->pCall,lID); + lID = RegisterCallback(self->pCall, NEWFRAME, FrameInterest, + SCCopyConnection(pCon), + SCDeleteConnection); SCSendOK(pCon); return 1; } diff --git a/pardef.c b/pardef.c index 3cf6220..9c4445f 100644 --- a/pardef.c +++ b/pardef.c @@ -129,7 +129,7 @@ int ParPrintf(void *object, int iOut, const char *fmt, ...) { if (ctx && pobj == ctx->obj && ctx->con) { con = ctx->con; } else { - con = SCLoad(pobj->conn); + con = pobj->conn; } } else if (ctx) { con = ctx->con; @@ -138,7 +138,7 @@ int ParPrintf(void *object, int iOut, const char *fmt, ...) { if (iOut < 0) { if (!con) return 0; /* no connection, no verbose output */ if (-iOut > pobj->verbose) return 0; /* check verbosity level */ - iOut = eStatus; + iOut = eValue; } va_start(ap, fmt); @@ -317,15 +317,17 @@ void ParLogForced(void *object) { ParEnd(); } /*-------------------------------------------------------------------------*/ -static int ParCallBack(int event, void *eventData, void *userData, - commandContext cc) { +static int ParCallBack(int event, void *eventData, void *userData) { char *pBuf = (char *)eventData; SConnection *con = (SConnection *)userData; + /* check kill condition */ + if(con == NULL || !SCisConnected(con)){ + return -1; + } + if (event == VALUECHANGE) { - SCPushContext2(con,cc); SCWrite(con,pBuf,eValue); - SCPopContext(con); return 1; } return 1; @@ -386,7 +388,7 @@ static void ParListSugar(SConnection *con, ParData *o) { } p = p->next; } - SCWrite(con, buf, eStatus); + SCWrite(con, buf, eValue); } /*----------------------------------------------------------------------------*/ void ParSaveConn(void *object, SConnection *con) { @@ -394,8 +396,11 @@ void ParSaveConn(void *object, SConnection *con) { int rights; rights = SCGetRights(con); - if (rights >= usMugger && rights <= usUser && con->pSock != NULL) { - o->conn = SCSave(con, o->conn); + if (rights >= usMugger && rights <= usUser && con->sockHandle >= 0) { + if(o->conn != NULL){ + SCDeleteConnection(o->conn); + } + o->conn = SCCopyConnection(con); } } /*----------------------------------------------------------------------------*/ @@ -449,14 +454,14 @@ static int ParExecute(SConnection *con, SicsInterp *sics, void *object, int argc o->pCall = CreateCallBackInterface(); } assert(o->pCall); - id = RegisterCallback(o->pCall, SCGetContext(con),VALUECHANGE, ParCallBack, con, NULL); - SCRegister(con, pServ->pSics, o->pCall, id); + id = RegisterCallback(o->pCall,VALUECHANGE, ParCallBack, + SCCopyConnection(con), SCDeleteConnection); SCSendOK(con); ParEnd(); return 1; } else if (strcmp(argv[1],"uninterest") == 0) { if (o->pCall) { - RemoveCallback2(o->pCall, con); + RemoveCallbackCon(o->pCall, con); } SCSendOK(con); ParEnd(); @@ -1251,7 +1256,7 @@ void ParKill(void *object) { if (o->creationCmd) free(o->creationCmd); if (o->pCall) DeleteCallBackInterface(o->pCall); if (o->desc) DeleteDescriptor(o->desc); - if (o->conn) SCStoreFree(o->conn); + if (o->conn) SCDeleteConnection(o->conn); p = o->infoList; while (p) { q = p->next; diff --git a/pardef.h b/pardef.h index dcdb0ba..8c7d5fb 100644 --- a/pardef.h +++ b/pardef.h @@ -51,7 +51,7 @@ typedef struct ParData { int period; /* logging interval */ ParInfo *infoList; /* list for additional info on parameters */ pICallBack pCall; /* sics callback function */ - SCStore *conn; /* last connection with user or manager priv. */ + SConnection *conn; /* last connection with user or manager priv. */ int verbose; /* verbosity, mainly for tests */ } ParData; diff --git a/pmacprot.c b/pmacprot.c new file mode 100644 index 0000000..3efa3a0 --- /dev/null +++ b/pmacprot.c @@ -0,0 +1,204 @@ +/** + * This is an asynchronous protocol driver for the Delta-Tau PMAC + * series of controllers, connected via TCP/IP. The PMAC needs its + * commands in a special purpose data structure, describe below. + * As responses, it can send any of the following formats: + * datadatadata>CR> + * ERRxxx + * data + * There can be multiple data and errors in a string. However, I wish to + * restrict this to processing one command at any time. This driver owes + * some insight and little code to the EPICS driver by + * Pete Leicester, Diamond. + * + * ** Before this can be used, I3=2 and I6=1 must be set on the PMAC ** + * + * copyright: see file COPYRIGHT + * + * Mark Koennecke, December 2008 + */ +#include +#include +#include +#include + +#define ETHERNET_DATA_SIZE 1492 +#define INPUT_SIZE (ETHERNET_DATA_SIZE+1) /* +1 to allow space to add terminating ACK */ +#define STX '\2' +#define CTRLB '\2' +#define CTRLC '\3' +#define ACK '\6' +#define CTRLF '\6' +#define BELL '\7' +#define CTRLG '\7' +#define CTRLP '\16' +#define CTRLV '\22' +#define CTRLX '\24' + +/* PMAC ethernet command structure */ +#pragma pack(1) +typedef struct tagEthernetCmd +{ + unsigned char RequestType; + unsigned char Request; + unsigned short wValue; + unsigned short wIndex; + unsigned short wLength; /* length of bData */ + unsigned char bData[ETHERNET_DATA_SIZE]; +} ethernetCmd; +#pragma pack() + +#define ETHERNET_CMD_HEADER ( sizeof(ethernetCmd) - ETHERNET_DATA_SIZE ) + +/* PMAC ethernet commands - RequestType field */ +#define VR_UPLOAD 0xC0 +#define VR_DOWNLOAD 0x40 + +/* PMAC ethernet commands - Request field */ +#define VR_PMAC_SENDLINE 0xB0 +#define VR_PMAC_GETLINE 0xB1 +#define VR_PMAC_FLUSH 0xB3 +#define VR_PMAC_GETMEM 0xB4 +#define VR_PMAC_SETMEN 0xB5 +#define VR_PMAC_SETBIT 0xBA +#define VR_PMAC_SETBITS 0xBB +#define VR_PMAC_PORT 0xBE +#define VR_PMAC_GETRESPONSE 0xBF +#define VR_PMAC_READREADY 0xC2 +#define VR_CTRL_RESPONSE 0xC4 +#define VR_PMAC_GETBUFFER 0xC5 +#define VR_PMAC_WRITEBUFFER 0xC6 +#define VR_PMAC_WRITEERROR 0xC7 +#define VR_FWDOWNLOAD 0xCB +#define VR_IPADDRESS 0xE0 + +/*--------------------------------------------------------------------------- + * a private data structurli to keep track of the PMAC + *---------------------------------------------------------------------------*/ +typedef struct { + ethernetCmd cmd; + char *ptr; + int bytesToWrite; + int expectACK; +}PMACPrivate, *pPMACPrivate; + +/*---------------------------------------------------------------------------*/ +static int PMACHandler(Ascon *a){ + char *data = NULL; + int ret, l; + char chr; + pPMACPrivate priv = NULL; + + priv = a->private; + + switch(a->state){ + case AsconWriteStart: + data = GetCharArray(a->wrBuffer); + memset(priv,0,sizeof(PMACPrivate)); + priv->cmd.RequestType = VR_DOWNLOAD; + priv->cmd.Request = VR_PMAC_GETRESPONSE; + priv->cmd.wValue = 0; + priv->cmd.wIndex = 0; + priv->cmd.wLength = htons(strlen(data)); /* may be one more */ + priv->bytesToWrite = strlen(data) + 1 + ETHERNET_CMD_HEADER; + strcpy((char *)priv->cmd.bData,data); + priv->expectACK = 1; + priv->ptr = (char *)&priv->cmd; + a->state = AsconWriting; + a->wrPos = 0; + break; + case AsconWriting: + AsconReadGarbage(a->fd); + l = priv->bytesToWrite - a->wrPos; + ret = AsconWriteChars(a->fd, priv->ptr, l); + if (ret < 0) { + if(errno != EINTR && errno != EAGAIN){ + AsconError(a, "send failed:", errno); + } + /* + * Ooops: which state shall we go to after a write fail? + * This seems to retry. + */ + } else { + a->wrPos += ret; + if (a->wrPos >= priv->bytesToWrite) { + a->state = AsconWriteDone; + } else { + priv->ptr += ret; + } + } + break; + case AsconReading: + ret = AsconReadChar(a->fd, &chr); + if(ret < 0){ + /* EINTR means we must retry */ + if(errno != EINTR && errno != EAGAIN){ + AsconError(a, "AsconReadChar failed:", errno); + } + return 1; + } else if (ret > 0) { + a->start = DoubleTime(); + if(chr == STX || chr == BELL){ + priv->expectACK = 0; + return 1; + } + if(priv->expectACK && chr == ACK){ + if(GetDynStringLength(a->rdBuffer) == 0){ + DynStringConcat(a->rdBuffer,"ACK"); + } + DynStringConcatChar(a->rdBuffer, '\0'); + a->state = AsconReadDone; + break; + } + if(priv->expectACK == 0 && chr == '\r'){ + DynStringConcatChar(a->rdBuffer, '\0'); + a->state = AsconReadDone; + break; + } + if (DynStringConcatChar(a->rdBuffer, chr) == 0) { + AsconError(a, "DynStringConcatChar failed:", ENOMEM); + break; + } + } else if(ret == 0){ + if (a->timeout > 0) { + if (DoubleTime() - a->start > a->timeout) { + AsconError(a, "read timeout", 0); + a->state = AsconTimeout; + } + } + } + break; + default: + return AsconStdHandler(a); + } + return 1; +} +/*------------------------------------------------------------------------*/ +static int PMACInit(Ascon *a, SConnection *con, + int argc, char *argv[]) { + pPMACPrivate priv = NULL; + + priv = calloc(sizeof(PMACPrivate), 1); + a->fd = -1; + a->state = AsconConnectStart; + a->reconnectInterval = 10; + a->hostport = strdup(argv[1]); + if(argc > 2){ + a->timeout = atof(argv[2]); + } else { + a->timeout = 2.0; /* sec */ + } + a->private = priv; + a->killPrivate = free; + return 1; +} +/*------------------------------------------------------------------------*/ +void AddPMACProtocoll(){ + AsconProtocol *prot = NULL; + + prot = calloc(sizeof(AsconProtocol), 1); + prot->name = strdup("pmac"); + prot->init = PMACInit; + prot->handler = PMACHandler; + AsconInsertProtocol(prot); +} diff --git a/polterwrite.c b/polterwrite.c index c4c535b..148055e 100644 --- a/polterwrite.c +++ b/polterwrite.c @@ -56,8 +56,7 @@ typedef struct { static void PoldiLink(pPolterdi s, SConnection *pCon); /*------------------ The Countstart Callback Function ----------------------*/ - static int Countstartcallback(int iEvent, void *pEventData, void *pUser, - commandContext cc) + static int Countstartcallback(int iEvent, void *pEventData, void *pUser) { pPolterdi self = NULL; @@ -75,8 +74,7 @@ typedef struct { return 1; } /*------------------ The Countend Callback Function ----------------------*/ - static int Countendcallback(int iEvent, void *pEventData, void *pUser, - commandContext cc) + static int Countendcallback(int iEvent, void *pEventData, void *pUser) { pPolterdi self = NULL; @@ -723,10 +721,9 @@ int PolterInstall(SConnection *pCon, SicsInterp *pSics, KillPolterdi(pNew); return 0; } - comCon.transID = 0; strncpy(comCon.deviceID,"internal",SCDEVIDLEN); - RegisterCallback(pCall,comCon,COUNTSTART,Countstartcallback,pNew,NULL); - RegisterCallback(pCall,comCon,COUNTEND,Countendcallback,pNew,NULL); + RegisterCallback(pCall,COUNTSTART,Countstartcallback,pNew,NULL); + RegisterCallback(pCall,COUNTEND,Countendcallback,pNew,NULL); AddCommand(pSics,"storedata",PolterAction,KillPolterdi,pNew); return 1; diff --git a/psi.c b/psi.c index 48a523a..5e4fdd2 100644 --- a/psi.c +++ b/psi.c @@ -79,6 +79,8 @@ extern int MakeLMD200(SConnection *pCon, SicsInterp *pSics, void *pData, extern void AddJulChoProtocoll(); /* from sinqhttpprot.c */ extern void AddHttpProtocoll(); +/* from pmacprot.c */ +extern void AddPMACProtocoll(); /*--------------------------------------------------------------------------*/ void SiteInit(void) { @@ -104,6 +106,7 @@ void SiteInit(void) { */ AddJulChoProtocoll(); AddHttpProtocoll(); + AddPMACProtocoll(); } diff --git a/ptasdrive.c b/ptasdrive.c index 241beb3..3d69982 100644 --- a/ptasdrive.c +++ b/ptasdrive.c @@ -320,20 +320,20 @@ int TASDrive(SConnection *pCon, SicsInterp *pSics, void *pData, { SCSetInterrupt(pCon,eContinue); sprintf(pBueffel,"Driving aborted"); - SCWrite(pCon,pBueffel,eStatus); + SCWrite(pCon,pBueffel,eError); } return 0; } else if(status == DEVDONE) { sprintf(pBueffel,"Driving done"); - SCWrite(pCon,pBueffel,eStatus); + SCWrite(pCon,pBueffel,eValue); } else { sprintf(pBueffel, "Driving finished"); - SCWrite(pCon,pBueffel,eStatus); + SCWrite(pCon,pBueffel,eValue); } return rStatus; } diff --git a/scontroller.c b/scontroller.c index 2247b71..4766cae 100644 --- a/scontroller.c +++ b/scontroller.c @@ -35,11 +35,11 @@ ---------------------------------------------------------------------------*/ EXTERN void SerialMurder(ClientData pData) { - /* + if(pServ->pReader != NULL){ NetReadRemoveUserSocket(pServ->pReader, SerialGetSocket(&(pData))); - */ - SerialClose(&(pData)); - free(pData); + } + SerialClose(&(pData)); + free(pData); } /*------------------ a forward declaration -----------------------------*/ EXTERN int SurielSend(ClientData clientData, Tcl_Interp *interp, diff --git a/sinqhttpprot.c b/sinqhttpprot.c index e55b0ae..48c4189 100644 --- a/sinqhttpprot.c +++ b/sinqhttpprot.c @@ -8,6 +8,7 @@ * * Mark Koennecke, June 2008 */ +#include #include #include #include @@ -97,6 +98,8 @@ static int HttpHandler(Ascon *a) { int socke, selStat; fd_set rmask; struct timeval tmo = {0,0}; + char buffer[1024]; + ghttp_current_status procStatus; switch (a->state) { case AsconConnectStart: @@ -109,6 +112,7 @@ static int HttpHandler(Ascon *a) { if(configRequest(a)){ a->state = AsconWriting; } + return 1; break; case AsconWriting: status = ghttp_process(pHttp->request); @@ -122,7 +126,10 @@ static int HttpHandler(Ascon *a) { DynStringConcat(a->rdBuffer,"Server error"); a->state = AsconReadDone; } else { - a->state = AsconWriteDone; + procStatus = ghttp_get_status(pHttp->request); + if(procStatus.proc == ghttp_proc_response_hdrs || procStatus.proc == ghttp_proc_response){ + a->state = AsconWriteDone; + } } a->start = DoubleTime(); DynStringClear(a->rdBuffer); @@ -131,21 +138,28 @@ static int HttpHandler(Ascon *a) { socke = ghttp_get_socket(pHttp->request); FD_ZERO(&rmask); FD_SET(socke,&rmask); - selStat = uselect(socke+1,&rmask, NULL, NULL, &tmo); - if(selStat != 0){ - status = ghttp_process(pHttp->request); - a->state = AsconReading; - } else { + selStat = uselect(socke+1,&rmask, NULL, NULL, &tmo); + if(selStat > 0 && FD_ISSET(socke,&rmask)){ + status = ghttp_process(pHttp->request); + a->state = AsconReading; + } else { if(DoubleTime() > a->start + a->timeout){ AsconError(a," read timeout", 0); a->state = AsconTimeout; /* this to clear the line */ ghttp_close(pHttp->request); } - } - return 1; + } + return 1; break; case AsconReading: + socke = ghttp_get_socket(pHttp->request); + FD_ZERO(&rmask); + FD_SET(socke,&rmask); + selStat = select(socke+1,&rmask, NULL, NULL, &tmo); + if(selStat == 0 ){ + return 1; + } status = ghttp_process(pHttp->request); switch(status){ case ghttp_not_done: diff --git a/tasinit.c b/tasinit.c index f61dea1..fc3afec 100644 --- a/tasinit.c +++ b/tasinit.c @@ -269,8 +269,7 @@ static int TasSaveStatus(void *self, char *name, FILE *fd) used on the variables which switch the counter box into the appropriate mode. -----------------------------------------------------------------------*/ -static int MonitorCallback(int iEvent, void *pEvent, void *pUser, - commandContext cc) +static int MonitorCallback(int iEvent, void *pEvent, void *pUser) { pTASdata self = (pTASdata)pUser; assert(self); @@ -283,8 +282,7 @@ static int MonitorCallback(int iEvent, void *pEvent, void *pUser, return 1; } /*---------------------------------------------------------------------*/ -static int TimerCallback(int iEvent, void *pEvent, void *pUser, - commandContext cc) +static int TimerCallback(int iEvent, void *pEvent, void *pUser) { pTASdata self = (pTASdata)pUser; assert(self); @@ -319,8 +317,7 @@ static int RecalcAction(SConnection *pCon, SicsInterp *pSics, void *pData, to allow for the analyzer shielding to settle down. This is done through this callback function ---------------------------------------------------------------------------*/ -static int A6WaitCallback(int iEvent, void *pEventData, void *pUserData, - commandContext cc) +static int A6WaitCallback(int iEvent, void *pEventData, void *pUserData) { if(iEvent == MOTEND) { @@ -416,16 +413,14 @@ int TASFactory(SConnection *pCon, SicsInterp *pSics, void *pData, the variables should have been accessed earlier on. */ pVar = FindVariable(pSics,"MN"); - comCon.transID = 0; - strncpy(comCon.deviceID,"internal",SCDEVIDLEN); if(pVar) { - RegisterCallback(pVar->pCall,comCon,VALUECHANGE,MonitorCallback,pNew,NULL); + RegisterCallback(pVar->pCall,VALUECHANGE,MonitorCallback,pNew,NULL); } pVar = FindVariable(pSics,"TI"); if(pVar) { - RegisterCallback(pVar->pCall,comCon,VALUECHANGE,TimerCallback,pNew,NULL); + RegisterCallback(pVar->pCall,VALUECHANGE,TimerCallback,pNew,NULL); } /* @@ -434,7 +429,7 @@ int TASFactory(SConnection *pCon, SicsInterp *pSics, void *pData, pMot = FindMotor(pSics,"a6"); if(pMot != NULL) { - RegisterCallback(pMot->pCall,comCon,MOTEND,A6WaitCallback,NULL,NULL); + RegisterCallback(pMot->pCall,MOTEND,A6WaitCallback,NULL,NULL); } diff --git a/tasscan.c b/tasscan.c index 64953ab..c3f842a 100644 --- a/tasscan.c +++ b/tasscan.c @@ -163,7 +163,7 @@ static int TASHeader(pScanData self) self->fd = fopen(self->pFile,"w"); if(!self->fd) { - SCWrite(self->pCon,"ERROR: cannot write data file",eError); + SCWrite(self->pCon,"ERROR: cannot write data file",eLogError); return 0; } @@ -184,7 +184,7 @@ static int TASHeader(pScanData self) } else { - SCWrite(self->pCon,"WARNING: failed to decode file number",eWarning); + SCWrite(self->pCon,"WARNING: failed to decode file number",eLog); } /* the bizarre R, A, V header */ @@ -493,7 +493,7 @@ static int TASHeader(pScanData self) /* write header to screen as well */ - SCWrite(self->pCon,pHeader,eWarning); + SCWrite(self->pCon,pHeader,eLog); /* close the file, we will reopen later with append for the data @@ -530,7 +530,7 @@ static int TASScanPoint(pScanData self, int iPoint) self->fd = fopen(self->pFile,"a"); if(!self->fd) { - SCWrite(self->pCon,"ERROR: cannot append to data file",eError); + SCWrite(self->pCon,"ERROR: cannot append to data file",eLogError); return 0; } @@ -598,7 +598,7 @@ static int TASScanPoint(pScanData self, int iPoint) if(fVal < -990.){ sprintf(pError,"WARNING: problem reading %s", tasMotorOrder[pTAS->addOutput[i]]); - SCWrite(self->pCon, pError,eWarning); + SCWrite(self->pCon, pError,eLog); } } else @@ -613,7 +613,7 @@ static int TASScanPoint(pScanData self, int iPoint) write both to file and onto screen */ fprintf(self->fd,"%s\n",pBueffel); - SCWrite(self->pCon,pBueffel,eWarning); + SCWrite(self->pCon,pBueffel,eLog); /* close the file @@ -759,7 +759,7 @@ static int RunPolScan(pScanData self, int iPoint) fd = fopen(pTAS->tasPar[POLFIL]->text,"r"); if(!fd){ SCWrite(self->pCon,"ERROR: failed to open polarisation analysis file", - eError); + eLogError); return 0; } pTAS->iPOL = 0; @@ -815,12 +815,12 @@ static int TASScanCount(pScanData self, int iPoint) iRet = Wait4Success(GetExecutor()); if(iRet == DEVINT) { - SCWrite(self->pCon,"Counting aborted due to Interrupt",eStatus); + SCWrite(self->pCon,"Counting aborted due to Interrupt",eLog); status = 0; } else if(iRet == DEVERROR) { - SCWrite(self->pCon,"Counting finished with Problems",eStatus); + SCWrite(self->pCon,"Counting finished with Problems",eLog); status = 0; } else diff --git a/tricssupport.c b/tricssupport.c index aecda52..abde817 100644 --- a/tricssupport.c +++ b/tricssupport.c @@ -55,23 +55,26 @@ static void KillTricsSupport(void *pData){ } } /*=====================================================================*/ -static int FrameSupInterest(int iEvent, void *pEvent, void *pUser, - commandContext cc){ +static int FrameSupInterest(int iEvent, void *pEvent, void *pUser){ SConnection *pCon = NULL; int *iFrame; char pBueffel[512]; + pCon = (SConnection *)pUser; + /* check kill condition */ + if(pCon == NULL || !SCisConnected(pCon)) + { + return -1; + } + if(iEvent != NEWFRAME){ return 0; } - pCon = (SConnection *)pUser; iFrame = (int *)pEvent; assert(pCon); sprintf(pBueffel,"framenumber = %d",*iFrame); - SCPushContext2(pCon,cc); SCWrite(pCon,pBueffel,eWarning); - SCPopContext(pCon); return 1; } /*====================================================================== @@ -185,10 +188,9 @@ int TricsSupportAction(SConnection *pCon, SicsInterp *pSics, void *pData, return 1; } else if(strcmp(argv[1],"interest") == 0){ - lID = RegisterCallback(self->pCall, SCGetContext(pCon), + lID = RegisterCallback(self->pCall, NEWFRAME, FrameSupInterest, - pCon, NULL); - SCRegister(pCon,pSics, self->pCall,lID); + SCCopyConnection(pCon), SCDeleteConnection); SCSendOK(pCon); return 1; } else if(strcmp(argv[1],"newframe") == 0){