
- Fixed some issues with error returns not being properly handled in devexec - Fixed a bug in motorlist which caused limit checks to fail - Fixed an issue with the TDCHM not properly updating the counter values on finish - Readded getHipadabaPar in ChainCallback as this caused a problem in ei - Made tasdrive ignore sgu, sgl when out of plane not allowed
757 lines
20 KiB
C
757 lines
20 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
|
|
|
|
----------------------------------------------------------------------*/
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
#include <HistDriv.i>
|
|
#include <tcl.h>
|
|
#include <ghttp.h>
|
|
#include <stptok.h>
|
|
#include <countdriv.h>
|
|
#include <trace.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" };
|
|
static char subsample[] = { "/admin/processhmdata.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 HMNOMEMORY -709
|
|
#define BADSUBSAMPLE -710
|
|
/*=====================================================================
|
|
our driver private data structure
|
|
======================================================================*/
|
|
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;
|
|
int tricsswap;
|
|
} sinqHttp, *pSinqHttp;
|
|
/*------------------------------------------------------------------*/
|
|
static int sinqHttpGetPrepare(pSinqHttp 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 sinqHttpCheckResponse(pSinqHttp self)
|
|
{
|
|
char *pPtr = NULL;
|
|
int len;
|
|
|
|
self->failCount = 0;
|
|
pPtr = ghttp_get_body(self->syncRequest);
|
|
if (pPtr == NULL) {
|
|
return 1;
|
|
}
|
|
len = ghttp_get_body_len(self->syncRequest);
|
|
if (len > 511) {
|
|
len = 510;
|
|
}
|
|
if (strstr(pPtr, "ERROR") != NULL) {
|
|
memset(self->hmError, 0, 512 * sizeof(char));
|
|
strlcpy(self->hmError, pPtr, sizeof(self->hmError));
|
|
self->errorCode = HTTPERROR;
|
|
return 0;
|
|
} else if (strstr(pPtr, "Authentication Error") != NULL) {
|
|
memset(self->hmError, 0, 512 * sizeof(char));
|
|
strlcpy(self->hmError, pPtr, sizeof(self->hmError));
|
|
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);
|
|
traceIO(self->hmAddress,"OUT:%s",request);
|
|
httpStatus = ghttp_process(self->syncRequest);
|
|
if (httpStatus != ghttp_done) {
|
|
ghttp_close(self->syncRequest);
|
|
sinqHttpGetPrepare(self, request);
|
|
ghttp_prepare(self->syncRequest);
|
|
httpStatus = ghttp_process(self->syncRequest);
|
|
}
|
|
if (httpStatus != ghttp_done) {
|
|
strlcpy(self->hmError, "Reconnect", 511);
|
|
self->errorCode = SERVERERROR;
|
|
return 0;
|
|
} else {
|
|
traceIO(self->hmAddress,"IN:%s",request);
|
|
return sinqHttpCheckResponse(self);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/*====================================================================*/
|
|
static int SinqHttpConfigure(pHistDriver self, SConnection * pCon,
|
|
pStringDict pOpt, SicsInterp * pSics)
|
|
{
|
|
char hmname[512], buffer[132];
|
|
char confCommand[512], url[512];
|
|
pSinqHttp pPriv = NULL;
|
|
int status, iInit;
|
|
float fVal;
|
|
int i;
|
|
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;
|
|
}
|
|
|
|
/*
|
|
* 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;
|
|
}
|
|
}
|
|
|
|
status = StringDictGet(pOpt,"tricsswap", buffer, sizeof(buffer));
|
|
if(status == 1){
|
|
pPriv->tricsswap = atoi(buffer);
|
|
}
|
|
/*
|
|
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);
|
|
/* puts(confData); */
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
/*---------------------------------------------------------------------*/
|
|
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;
|
|
}
|
|
/*--------------------------------------------------------------------*/
|
|
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);
|
|
|
|
status = sinqHttpGet(pPriv, continuedaq);
|
|
if (status != 1) {
|
|
return HWFault;
|
|
}
|
|
pPriv->pause = 0;
|
|
return 1;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------*/
|
|
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) {
|
|
strlcpy(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;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------*/
|
|
static int SinqHttpStatus(pHistDriver self, SConnection * pCon)
|
|
{
|
|
pSinqHttp pPriv = NULL;
|
|
ghttp_status httpStatus;
|
|
char daqStatus[20];
|
|
int status, len;
|
|
char *pPtr = NULL;
|
|
|
|
pPriv = (pSinqHttp) self->pPriv;
|
|
assert(pPriv != NULL);
|
|
|
|
if (pPriv->pause == 1) {
|
|
return HWPause;
|
|
}
|
|
|
|
if (pPriv->asyncRunning == 0) {
|
|
status = sinqHttpGetPrepare(pPriv, statusdaq);
|
|
traceIO(pPriv->hmAddress,"OUT:%s", 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) {
|
|
strlcpy(pPriv->hmError, "Reconnect", 511);
|
|
pPriv->errorCode = SERVERERROR;
|
|
pPriv->asyncRunning = 0;
|
|
return HWFault;
|
|
}
|
|
break;
|
|
case ghttp_not_done:
|
|
return HWBusy;
|
|
break;
|
|
case ghttp_done:
|
|
pPriv->asyncRunning = 0;
|
|
status = sinqHttpCheckResponse(pPriv);
|
|
if (status != 1) {
|
|
return HWFault;
|
|
}
|
|
traceIO(pPriv->hmAddress,"IN:%s", statusdaq);
|
|
break;
|
|
}
|
|
|
|
status = readStatus(self);
|
|
if (status != 1) {
|
|
return HWFault;
|
|
}
|
|
|
|
if (StringDictGet(self->pOption, "daq", daqStatus, 20) != 1) {
|
|
pPriv->errorCode = BADSTATUS;
|
|
strlcpy(pPriv->hmError, "ERROR: status does not contain DAQ field",
|
|
511);
|
|
return HWFault;
|
|
}
|
|
if (strstr(daqStatus, "1") != NULL) {
|
|
return HWBusy;
|
|
} else if (strstr(daqStatus, "0") != NULL) {
|
|
return HWIdle;
|
|
} else {
|
|
pPriv->errorCode = BADSTATUS;
|
|
snprintf(pPriv->hmError, 511, "ERROR: invalid DAQ status %s",
|
|
daqStatus);
|
|
return HWFault;
|
|
}
|
|
|
|
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);
|
|
|
|
strlcpy(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);
|
|
if (code == SERVERERROR) {
|
|
pPriv->failCount++;
|
|
if (pPriv->failCount > 2) {
|
|
return COTERM;
|
|
} else {
|
|
return COREDO;
|
|
}
|
|
}
|
|
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;
|
|
}
|
|
/*-------------------------------------------------------------------
|
|
* This is an ugly hack to swap TRICS data into the
|
|
* correct order.
|
|
*/
|
|
static void swapTrics(HistInt *data, pHMdata hmdata, int length)
|
|
{
|
|
int x,y, xdim, ydim;
|
|
HistInt *tmpData = NULL, val;
|
|
|
|
/*
|
|
* do nothing if no match
|
|
*/
|
|
xdim = hmdata->iDim[0];
|
|
ydim = hmdata->iDim[1];
|
|
if(xdim*ydim < length){
|
|
return;
|
|
}
|
|
tmpData = malloc(length*sizeof(HistInt));
|
|
if(tmpData == NULL){
|
|
return;
|
|
}
|
|
memcpy(tmpData, data, length*sizeof(HistInt));
|
|
for(y = 0; y < ydim; y++){
|
|
for(x = 0; x < xdim; x++){
|
|
val = tmpData[x*ydim + y];
|
|
data[y*xdim+x] = val;
|
|
}
|
|
}
|
|
free(tmpData);
|
|
}
|
|
/*-------------------------------------------------------------------*/
|
|
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;
|
|
long dataSum = 0;
|
|
|
|
pPriv = (pSinqHttp) self->pPriv;
|
|
assert(pPriv != NULL);
|
|
|
|
snprintf(command, 255, "%s?bank=%d&start=%d&end=%d", gethm, bank,
|
|
start, end);
|
|
|
|
/* printf("SinqHttpGetHistogram:%d-%d\n", 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;
|
|
strlcpy(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]);
|
|
dataSum += data[i];
|
|
}
|
|
/* printf("Read %ld counts from HM\n", dataSum); */
|
|
|
|
if(pPriv->tricsswap == 1){
|
|
swapTrics(data, self->data, end-start);
|
|
} else if(pPriv->tricsswap == 2) {
|
|
memcpy(data,hmdata,(end-start)*sizeof(HistInt));
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
static HistInt *SinqHttpSubSample(pHistDriver self, SConnection * pCon,
|
|
int bank, char *hmcommand)
|
|
{
|
|
char command[1024];
|
|
HistInt *hmdata = NULL;
|
|
HistInt *resultdata = NULL;
|
|
pSinqHttp pPriv = NULL;
|
|
int status, len, i;
|
|
|
|
pPriv = (pSinqHttp) self->pPriv;
|
|
assert(pPriv != NULL);
|
|
|
|
snprintf(command, 1023, "%s?bank=%d&command=%s", subsample, bank,
|
|
hmcommand);
|
|
|
|
status = sinqHttpGet(pPriv, command);
|
|
if (status != 1) {
|
|
if(pCon != NULL){
|
|
SCPrintf(pCon,eError,"ERROR: subsampling failed with %s", pPriv->hmError);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
len = ghttp_get_body_len(pPriv->syncRequest);
|
|
if (len <= 0) {
|
|
strlcpy(pPriv->hmError, "ERROR: no data returned from subsampling",
|
|
511);
|
|
pPriv->errorCode = BADSUBSAMPLE;
|
|
return NULL;
|
|
}
|
|
resultdata = malloc(len + 4);
|
|
if (resultdata == NULL) {
|
|
strlcpy(pPriv->hmError,
|
|
"ERROR: failed to allocate buffer for subsampling results",
|
|
511);
|
|
pPriv->errorCode = HMNOMEMORY;
|
|
return NULL;
|
|
}
|
|
resultdata[0] = len / sizeof(HistInt);
|
|
hmdata = (HistInt *) ghttp_get_body(pPriv->syncRequest);
|
|
for (i = 0; i < len / sizeof(HistInt); i++) {
|
|
resultdata[i + 1] = ntohl(hmdata[i]);
|
|
}
|
|
return resultdata;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------*/
|
|
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;
|
|
strlcpy(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 SinqHttpFreePrivate(pHistDriver self)
|
|
{
|
|
pSinqHttp pPriv = NULL;
|
|
|
|
pPriv = (pSinqHttp) self->pPriv;
|
|
if (pPriv == NULL) {
|
|
return 1;
|
|
}
|
|
|
|
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->syncRequest = ghttp_request_new();
|
|
if (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->GetHistogram = SinqHttpGetHistogram;
|
|
pNew->SubSample = SinqHttpSubSample;
|
|
pNew->GetMonitor = SinqHttpGetMonitor;
|
|
pNew->GetTime = SinqHttpGetTime;
|
|
pNew->Preset = SinqHttpPreset;
|
|
pNew->FreePrivate = SinqHttpFreePrivate;
|
|
pNew->Pause = SinqHttpPause;
|
|
pNew->Continue = SinqHttpContinue;
|
|
|
|
return pNew;
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
int isSINQHTTP(pHistDriver self){
|
|
if(self->Start == SinqHttpStart){
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|