diff --git a/dornier2.c b/dornier2.c index 0c1c749..9e3293c 100644 --- a/dornier2.c +++ b/dornier2.c @@ -595,7 +595,7 @@ static int DornierStatNew(pVelSelDriv self, int *iCode, float *fCur){ { pVelSelDriv pNew = NULL; pDornier pDorn = NULL; - const char *pPtr = NULL; + char *pPtr = NULL; int iVal, iRet, iPort; char pHost[132]; diff --git a/libpsi.a b/libpsi.a index 9264a7b..4b014f3 100644 Binary files a/libpsi.a and b/libpsi.a differ diff --git a/make_gen b/make_gen index 3d8d103..7abd7ef 100644 --- a/make_gen +++ b/make_gen @@ -16,7 +16,7 @@ OBJ=psi.o buffer.o ruli.o dmc.o nxsans.o nextrics.o sps.o pimotor.o \ el755driv.o amorscan.o serial.o scontroller.o t_update.o \ t_rlp.o t_conv.o el737hpdriv.o dornier2.o el734hp.o \ el737hpv2driv.o swmotor2.o tricssupport.o amorcomp.o \ - $(MZOBJ) amordrive.o amorset.o tcpdornier.o\ + $(MZOBJ) amordrive.o amorset.o tcpdornier.o sinqhttp.o\ dgrambroadcast.o sinq.o tabledrive.o tcpdocho.o MZOBJ=fsm.o logger.o sugar.o pardef.o ease.o strobj.o oxinst.o \ diff --git a/makefile_linux b/makefile_linux index b26a726..1c00e31 100644 --- a/makefile_linux +++ b/makefile_linux @@ -10,9 +10,9 @@ include ../linux_def CC = gcc -CFLAGS = -I$(HDFROOT)/include -DHDF4 -DHDF5 $(NI) -Ihardsup \ +CFLAGS = -I$(HDFROOT)/include -DHDF4 -DHDF5 $(NI) -Ihardsup \ -I.. -fwritable-strings -DCYGNUS -DNONINTF -g $(DFORTIFY) \ - -Wall -Wno-unused -Wno-comment -Wno-switch -Werror + -Wall -Wno-unused -Wno-comment -Wno-switch EXTRA=nintf.o diff --git a/pimotor.c b/pimotor.c index 94d6b87..d162237 100644 --- a/pimotor.c +++ b/pimotor.c @@ -297,7 +297,7 @@ pC804Driv pNew = NULL; int iRet, iVal, iTmo; double dVal; - const char *pPar = NULL; + char *pPar = NULL; char pCommand[20], pReply[40]; /* allocate space: the final frontier */ diff --git a/pipiezo.c b/pipiezo.c index 80d0d2c..6c9ef39 100644 --- a/pipiezo.c +++ b/pipiezo.c @@ -284,7 +284,7 @@ pPiPiezo pNew = NULL; int iRet, iVal, iTmo; double dVal; - const char *pPar = NULL; + char *pPar = NULL; char pCommand[20], pReply[40]; /* allocate space: the final frontier */ diff --git a/psi.c b/psi.c index eaa9a0b..9348472 100644 --- a/psi.c +++ b/psi.c @@ -54,7 +54,7 @@ #include "sinq.h" #include "tabledrive.h" #include "amorset.h" - +#include "sinqhttp.h" /* from tcpdornier.c */ @@ -259,6 +259,8 @@ static HistDriver *CreatePsiHistMem(char *name, pStringDict pOptions){ pNew = CreateSINQDriver(pOptions); } else if(strcmp(name,"tdc") == 0){ pNew = MakeTDCHM(pOptions); + } else if(strcmp(name,"sinqhttp") == 0){ + pNew = CreateSinqHttpDriver(pOptions); } return pNew; } diff --git a/serial.c b/serial.c index bdaf701..f6cb19b 100644 --- a/serial.c +++ b/serial.c @@ -11,8 +11,8 @@ #include #include "sics.h" - extern int Controller(ClientData pData, Tcl_Interp *pInter, - int argc, const char *argv[]); + extern int Controller(ClientData clientData, Tcl_Interp *interp, + int argc, CONST char *argv[]); int SerialInit(SConnection *pCon,SicsInterp *pSics, void *pData, int argc, char *argv[]) diff --git a/sinqhttp.c b/sinqhttp.c new file mode 100644 index 0000000..fe2e48e --- /dev/null +++ b/sinqhttp.c @@ -0,0 +1,437 @@ +/* + 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 + for communications. For all http work the ghttp library from the gnome + project is used. + + This HM is meant to be used in conjunction with a counter module + chained through the hmcontrol module. No need to handle counters here + when hmcontrol can do the chaining. + + copyright: see file COPYRIGHT + + Mark Koennecke, January 2005 + +----------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include + +extern char *trim(char *); +/*=================================================================== + The request strings to append to the computer address +====================================================================*/ +static char startdaq[] = {"/sinqhm/startdaq.egi"}; +static char stopdaq[] = {"/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"}; +/*==================================================================== + error codes +======================================================================*/ +#define BADURL -701 +#define HTTPERROR -702 +#define NOBODY -703 +#define BODYSHORT -704 +#define NOTIMPLEMENTED -705 +/*===================================================================== + our driver private data structure +======================================================================*/ +typedef struct { + ghttp_request *syncRequest; + char hmAddress[512]; + char hmError[512]; + int errorCode; + pStringDict lastStatus; + int pause; +}sinqHttp, *pSinqHttp; +/*-------------------------------------------------------------------*/ +static int sinqHttpGet(pSinqHttp self, char *request){ + char url[512]; + ghttp_status httpStatus; + char *pPtr = NULL; + int len; + + self->errorCode = 0; + memset(self->hmError,0,512*sizeof(char)); + snprintf(url,511,"%s%s",self->hmAddress,request); + ghttp_set_type(self->syncRequest,ghttp_type_get); + if(ghttp_set_uri(self->syncRequest,url) < 0){ + self->errorCode = BADURL; + return 0; + } + ghttp_prepare(self->syncRequest); + ghttp_clean(self->syncRequest); + httpStatus = ghttp_process(self->syncRequest); + if(httpStatus != ghttp_done){ + pPtr = ghttp_get_body(self->syncRequest); + len = ghttp_get_body_len(self->syncRequest); + if(len > 511){ + len = 510; + } + memset(self->hmError,0,512*sizeof(char)); + strncpy(self->hmError,pPtr, len); + self->errorCode = HTTPERROR; + return 0; + } + return 1; +} +/*====================================================================*/ +static int SinqHttpConfigure(pHistDriver self, SConnection *pCon, + pStringDict pOpt, SicsInterp *pSics){ + char hmname[512]; + char confCommand[512], url[512]; + pSinqHttp pPriv = NULL; + int status, iInit; + float fVal; + char *confData = NULL; + ghttp_status httpStatus; + + pPriv = (pSinqHttp)self->pPriv; + assert(pPriv != NULL); + + /* + * The HM computer address + */ + if(StringDictGet(pOpt,"hmaddress",pPriv->hmAddress, 511) != 1){ + SCWrite(pCon, + "ERROR: required configuration parameter hmaddress 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. + */ + status = StringDictGetAsNumber(pOpt,"init",&fVal); + iInit = 0; + if(status == 1) { + if(fVal > 0.9 ) { + iInit = 1; + } + } + + /* + actually do configure + */ + if(iInit == 0){ + memset(confCommand,0,512*sizeof(char)); + if(StringDictGet(pOpt,"hmconfigscript",confCommand,511) != 1){ + SCWrite(pCon, + "ERROR: required parameter hmconfigscript not found!", + eError); + return 0; + } + status = Tcl_Eval(pSics->pTcl,confCommand); + if(status != TCL_OK){ + snprintf(confCommand,511,"ERROR: Tcl reported %s while evaluating hmconfigscript", + Tcl_GetStringResult(pSics->pTcl)); + SCWrite(pCon,confCommand,eError); + return 0; + } else { + /* + uplod new configuration to HM + */ + snprintf(url,511,"%s%s",pPriv->hmAddress,configure); + status = ghttp_set_uri(pPriv->syncRequest,url); + if(status < 0){ + SCWrite(pCon,"ERROR: invalid URI for HM request",eError); + return 0; + } + ghttp_set_type(pPriv->syncRequest,ghttp_type_post); + confData = (char *)Tcl_GetStringResult(pSics->pTcl); + ghttp_set_body(pPriv->syncRequest,confData,strlen(confData)); + ghttp_prepare(pPriv->syncRequest); + ghttp_clean(pPriv->syncRequest); + httpStatus = ghttp_process(pPriv->syncRequest); + if(httpStatus != ghttp_done){ + confData = (char *)ghttp_get_body(pPriv->syncRequest); + snprintf(confCommand,511,"ERROR: http error %s occurred", + confData); + SCWrite(pCon,confCommand,eError); + return 0; + } + } + } + return 1; +} +/*--------------------------------------------------------------------*/ +static int SinqHttpStart(pHistDriver self, SConnection *pCon){ + pSinqHttp pPriv = NULL; + int status; + + pPriv = (pSinqHttp)self->pPriv; + assert(pPriv != NULL); + + status = sinqHttpGet(pPriv,startdaq); + if(status != 1){ + return HWFault; + } + return 1; +} +/*---------------------------------------------------------------------*/ +static int SinqHttpHalt(pHistDriver self){ + pSinqHttp pPriv = NULL; + int status; + + pPriv = (pSinqHttp)self->pPriv; + assert(pPriv != NULL); + + status = sinqHttpGet(pPriv,stopdaq); + if(status != 1){ + return HWFault; + } + return 1; +} +/*---------------------------------------------------------------------*/ +static int SinqHttpPause(pHistDriver self,SConnection *pCon){ + pSinqHttp pPriv = NULL; + int status; + + pPriv = (pSinqHttp)self->pPriv; + assert(pPriv != NULL); + + status = sinqHttpGet(pPriv,pausedaq); + if(status != 1){ + return HWFault; + } + pPriv->pause == 1; + return 1; +} +/*---------------------------------------------------------------------*/ +static int SinqHttpContinue(pHistDriver self, SConnection *pCon){ + pSinqHttp pPriv = NULL; + int status; + + pPriv = (pSinqHttp)self->pPriv; + assert(pPriv != NULL); + + pPriv->pause == 0; + status = sinqHttpGet(pPriv,continuedaq); + if(status != 1){ + return HWFault; + } + return 1; +} +/*--------------------------------------------------------------------*/ +static int readStatus(pSinqHttp self){ + char *pPtr = NULL, *pLinePtr; + char line[132]; + char name[80], value[80]; + + pPtr = ghttp_get_body(self->syncRequest); + if(pPtr == NULL){ + strncpy(self->hmError,"No body in status response",131); + self->errorCode = NOBODY; + return 0; + } + pPtr = stptok(pPtr,line,132,"\n"); + while(pPtr != NULL){ + 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)); + } else { + StringDictAddPair(self->lastStatus,trim(name),trim(value)); + } + pPtr = stptok(pPtr,line,131,"\n"); + } + return 1; +} +/*---------------------------------------------------------------------*/ +static int SinqHttpStatus(pHistDriver self,SConnection *pCon){ + pSinqHttp pPriv = NULL; + int status, len; + char *pPtr = NULL; + + pPriv = (pSinqHttp)self->pPriv; + assert(pPriv != NULL); + + if(pPriv->pause == 1){ + return HWPause; + } + + status = sinqHttpGet(pPriv,statusdaq); + if(status != 1){ + return HWFault; + } + + status = readStatus(pPriv); + if(status != 1){ + return HWFault; + } + + /* + * TODO: evaluate status fields + */ + + return HWIdle; +} +/*---------------------------------------------------------------------*/ +static int SinqHttpError(pHistDriver self, int *code, + char *error, int errLen){ + pSinqHttp pPriv = NULL; + int status; + + pPriv = (pSinqHttp)self->pPriv; + assert(pPriv != NULL); + + strncpy(error,pPriv->hmError, errLen); + *code = pPriv->errorCode; + return 1; +} +/*--------------------------------------------------------------------*/ +static int SinqHttpFixIt(pHistDriver self, int code){ + pSinqHttp pPriv = NULL; + + pPriv = (pSinqHttp)self->pPriv; + assert(pPriv != NULL); + + /* + * not much to fix here: ghttplib already tries hard to fix + * connection problems... But abort any pending transactions... + */ + ghttp_close(pPriv->syncRequest); + return COTERM; +} +/*--------------------------------------------------------------------*/ +static int SinqHttpGetData(pHistDriver self,SConnection *pCon){ + /* + * do noting, monitors are with the counter, histogram memory + * caching and retrieval is handled via GetHistogram + */ + return 1; +} +/*-------------------------------------------------------------------*/ +static int SinqHttpGetHistogram(pHistDriver self, SConnection *pCon, + int bank, int start, int end, HistInt *data){ + char command[256]; + HistInt *hmdata; + pSinqHttp pPriv = NULL; + int status, len, i; + + pPriv = (pSinqHttp)self->pPriv; + assert(pPriv != NULL); + + snprintf(command,255,"%s?bank=%d&start=%d&end=%d",gethm,bank, + start,end); + + status = sinqHttpGet(pPriv,command); + if(status != 1){ + return HWFault; + } + + len = ghttp_get_body_len(pPriv->syncRequest); + if(len < (end-start)*sizeof(int)){ + pPriv->errorCode = BODYSHORT; + strncpy(pPriv->hmError,"Not enough data received from HM",511); + return HWFault; + } + hmdata = (HistInt *)ghttp_get_body(pPriv->syncRequest); + for(i = 0; i < (end - start); i++){ + data[i] = ntohl(hmdata[i]); + } + return 1; +} +/*--------------------------------------------------------------------*/ +static int SinqHttpSetHistogram(pHistDriver self, SConnection *pCon, + int bank, int start, int end, HistInt *data){ + pSinqHttp pPriv = NULL; + + pPriv = (pSinqHttp)self->pPriv; + assert(pPriv != NULL); + + pPriv->errorCode = NOTIMPLEMENTED; + strncpy(pPriv->hmError,"Not implemented",511); + return HWFault; +} +/*---------------------------------------------------------------------*/ +static long SinqHttpGetMonitor(pHistDriver self, int i, + SConnection *pCon){ + return 0; +} +/*---------------------------------------------------------------------*/ +static float SinqHttpGetTime(pHistDriver self, SConnection *pCon){ + return -999.99; +} +/*---------------------------------------------------------------------*/ +static int SinqHttpPreset(pHistDriver self, SConnection *pCon, int val){ + return 1; +} +/*---------------------------------------------------------------------*/ +static int SinqHttpFreePrivate(pHistDriver self){ + pSinqHttp pPriv = NULL; + + pPriv = (pSinqHttp)self->pPriv; + if(pPriv == NULL){ + return 1; + } + + if(pPriv->lastStatus != NULL){ + DeleteStringDict(pPriv->lastStatus); + } + if(pPriv->syncRequest != NULL){ + ghttp_request_destroy(pPriv->syncRequest); + } + free(pPriv); + return 1; +} +/*-------------------------------------------------------------------*/ +pHistDriver CreateSinqHttpDriver(pStringDict pOption){ + pHistDriver pNew = NULL; + pSinqHttp pInternal = NULL; + + /* create the general driver */ + pNew = CreateHistDriver(pOption); + if(!pNew){ + return NULL; + } + + /* add our options */ + StringDictAddPair(pOption,"hmaddress","http://unknown.psi.ch:9090"); + StringDictAddPair(pOption,"hmconfigurescript","hmconfigure"); + + /* initialise our private data structure */ + pInternal = (pSinqHttp)malloc(sizeof(sinqHttp)); + if(!pInternal){ + free(pNew); + return NULL; + } + memset(pInternal,0,sizeof(sinqHttp)); + pNew->pPriv = pInternal; + pInternal->lastStatus = CreateStringDict(); + pInternal->syncRequest = ghttp_request_new(); + if(pInternal->lastStatus == NULL && pInternal->syncRequest == NULL){ + free(pNew); + free(pInternal); + return NULL; + } + + + /* configure all those functions */ + pNew->Configure = SinqHttpConfigure; + pNew->Start = SinqHttpStart; + pNew->Halt = SinqHttpHalt; + pNew->GetCountStatus = SinqHttpStatus; + pNew->GetError = SinqHttpError; + pNew->TryAndFixIt = SinqHttpFixIt; + pNew->GetData = SinqHttpGetData; + pNew->GetHistogram = SinqHttpGetHistogram; + pNew->SetHistogram = SinqHttpSetHistogram; + pNew->GetMonitor = SinqHttpGetMonitor; + pNew->GetTime = SinqHttpGetTime; + pNew->Preset = SinqHttpPreset; + pNew->FreePrivate = SinqHttpFreePrivate; + pNew->Pause = SinqHttpPause; + pNew->Continue = SinqHttpContinue; + + return pNew; +} diff --git a/sinqhttp.h b/sinqhttp.h new file mode 100644 index 0000000..e898a66 --- /dev/null +++ b/sinqhttp.h @@ -0,0 +1,22 @@ +/* + 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 + for communications. For all http work the ghttp library from the gnome + project is used. + + This HM is meant to be used in conjunction with a counter module + chained through the hmcontrol module. No need to handle counters here + when hmcontrol can do the chaining. + + copyright: see file COPYRIGHT + + Mark Koennecke, January 2005 + +----------------------------------------------------------------------*/ +#ifndef SINQHTTP_H_ +#define SINQHTTP_H_ +#include + +pHistDriver CreateSinqHttpDriver(pStringDict pOption); + +#endif /*SINQHTTP_H_*/ diff --git a/tcpdornier.c b/tcpdornier.c index 4ee022b..d6c8bda 100644 --- a/tcpdornier.c +++ b/tcpdornier.c @@ -849,7 +849,7 @@ static int TcpAsMotHalt(void *pData){ pVelSelDriv pNew = NULL; pTcpDornier pDorn = NULL; MotorDriver *pAstDriv = NULL; - const char *pPtr = NULL; + char *pPtr = NULL; char host[132]; int iVal, iRet, port; @@ -1015,7 +1015,7 @@ int VelSelTcpFactory(SConnection *pCon, SicsInterp *pSics, void *pData, int iRet; pEVDriver pMonDriv = NULL; pTcpAsMotorDriver pAstDriv = NULL; - const char *pPtr = NULL; + char *pPtr = NULL; double d; float limit; diff --git a/velodornier.c b/velodornier.c index b5cc384..3e8e213 100644 --- a/velodornier.c +++ b/velodornier.c @@ -577,7 +577,7 @@ typedef enum {vStart, eRegel, eHalted} eVeloMode; { pVelSelDriv pNew = NULL; pDornier pDorn = NULL; - const char *pPtr = NULL; + char *pPtr = NULL; int iVal, iRet; /* the most likely error is the parameters specified are wrong!