diff --git a/libpsi.a b/libpsi.a index 476d569..c5e0124 100644 Binary files a/libpsi.a and b/libpsi.a differ diff --git a/sinqhttp.c b/sinqhttp.c index dcfe91f..f7e3139 100644 --- a/sinqhttp.c +++ b/sinqhttp.c @@ -1,6 +1,6 @@ /* - This is a histogram mmeory driver for the 2005-6 version of the - histogram mmeory software based on RTAI-Linux and an embedded WWW-server + This is a histogram memory driver for the 2005-6 version of the + histogram memory software based on RTAI-Linux and an embedded WWW-server for communications. For all http work the ghttp library from the gnome project is used. @@ -27,11 +27,12 @@ extern char *trim(char *); ====================================================================*/ static char startdaq[] = {"/sinqhm/startdaq.egi"}; static char stopdaq[] = {"/sinqhm/stopdaq.egi"}; -static char pausedaq[] = {"/sinqhm/stopdaq.egi"}; +static char pausedaq[] = {"/sinqhm/pausedaq.egi"}; static char continuedaq[] = {"/sinqhm/continuedaq.egi"}; static char statusdaq[] = {"/sinqhm/textstatus.egi"}; static char gethm[] = {"/sinqhm/readhmdata.egi"}; static char configure[] = {"/sinqhm/configure.egi"}; +static char preset[] = {"/sinqhm/presethm.egi"}; /*==================================================================== error codes ======================================================================*/ @@ -42,24 +43,32 @@ static char configure[] = {"/sinqhm/configure.egi"}; #define NOTIMPLEMENTED -705 #define SERVERERROR -706 #define BADSTATUS -707 +#define BADAUTH -708 /*===================================================================== our driver private data structure ======================================================================*/ typedef struct { ghttp_request *syncRequest; char hmAddress[512]; + char userName[132]; + char passWord[132]; char hmError[512]; int errorCode; - pStringDict lastStatus; int pause; int failCount; + int asyncRunning; }sinqHttp, *pSinqHttp; -/*-------------------------------------------------------------------*/ -static int sinqHttpGet(pSinqHttp self, char *request){ +/*------------------------------------------------------------------*/ +static int sinqHttpGetPrepare(pSinqHttp self, char *request){ char url[512]; ghttp_status httpStatus; - char *pPtr = NULL; - int len; + + if(self->asyncRunning){ + while((httpStatus = ghttp_process(self->syncRequest)) + == ghttp_not_done){ + } + self->asyncRunning = 0; + } self->errorCode = 0; ghttp_clean(self->syncRequest); @@ -71,25 +80,59 @@ static int sinqHttpGet(pSinqHttp self, char *request){ self->errorCode = BADURL; return 0; } + ghttp_set_authinfo(self->syncRequest,self->userName, + self->passWord); + ghttp_set_sync(self->syncRequest,ghttp_sync); + return 1; +} +/*-------------------------------------------------------------------*/ +static int sinqHttpCheckResponse(pSinqHttp self){ + char *pPtr = NULL; + int len; + + self->failCount = 0; + pPtr = ghttp_get_body(self->syncRequest); + len = ghttp_get_body_len(self->syncRequest); + if(len > 511){ + len = 510; + } + if(strstr(pPtr,"ERROR") != NULL){ + memset(self->hmError,0,512*sizeof(char)); + strncpy(self->hmError,pPtr, len); + self->errorCode = HTTPERROR; + return 0; + } else if(strstr(pPtr,"Authentication Error") != NULL){ + memset(self->hmError,0,512*sizeof(char)); + strncpy(self->hmError,pPtr, len); + self->errorCode = BADAUTH; + return 0; + } + return 1; +} +/*-------------------------------------------------------------------*/ +static int sinqHttpGet(pSinqHttp self, char *request){ + ghttp_status httpStatus; + char *pPtr = NULL; + + if(!sinqHttpGetPrepare(self,request)){ + return 0; + } + /* + * try two times: a reconnect is no error + */ ghttp_prepare(self->syncRequest); httpStatus = ghttp_process(self->syncRequest); if(httpStatus != ghttp_done){ - strncpy(self->hmError,ghttp_get_error(self->syncRequest), 511); - self->errorCode = SERVERERROR; - return 0; - } else { - self->failCount = 0; - pPtr = ghttp_get_body(self->syncRequest); - len = ghttp_get_body_len(self->syncRequest); - if(len > 511){ - len = 510; - } - if(strstr(pPtr,"ERROR") != NULL){ - memset(self->hmError,0,512*sizeof(char)); - strncpy(self->hmError,pPtr, len); - self->errorCode = HTTPERROR; + ghttp_close(self->syncRequest); + sinqHttpGetPrepare(self,request); + httpStatus = ghttp_process(self->syncRequest); + } + if(httpStatus != ghttp_done){ + strncpy(self->hmError,"Reconnect", 511); + self->errorCode = SERVERERROR; return 0; - } + } else { + return sinqHttpCheckResponse(self); } return 1; } @@ -117,6 +160,23 @@ static int SinqHttpConfigure(pHistDriver self, SConnection *pCon, return 0; } + /* + * looser credentials + */ + if(StringDictGet(pOpt,"username",pPriv->userName, 131) != 1){ + SCWrite(pCon, + "ERROR: required configuration parameter username not found", + eError); + return 0; + } + if(StringDictGet(pOpt,"password",pPriv->passWord, 131) != 1){ + SCWrite(pCon, + "ERROR: required configuration parameter password not found", + eError); + return 0; + } + + /* actual configuration. Check for flag INIT in options. We do not need to configure, if the HM has configured itself already. What is does, these days. @@ -161,6 +221,9 @@ static int SinqHttpConfigure(pHistDriver self, SConnection *pCon, confData = (char *)Tcl_GetStringResult(pSics->pTcl); status = ghttp_set_body(pPriv->syncRequest,confData, strlen(confData)); + ghttp_set_authinfo(pPriv->syncRequest, pPriv->userName, + pPriv->passWord); + ghttp_set_sync(pPriv->syncRequest,ghttp_sync); status = ghttp_prepare(pPriv->syncRequest); httpStatus = ghttp_process(pPriv->syncRequest); confData = (char *)ghttp_get_body(pPriv->syncRequest); @@ -176,6 +239,11 @@ static int SinqHttpConfigure(pHistDriver self, SConnection *pCon, SCWrite(pCon,confCommand,eError); return 0; } + if(strstr(confData,"Authentication Error") != NULL){ + snprintf(confCommand,511,"%s",confData); + SCWrite(pCon,confCommand,eError); + return 0; + } } } } @@ -240,10 +308,15 @@ static int SinqHttpContinue(pHistDriver self, SConnection *pCon){ return 1; } /*--------------------------------------------------------------------*/ -static int readStatus(pSinqHttp self){ +static int readStatus(pHistDriver pDriv){ char *pPtr = NULL, *pLinePtr; char line[132]; char name[80], value[80]; + pSinqHttp self = NULL; + char *daqPtr = NULL, *daqValPtr = NULL; + + self = (pSinqHttp)pDriv->pPriv; + assert(self != NULL); pPtr = ghttp_get_body(self->syncRequest); if(pPtr == NULL){ @@ -256,10 +329,11 @@ static int readStatus(pSinqHttp self){ pLinePtr = line; pLinePtr = stptok(pLinePtr,name,80,":"); pLinePtr = stptok(pLinePtr,value,80,":"); - if(StringDictExists(self->lastStatus,trim(name)) == 1){ - StringDictUpdate(self->lastStatus,trim(name),trim(value)); + strtolower(name); + if(StringDictExists(pDriv->pOption,trim(name)) == 1){ + StringDictUpdate(pDriv->pOption,trim(name),trim(value)); } else { - StringDictAddPair(self->lastStatus,trim(name),trim(value)); + StringDictAddPair(pDriv->pOption,trim(name),trim(value)); } pPtr = stptok(pPtr,line,131,"\n"); } @@ -268,6 +342,7 @@ static int readStatus(pSinqHttp self){ /*---------------------------------------------------------------------*/ static int SinqHttpStatus(pHistDriver self,SConnection *pCon){ pSinqHttp pPriv = NULL; + ghttp_status httpStatus; char daqStatus[20]; int status, len; char *pPtr = NULL; @@ -279,17 +354,48 @@ static int SinqHttpStatus(pHistDriver self,SConnection *pCon){ return HWPause; } - status = sinqHttpGet(pPriv,statusdaq); - if(status != 1){ - return HWFault; + if(pPriv->asyncRunning == 0){ + status = sinqHttpGetPrepare(pPriv,statusdaq); + ghttp_set_sync(pPriv->syncRequest,ghttp_async); + ghttp_prepare(pPriv->syncRequest); + if(status != 1){ + return HWFault; + } + pPriv->asyncRunning = 1; + } + httpStatus = ghttp_process(pPriv->syncRequest); + switch(httpStatus){ + case ghttp_error: + ghttp_close(pPriv->syncRequest); + sinqHttpGetPrepare(pPriv,statusdaq); + ghttp_prepare(pPriv->syncRequest); + httpStatus = ghttp_process(pPriv->syncRequest); + if(httpStatus != ghttp_done){ + strncpy(pPriv->hmError,"Reconnect", 511); + pPriv->errorCode = SERVERERROR; + return HWFault; + pPriv->asyncRunning = 0; + } + break; + case ghttp_not_done: + return HWBusy; + break; + case ghttp_done: + pPriv->asyncRunning = 0; + status = sinqHttpCheckResponse(pPriv); + if(status != 1){ + return HWFault; + } + break; } - status = readStatus(pPriv); + + status = readStatus(self); if(status != 1){ return HWFault; } - if(StringDictGet(pPriv->lastStatus,"DAQ",daqStatus,20) != 1){ + if(StringDictGet(self->pOption,"daq",daqStatus,20) != 1){ pPriv->errorCode = BADSTATUS; strncpy(pPriv->hmError,"ERROR: status does not contain DAQ field",511); return HWFault; @@ -403,6 +509,18 @@ static float SinqHttpGetTime(pHistDriver self, SConnection *pCon){ } /*---------------------------------------------------------------------*/ static int SinqHttpPreset(pHistDriver self, SConnection *pCon, int val){ + pSinqHttp pPriv = NULL; + int status; + char command[512]; + + pPriv = (pSinqHttp)self->pPriv; + assert(pPriv != NULL); + + snprintf(command,512,"%s?value=%d",preset,val); + status = sinqHttpGet(pPriv,command); + if(status != 1){ + return HWFault; + } return 1; } /*---------------------------------------------------------------------*/ @@ -414,9 +532,6 @@ static int SinqHttpFreePrivate(pHistDriver self){ return 1; } - if(pPriv->lastStatus != NULL){ - DeleteStringDict(pPriv->lastStatus); - } if(pPriv->syncRequest != NULL){ ghttp_request_destroy(pPriv->syncRequest); } @@ -446,9 +561,8 @@ pHistDriver CreateSinqHttpDriver(pStringDict pOption){ } memset(pInternal,0,sizeof(sinqHttp)); pNew->pPriv = pInternal; - pInternal->lastStatus = CreateStringDict(); pInternal->syncRequest = ghttp_request_new(); - if(pInternal->lastStatus == NULL && pInternal->syncRequest == NULL){ + if(pInternal->syncRequest == NULL){ free(pNew); free(pInternal); return NULL;