diff --git a/SCinter.c b/SCinter.c index b797ef0b..24e24284 100644 --- a/SCinter.c +++ b/SCinter.c @@ -79,6 +79,7 @@ #include "obdes.h" #include "lld.h" #include "dynstring.h" +#include "commandlog.h" /* M.Z. */ #include "definealias.h" @@ -354,6 +355,14 @@ int InterpExecute(SicsInterp * self, SConnection * pCon, char *pText) } MacroPop(); + /* + * log in history if succesfull + */ + if(iRet == 1){ + WriteCommandHistory(pText); + } + + deleteArgv: if (argv) { /* delete argv */ diff --git a/ascon.c b/ascon.c index a291cef2..9086fc6c 100644 --- a/ascon.c +++ b/ascon.c @@ -218,15 +218,22 @@ int AsconConnectSuccess(int fd) FD_SET(fd, &rmask); ret = uselect(fd + 1, &rmask, &wmask, NULL, &tmo); if (ret > 0) { - assert(FD_ISSET(fd, &wmask)); + /** + * This assertion triggered for some reason: as writing is only done later + * I moved the test for ISSET(wmask) down there + * assert(FD_ISSET(fd, &wmask)); + */ + if (FD_ISSET(fd, &rmask)) { /* there may already be data for read */ if (recv(fd, NULL, 0, 0) < 0) { /* zero length, check only return value */ ret = ASCON_RECV_ERROR; /* first recv failed */ } } else { - if (send(fd, NULL, 0, 0) < 0) { /* zero length, check only return value */ - ret = ASCON_SEND_ERROR; /* first send failed */ - } + if(FD_ISSET(fd,&wmask)){ + if (send(fd, NULL, 0, 0) < 0) { /* zero length, check only return value */ + ret = ASCON_SEND_ERROR; /* first send failed */ + } + } } } fcntl(fd, F_SETFL, oldopts & ~O_NONBLOCK); /* reset to blocking mode */ @@ -698,3 +705,8 @@ char *AsconGetError(Ascon *a) { return GetCharArray(a->errmsg); } + +int AsconLastState(Ascon *a) +{ + return (int)a->state; +} diff --git a/ascon.h b/ascon.h index c1b3dc75..93651aba 100644 --- a/ascon.h +++ b/ascon.h @@ -94,4 +94,10 @@ char *ConcatArgs(int argc, char *argv[]); */ void AsconError(Ascon *a, char *msg, int errorno); +/** + * \brief return the last ascon state. Only used for statistics + * \param a The Adcon to query + * \return the AsconState as an integer. + */ +int AsconLastState(Ascon *a); #endif diff --git a/asynnet.c b/asynnet.c index 80e8336c..a34254ea 100644 --- a/asynnet.c +++ b/asynnet.c @@ -43,7 +43,7 @@ #define DATASOCKET 1 #define MAXCONNECTIONS 1024 #define RBUFFERSIZE 262144 /* 256kb */ -#define WBUFFERSIZE 4*262144 /* 512kb */ +#define WBUFFERSIZE 10*262144 /* 512kb */ /*--------------------------------------------------------------------------*/ typedef struct { int socket; diff --git a/asynnet.h b/asynnet.h index 46a1b556..a93fbfb9 100644 --- a/asynnet.h +++ b/asynnet.h @@ -42,6 +42,7 @@ * port or data is ready. * \param handle The handle of the new network connection * \return 1 if the new connection can be accepted or 0 if not. + * Same for data. */ typedef int (*ANETcallback) (int handle, void *userData); /** diff --git a/commandlog.c b/commandlog.c index 51e97019..888596ce 100644 --- a/commandlog.c +++ b/commandlog.c @@ -16,6 +16,10 @@ - timestamps look different and are omitted if no other text is written - socket number information is written on the timestamp line + Added command history logging. Due to problems this is currently disabled by + writeHistory = 0 and code in SetWriteHistory + + Mark Koennecke, July 2010 --------------------------------------------------------------------------*/ #include #include @@ -28,7 +32,7 @@ #include "scaldate.h" #include "network.h" #include "circular.h" - +#include "stptok.h" /* in conman.c */ int TelnetWrite(mkChannel * pSock, char *pText); @@ -36,6 +40,9 @@ int TelnetWrite(mkChannel * pSock, char *pText); static FILE *fd = NULL; static FILE *fauto = NULL; static char pFile[256]; +/*------------------------- command history logging --------------------*/ +static char pHistoryFilter[1024] = ""; +static int writeHistory = 0; /*-------------------- the tail buffer ---------------------------------*/ static pCircular pTail = NULL; #define MAXTAIL 1000 @@ -484,6 +491,31 @@ int CommandLog(SConnection * pCon, SicsInterp * pSics, void *pData, } SCPrintf(pCon, eValue, "%s.intervall [min] = %d", argv[0], iIntervall); return 1; + } else if (strcmp(argv[1], "history") == 0) { + if (argc > 2) { + iRet = Tcl_GetInt(pSics->pTcl, argv[2], &iVal); + if (iRet != TCL_OK) { + SCWrite(pCon, "ERROR: failed to convert new history to number", + eError); + return 0; + } + writeHistory = iVal; + } + SCPrintf(pCon, eValue, "%s.writeHistory = %d", argv[0], writeHistory); + return 1; + } else if (strcmp(argv[1], "historyfilter") == 0) { + if (argc > 2) { + if(strlen(argv[2]) < 1024){ + strcpy(pHistoryFilter,argv[2]); + } else { + SCWrite(pCon,"ERROR: history filter to long", eError); + return 0; + } + SCSendOK(pCon); + return 1; + } + SCPrintf(pCon, eValue, "%s.historyFilter = %s", argv[0], pHistoryFilter); + return 1; } else if (strcmp(argv[1], "compact") == 0) { if (argc > 2) { iCompact = atoi(argv[2]); @@ -554,13 +586,51 @@ static int openHistoryLog() return 1; } } +/*--------------------------------------------------------------------------- + * This is to suppress certain stuff from the history log in order to stop it + * from filling with garbage + -----------------------------------------------------------------------------*/ +static int historyFilter(char *command) +{ + static char *toRemove[] = {"sct", "hupdate","contextdo","transact", NULL}; + char token[50]; + char *pPtr = NULL; + int i = 0; + + while(toRemove[i] != NULL){ + if(strstr(command,toRemove[i]) != NULL){ + return 0; + } + i++; + } + + pPtr = pHistoryFilter; + while((pPtr = stptok(pPtr,token,50,":")) != NULL){ + if(strstr(command,token) != NULL){ + return 0; + } + } + + return 1; +} /*-----------------------------------------------------------------------*/ void WriteCommandHistory(char *txt) { + if(writeHistory == 0){ + return; + } if(comHistory == NULL){ openHistoryLog(); } if(comHistory != NULL){ - fprintf(comHistory,"%s\n", txt); + if(historyFilter(txt)){ + fprintf(comHistory,"%s\n", txt); + } } } +/*-----------------------------------------------------------------------*/ +void SetWriteHistory(int i) +{ + /* writeHistory = i;*/ + writeHistory = 0; +} diff --git a/commandlog.h b/commandlog.h index 920f5847..d02d1da3 100644 --- a/commandlog.h +++ b/commandlog.h @@ -18,4 +18,5 @@ int CommandLog(SConnection * pCon, SicsInterp * pSics, void *pData, void CommandLogClose(void *pData); void WriteCommandHistory(char *txt); +void SetWriteHistory(int i); #endif diff --git a/conman.c b/conman.c index 44301165..4f209a2b 100644 --- a/conman.c +++ b/conman.c @@ -1416,12 +1416,6 @@ int SCInvoke(SConnection * self, SicsInterp * pInter, char *pCommand) SCDeleteConnection(pCopy); StatusFileTask(NULL); /* save changed parameters */ - /* - * log successful commands for later evaluation - */ - if(iRet == 1){ - WriteCommandHistory(pCommand); - } self->inUse--; return iRet; } diff --git a/counter.c b/counter.c index 188847f8..6e4ae892 100644 --- a/counter.c +++ b/counter.c @@ -214,7 +214,7 @@ static int CheckCountStatus(void *pData, SConnection * pCon) int eCt; char pError[80], pBueffel[132]; int iErr; - float fControl; + float fControl, rate; MonEvent sMon; self = (pCounter) pData; @@ -239,6 +239,13 @@ static int CheckCountStatus(void *pData, SConnection * pCon) } } + if(self->pDriv->fTime > .0){ + rate = (float)(self->pDriv->lCounts[1])/self->pDriv->fTime; + if(rate > 5000){ + SCWrite(pCon,"WARNING: Your control monitor is running into dead time", + eWarning); + } + } /* handle count parameters and notify listeners on progress */ diff --git a/countersec.c b/countersec.c index 8e47afb3..9fdc3520 100644 --- a/countersec.c +++ b/countersec.c @@ -68,6 +68,8 @@ static int SecStartCount(void *pData, SConnection *pCon) self->tStart = time(NULL); node = GetHipadabaNode(self->pDes->parNode, "status"); UpdateHipadabaPar(node,MakeHdbText("run"), pCon); + node = GetHipadabaNode(self->pDes->parNode, "control"); + UpdateHipadabaPar(node,MakeHdbFloat(.0), pCon); SetHdbProperty(node,"geterror", NULL); /* * set time to 0. Otherwise, if there is a delay, @@ -145,14 +147,6 @@ static int SecCtrCheckStatus(void *pData, SConnection *pCon) } ReleaseHdbValue(&v); - /* - * check for overrun timers - */ - if(self->getMode(self) == eTimer && - time(NULL) > (self->tStart + (int)self->getPreset(self)) && self->haltFixFlag == 0){ - SecCtrHalt(self); - self->haltFixFlag = 1; - } node = GetHipadabaNode(self->pDes->parNode,"control"); assert(node != NULL); @@ -167,6 +161,20 @@ static int SecCtrCheckStatus(void *pData, SConnection *pCon) sMon.fPreset = fPreset; sMon.pName = self->name; self->badStatusCount = 0; + + /* + * check for overrun counter boxes + */ + if(self->getMode(self) == eTimer && + (sMon.fCurrent > sMon.fPreset +1) + && self->haltFixFlag == 0){ + SecCtrHalt(self); + self->haltFixFlag = 1; + } + + /* + * invoke notifiactions, if necessary + */ if (self->iCallbackCounter > 20) { InvokeCallBack(self->pCall, MONITOR, &sMon); self->iCallbackCounter = 0; diff --git a/devser.c b/devser.c index 6c8d1c40..1a0fe6c7 100644 --- a/devser.c +++ b/devser.c @@ -22,6 +22,18 @@ struct DevSer { DevAction *actions; /* the action queue */ DevAction *toKill; /* list of actions to be killed */ int steps; + double startTime; /* fields for statistics */ + double comCount; + long nComCount; + double comMax; + long errorCount; + int inError; + double asconStart; + double asconSum; + double asconMax; + long asconCount; + int asconState, asconMaxState; + int maxCount; }; static char *devPrio[NumberOfPRIO] = { @@ -133,6 +145,80 @@ static DevAction *DevNextAction(DevSer * devser) } return NULL; } +static void LogStart(DevSer *self) +{ + if(self->startTime > 0){ + printf("DEVSER: there is something fucked up in LogStart. Investigate!\n"); + } + self->startTime = DoubleTime(); +} +static void LogResponse(DevSer *self, int error) +{ + double responseTime; + + if(self->startTime < 0){ + printf("DEVSER: there is something fucked up in LogResponse, Investigate!\n"); + self->startTime = -1; + return; + } + responseTime = DoubleTime() - self->startTime; + self->comCount += responseTime; + if(responseTime > self->comMax){ + self->comMax = responseTime; + } + self->nComCount++; + if(error == 1 && self->inError == 0){ + self->errorCount++; + self->inError = 1; + } else if(error == 0){ + self->inError = 0; + } + self->startTime = -1; +} +static void StartAscon(DevSer *self) +{ + self->asconStart = DoubleTime(); + self->asconState = AsconLastState(self->ascon); +} +static void AsconLog(DevSer *self) +{ + double used; + + used = DoubleTime() - self->asconStart; + self->asconSum += used; + self->asconCount++; + if(used > self->asconMax){ + self->asconMax = used; + self->asconMaxState = self->asconState; + } + if(used > self->asconMax/2.){ + self->maxCount++; + } +} +void DevStatistics(DevSer *devser, double *avg, double *max, + long *errCount, int *errState) +{ + if(devser->nComCount > 0){ + *avg = devser->comCount/devser->nComCount; + } else { + *avg = 0; /* no data!*/ + } + *max = devser->comMax; + *errCount = devser->errorCount; + *errState = devser->inError; +} +void DevAsconStatistics(DevSer *self, double *avg, \ + double *max, int *maxState, int *longCount) +{ + if(self->asconCount > 0){ + *avg = self->asconSum/self->asconCount; + } else { + *avg = .0; + } + *max = self->asconMax; + *maxState = self->asconMaxState; + *longCount = self->maxCount; +} static int DevQueueTask(void *ds) { @@ -155,13 +241,26 @@ static int DevQueueTask(void *ds) } while (action != NULL) { + StartAscon(devser); status = AsconTask(devser->ascon); + AsconLog(devser); if (status == AsconFailure) { replyData = AsconGetError(devser->ascon); + /** + * TODO: this may be a place to record the end time + */ + if(devser->startTime > 0){ + LogResponse(devser,1); + } else { + /* This is a follow up error and should not go into statistics */ + } } else if (status == AsconReady) { replyData = AsconRead(devser->ascon); + if(replyData != NULL){ + LogResponse(devser,0); + } } else { - return 1; + return 1; } if (devser->steps > 0) { /* debugging mode */ devser->steps--; @@ -169,6 +268,7 @@ static int DevQueueTask(void *ds) sendData = action->hdl(action->data, replyData, (status == AsconFailure)); if (sendData != NULL) { AsconWrite(devser->ascon, sendData, 0); + LogStart(devser); return 1; } if (devser->killCurrent) { @@ -200,6 +300,7 @@ DevSer *DevMake(SConnection * con, int argc, char *argv[]) devser->actions = NULL; devser->toKill = NULL; devser->steps = -1; /* no debugging by default */ + devser->startTime = -1; TaskRegister(pServ->pTasker, DevQueueTask, NULL, NULL, devser, 0); return devser; } diff --git a/devser.h b/devser.h index 4c30bc23..d0f14a35 100644 --- a/devser.h +++ b/devser.h @@ -162,4 +162,23 @@ DevPrio DevText2Prio(char *text); */ char * DevList(DevSer * devser); +/** + * \brief Get statistics + * \param devser The device serializer + * \param avg The average response time + * \param max The maximum response time + * \param errCount The count of communication errors detected so far. + * \param errFlag A flag if the device is in an error state or not + */ +void DevStatistics(DevSer *devser, double *avg, double *max, + long *errCount, int *errFlag); +/** + * \brief Get Ascon invocation statistics. This can help to stop + * blocking behaviour in protocol handlers. + * \param devser The device serializer to query + * \param avg The avgerage time spent in AsconTask invocations + * \param max The maximum time spent in a AsconTask call. + */ +void DevAsconStatistics(DevSer *self, double *avg, + double *max, int *maxState, int *longCount); #endif diff --git a/dynstring.c b/dynstring.c index a24136d4..873d076d 100644 --- a/dynstring.c +++ b/dynstring.c @@ -174,7 +174,27 @@ int DynStringConcatChar(pDynString self, char c) self->iTextLen++; return 1; } +/*---------------------------------------------------------------------------*/ +int DynStringConcatBytes(pDynString self, char *data, int datalen) +{ + int iRequested, iRet; + assert(self); + assert(self->iMAGIC == DYNMAGIC); + + iRequested = self->iTextLen + datalen; + if (iRequested >= self->iBufferSize) { + iRet = Resize(self, iRequested); + if (!iRet) { + return 0; + } + } + + memcpy(self->pBuffer + self->iTextLen,data,datalen); + self->iTextLen += datalen; + return 1; + +} /*---------------------------------------------------------------------------*/ int DynStringInsert(pDynString self, char *pText, int iPos) { diff --git a/dynstring.h b/dynstring.h index cc44feb8..d61694de 100644 --- a/dynstring.h +++ b/dynstring.h @@ -54,7 +54,10 @@ int DynStringConcatChar(pDynString self, char c); /* adds one character at the end of the string */ - +int DynStringConcatBytes(pDynString self, char *data, int datalen); +/* + * adds datalen bytes from data to the buffer + */ int DynStringInsert(pDynString self, char *pText, int iPos); /* diff --git a/exebuf.c b/exebuf.c index 665fbd3f..905c9118 100644 --- a/exebuf.c +++ b/exebuf.c @@ -217,7 +217,6 @@ int exeBufProcess(pExeBuf self, SicsInterp * pSics, /* print only SICS commands */ SCPrintf(pCon, eLog, "%s:%d>> %s", self->name, self->lineno, cmd); - WriteCommandHistory(cmd); } else { /* debugging */ /* SCPrintf(pCon, eValue, "%s:%d>> %s",self->name,self->lineno,cmd); */ diff --git a/fourmess.c b/fourmess.c index 19c95df2..f9e7eae5 100644 --- a/fourmess.c +++ b/fourmess.c @@ -729,6 +729,10 @@ static int GenIndex(pSICSOBJ self, SConnection * pCon, pHdb commandNode, AddRefIdx(priv->messList, hkl); count++; } + if(SCGetInterrupt(pCon) != eContinue){ + SCWrite(pCon,"ERROR: reflection generation aborted", eError); + return 0; + } } } } @@ -768,6 +772,10 @@ static int GenInconsumerate(pSICSOBJ self, SConnection * pCon, hkl[j] -= qvec[j]; } AddRefIdx(priv->messList, hkl); + if(SCGetInterrupt(pCon) != eContinue){ + SCWrite(pCon,"ERROR: generating incommensurate reflections aborted", eError); + return 0; + } } SCPrintf(pCon, eValue, "%d additional inconsumerate reflections generated", diff --git a/genbinprot.c b/genbinprot.c new file mode 100644 index 00000000..e24d1e09 --- /dev/null +++ b/genbinprot.c @@ -0,0 +1,154 @@ +/* + * genbinprot.c + * + * This is a generic binary protocol handler for scriptcontext. It expects a + * command of the form: + * + * writepointer:writecount:readpointer:readcount + * + * And will writecount bytes from the data area writepointer and + * read readcount bytes into the memory area under readpointer. + * If writecount is 0, the nothing will be written. This can + * be used to read a binary message in parts. Both writepointer and + * readpointer are memory addresses in hexadecimal. + * + * This is a workaround for the essential weakness of devser not being + * able to work with binary protocols. + * + * Created on: Jul 7, 2010 + * Author: koennecke + */ +#include +#include +#include +#include +#include +#include + +/*-----------------------------------------------------------------*/ +typedef struct { + char *writePointer; + unsigned int toWrite; + char *readPointer; + unsigned int readCount; + unsigned int toRead; +}GenBin, *pGenBin; +/*------------------------------------------------------------------*/ +static void initGenBin(Ascon *a) +{ + pGenBin self = (pGenBin)a->private; + char *pPtr = NULL, pToken[60]; + long lval; + + pPtr = GetCharArray(a->wrBuffer); + + pPtr = stptok(pPtr,pToken,60,":"); + sscanf(pToken,"%lx",&lval); + self->writePointer = (char *)lval; + + pPtr = stptok(pPtr,pToken,60,":"); + sscanf(pToken,"%d",&self->toWrite); + + pPtr = stptok(pPtr,pToken,60,":"); + sscanf(pToken,"%lx",&lval); + self->readPointer = (char *)lval; + + pPtr = stptok(pPtr,pToken,60,":"); + sscanf(pToken,"%d",&self->toRead); + + a->wrPos = 0; + self->readCount = 0; +} +/*------------------------------------------------------------------*/ +static int GenBinHandler(Ascon *a) +{ + pGenBin self = (pGenBin)a->private; + unsigned int toWrite; + int ret; + char chr; + + switch(a->state){ + case AsconWriteStart: + AsconReadGarbage(a->fd); + initGenBin(a); + a->state = AsconWriting; + break; + case AsconWriting: + toWrite = self->toWrite - a->wrPos; + if(toWrite == 0){ + a->state = AsconWriteDone; + } else { + ret = AsconWriteChars(a->fd, self->writePointer+a->wrPos, toWrite); + if (ret < 0) { + if (errno != EINTR && errno != EAGAIN) { + AsconError(a, "send failed:", errno); + } + } else { + a->wrPos += ret; + if(a->wrPos >= self->toWrite){ + a->state = AsconWriteDone; + } + } + } + break; + case AsconReading: + if(self->readCount >= self->toRead){ + a->state = AsconReadDone; + DynStringCopy(a->rdBuffer,"OK"); + } else { + 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(); + self->readPointer[self->readCount] = chr; + self->readCount++; + } 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 GenBinInit(Ascon * a, SConnection * con, int argc, char *argv[]) +{ + pGenBin priv = NULL; + + priv = calloc(sizeof(GenBin), 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 AddGenBinProtocoll() +{ + AsconProtocol *prot = NULL; + + prot = calloc(sizeof(AsconProtocol), 1); + prot->name = strdup("genbin"); + prot->init = GenBinInit; + prot->handler = GenBinHandler; + AsconInsertProtocol(prot); +} diff --git a/hipadaba.c b/hipadaba.c index 20a95ab6..58437c0b 100644 --- a/hipadaba.c +++ b/hipadaba.c @@ -448,7 +448,81 @@ void ReleaseHdbValue(hdbValue * v) break; } } +/*-----------------------------------------------------------------------------*/ +static unsigned short fletcher16( char *data, size_t len) +{ + unsigned short sum1 = 0xff, sum2 = 0xff, result; + unsigned char checkA, checkB; + if(data == NULL){ + return 0; + } + while (len) { + size_t tlen = len > 21 ? 21 : len; + len -= tlen; + do { + sum1 += *data++; + sum2 += sum1; + } while (--tlen); + sum1 = (sum1 & 0xff) + (sum1 >> 8); + sum2 = (sum2 & 0xff) + (sum2 >> 8); + } + /* Second reduction step to reduce sums to 8 bits */ + sum1 = (sum1 & 0xff) + (sum1 >> 8); + sum2 = (sum2 & 0xff) + (sum2 >> 8); + checkA = (unsigned char)sum1; + checkB = (unsigned char)sum2; + result = checkA; + result = result << 8 | checkB; + return result ; +} +/*------------------------------------------------------------------------*/ +unsigned short getHdbCheckSum(hdbValue *val) +{ + char *data; + size_t len; + + len = getHdbValueLength(*val); + switch (val->dataType) { + case HIPNONE: + return 0; + break; + case HIPINT: + data = (char *)&val->v.intValue; + return fletcher16(data,len); + break; + case HIPFLOAT: + data = (char *)&val->v.doubleValue; + return fletcher16(data,len); + break; + case HIPTEXT: + data = val->v.text; + return fletcher16(data,len); + break; + case HIPINTAR: + case HIPINTVARAR: + data = (char *)val->v.intArray; + return fletcher16(data,len); + break; + case HIPFLOATAR: + case HIPFLOATVARAR: + data = (char *)val->v.floatArray; + return fletcher16(data,len); + break; + case HIPOBJ: + data = (char *)val->v.obj; + return fletcher16(data,len); + break; + case HIPFUNC: + data = (char *)val->v.func; + return fletcher16(data,len); + break; + default: + assert(0); + break; + } + return 0; +} /*------------------------------------------------------------------------*/ int compareHdbValue(hdbValue v1, hdbValue v2) { @@ -457,6 +531,12 @@ int compareHdbValue(hdbValue v1, hdbValue v2) if (v1.dataType != v2.dataType) { return 0; } + + if((v1.doNotFree == 1 && v1.v.obj == NULL) + || (v2.doNotFree == 1 && v2.v.obj == NULL)){ + return 0; + } + switch (v1.dataType) { case HIPNONE: return 0; @@ -971,12 +1051,17 @@ int NotifyHipadabaPar(pHdb node, void *callData) int GetHipadabaPar(pHdb node, hdbValue *v, void *callData) { int status; + unsigned short checksum; memset(v,0,sizeof(hdbValue)); v->dataType = node->value.dataType; + checksum = getHdbCheckSum(&node->value); status = SendDataMessage(node, get, v, callData); copyHdbValue(&node->value, v); + if(getHdbCheckSum(&node->value) != checksum){ + NotifyHipadabaPar(node, callData); + } if (status != 1) { return status; } diff --git a/hipadaba.h b/hipadaba.h index d7047576..29523287 100644 --- a/hipadaba.h +++ b/hipadaba.h @@ -253,6 +253,12 @@ int cloneHdbValue(hdbValue * source, hdbValue * clone); * @return the number of data bytes */ int getHdbValueLength(hdbValue v); +/** + * calculate a checksum of the data in val + * @param val The hdbValue to calcululate the checksum for + * @return The checksum + */ +unsigned short getHdbCheckSum(hdbValue *val); /*========================== function protoypes: Nodes =======================*/ /** * make a new hipadaba node diff --git a/logger.c b/logger.c index 4353bb83..1715029f 100644 --- a/logger.c +++ b/logger.c @@ -227,7 +227,9 @@ int LoggerWrite0(Logger * log, time_t now, int period, char *value) } assert(log->old); assert(l < log->oldsize); - strcpy(log->old, value); + if(log->old != value){ + strcpy(log->old, value); + } assert(log->old[l] == '\0'); log->last = now; return 1; diff --git a/macro.c b/macro.c index c58f7c1e..63cd295d 100644 --- a/macro.c +++ b/macro.c @@ -118,33 +118,6 @@ int MacroPop(void) } return 1; } -/*--------------------------------------------------------------------------- - * This is to suppress certain stuff from the history log in order to stop it - * from filling with garbage - -----------------------------------------------------------------------------*/ -static int historyFilter(pDummy pDum, char *command, char *fullCommand) -{ - static char *toRemove[] = {"sct", "hupdate",NULL}; - static char *typeRemove[] = {"ScriptContext",NULL}; - int i = 0; - - while(toRemove[i] != NULL){ - if(strcmp(command,toRemove[i]) == 0){ - return 0; - } - i++; - } - - i = 0; - while(typeRemove[i] != NULL){ - if(strcmp(pDum->pDescriptor->name, typeRemove[i]) == 0) { - return 0; - } - i++; - } - - return 1; -} /*---------------------------------------------------------------------------*/ static int SicsUnknownProc(ClientData pData, Tcl_Interp * pInter, int argc, char *argv[]) @@ -155,7 +128,7 @@ static int SicsUnknownProc(ClientData pData, Tcl_Interp * pInter, SicsInterp *pSinter = NULL; SConnection *pCon = NULL; CommandList *pCommand = NULL; - char *lastCommand = NULL, comBuffer[132], comHistory[256]; + char *lastCommand = NULL, comBuffer[132]; int iRet = 0, i; int iMacro; Statistics *old; @@ -216,18 +189,6 @@ static int SicsUnknownProc(ClientData pData, Tcl_Interp * pInter, StatisticsEnd(old); SCsetMacro(pCon, iMacro); - if(iRet == 1){ - /* - * this is OK because comBuffer is length restricted - */ - strcpy(comHistory,"SICSUNKNOWN: "); - strcat(comHistory,comBuffer); - /* This gives just to many unwanted entries.... TODO: Filter better - if(historyFilter(pCommand->pData, myarg[0], comBuffer) == 1){ - WriteCommandHistory(comHistory); - } - */ - } /* lastUnkown gets deeply stacked with each SICS command exec'd. This is not reflected in code. However, lastUnknown has already @@ -240,6 +201,7 @@ static int SicsUnknownProc(ClientData pData, Tcl_Interp * pInter, /* finish */ if (iRet == 1) { + WriteCommandHistory(comBuffer); return TCL_OK; } else { Tcl_SetVar(pInter, SICSERROR, "yes", TCL_GLOBAL_ONLY); @@ -989,7 +951,9 @@ static int TclAction(SConnection * pCon, SicsInterp * pSics, void *pData, return 0; } Tcl_ResetResult(pTcl); + SetWriteHistory(0); iRet = Tcl_Eval(pTcl, pCommand); + SetWriteHistory(1); if (iRet == TCL_OK) { if (strlen(pTcl->result) > 0) { SCPrintf(pCon, eValue, "%s", pTcl->result); diff --git a/make_gen b/make_gen index 6c3c41c5..9acf4d4d 100644 --- a/make_gen +++ b/make_gen @@ -41,7 +41,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \ sgclib.o sgfind.o sgio.o sgsi.o sghkl.o singlediff.o singlebi.o \ singlenb.o simindex.o simidx.o uselect.o singletas.o motorsec.o \ rwpuffer.o asynnet.o background.o countersec.o hdbtable.o velosec.o \ - histmemsec.o sansbc.o sicsutil.o strlutil.o + histmemsec.o sansbc.o sicsutil.o strlutil.o genbinprot.o MOTOROBJ = motor.o simdriv.o COUNTEROBJ = countdriv.o simcter.o counter.o diff --git a/motorsec.c b/motorsec.c index dffc1fa2..7cf48223 100644 --- a/motorsec.c +++ b/motorsec.c @@ -96,16 +96,26 @@ static long SecMotorRun(void *sulf, SConnection * pCon, float fNew) { pMotor self = (pMotor) sulf; hdbValue v; - int accesscode; + int accesscode, status; + pHdb node = NULL; assert(SICSHdbGetPar(self, NULL, "accesscode", &v) == 1); accesscode = (int)v.v.doubleValue; if(!SCMatchRights(pCon, accesscode)){ return 0; } + self->stopped = 0; v = MakeHdbFloat(fNew); - return SetHipadabaPar(self->pDescriptor->parNode, v, pCon); + status = SetHipadabaPar(self->pDescriptor->parNode, v, pCon); + node = GetHipadabaNode(self->pDescriptor->parNode, "status"); + if(node != NULL){ + v = MakeHdbText(strdup("run")); + UpdateHipadabaPar(node,v,pCon); + ReleaseHdbValue(&v); + } + + return status; } /*--------------------------------------------------------------------------*/ @@ -299,7 +309,9 @@ static int SecMotorStatus(void *sulf, SConnection * pCon) if (SCGetInterrupt(pCon) < (int) interrupt) { SCSetInterrupt(pCon, (int) interrupt); } - self->errorCount++; + if(self->stopped == 0) { + self->errorCount++; + } break; case HWIdle: self->posCount = 10000; diff --git a/network.c b/network.c index eae0cea1..afe60a3f 100644 --- a/network.c +++ b/network.c @@ -626,7 +626,9 @@ int NETReadTillTerm(mkChannel * self, long timeout, } } } else { - /* this is for accepting a terminator consisting of multiple characters, pTerm[0] is & */ + /* this is for accepting a terminator consisting of multiple characters, pTerm[0] is & + * There is evidence that this code is broken. M.K. + */ if (matchIndex == 1 && c == pTerm[1]) { matchIndex++; } else { diff --git a/nread.c b/nread.c index 549f6db5..faa00402 100644 --- a/nread.c +++ b/nread.c @@ -1007,13 +1007,13 @@ static void killCommandCBData(void *data) /*----------------------------------------------------------------------------------*/ static int testAndInvokeInterrupt(pCommandCBData self, int handle) { - char *pPtr; + char *pPtr, *pInt; char buffer[512]; int iInt; pPtr = GetCharArray(self->command); - if (strstr(pPtr, "INT1712") != NULL) { - sscanf(pPtr, "%s %d", buffer, &iInt); + if ((pInt = strstr(pPtr, "INT1712")) != NULL) { + sscanf(pInt, "%s %d", buffer, &iInt); if (SCMatchRights(self->pCon, usUser)) { TaskSignal(pServ->pTasker, SICSINT, &iInt); snprintf(buffer, 512, "INTERRUPT %d issued on sock %d", diff --git a/nserver.c b/nserver.c index 37364fe3..3ab906f9 100644 --- a/nserver.c +++ b/nserver.c @@ -37,6 +37,7 @@ #include "tcldrivable.h" #include "nserver.h" #include "sicshipadaba.h" +#include "commandlog.h" int ServerSetupInterrupt(int iPort, pNetRead pNet, pTaskMan pTasker); /* @@ -122,6 +123,7 @@ int InitServer(char *file, pServer * pServ) NetWatchInit(); /* initialise the server from script */ + SetWriteHistory(0); if (file == NULL) { iRet = InitObjectCommands(self, DEFAULTINIFILE); } else { @@ -259,6 +261,7 @@ int InitServer(char *file, pServer * pServ) strcpy(pBueffel, "restore"); SCInvoke(self->dummyCon, self->pSics, pBueffel); } + SetWriteHistory(1); INIT(StatusFileInit); diff --git a/ofac.c b/ofac.c index a40791f9..16202525 100644 --- a/ofac.c +++ b/ofac.c @@ -40,6 +40,7 @@ static void InitGeneral(void) INIT(UdpInit); INIT(HelpInit); INIT(AddTestProt); + INIT(AddGenBinProtocoll); INIT(SiteInit); /* site specific initializations */ } diff --git a/polldriv.c b/polldriv.c index 0c800eab..de89f650 100644 --- a/polldriv.c +++ b/polldriv.c @@ -28,20 +28,17 @@ static int timeDue(struct __POLLDRIV *self, time_t now, SConnection * pCon) /*------------------ HDB Driver -----------------------------------------*/ static int pollHdb(struct __POLLDRIV *self, SConnection * pCon) { - hdbValue old, newVal; + hdbValue newVal; pHdb node = NULL; - memset(&old, 0, sizeof(hdbValue)); memset(&newVal, 0, sizeof(hdbValue)); node = (pHdb) self->objPointer; + assert(node != NULL); - old = node->value; + self->nextPoll = time(NULL) + self->pollIntervall; if (GetHipadabaPar(node, &newVal, pCon) == 1) { - if (!compareHdbValue(old, newVal)) { - UpdateHipadabaPar(node, newVal, pCon); - } - ReleaseHdbValue(&newVal); + ReleaseHdbValue(&newVal); return 1; } else { return 0; diff --git a/scriptcontext.c b/scriptcontext.c index c62e0110..e8608cc0 100644 --- a/scriptcontext.c +++ b/scriptcontext.c @@ -366,6 +366,9 @@ static char *SctActionHandler(void *actionData, char *lastReply, if (!commError && controller->verbose && lastReply != NULL && *lastReply != '\0') { SCPrintf(con, eLog, "%6.3f reply : %s\n", secondsOfMinute(), lastReply); + /** + * TODO: This is the end place of any communication for statistics measurement + */ } /* @@ -413,17 +416,20 @@ static char *SctActionHandler(void *actionData, char *lastReply, /* * an error occurred in the script: store error message in * a property, and write the error message the first time it - * occurs + * occurs. + * + * Replaced <> by - because it messed up XML for Gumtree + * Mark Koennecke */ snprintf(eprop, sizeof eprop, "error_during_%s", data->name); emsg = GetHdbProp(node, eprop); if (emsg == NULL || con != controller->conn) { GetHdbPath(node, path, sizeof path); SCPrintf(con, eError, - "ERROR: action <%s> in {%s} node %s:\nERROR: %s", + "ERROR: action - %s - in {%s} node %s:\nERROR: %s", data->name, origScript, path, result); } - snprintf(msg, sizeof msg, "<%s> %s", origScript, result); + snprintf(msg, sizeof msg, "- %s - %s", origScript, result); if (strcasecmp(data->name, "read") == 0) { SetHdbProperty(node, "geterror", result); } @@ -476,7 +482,7 @@ static char *SctActionHandler(void *actionData, char *lastReply, if (emsg != NULL) { GetHdbPath(node, path, sizeof path); SCPrintf(con, eError, - "action <%s>: success after error message (%s)\n %s", + "action - %s -: success after error message (%s)\n %s", data->name, path, emsg); SetHdbProperty(node, eprop, NULL); } @@ -504,6 +510,9 @@ static char *SctActionHandler(void *actionData, char *lastReply, if (controller->verbose) { SCPrintf(con, eLog, "%6.3f send : %s", secondsOfMinute(), send); } + /** + * TODO: this is another point where to introduce statistics, this is the start + */ return send; } } @@ -1071,6 +1080,7 @@ static int SctQueueCmd(pSICSOBJ ccmd, SConnection * con, typedef struct SctTransact { char *command; + char *reply; int sent; SConnection *con; SctController *controller; @@ -1085,6 +1095,9 @@ static void KillSctTransact(void *data) if (self->command) { free(self->command); } + if (self->reply) { + free(self->reply); + } if (self->con) { SCDeleteConnection(self->con); } @@ -1107,7 +1120,9 @@ static char *TransactionHandler(void *actionData, char *lastReply, if (st->controller->verbose) { SCPrintf(st->con, eLog, "%6.3f reply : %s", secondsOfMinute(), lastReply); } - SCWrite(st->con, lastReply, eValue); + /* printf("Transact: %s got %s\n", st->command, lastReply); */ + + st->reply = strdup(lastReply); return NULL; } } @@ -1141,6 +1156,11 @@ static int SctTransactCmd(pSICSOBJ ccmd, SConnection * con, break; } } + if(st->reply != NULL){ + SCWrite(con,st->reply,eValue); + } else { + SCWrite(con,"ERROR: no reply!",eError); + } KillSctTransact(st); return 1; } @@ -1207,6 +1227,31 @@ static int SctListActions(pSICSOBJ ccmd, SConnection * con, return 1; } +static int SctStatistics(pSICSOBJ ccmd, SConnection * con, + Hdb * cmdNode, Hdb * par[], int nPar) +{ + SctController *c; + double avg, max; + long errCount; + int errState, maxState, maxCount; + char state[16]; + + c = (SctController *) ccmd->pPrivate; + DevStatistics(c->devser,&avg, &max, &errCount, &errState); + if(errState == 1){ + strcpy(state,"in error"); + } else { + strcpy(state,"good"); + } + SCPrintf(con,eValue,"Average roundtrip time: %lf, maximum roundtrip time %lf, com error count: %ld, com state: %s", + avg, max, errCount, state); + DevAsconStatistics(c->devser,&avg, &max, &maxState, &maxCount); + SCPrintf(con,eValue,"Average time in AsconTask: %lf, maximum time spent in AsconTask %lf, state of Ascon on max %d, count > max/2 %d", + avg, max, maxState, maxCount); + + return 1; +} + static hdbCallbackReturn SctDebugCallback(Hdb * node, void *userData, hdbMessage * msg) { @@ -1369,6 +1414,9 @@ static int SctMakeController(SConnection * con, SicsInterp * sics, cmd = AddSICSHdbPar(controller->node, "actions", usUser, MakeSICSFunc(SctListActions)); + cmd = AddSICSHdbPar(controller->node, + "statistics", usSpy, MakeSICSFunc(SctStatistics)); + cb = MakeHipadabaCallback(SctDebugCallback, controller, NULL); if (cb) AppendHipadabaCallback(par, cb); diff --git a/sicscron.c b/sicscron.c index 0be410c7..5ba9ff12 100644 --- a/sicscron.c +++ b/sicscron.c @@ -7,6 +7,8 @@ copyright: see copyright.h Mark Koennecke, November 1999 + + modified to give more error output: Mark Koennecke, December 2010 ------------------------------------------------------------------------*/ #include #include @@ -16,7 +18,7 @@ #include "sics.h" #include "splitter.h" #include "sicscron.h" - +#include "commandlog.h" typedef struct { int iInterval; @@ -61,6 +63,8 @@ static int CronTask(void *pData) int iRet; Tcl_Interp *pTcl = pServ->pSics->pTcl; time_t now; + struct tm *nowtm; + char buffer[1024]; if (!self) { return 0; @@ -75,14 +79,16 @@ static int CronTask(void *pData) MacroPop(); if (iRet != TCL_OK) { if (strcmp(pTcl->result, "stop") == 0) { - SCPrintf(self->pCon, eLogError, "sicscron script '%s' stopped", - self->pCommand); + snprintf(buffer,1024,"sicscron script '%s' stopped with %s", + self->pCommand, pTcl->result); + SCPrintf(self->pCon, eLogError, buffer); + WriteToCommandLog("SICSCRON:", buffer); self->iEnd = 0; return 0; } - SCPrintf(self->pCon, eLogError, - "ERROR in sicscron script '%s':", self->pCommand); - SCPrintf(self->pCon, eLogError, "ERROR: %s", pTcl->result); + snprintf(buffer,1024,"ERROR in sicscron script '%s': %s", self->pCommand, pTcl->result); + SCPrintf(self->pCon, eLogError,buffer); + WriteToCommandLog("SICSCRON:", buffer); } if (self->iEnd == 2) { /* dolater command */ self->iEnd = 0; @@ -92,6 +98,11 @@ static int CronTask(void *pData) if (now > self->tNext) self->tNext = now + 1; } +/* printf("CronTask return: %d\n", self->iEnd > 0);*/ + if(self->iEnd <= 0){ + snprintf(buffer,1024,"crontask terminating at %s on %d", ctime(&now), self->iEnd); + WriteToCommandLog("SICSCRON", buffer); + } return self->iEnd > 0; } @@ -106,7 +117,7 @@ static void CronSignal(void *pData, int iID, void *pSigData) if (iID == SICSINT) { iInt = (int *) pSigData; - if (*iInt >= eEndServer) { + if (*iInt == eEndServer) { self->iEnd = 0; } } diff --git a/sicshdbadapter.c b/sicshdbadapter.c index 3605d49f..e9114fee 100644 --- a/sicshdbadapter.c +++ b/sicshdbadapter.c @@ -337,7 +337,6 @@ static long totalSum(int *data, int length) /*----------------------------------------------------------------------*/ typedef struct { pHistMem pHM; - long oldSum; } HMAdapter, *pHMAdapter; /*-------------------------------------------------------------------------*/ static hdbCallbackReturn HMDataGetCallback(pHdb currentNode, @@ -360,14 +359,7 @@ static hdbCallbackReturn HMDataGetCallback(pHdb currentNode, currentNode->value.arrayLength = GetHistLength(pHMA->pHM); currentNode->value.v.intArray = (int *) GetHistogramPointer(pHMA->pHM, pCon); - sum1 = - totalSum(currentNode->value.v.intArray, - currentNode->value.arrayLength); - if (sum1 != pHMA->oldSum) { - UpdateHipadabaPar(currentNode, currentNode->value, NULL); - pHMA->oldSum = sum1; - } - return hdbContinue; + return hdbContinue; } /*----------------------------------------------------------------------*/ @@ -377,14 +369,14 @@ static pHdb MakeHMDataNode(pHistMem pHM, char *name) pHdbCallback pCall = NULL; pHMAdapter pHMA = NULL; - node = MakeHipadabaNode(name, HIPINTVARAR, 2); + node = MakeHipadabaNode(name, HIPINTVARAR, GetHistLength(pHM)); pHMA = malloc(sizeof(HMAdapter)); if (node == NULL || pHMA == NULL) { return NULL; } pHMA->pHM = pHM; - pHMA->oldSum = 0; node->value.doNotFree = 1; + node->value.v.intArray = (int *)GetHistogramPointer(pHM, pServ->dummyCon); pCall = MakeHipadabaCallback(HMDataGetCallback, pHMA, free); if (pCall == NULL) { return NULL; diff --git a/sicshipadaba.c b/sicshipadaba.c index 21532af7..4ec7e9bc 100644 --- a/sicshipadaba.c +++ b/sicshipadaba.c @@ -34,6 +34,7 @@ #include #include "sicsobj.h" #include +#include "commandlog.h" #define MAX_HDB_PATH 1024 @@ -828,7 +829,9 @@ static hdbCallbackReturn SICSScriptReadCallback(pHdb node, void *userData, if (pCon != NULL) { MacroPush(pCon); } + SetWriteHistory(0); status = Tcl_Eval(InterpGetTcl(pServ->pSics), command); + SetWriteHistory(1); if (pCon != NULL) { MacroPop(); } diff --git a/sicsstat.tcl b/sicsstat.tcl index c4461394..4f286674 100644 --- a/sicsstat.tcl +++ b/sicsstat.tcl @@ -1,60 +1,13 @@ exe batchpath ./ exe syspath ./ -sample -sample setAccess 2 -title -title setAccess 2 -user -user setAccess 2 -email unknown -email setAccess 2 -address unknown -address setAccess 2 -fax unknown -fax setAccess 2 -phone unknown -phone setAccess 2 -# Motor som -som sign 1.000000 -som SoftZero 0.000000 -som SoftLowerLim -180.000000 -som SoftUpperLim 180.000000 -som Fixed -1.000000 -som InterruptMode 0.000000 -som precision 0.010000 -som ignorefault 0.000000 -som AccessCode 2.000000 -som failafter 3.000000 -som maxretry 3.000000 -som movecount 10.000000 -# Motor stt -stt sign 1.000000 -stt SoftZero 0.000000 -stt SoftLowerLim 0.000000 -stt SoftUpperLim 120.000000 -stt Fixed -1.000000 -stt InterruptMode 0.000000 -stt precision 0.010000 -stt ignorefault 0.000000 -stt AccessCode 2.000000 -stt failafter 3.000000 -stt maxretry 3.000000 -stt movecount 10.000000 -# Motor dth -dth sign 1.000000 -dth SoftZero 0.000000 -dth SoftLowerLim 0.000000 -dth SoftUpperLim 200.000000 -dth Fixed -1.000000 -dth InterruptMode 0.000000 -dth precision 0.010000 -dth ignorefault 0.000000 -dth AccessCode 2.000000 -dth failafter 3.000000 -dth maxretry 3.000000 -dth movecount 10.000000 + +#--- BEGIN (commands producing errors on last restore) +#--- END (commands producing errors on last restore) + # Counter counter -counter SetPreset 1000.000000 +counter SetPreset 7.000000 counter SetMode Timer -hm CountMode timer -hm preset 3.000000 +hm preset 7 +hm mode monitor +title UNKNOWN +title setAccess 2 diff --git a/singletas.c b/singletas.c index 00d9c887..7c20613c 100644 --- a/singletas.c +++ b/singletas.c @@ -48,7 +48,7 @@ static int calculateTASSettings(pSingleDiff self, return 0; } - status = calcTasQAngles(self->UB, mn, 1, qe, &angles); + status = calcTasQAngles(self->UB, mn, 1,0, qe, &angles); if (status < 0) { status = 0; } else { diff --git a/singlex.c b/singlex.c index 5a9453de..10b238f6 100644 --- a/singlex.c +++ b/singlex.c @@ -665,7 +665,7 @@ int MakeSingleX(SConnection * pCon, SicsInterp * pSics, if (AddCommand(pSics, "singlex", SingleXAction, KillSICSOBJ, pNew)) { HKLFactory(pCon, pSics, data, argc, argv); HKLMotInstall(pCon, pSics, data, argc, argv); - CreateUBCalc(pCon, pSics, "ubcalc", "hkl"); + CreateUBCalc(pCon, pSics, "ubcalcint", "hkl"); InstallFourMess(pCon, pSics); MakeCone(pCon, pSics, data, argc, argv); InitSimpleIndex(pCon, pSics); diff --git a/stdscan.c b/stdscan.c index 2b7e44ae..c177c245 100644 --- a/stdscan.c +++ b/stdscan.c @@ -524,7 +524,7 @@ int WriteScanPoints(pScanData self, int iPoint) DynarGet(self->pScanVar, i2, &pPtr); pVar = (pVarEntry) pPtr; if (pVar) { - snprintf(pItem,sizeof(pItem)-1, "%-9.3f ", GetScanVarPos(pVar, i)); + snprintf(pItem,sizeof(pItem)-1, "%-9.4f ", GetScanVarPos(pVar, i)); strlcat(pLine, pItem,1024); } } diff --git a/tasdrive.c b/tasdrive.c index 36e842c4..c2e12494 100644 --- a/tasdrive.c +++ b/tasdrive.c @@ -258,6 +258,7 @@ static int startTASMotor(pMotor mot, SConnection * pCon, char *name, SCWrite(pCon, buffer, eWarning); return OKOK; } + mot->stopped = 0; if (ABS(val - target) > MOTPREC) { status = mot->pDrivInt->SetValue(mot, pCon, (float) target); if (status != OKOK) { @@ -524,7 +525,7 @@ static int checkMotors(ptasMot self, SConnection * pCon) for (i = 0; i < length; i++) { mask[i] = 1; } - if (self->math->outOfPlaneAllowed != 0) { + if (self->math->outOfPlaneAllowed == 0) { mask[SGU] = 0; mask[SGL] = 0; } diff --git a/tasub.c b/tasub.c index 8e8dd87a..9948e276 100644 --- a/tasub.c +++ b/tasub.c @@ -1857,7 +1857,7 @@ int TasUBWrapper(SConnection * pCon, SicsInterp * pSics, void *pData, ptasUB self = NULL; char pBueffel[131]; int status, newSS; - double misalign = .0; + double misalign = .0, a3offset; self = (ptasUB) pData; assert(self != NULL); @@ -2039,6 +2039,28 @@ int TasUBWrapper(SConnection * pCon, SicsInterp * pSics, void *pData, SCWrite(pCon, pBueffel, eValue); return 1; } + } else if (strcmp(argv[1], "a3offset") == 0) { + if (argc > 2) { + strtolower(argv[2]); + if (!SCMatchRights(pCon, usMugger)) { + return 0; + } + status = Tcl_GetDouble(InterpGetTcl(pSics), argv[2], &a3offset); + if (status != TCL_OK) { + SCWrite(pCon, "ERROR: failed to convert argument to number", + eError); + return 0; + } + self->machine.a3offset = a3offset; + invokeUpdate(self,pCon,"main"); + SCSendOK(pCon); + return 1; + } else { + snprintf(pBueffel, 131, "%s.a3offset = %lf", argv[0], + self->machine.a3offset); + SCWrite(pCon, pBueffel, eValue); + return 1; + } } else if (strcmp(argv[1], "silent") == 0) { if (argc > 2) { strtolower(argv[2]); diff --git a/tasublib.c b/tasublib.c index 73795334..cd7f2cff 100644 --- a/tasublib.c +++ b/tasublib.c @@ -540,8 +540,8 @@ int calcTasMisalignment(ptasMachine machine, tasQEPosition qe, double *misalign } /*-------------------------------------------------------------------------------*/ -int calcTasQAngles(MATRIX UB, MATRIX planeNormal, int ss, tasQEPosition qe, - ptasAngles angles) +int calcTasQAngles(MATRIX UB, MATRIX planeNormal, int ss, double a3offset, + tasQEPosition qe, ptasAngles angles) { MATRIX R, QC; double om, q, theta, cos2t; @@ -596,14 +596,14 @@ int calcTasQAngles(MATRIX UB, MATRIX planeNormal, int ss, tasQEPosition qe, theta = calcTheta(qe.ki, qe.kf, angles->sample_two_theta); - angles->a3 = om + theta; + angles->a3 = om + theta + a3offset; /* put a3 into -180, 180 properly. We can always turn by 180 because the scattering geometry is symmetric in this respect. It is like looking at the scattering plane from the other side */ angles->a3 -= 180.; - if (angles->a3 < -180.) { + if (angles->a3 < -180 - a3offset) { angles->a3 += 360.; } @@ -680,7 +680,8 @@ int calcAllTasAngles(ptasMachine machine, tasQEPosition qe, } status = calcTasQAngles(machine->UB, machine->planeNormal, - machine->ss_sample, qe, angles); + machine->ss_sample, + machine->a3offset, qe, angles); if (status != 1) { return status; } diff --git a/tasublib.h b/tasublib.h index 0915c3e4..f94e6f2c 100644 --- a/tasublib.h +++ b/tasublib.h @@ -53,6 +53,7 @@ typedef struct { MATRIX UB; MATRIX planeNormal; int ss_sample; /* scattering sense sample */ + double a3offset; } tasMachine, *ptasMachine; /** * a position in Q - Energy space @@ -178,12 +179,14 @@ MATRIX calcPlaneNormal(tasReflection r1, tasReflection r2); * @param UB The UB matrix to use * @param planeNormal The normal to the scattering plane to use * @param ss The scattering sense at the sample + * @param The Mark Laver offset to a3. 0 is always a good value for this * @param qe The desired Q Energy position * @param angles The resulting angles. * @return 1 on success, a negative error code when errors are encountered */ int calcTasQAngles(MATRIX UB, MATRIX planeNormal, - int ss, tasQEPosition qe, ptasAngles angles); + int ss, double a3offset, + tasQEPosition qe, ptasAngles angles); /** * calculate QH, QK, QL from the angles given * @param UB The UB matrix to use diff --git a/tcl/sinqhttp.tcl b/tcl/sinqhttp.tcl index 675a643e..15177d94 100644 --- a/tcl/sinqhttp.tcl +++ b/tcl/sinqhttp.tcl @@ -13,6 +13,11 @@ # copyright: see file COPYRIGHT # # Mark Koennecke, May 2009 +# +# You will need to override hmhttpevalstatus to implement +# an update of the detector data +# +# Mark Koennecke, April 2010 #--------------------------------------------------------- proc hmhttpsend {url} { sct send $url @@ -36,7 +41,7 @@ proc hmhttpreply {} { sct geterror $data clientput $data } else { - hdelprop [sct] geterror + hdelprop [sct] geterror } return idle } @@ -127,7 +132,7 @@ proc hmhttpevalstatus {name} { #--------------------------------------------------------- proc MakeHTTPHM {name rank host initscript {tof NULL} } { sicsdatafactory new ${name}transfer - makesctcontroller ${name}sct sinqhttp $host ${name}transfer 600 spy 007 + makesctcontroller ${name}sct sinqhttpopt $host ${name}transfer 600 spy 007 MakeSecHM $name $rank $tof hsetprop /sics/${name}/control write hmhttpcontrol hsetprop /sics/${name}/control hmhttpreply hmhttpreply diff --git a/test/DataNumber b/test/DataNumber index dc4b2aa0..591b2951 100644 --- a/test/DataNumber +++ b/test/DataNumber @@ -1,3 +1,3 @@ - 294 + 302 NEVER, EVER modify or delete this file You'll risk eternal damnation and a reincarnation as a cockroach! diff --git a/test/sicsstat.tcl b/test/sicsstat.tcl index cf80fb78..6d591f39 100644 --- a/test/sicsstat.tcl +++ b/test/sicsstat.tcl @@ -234,9 +234,9 @@ singlex peaksearch/chimin 90 singlex peaksearch/chimax 180 #HKL Settings hkl scantolerance 2.500000 -ubcalc difftheta 0.300000 -ubcalc maxindex 5 -ubcalc maxlist 10 +ubcalcint difftheta 0.300000 +ubcalcint maxindex 5 +ubcalcint maxlist 10 fmesstable clear messref anglesheader stt,om,chi,phi messref clear @@ -251,5 +251,7 @@ cone qscale 1 cone center unknown simidx sttlim 0.2 simidx anglim 0.5 +apple preset 0 +apple mode monitor simi preset 0 simi mode monitor diff --git a/test/testini.tcl b/test/testini.tcl index 2998ca98..366fe3d8 100644 --- a/test/testini.tcl +++ b/test/testini.tcl @@ -528,7 +528,7 @@ amorhmsct poll /sics/amorhm/collapse 20 #source ../sim/mars/julcho.tcl -MakeSinq +MakeSinqRedirect lnsl15 10500 MakeSingleX singlex configure stt a4 @@ -636,13 +636,13 @@ proc tofappleinit {} { set hmhttp 0 if {$hmhttp == 1} { source ../tcl/sinqhttp.tcl - MakeHTTPHM apple 1 hm02 appleinit +# MakeHTTPHM apple 1 hm01 appleinit # MakeHTTPHM apple 1 localhost:8080 appleinit - apple dim 16384 +# apple dim 16384 #---------- for TOF -# MakeHTTPHM apple 2 hm02 tofappleinit tof -# apple dim 16384 10 -# apple genbin 10 20 100 + MakeHTTPHM apple 2 hm01 tofappleinit tof + apple dim 16384 10 + apple genbin 10 20 100 applesct debug 0 apple init } @@ -752,3 +752,6 @@ zugsct debug 0 source ../tcl/stddrive.tcl source ../sim/poldi_sics/zug.tcl } + +#MakeSPSS7 s7 203 251 129.129.195.55:2005 +#MakeSPSS7 s7 203 251 localhost:8090 diff --git a/tmp/rafin.dat b/tmp/rafin.dat index b2ca3c5f..568235d8 100644 --- a/tmp/rafin.dat +++ b/tmp/rafin.dat @@ -1,19 +1,21 @@ -sample La Cu2 O4+x - 2 1 0 0 23. 5. 4 1 .5 0 - 0 2.3167 - 1 0.0 1 0.0 1 0.0 0 0.0 -1 5.32 1 5.40 1 13.18 0 90 0 90 0 90 --2 0 0 51.30 28.02 131.50 17.44 1773 - 0 0 2 20.58 13.91 182.04 289.68 1780 - 0 -2 0 51.23 25.61 140.29 197.69 1784 --2 -2 0 75.59 38.04 95.27 221.22 1787 --2 -2 2 79.32 40.26 108.56 272.88 1791 --2 0 4 68.20 34.42 144.68 323.66 1819 - 1 -1 3 48.02 24.08 185.50 236.97 1801 --2 2 0 75.82 37.79 174.43 15.78 1804 - 1 -1 1 37.50 18.65 185.79 211.98 1809 - 0 0 6 64.07 31.95 181.88 285.97 1812 - 0 0 8 89.90 42.93 181.81 284.09 1816 -1 0 0 -0 1 0 -1 0 0 + 1/3 1/3 2 map 5K, CuCrO2 +2 1 0 0 45 3 4 1 .5 0 +0 1.178 +0 .0 0 .0 0 .0 +0 2.9667 0 2.9667 0 17.3977 0 90 0 90 0 120 + 1.0000 1.0000 0.0000 46.742 23.322 182.960 178.382 + -1.0000 2.0000 0.0000 46.740 23.244 182.601 238.437 + 0.0000 0.0000 6.0000 23.867 11.737 92.919 77.023 + 0.0000 -2.0000 1.0000 54.687 27.298 173.003 28.437 + 0.0000 1.0000 1.0000 26.807 13.375 175.101 208.398 + 1.0000 0.0000 2.0000 27.727 13.848 165.785 149.054 + 0.0000 -1.0000 5.0000 33.282 16.614 140.921 28.625 + 1.0000 0.0000 5.0000 33.270 16.627 145.492 150.046 + -1.0000 1.0000 8.0000 41.915 20.725 131.535 265.171 + 1.0000 0.0000 8.0000 41.915 20.978 132.105 151.023 + 0.0000 2.0000 2.0000 55.172 27.515 174.425 208.367 + -2.0000 0.0000 2.0000 55.177 27.515 170.078 328.031 + 3.0000 0.0000 0.0000 86.800 43.319 181.531 148.375 + 0.0000 3.0000 0.0000 86.802 43.319 182.796 208.429 + +-1