diff --git a/cnvrt.c b/cnvrt.c new file mode 100644 index 0000000..0a1f040 --- /dev/null +++ b/cnvrt.c @@ -0,0 +1,105 @@ +#include +#include +#include +#include "sics.h" + +/* + * conversions: + * hex2float + * float2hex + * + * Markus Zolliker Aug 2010 + */ + +/*-------------------------------------------------------------------------*/ +void double2ieee(double input, char ieee[4]) +{ + +/* convert double to IEEE 32 bit floating number (denormalized numbers are considered as zero) */ + + long mantissa; + int exponent; + + if (input == 0) { + ieee[0] = 0; + ieee[1] = 0; + ieee[2] = 0; + ieee[3] = 0; + } else { + mantissa = 0x1000000 * (frexp(fabs(input), &exponent)); + exponent = exponent - 1 + 127; + if (exponent < 0) { + exponent = 0; + } else if (exponent > 0xFE) { + exponent = 0xFE; + } + if (input < 0) { + ieee[0] = 0x80 | (exponent >> 1); + } else { + ieee[0] = exponent >> 1; + } + ieee[1] = (exponent & 1) << 7 | ((mantissa & 0x7F0000) >> 16); + ieee[2] = (mantissa & 0xFF00) >> 8; + ieee[3] = mantissa & 0xFF; + } + return; +} + +/*-------------------------------------------------------------------------*/ +double ieee2double(char ieee[4]) +{ + +/* IEEE 32 bit floating number to double (denormalized numbers are considered as zero) */ + + long mantissa; + double output; + int exponent; + + mantissa = ((ieee[1] << 16) & 0x7FFFFF) + | ((ieee[2] << 8) & 0xFF00) + | ((ieee[3]) & 0xFF); + + exponent = (ieee[0] & 0x7F) * 2 + ((ieee[1] >> 7) & 1); /* raw exponent */ + if (exponent == 0 && mantissa == 0) { + return 0.0; + } + output = ldexp(mantissa, -23) + 1.0; + if (ieee[0] & 0x80) { + output = -output; + } + return output * ldexp(1, exponent - 127); +} + +/*-------------------------------------------------------------------------*/ +int CnvrtAction(SConnection *con, SicsInterp *sics, void *data, + int argc, char *argv[]) { + double f; + char ieee[4]; + char result[32]; + + if (argc != 3) goto Usage; + if (strcasecmp(argv[1], "float2xieee") == 0) { + double2ieee(atof(argv[2]), ieee); + SCPrintf(con, eValue, "%2.2x%2.2x%2.2x%2.2x", + ieee[0] & 0xFF, ieee[1] & 0xFF, ieee[2] & 0xFF, ieee[3] & 0xFF); + return 1; + } else if (strcasecmp(argv[1], "xieee2float") == 0) { + ieee[0]=0; + ieee[1]=0; + ieee[2]=0; + ieee[3]=0; + sscanf(argv[2], "%2hhx%2hhx%2hhx%2hhx", + ieee, ieee+1, ieee+2, ieee+3); + snprintf(result, sizeof result, "%.7g", ieee2double(ieee)); + if (strchr(result, '.') == NULL && strchr(result, 'e') == NULL) { + SCPrintf(con, eValue, "%s.", result); + } else { + SCWrite(con, result, eValue); + } + return 1; + } + Usage: + SCPrintf(con, eError, "ERROR: Usage: cnvrt float2xieee "); + SCPrintf(con, eError, " cnvrt xieee2float "); + return 0; +} diff --git a/cnvrt.h b/cnvrt.h new file mode 100644 index 0000000..e1f6df2 --- /dev/null +++ b/cnvrt.h @@ -0,0 +1,6 @@ +/* convert double to IEEE 32 bit floating number and vice versa + (denormalized numbers are considered as zero) */ + +void double2ieee(double input, char ieee[4]); +double ieee2double(char ieee[4]); + diff --git a/el734hp.c b/el734hp.c index d3083d5..9c923d7 100644 --- a/el734hp.c +++ b/el734hp.c @@ -85,6 +85,7 @@ static int transactEL734(prs232 self, void *send, int sendLen, { int status, len, oldTimeout; char *pReply = NULL; + char rubbish[2024]; /* try to read away rubbish on the line first @@ -92,8 +93,8 @@ static int transactEL734(prs232 self, void *send, int sendLen, oldTimeout = getRS232Timeout(self); setRS232Timeout(self, 0); if (availableRS232(self)) { - len = replylen; - readRS232(self, reply, &len); + len = sizeof(rubbish); + readRS232(self, rubbish, &len); } setRS232Timeout(self, oldTimeout); @@ -133,6 +134,7 @@ static void checkEmpty(pEL734Driv self, char *pReply, int *replylen) { int oldTimeout; + /* if (strlen(pReply) < 1) { oldTimeout = getRS232Timeout(self->controller); setRS232Timeout(self->controller, 0); @@ -141,6 +143,12 @@ static void checkEmpty(pEL734Driv self, char *pReply, int *replylen) } setRS232Timeout(self->controller, oldTimeout); } + */ + if (strlen(pReply) < 1) { + readRS232(self->controller, pReply, replylen); + /* printf("checkEmpty read %s\n", pReply); */ + } + } /*--------------------------------------------------------------------*/ @@ -329,6 +337,7 @@ static int EL734Status(void *pData) return HWFault; } + replyLen = 79; checkEmpty(self, pReply, &replyLen); if (!checkResponse(self, pReply)) { diff --git a/make_gen b/make_gen index 996e6ce..6fc935a 100644 --- a/make_gen +++ b/make_gen @@ -40,7 +40,7 @@ libpsi.a: $(OBJ) clean: rm -f *.a *.o *.d -SINQOPT=-DGRAPH_MHC3 -DUSE_MULTICAST -DSEND_PORT=0xABCB -DSERVER_HOST="\"acslg1mc\"" +SINQOPT=-DGRAPH_MHC3 -DUSE_MULTICAST -DSEND_PORT=0xABCB -DSERVER_HOST="\"hipa129-sta\"" dgrambroadcast.o: dgrambroadcast.h dgrambroadcast.c $(CC) $(SINQOPT) -c -g dgrambroadcast.c diff --git a/sinqhttpopt.c b/sinqhttpopt.c index 5f29560..b327a9f 100644 --- a/sinqhttpopt.c +++ b/sinqhttpopt.c @@ -92,6 +92,7 @@ typedef struct { int sockHandle; int bytesExpected; char *contentType; + int headerReceived; } HttpProt, *pHttpProt; /*---------------------------------------------------------------------*/ static int HTTPcallback(int handle, void *userData) @@ -168,6 +169,8 @@ static void sendRequest(pHttpProt pHttp, char *data) dataCopy = strdup(data); + pHttp->node = NULL; + pHttp->headerReceived = 0; pPtr = strchr(dataCopy,':'); if(pPtr == NULL){ path = dataCopy; @@ -190,6 +193,11 @@ static void sendRequest(pHttpProt pHttp, char *data) *pPtr = '\0'; sendPost(pHttp,path, pPtr+1); free(dataCopy); + } else if(strstr(dataCopy,"processhmdata.egi") != NULL){ + path = dataCopy; + sendGet(pHttp,path); + free(dataCopy); + return; } } } @@ -212,6 +220,11 @@ static void handleReply(Ascon * a) if (strstr(pType, "sinqhm") != NULL) { hmData = (HistInt *) pPtr; len = len / sizeof(HistInt); + /* + if(len == 0) { + printf("Blllllllllaaaaaaaaaaeeeeeeeeeerrrrrrrrrrrkkkk!\n"); + } + */ if(pHttp->node == NULL){ clearSICSData(pHttp->binData); dataPtr = getSICSDataPointer(pHttp->binData, 0, len); @@ -221,6 +234,9 @@ static void handleReply(Ascon * a) assignSICSType(pHttp->binData, 0, len, INTTYPE); DynStringClear(a->rdBuffer); DynStringCopy(a->rdBuffer, "SICSDATA"); + /* + printf("SICSDATA received..........\n"); + */ } else { if(pHttp->node->value.arrayLength != len){ if(pHttp->node->value.v.intArray != NULL){ @@ -240,10 +256,10 @@ static void handleReply(Ascon * a) /* path = GetHipadabaPath(pHttp->node); if(path != NULL){ - printf("Sinqhttpprot has updated node: %s\n", path); + printf("Sinqhttpopt has updated node: %s, length = %d\n", path, len); free(path); } - */ + */ } } } @@ -291,6 +307,7 @@ static int processHeader(Ascon *a) } } } + pHttp->headerReceived = 1; /** * Hack off the header */ @@ -366,36 +383,59 @@ static int HttpHandler(Ascon * a) DynStringClear(a->rdBuffer); return 1; break; + case AsconReadStart: + a->state= AsconReading; + return 1; + break; case AsconReading: ANETprocess(); /** - * Here we have basically three conditions to check: + * Here we have basically four conditions to check: * - detected means that we received * the complete header. * - enough bytes read: termination * - socket closed means all data has been read + * - timeout waiting for a response */ if(strstr(GetCharArray(a->rdBuffer), "\r\n\r\n") != NULL){ status = processHeader(a); if(status != 1){ a->state = AsconReadDone; - return 1; + break; } } if(!ANETvalidHandle(pHttp->sockHandle)){ - handleReply(a); - a->state = AsconReadDone; - return 1; + if(pHttp->headerReceived) { + handleReply(a); + a->state = AsconReadDone; + } else { + /* + * We only noticed when attempting to read that the WWW-server has closed + * the connection. ANETclose will have killed the read and write buffers. + * So redo everything...... + */ + a->state = AsconWriteStart; + return 1; + } + break; } if(pHttp->bytesExpected > 0 && GetDynStringLength(a->rdBuffer) >= pHttp->bytesExpected ){ handleReply(a); a->state = AsconReadDone; - return 1; + break; } + if (a->timeout > 0) { + if (DoubleTime() - a->start > a->timeout) { + AsconError(a, "no response", 0); + printf("Timeout on httpopt\n"); + ANETclose(pHttp->sockHandle); + a->state = AsconTimeout; + } + } return 0; break; default: - return AsconStdHandler(a); + return AsconBaseHandler(a); } return 1; } diff --git a/sinqhttpprot.c b/sinqhttpprot.c index 4399c25..2b7af19 100644 --- a/sinqhttpprot.c +++ b/sinqhttpprot.c @@ -192,6 +192,8 @@ static int HttpHandler(Ascon * a) if (procStatus.proc == ghttp_proc_response_hdrs || procStatus.proc == ghttp_proc_response) { a->state = AsconWriteDone; + } else { + return 0; } } a->start = DoubleTime(); @@ -234,7 +236,7 @@ static int HttpHandler(Ascon * a) /* this to clear the line */ ghttp_close(pHttp->request); } - return 1; + return 0; case ghttp_done: handleReply(a); a->state = AsconReadDone; diff --git a/spss7.c b/spss7.c index 6cd852d..04f2c1d 100644 --- a/spss7.c +++ b/spss7.c @@ -125,7 +125,7 @@ static int decodeString(char *pPtr, char *string, int maxlen) fullength = maxlen; used = maxlen; } - memset(string,0,fullength); + memset(string,0,fullength+1); memcpy(string, pPtr+2, used); return fullength + 2; } @@ -164,11 +164,11 @@ static char *S7WriteHandler(void *actionData, char *reply, int comerror) static void UpdateSPSDataBase(pS7Action self) { char *pPtr; - char name[14], unit[8], description[24], reference[10], error[50]; + char name[15], unit[9], description[25], reference[11], error[50]; unsigned char type, alarm; - short val; + unsigned short val; int ival; - unsigned char bval; + unsigned char bval, b2; float fval; pHdb node = NULL; hdbValue hdbVal; @@ -183,10 +183,18 @@ static void UpdateSPSDataBase(pS7Action self) pPtr += decodeString(pPtr, description,24); pPtr += decodeString(pPtr, reference,10); node = GetHipadabaNode(self->spsNode,name); + if(node == NULL){ + printf("Something very fishy is happening here: did Roman change the SPS layout under our feet?\n"); + continue; + } switch (type) { case 1: case 4: - memcpy(&bval,pPtr+1,1); + memcpy(&bval,pPtr,1); + /* + memcpy(&b2,pPtr+1,1); + printf("Bytes: %d %d\n", bval, b2); + */ hdbVal = MakeHdbInt(bval); UpdateHipadabaPar(node,hdbVal,NULL); pPtr += 2; @@ -300,7 +308,7 @@ static hdbCallbackReturn S7WriteCallback(pHdb currentNode, static void InitializeSPSDataBase(pS7Action self, pHdb parent) { char *pPtr; - char name[14], unit[8], description[24], reference[10], num[10], error[50]; + char name[15], unit[9], description[25], reference[11], num[11], error[50]; unsigned char type, alarm; short val; int ival; @@ -371,6 +379,7 @@ static char *S7InitHandler(void *actionData, char *reply, int comerror) { pS7Action self = (pS7Action)actionData; short dblength; + pHdb node = NULL; /* * Start: read length of the database @@ -393,6 +402,12 @@ static char *S7InitHandler(void *actionData, char *reply, int comerror) memcpy(&dblength, self->replyData+16,2); dblength = ntohs(dblength); InitializeSPSDataBase(self,self->spsNode); + node = GetHipadabaNode(self->spsNode,"init"); + /* + if(node != NULL){ + UpdateHipadabaPar(node,MakeHdbInt(1), NULL); + } + */ return NULL; } } diff --git a/swmotor.c b/swmotor.c index 5446228..3dc9c94 100644 --- a/swmotor.c +++ b/swmotor.c @@ -6,6 +6,9 @@ copyright: see file copyright.h Mark Koennecke, May 2001 + + Reworked a bit to work with second generation motors + Mark Koennecke, February 2011 --------------------------------------------------------------------------*/ #include #include @@ -20,6 +23,7 @@ #include "hardsup/el734_def.h" #include "hardsup/el734fix.h" #include +#include "macro.h" #include "swmotor.h" #include "swmotor.i" @@ -386,7 +390,11 @@ int SWMotorAction(SConnection * pCon, SicsInterp * pSics, void *pData, /* check for list */ if (strcmp(pCurrent->text, "list") == 0) { - MotorListLL(self->pMaster, pCon); + snprintf(pBueffel,sizeof(pBueffel),"%s list", self->pMaster->name); + MacroPush(pCon); + iRet = Tcl_Eval(InterpGetTcl(pSics),pBueffel); + MacroPop(); + SCWrite(pCon,(char *)Tcl_GetStringResult(InterpGetTcl(pSics)), eValue); DeleteTokenList(pList); return 1; } /* check for reset */ @@ -397,7 +405,11 @@ int SWMotorAction(SConnection * pCon, SicsInterp * pSics, void *pData, DeleteTokenList(pList); return 0; } - MotorReset(self->pMaster); + snprintf(pBueffel,sizeof(pBueffel),"%s reset", self->pMaster->name); + MacroPush(pCon); + iRet = Tcl_Eval(InterpGetTcl(pSics),pBueffel); + MacroPop(); + SCWrite(pCon,(char *)Tcl_GetStringResult(InterpGetTcl(pSics)), eValue); DeleteTokenList(pList); SCSendOK(pCon); return 1;