Files
sics/site_ansto/anstohttp.c
Ferdi Franceschini 877b46164b Added option to get histograms from filesystem as well as from socket.
Added: direct, hmdatapath, and scanpoint config parameters.

r1492 | ffr | 2007-02-16 09:46:51 +1100 (Fri, 16 Feb 2007) | 3 lines
2012-11-15 12:59:13 +11:00

805 lines
27 KiB
C

/*
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.
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 (original SINQ version)
Mark Lesha, 9 October 2006 (ANSTO version)
----------------------------------------------------------------------*/
#include <stdlib.h>
#include <assert.h>
#include <HistDriv.i>
#include <tcl.h>
#include <ghttp.h>
#include <stptok.h>
#include <countdriv.h>
#include <zlib.h>
extern char *trim(char *);
/*===================================================================
The request strings to append to the computer address
====================================================================*/
static char startdaq[] = {"/admin/startdaq.egi"};
static char stopdaq[] = {"/admin/stopdaq.egi"};
static char pausedaq[] = {"/admin/pausedaq.egi"};
static char continuedaq[] = {"/admin/continuedaq.egi"};
static char statusdaq[] = {"/admin/textstatus.egi"};
static char gethm[] = {"/admin/readhmdata.egi"};
static char configure[] = {"/admin/configure.egi"};
static char preset[] = {"/admin/presethm.egi"};
/*====================================================================
error codes
======================================================================*/
#define BADURL -701
#define HTTPERROR -702
#define NOBODY -703
#define BODYSHORT -704
#define NOTIMPLEMENTED -705
#define SERVERERROR -706
#define BADSTATUS -707
#define BADAUTH -708
#define IMMEDFAIL -709
/*=====================================================================
our driver private data structure
======================================================================*/
#define MAXSTRLEN 512
typedef struct {
ghttp_request *syncRequest;
char hmAddress[512];
char userName[132];
char passWord[132];
char hmError[512];
int errorCode;
int pause;
int failCount;
int asyncRunning;
}anstoHttp, *pAnstoHttp;
/*------------------------------------------------------------------*/
static int anstoHttpGetPrepare(pAnstoHttp self, char *request){
char url[512];
ghttp_status httpStatus;
if(self->asyncRunning){
while((httpStatus = ghttp_process(self->syncRequest))
== ghttp_not_done){
}
self->asyncRunning = 0;
}
self->errorCode = 0;
ghttp_clean(self->syncRequest);
memset(self->hmError,0,512*sizeof(char));
snprintf(url,511,"%s%s",self->hmAddress,request);
ghttp_set_type(self->syncRequest,ghttp_type_get);
ghttp_set_header(self->syncRequest,"connection","keep-alive");
if(ghttp_set_uri(self->syncRequest,url) < 0){
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 anstoHttpCheckResponse(pAnstoHttp self){
char *pPtr = NULL;
int len;
self->failCount = 0;
pPtr = ghttp_get_body(self->syncRequest);
if(pPtr == NULL) // MJL check ghttp_get_body for NULL return
return 1; // empty response is okay
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 anstoHttpGet(pAnstoHttp self, char *request){
ghttp_status httpStatus;
char *pPtr = NULL;
if(!anstoHttpGetPrepare(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){
ghttp_close(self->syncRequest);
if (!anstoHttpGetPrepare(self,request))
return 0; // MJL return here if failed
ghttp_prepare(self->syncRequest); // MJL be sure to call ghttp_prepare before each ghttp_process
httpStatus = ghttp_process(self->syncRequest);
}
if(httpStatus != ghttp_done){
strncpy(self->hmError,"Reconnect", 511);
self->errorCode = SERVERERROR;
return 0;
} else {
return anstoHttpCheckResponse(self);
}
return 1;
}
/*====================================================================*/
static int AnstoHttpConfigure(pHistDriver self, SConnection *pCon,
pStringDict pOpt, SicsInterp *pSics){
char hmname[512];
char confCommand[512], url[512];
pAnstoHttp pPriv = NULL;
int status, iInit;
float fVal;
int i;
char *confData = NULL;
ghttp_status httpStatus;
pPriv = (pAnstoHttp)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;
}
/*
* 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.
*/
status = StringDictGetAsNumber(pOpt,"init",&fVal);
iInit = 0;
if(status == 1) {
if(fVal > 0.9 ) {
iInit = 1;
}
}
/*
actually do configure
*/
if(iInit == 1){
for(i = 0; i < 2; i++){
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
*/
ghttp_clean(pPriv->syncRequest);
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;
}
status = ghttp_set_type(pPriv->syncRequest,ghttp_type_post);
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);
if(httpStatus != ghttp_done){
/* we may need to reconnect.....
*/
if(i == 0){
ghttp_close(pPriv->syncRequest);
continue;
}
/*
* no we have a real error
*/
confData = (char *)ghttp_get_error(pPriv->syncRequest);
snprintf(confCommand,511,"ERROR: http error %s occurred",
confData);
SCWrite(pCon,confCommand,eError);
return 0;
} else if(confData != NULL){
if(strstr(confData,"ERROR") != NULL){
snprintf(confCommand,511,"%s",confData);
SCWrite(pCon,confCommand,eError);
return 0;
}
if(strstr(confData,"Authentication Error") != NULL){
snprintf(confCommand,511,"%s",confData);
SCWrite(pCon,confCommand,eError);
return 0;
}
}
}
}
}
// MJL NOTE: Added extra init parameters here, these get committed
// regardless of whether we are doing the first init or not
// (i.e. will get committed even if init=1).
// Need to do init on the histogram object (e.g. 'hm init')
// in order to commit changed settings during operation.
// Specifically, this is important if FAT settings need to be
// modified during operation. To do this, the command
// 'hm configure FAT_Xxxx vvv' needs to be performed,
// where Xxxx is the name of the item in the FAT, and vvv is the desired value.
// If the requested FAT variable doesn't exist or cannot be modified
// during operation, the set fails but no indication is given.
//
// Now, to find out what entries are FAT_Xxxx format,
/// by traversing the dictionary list.
char pValue[256];
const char *pItem=NULL;
do {
pItem=StringDictGetNext(pOpt,pValue,256);
if (pItem)
{
if (strncasecmp(pItem,"FAT_",4)==0)
{
// Try committing the setting to the histogram server
// Make special http request to set the FAT parameter
char modify_FAT_http_request[1024];
sprintf(modify_FAT_http_request,
"/admin/selectdynamicfatmodify.egi?dynamicFATmodifyparamname=%s&dynamicFATmodifyparamvalue=%s",
pItem+4,pValue);
// Send the request. When one doesn't work, drop out of the loop.
int status = anstoHttpGet(pPriv,modify_FAT_http_request);
if(status != 1)
return 0;
}
}
} while(pItem);
return 1;
}
/*--------------------------------------------------------------------*/
static int readStatus(pHistDriver pDriv){
char *pPtr = NULL, *pLinePtr;
char line[132];
char name[80], value[80];
pAnstoHttp self = NULL;
char *daqPtr = NULL, *daqValPtr = NULL;
self = (pAnstoHttp)pDriv->pPriv;
assert(self != NULL);
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,":");
strtolower(name);
if(StringDictExists(pDriv->pOption,trim(name)) == 1){
StringDictUpdate(pDriv->pOption,trim(name),trim(value));
} else {
StringDictAddPair(pDriv->pOption,trim(name),trim(value));
}
pPtr = stptok(pPtr,line,131,"\n");
}
return 1;
}
/*---------------------------------------------------------------------*/
// The status code now allows pCon==NULL to be passed in.
// This allows the status to be checked from all the start, stop, pause
// and continue callbacks, so we can wait for the server to actually
// change to the correct operating state before continuing.
static int AnstoHttpStatus(pHistDriver self,SConnection *pCon){ // pCon=NULL allowed
pAnstoHttp pPriv = NULL;
ghttp_status httpStatus;
char daqStatus[20];
int status, len;
char *pPtr = NULL;
pPriv = (pAnstoHttp)self->pPriv;
assert(pPriv != NULL);
// MJL for the ANSTO histogram server we STILL need status checking to occur
// even when in paused mode (our pause mode has a different functionality).
// So the code below is removed.
/// if(pPriv->pause == 1){
/// return HWPause;
/// }
if(pPriv->asyncRunning == 0){
status = anstoHttpGetPrepare(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);
anstoHttpGetPrepare(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:
// MJL this is not a problem, the server is just slow.
// return HWRedo not HWBusy (original) or falut
return HWRedo;
break;
case ghttp_done:
pPriv->asyncRunning = 0;
status = anstoHttpCheckResponse(pPriv);
if(status != 1){
return HWFault;
}
break;
}
status = readStatus(self);
if(status != 1){
return HWFault;
}
if(StringDictGet(self->pOption,"daq",daqStatus,20) != 1){
pPriv->errorCode = BADSTATUS;
strncpy(pPriv->hmError,"ERROR: status does not contain DAQ field",511);
return HWFault;
}
///if (pCon) SCWrite(pCon,daqStatus,eError); // MJL DEBUG
if(strstr(daqStatus,"Started") != NULL){
return HWBusy;
} else if(strstr(daqStatus,"Paused") != NULL){
return HWIdle;
} else if(strstr(daqStatus,"Stopped") != NULL){
return HWIdle;
} else {
pPriv->errorCode = BADSTATUS;
snprintf(pPriv->hmError,511,"ERROR: invalid DAQ status %s",daqStatus);
return HWFault;
}
return HWFault; // shouldn't get here
}
#define MAX_STATUS_READ_RETRIES 150
#define STATUS_READ_DELAY_US 200000
//
static int AnstoHttpStatusWithRetries(pHistDriver self, int requiredstate,SConnection *pCon) // pCon=NULL allowed
{
int retries,retcode,initialentry=1;
for(retries=0;retries<MAX_STATUS_READ_RETRIES&&(initialentry||retcode!=requiredstate);retries++)
{
retcode=AnstoHttpStatus(self,pCon);
usleep(STATUS_READ_DELAY_US);
initialentry=0;
}
return retcode;
}
/*--------------------------------------------------------------------*/
static int AnstoHttpStart(pHistDriver self, SConnection *pCon){
pAnstoHttp pPriv = NULL;
int status;
pPriv = (pAnstoHttp)self->pPriv;
assert(pPriv != NULL);
status = anstoHttpGet(pPriv,startdaq);
if(status != 1){
return HWFault;
}
AnstoHttpStatusWithRetries(self,HWBusy,pCon);
return OKOK;
}
/*---------------------------------------------------------------------*/
static int AnstoHttpHalt(pHistDriver self){ // hmm, why isn't there a pCon like all the other ones...?
pAnstoHttp pPriv = NULL;
int status;
pPriv = (pAnstoHttp)self->pPriv;
assert(pPriv != NULL);
status = anstoHttpGet(pPriv,stopdaq);
if(status != 1){
return HWFault;
}
AnstoHttpStatusWithRetries(self,HWIdle,NULL); // no pCon available :(
return OKOK;
}
/*---------------------------------------------------------------------*/
static int AnstoHttpPause(pHistDriver self,SConnection *pCon){
pAnstoHttp pPriv = NULL;
int status;
pPriv = (pAnstoHttp)self->pPriv;
assert(pPriv != NULL);
status = anstoHttpGet(pPriv,pausedaq);
if(status != 1){
return HWFault;
}
pPriv->pause = 1;
AnstoHttpStatusWithRetries(self,HWIdle,pCon);
return OKOK;
}
/*---------------------------------------------------------------------*/
static int AnstoHttpContinue(pHistDriver self, SConnection *pCon){
pAnstoHttp pPriv = NULL;
int status;
pPriv = (pAnstoHttp)self->pPriv;
assert(pPriv != NULL);
status = anstoHttpGet(pPriv,continuedaq);
if(status != 1){
return HWFault;
}
pPriv->pause = 0;
AnstoHttpStatusWithRetries(self,HWBusy,pCon);
return OKOK;
}
/*---------------------------------------------------------------------*/
static int AnstoHttpError(pHistDriver self, int *code,
char *error, int errLen){
pAnstoHttp pPriv = NULL;
int status;
pPriv = (pAnstoHttp)self->pPriv;
assert(pPriv != NULL);
strncpy(error,pPriv->hmError, errLen);
*code = pPriv->errorCode;
return OKOK;
}
/*--------------------------------------------------------------------*/
static int AnstoHttpFixIt(pHistDriver self, int code){
pAnstoHttp pPriv = NULL;
pPriv = (pAnstoHttp)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);
if(code == SERVERERROR){
pPriv->failCount++;
if(pPriv->failCount > 2){
return COTERM;
} else {
return COREDO;
}
}
return COTERM;
}
/*--------------------------------------------------------------------*/
static int AnstoHttpGetData(pHistDriver self,SConnection *pCon){
/*
* do noting, monitors are with the counter, histogram memory
* caching and retrieval is handled via GetHistogram
*/
return OKOK;
}
/*-------------------------------------------------------------------*/
/** \brief Reads histogram data from a zipped file produced by the
* histogram memory server
*
* \param self (r) provides access to the histogram data structure
* \param bank number n maps to a HDS_Pn file.
*/
static int GetHMfromFile(pHistDriver self, SConnection *pCon,
int bank, int start, int end, HistInt *data){
HistInt *hmdata;
pAnstoHttp pPriv = NULL;
int status, len, i, size;
int errMsgLen;
FILE *fp;
char command[256];
char hmDataPath[MAXSTRLEN];
char DAQdir[MAXSTRLEN];
char DSfilepath[MAXSTRLEN];
char scanpoint[32];
memset(command, 0, sizeof(command));
memset(hmDataPath, 0, sizeof(hmDataPath));
memset(DAQdir, 0, sizeof(DAQdir));
memset(DSfilepath, 0, sizeof(DSfilepath));
memset(scanpoint, 0, sizeof(scanpoint));
pPriv = (pAnstoHttp)self->pPriv;
assert(pPriv != NULL);
errMsgLen = sizeof(pPriv->hmError);
if (bank < 0) {
snprintf(pPriv->hmError,errMsgLen,"Negative bank numbers are not supported when reading from the filesystem");
pPriv->errorCode = IMMEDFAIL;
return HWFault;
}
StringDictGet(self->pOption, "daq_dirname",DAQdir, sizeof(DAQdir)-1);
StringDictGet(self->pOption, "hmdatapath",hmDataPath, sizeof(hmDataPath)-1);
StringDictGet(self->pOption, "scanpoint",scanpoint, sizeof(scanpoint)-1);
snprintf(DSfilepath,sizeof(DSfilepath),"%s/%s/DATASET_%s/HDS_P%d",hmDataPath,DAQdir,scanpoint,bank);
if ((fp=gzopen(DSfilepath, "rb")) == NULL) {
snprintf(pPriv->hmError,errMsgLen,"Failed to open hm data file for reading");
pPriv->errorCode = IMMEDFAIL;
return HWFault;
}
size = end - start;
gzread(fp, data, size*sizeof(HistInt));
data+=size;
start+=size;
gzclose(fp);
return OKOK;
}
/**\brief Gets histogram data directly from the histogram memory http server.
*/
static int GetHMfromSocket(pHistDriver self, SConnection *pCon,
int bank, int start, int end, HistInt *data){
char command[256];
HistInt *hmdata;
pAnstoHttp pPriv = NULL;
int status, len, i;
// For the ANSTO Histogram Server, the transfer size may be large
// and this can lead to transmission of the data from the server in chunks.
// This is apparent from the presence of 'xxxxx; chunk length nnnnnn' in the
// data when the transfer size is greater than 128K.
// e.g. a request for 64K elements is split into two chunks,
// and each has the header '20000; chunk length 131072'.
// However for some reason ghttp_get_body_len returns only the data size,
// even though there are header(s) added to the data.
// So, for the time being we play it safe and divide the transfer
// into chunks of less than 128KB.
//
// MJL 22/11/06: Found that AppWeb 2.1.0 supports HTTP 1.1 chunking,
// but this can be turned off by specifying HttpChunking off in the AppWeb
// config file, which is what we do currently, so the transfer size limitation code below
// is no longer needed. I've left it in with a much larger size restriction,
// just in case it's required later on for any reason (to improve transfer reliability?).
// Apparently the AppWeb 2.1.0 HTTP chunking feature is broken, because when the
// data is opened directly from the web server using an editor like KHexEdit, the open
// stalls for large data sizes unless chunking is disabled. This shows it is
// an AppWeb problem, not a ghttp problem.
// For AppWeb versions before 2.1.0, HTTP chunking is not available anyway.
pPriv = (pAnstoHttp)self->pPriv;
assert(pPriv != NULL);
// How this limit is set in the server is not obvious... anyway, it should not change.
// MJL 22/11/06: Turned HTTP 1.1 chunking off at the histogram server, so we no longer
// need a size restriction. Leave the code in just in case it's needed for other reasons,
// but set a larger maximum request size.
//#define MAX_HTTP_REQUEST_BYTES 131072
#define MAX_HTTP_REQUEST_BYTES 1048576
// Do the HTTP data transfer in bite sized pieces
while(end>start)
{
int size=((end-start)>(MAX_HTTP_REQUEST_BYTES/sizeof(int)))
?(MAX_HTTP_REQUEST_BYTES/sizeof(int)):(end-start);
snprintf(command,255,"%s?bank=%d&start=%d&end=%d",gethm,bank,
start,start+size);
status = anstoHttpGet(pPriv,command);
if(status != 1){
return HWFault;
}
len = ghttp_get_body_len(pPriv->syncRequest);
if(len < size*sizeof(int)){
pPriv->errorCode = BODYSHORT;
strncpy(pPriv->hmError,"Not enough data received from HM",511);
return HWFault;
}
hmdata = (HistInt *)ghttp_get_body(pPriv->syncRequest);
if(hmdata == NULL){ // MJL check ghttp_get_body for NULL return
pPriv->errorCode = NOBODY;
strncpy(pPriv->hmError,"No body in HM data response",511);
return HWFault;
}
// MJL removed the ntohl, our histogram server doesn't apply htonl,
// so the data arrives in LE format. (Would have to buffer data
// at the server otherwise...)
// Doubt this will raise any conpatibility issues.
for(i = 0; i < size; i++){
//data[i] = ntohl(hmdata[i]);
data[i] = hmdata[i];
}
data+=size;
start+=size;
}
return OKOK;
}
static int AnstoHttpGetHistogram(pHistDriver self, SConnection *pCon,
int bank, int start, int end, HistInt *data){
char direct[2];
StringDictGet(self->pOption, "direct",direct, 2);
if (strcmp(direct,"1") == 0)
return GetHMfromSocket(self, pCon, bank, start, end, data);
else
return GetHMfromFile(self, pCon, bank, start, end, data);
}
/*--------------------------------------------------------------------*/
static int AnstoHttpSetHistogram(pHistDriver self, SConnection *pCon,
int bank, int start, int end, HistInt *data){
pAnstoHttp pPriv = NULL;
pPriv = (pAnstoHttp)self->pPriv;
assert(pPriv != NULL);
pPriv->errorCode = NOTIMPLEMENTED;
strncpy(pPriv->hmError,"Not implemented",511);
return HWFault;
}
/*---------------------------------------------------------------------*/
static long AnstoHttpGetMonitor(pHistDriver self, int i,
SConnection *pCon){
return 0;
}
/*---------------------------------------------------------------------*/
static float AnstoHttpGetTime(pHistDriver self, SConnection *pCon){
return -999.99;
}
/*---------------------------------------------------------------------*/
static int AnstoHttpPreset(pHistDriver self, SConnection *pCon, int val){
pAnstoHttp pPriv = NULL;
int status;
char command[512];
pPriv = (pAnstoHttp)self->pPriv;
assert(pPriv != NULL);
snprintf(command,512,"%s?value=%d",preset,val);
status = anstoHttpGet(pPriv,command);
if(status != 1){
return HWFault;
}
return 1;
}
/*---------------------------------------------------------------------*/
static int AnstoHttpFreePrivate(pHistDriver self){
pAnstoHttp pPriv = NULL;
pPriv = (pAnstoHttp)self->pPriv;
if(pPriv == NULL){
return 1;
}
if(pPriv->syncRequest != NULL){
ghttp_request_destroy(pPriv->syncRequest);
}
free(pPriv);
return 1;
}
/*-------------------------------------------------------------------*/
pHistDriver CreateAnstoHttpDriver(pStringDict pOption){
pHistDriver pNew = NULL;
pAnstoHttp 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 = (pAnstoHttp)malloc(sizeof(anstoHttp));
if(!pInternal){
free(pNew);
return NULL;
}
memset(pInternal,0,sizeof(anstoHttp));
pNew->pPriv = pInternal;
pInternal->syncRequest = ghttp_request_new();
memset(pInternal->hmError,0,sizeof(pInternal->hmError));
if(pInternal->syncRequest == NULL){
free(pNew);
free(pInternal);
return NULL;
}
/* direct = 0 Get HM from data files
* direct = 1 Get HM from http server */
StringDictAddPair(pOption, "direct", "1");
StringDictAddPair(pOption, "hmdatapath", "../HMData");
StringDictAddPair(pOption, "scanpoint", "0");
/* configure all those functions */
pNew->Configure = AnstoHttpConfigure;
pNew->Start = AnstoHttpStart;
pNew->Halt = AnstoHttpHalt;
pNew->GetCountStatus = AnstoHttpStatus;
pNew->GetError = AnstoHttpError;
pNew->TryAndFixIt = AnstoHttpFixIt;
pNew->GetData = AnstoHttpGetData;
pNew->GetHistogram = AnstoHttpGetHistogram;
pNew->SetHistogram = AnstoHttpSetHistogram;
pNew->GetMonitor = AnstoHttpGetMonitor;
pNew->GetTime = AnstoHttpGetTime;
pNew->Preset = AnstoHttpPreset;
pNew->FreePrivate = AnstoHttpFreePrivate;
pNew->Pause = AnstoHttpPause;
pNew->Continue = AnstoHttpContinue;
return pNew;
}