- Added two new protocols: for the Juelich chopper and for SINQHM HTTP
This commit is contained in:
80
julprot.c
Normal file
80
julprot.c
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/**
|
||||||
|
* This is a protocol implementation for the new SICS asynchronous I/O
|
||||||
|
* infrastructure and the Juelich chopper system as used at MARS.
|
||||||
|
*
|
||||||
|
* The Juelich chopper control program likes checksums to come with
|
||||||
|
* messages and uses $ as both send and reply terminators.
|
||||||
|
*
|
||||||
|
* copyright: see file COPYRIGHT
|
||||||
|
*
|
||||||
|
* Mark Koennecke, June 2008
|
||||||
|
*/
|
||||||
|
#include <errno.h>
|
||||||
|
#include <ascon.h>
|
||||||
|
#include <ascon.i>
|
||||||
|
#include <dynstring.h>
|
||||||
|
|
||||||
|
static int calculateJulCheckSum(char *realCommand){
|
||||||
|
int i, checkSum = 0;
|
||||||
|
|
||||||
|
for(i = 1; i < strlen(realCommand); i++){
|
||||||
|
checkSum += (int)realCommand[i];
|
||||||
|
}
|
||||||
|
return checkSum;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
int JulchoHandler(Ascon *a){
|
||||||
|
char *data = NULL;
|
||||||
|
int checkSum, ret;
|
||||||
|
char checkBuffer[30], chr;
|
||||||
|
|
||||||
|
switch(a->state){
|
||||||
|
case AsconWriteStart:
|
||||||
|
data = GetCharArray(a->wrBuffer);
|
||||||
|
checkSum = calculateJulCheckSum(data);
|
||||||
|
snprintf(checkBuffer,30,"{%d}$", checkSum);
|
||||||
|
DynStringConcat(a->wrBuffer,checkBuffer);
|
||||||
|
a->state = AsconWriting;
|
||||||
|
a->wrPos = 0;
|
||||||
|
break;
|
||||||
|
case AsconReading:
|
||||||
|
ret = AsconReadChar(a->fd, &chr);
|
||||||
|
if(ret < 0){
|
||||||
|
AsconError(a, "AsconReadChar failed:", errno);
|
||||||
|
return 1;
|
||||||
|
} else if (ret > 0) {
|
||||||
|
a->start = DoubleTime();
|
||||||
|
if(chr == '$'){
|
||||||
|
DynStringConcatChar(a->rdBuffer, '\0');
|
||||||
|
a->state = AsconReadDone;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
if (DynStringConcatChar(a->rdBuffer, chr) == 0) {
|
||||||
|
AsconError(a, "DynStringConcatChar failed:", ENOMEM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(ret == 0){
|
||||||
|
if (a->timeout > 0) {
|
||||||
|
if (DoubleTime() - a->start > a->timeout) {
|
||||||
|
AsconError(a, "read timeout", 0);
|
||||||
|
a->state = AsconTimeout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return AsconStdHandler(a);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
void AddJulChoProtocoll(){
|
||||||
|
AsconProtocol *prot = NULL;
|
||||||
|
|
||||||
|
prot = calloc(sizeof(AsconProtocol), 1);
|
||||||
|
prot->name = strdup("julcho");
|
||||||
|
prot->init = AsconStdInit;
|
||||||
|
prot->handler = JulchoHandler;
|
||||||
|
AsconInsertProtocol(prot);
|
||||||
|
}
|
2
make_gen
2
make_gen
@ -22,7 +22,7 @@ OBJ=psi.o buffer.o ruli.o dmc.o nxsans.o nextrics.o sps.o pimotor.o \
|
|||||||
$(MZOBJ) amordrive.o amorset.o tcpdornier.o sinqhttp.o\
|
$(MZOBJ) amordrive.o amorset.o tcpdornier.o sinqhttp.o\
|
||||||
dgrambroadcast.o sinq.o tabledrive.o tcpdocho.o julcho.o \
|
dgrambroadcast.o sinq.o tabledrive.o tcpdocho.o julcho.o \
|
||||||
ritastorage.o poldizug.o audinelib.o delcam.o el737hpdrivsps.o \
|
ritastorage.o poldizug.o audinelib.o delcam.o el737hpdrivsps.o \
|
||||||
rebin.o sanslirebin.o lmd200.o slsvme.o
|
rebin.o sanslirebin.o lmd200.o slsvme.o julprot.o sinqhttpprot.o
|
||||||
|
|
||||||
.SECONDARY.: sanslirebin.c
|
.SECONDARY.: sanslirebin.c
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ include ../sllinux_def
|
|||||||
|
|
||||||
CC = gcc
|
CC = gcc
|
||||||
CFLAGS = -I$(HDFROOT)/include -DHDF4 -DHDF5 $(NI) -Ihardsup \
|
CFLAGS = -I$(HDFROOT)/include -DHDF4 -DHDF5 $(NI) -Ihardsup \
|
||||||
-I.. -DCYGNUS -DNONINTF -g $(DFORTIFY) \
|
-I.. -DCYGNUS -DNONINTF -g $(DFORTIFY) \
|
||||||
-Wall -Wno-unused -Wno-comment -Wno-switch -Werror
|
-Wall -Wno-unused -Wno-comment -Wno-switch -Werror
|
||||||
|
|
||||||
EXTRA=nintf.o
|
EXTRA=nintf.o
|
||||||
|
11
psi.c
11
psi.c
@ -75,6 +75,11 @@ extern int MakeSansliRebin(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|||||||
/* from lmd200.c */
|
/* from lmd200.c */
|
||||||
extern int MakeLMD200(SConnection *pCon, SicsInterp *pSics, void *pData,
|
extern int MakeLMD200(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
int argc, char *argv[]);
|
int argc, char *argv[]);
|
||||||
|
/* from julchoprot.c */
|
||||||
|
extern void AddJulChoProtocoll();
|
||||||
|
/* from sinqhttpprot.c */
|
||||||
|
extern void AddHttpProtocoll();
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
void SiteInit(void) {
|
void SiteInit(void) {
|
||||||
|
|
||||||
@ -94,6 +99,12 @@ void SiteInit(void) {
|
|||||||
INIT(HaakeStartup);
|
INIT(HaakeStartup);
|
||||||
INIT(AmiStartup);
|
INIT(AmiStartup);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SICS specific Asynchronous I/O protocols
|
||||||
|
*/
|
||||||
|
AddJulChoProtocoll();
|
||||||
|
AddHttpProtocoll();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
221
sinqhttpprot.c
Normal file
221
sinqhttpprot.c
Normal file
@ -0,0 +1,221 @@
|
|||||||
|
/**
|
||||||
|
* This is an asynchronous protocol implementation for HTTP.
|
||||||
|
* It includes special features to store binary data coming
|
||||||
|
* from a SINQ http histogram memory in a sinqdata object.
|
||||||
|
* Which has to be specified on initialisation.
|
||||||
|
*
|
||||||
|
* copyright: see file COPYRIGHT
|
||||||
|
*
|
||||||
|
* Mark Koennecke, June 2008
|
||||||
|
*/
|
||||||
|
#include <ascon.h>
|
||||||
|
#include <ascon.i>
|
||||||
|
#include <ghttp.h>
|
||||||
|
#include <sicsdata.h>
|
||||||
|
#include <HistMem.h>
|
||||||
|
/*---------------------------------------------------------------------*/
|
||||||
|
typedef struct {
|
||||||
|
ghttp_request *request;
|
||||||
|
char *userName;
|
||||||
|
char *password;
|
||||||
|
pSICSData binData;
|
||||||
|
}HttpProt, *pHttpProt;
|
||||||
|
/*---------------------------------------------------------------------*/
|
||||||
|
static int configRequest(Ascon *a){
|
||||||
|
pHttpProt pHttp = (pHttpProt)a->private;
|
||||||
|
pDynString request;
|
||||||
|
char *uri = NULL;
|
||||||
|
|
||||||
|
request = CreateDynString(64,64);
|
||||||
|
if(request == NULL){
|
||||||
|
AsconError(a,"Out of memory", 122);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
DynStringConcat(request,"http://");
|
||||||
|
DynStringConcat(request,a->hostport);
|
||||||
|
DynStringConcatChar(request,'/');
|
||||||
|
DynStringConcat(request,GetCharArray(a->wrBuffer));
|
||||||
|
uri = GetCharArray(request);
|
||||||
|
|
||||||
|
ghttp_clean(pHttp->request);
|
||||||
|
ghttp_set_type(pHttp->request,ghttp_type_get);
|
||||||
|
ghttp_set_header(pHttp->request,"connection", "keep-alive");
|
||||||
|
if(ghttp_set_uri(pHttp->request,uri) < 0){
|
||||||
|
AsconError(a,"Bad URL", a->state);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(pHttp->userName != NULL && pHttp->password != NULL){
|
||||||
|
ghttp_set_authinfo(pHttp->request,
|
||||||
|
pHttp->userName, pHttp->password);
|
||||||
|
}
|
||||||
|
ghttp_set_sync(pHttp->request,ghttp_async);
|
||||||
|
ghttp_prepare(pHttp->request);
|
||||||
|
DeleteDynString(request);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------*/
|
||||||
|
static int HttpHandler(Ascon *a) {
|
||||||
|
ghttp_status status;
|
||||||
|
pHttpProt pHttp = (pHttpProt)a->private;
|
||||||
|
char *pPtr = NULL, *pType = NULL;
|
||||||
|
HistInt *hmData = NULL;
|
||||||
|
int i, len;
|
||||||
|
|
||||||
|
switch (a->state) {
|
||||||
|
case AsconKillMe: return 0;
|
||||||
|
case AsconConnectStart:
|
||||||
|
a->state = AsconConnecting;
|
||||||
|
break;
|
||||||
|
case AsconConnecting:
|
||||||
|
a->state = AsconConnectDone; /* success */
|
||||||
|
break;
|
||||||
|
case AsconWriteStart:
|
||||||
|
if(configRequest(a)){
|
||||||
|
a->state = AsconWriting;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case AsconWriting:
|
||||||
|
status = ghttp_process(pHttp->request);
|
||||||
|
if(status == ghttp_error){
|
||||||
|
ghttp_close(pHttp->request);
|
||||||
|
configRequest(a);
|
||||||
|
status = ghttp_process(pHttp->request);
|
||||||
|
}
|
||||||
|
if(status == ghttp_error){
|
||||||
|
AsconError(a,"Server error", 123);
|
||||||
|
DynStringConcat(a->rdBuffer,"Server error");
|
||||||
|
a->state = AsconReadDone;
|
||||||
|
} else {
|
||||||
|
a->state = AsconWriteDone;
|
||||||
|
}
|
||||||
|
a->start = DoubleTime();
|
||||||
|
DynStringClear(a->rdBuffer);
|
||||||
|
break;
|
||||||
|
case AsconReadStart:
|
||||||
|
status = ghttp_process(pHttp->request);
|
||||||
|
switch(status){
|
||||||
|
case ghttp_not_done:
|
||||||
|
if(DoubleTime() > a->start + a->timeout){
|
||||||
|
AsconError(a," read timeout", 0);
|
||||||
|
a->state = AsconTimeout;
|
||||||
|
/* this to clear the line */
|
||||||
|
ghttp_close(pHttp->request);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
case ghttp_done:
|
||||||
|
a->state = AsconReading;
|
||||||
|
break;
|
||||||
|
case ghttp_error:
|
||||||
|
/*
|
||||||
|
* A first error may not be an error but a
|
||||||
|
* reconnect
|
||||||
|
*/
|
||||||
|
ghttp_close(pHttp->request);
|
||||||
|
configRequest(a);
|
||||||
|
status = ghttp_process(pHttp->request);
|
||||||
|
if(status == ghttp_error){
|
||||||
|
AsconError(a,"Server error", a->state);
|
||||||
|
DynStringConcat(a->rdBuffer,"Server error");
|
||||||
|
a->state = AsconReadDone;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("Hugo\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case AsconReading:
|
||||||
|
pPtr = ghttp_get_body(pHttp->request);
|
||||||
|
len = ghttp_get_body_len(pHttp->request);
|
||||||
|
if(strstr(pPtr,"ERROR") != NULL){
|
||||||
|
AsconError(a,pPtr, a->state);
|
||||||
|
DynStringConcat(a->rdBuffer,pPtr);
|
||||||
|
} else if(strstr(pPtr,"Authentication Error") != NULL){
|
||||||
|
DynStringConcat(a->rdBuffer,pPtr);
|
||||||
|
AsconError(a,pPtr, a->state);
|
||||||
|
} else {
|
||||||
|
pType = (char *)ghttp_get_header(pHttp->request,"Content-Type");
|
||||||
|
if(strstr(pType,"sinqhm") == NULL){
|
||||||
|
/* text data */
|
||||||
|
for(i = 0; i < len; i++){
|
||||||
|
DynStringConcatChar(a->rdBuffer, pPtr[i]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hmData = (HistInt *)pPtr;
|
||||||
|
clearSICSData(pHttp->binData);
|
||||||
|
for(i = 0; i < len/sizeof(HistInt); i++){
|
||||||
|
setSICSDataInt(pHttp->binData, i, htonl(hmData[i]));
|
||||||
|
}
|
||||||
|
DynStringCopy(a->rdBuffer,"SICSDATA");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a->state = AsconReadDone;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return AsconStdHandler(a);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
static void killHttp(void *data){
|
||||||
|
pHttpProt prot = (pHttpProt)data;
|
||||||
|
if(prot == NULL){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(prot->request != NULL){
|
||||||
|
ghttp_close(prot->request);
|
||||||
|
}
|
||||||
|
if(prot->password != NULL){
|
||||||
|
free(prot->password);
|
||||||
|
}
|
||||||
|
if(prot->userName != NULL){
|
||||||
|
free(prot->userName);
|
||||||
|
}
|
||||||
|
free(prot);
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
static int HttpProtInit(Ascon *a, SConnection *con,
|
||||||
|
int argc, char *argv[]){
|
||||||
|
pHttpProt pHttp = NULL;
|
||||||
|
|
||||||
|
pHttp = calloc(sizeof(HttpProt), 1);
|
||||||
|
if(pHttp == NULL){
|
||||||
|
SCWrite(con,"ERROR: out of memory in HttpProtInit", eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(argc < 3){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
a->hostport = strdup(argv[1]);
|
||||||
|
pHttp->binData = (pSICSData)FindCommandData(pServ->pSics,
|
||||||
|
argv[2], "SICSData");
|
||||||
|
if(pHttp->binData == NULL){
|
||||||
|
SCWrite(con,"ERROR: SICSData objct not found", eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(argc > 3){
|
||||||
|
a->timeout = atof(argv[3]);
|
||||||
|
} else {
|
||||||
|
a->timeout = 10.;
|
||||||
|
}
|
||||||
|
if(argc > 5){
|
||||||
|
pHttp->userName = strdup(argv[4]);
|
||||||
|
pHttp->password = strdup(argv[5]);
|
||||||
|
}
|
||||||
|
pHttp->request = ghttp_request_new();
|
||||||
|
a->private = pHttp;
|
||||||
|
a->killPrivate = killHttp;
|
||||||
|
a->state = AsconConnectStart;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
void AddHttpProtocoll(){
|
||||||
|
AsconProtocol *prot = NULL;
|
||||||
|
|
||||||
|
prot = calloc(sizeof(AsconProtocol), 1);
|
||||||
|
prot->name = strdup("sinqhttp");
|
||||||
|
prot->init = HttpProtInit;
|
||||||
|
prot->handler = HttpHandler;
|
||||||
|
AsconInsertProtocol(prot);
|
||||||
|
}
|
Reference in New Issue
Block a user