- Currently disabled attempts at logging commands
- Added a warning for excessive data rates on monitors - Added statistics to devser and thus to scriptcontext - Added byte concatenation to dynstring - Added aborting for reflection generation to fourmess.c - Added data checksum testing to hipadaba, use for update tests - Fixed interrupt discovery in network.c, caused invalid interrupt codes which in turn confused sicscron which had to be fixed too. - Renamed ubcalc into ubcalcint in order to reclaim the ubcalc for Jurg - Added an a3offset to tasub in order to fix what I perceive an IS problem - Added support for the newer version of the Siemens SPS, the S7 - Added a not yet fully working sinqhttpopt driver which talks to http HM without libghttp SKIPPED: psi/delcam.c psi/make_gen psi/psi.c psi/sinq.c psi/sinq.h psi/sinqhttpopt.c psi/slsvme.c psi/spss7.c
This commit is contained in:
154
genbinprot.c
Normal file
154
genbinprot.c
Normal file
@ -0,0 +1,154 @@
|
||||
/*
|
||||
* genbinprot.c
|
||||
*
|
||||
* This is a generic binary protocol handler for scriptcontext. It expects a
|
||||
* command of the form:
|
||||
*
|
||||
* writepointer:writecount:readpointer:readcount
|
||||
*
|
||||
* And will writecount bytes from the data area writepointer and
|
||||
* read readcount bytes into the memory area under readpointer.
|
||||
* If writecount is 0, the nothing will be written. This can
|
||||
* be used to read a binary message in parts. Both writepointer and
|
||||
* readpointer are memory addresses in hexadecimal.
|
||||
*
|
||||
* This is a workaround for the essential weakness of devser not being
|
||||
* able to work with binary protocols.
|
||||
*
|
||||
* Created on: Jul 7, 2010
|
||||
* Author: koennecke
|
||||
*/
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <sics.h>
|
||||
#include <ascon.h>
|
||||
#include <ascon.i>
|
||||
#include <stptok.h>
|
||||
|
||||
/*-----------------------------------------------------------------*/
|
||||
typedef struct {
|
||||
char *writePointer;
|
||||
unsigned int toWrite;
|
||||
char *readPointer;
|
||||
unsigned int readCount;
|
||||
unsigned int toRead;
|
||||
}GenBin, *pGenBin;
|
||||
/*------------------------------------------------------------------*/
|
||||
static void initGenBin(Ascon *a)
|
||||
{
|
||||
pGenBin self = (pGenBin)a->private;
|
||||
char *pPtr = NULL, pToken[60];
|
||||
long lval;
|
||||
|
||||
pPtr = GetCharArray(a->wrBuffer);
|
||||
|
||||
pPtr = stptok(pPtr,pToken,60,":");
|
||||
sscanf(pToken,"%lx",&lval);
|
||||
self->writePointer = (char *)lval;
|
||||
|
||||
pPtr = stptok(pPtr,pToken,60,":");
|
||||
sscanf(pToken,"%d",&self->toWrite);
|
||||
|
||||
pPtr = stptok(pPtr,pToken,60,":");
|
||||
sscanf(pToken,"%lx",&lval);
|
||||
self->readPointer = (char *)lval;
|
||||
|
||||
pPtr = stptok(pPtr,pToken,60,":");
|
||||
sscanf(pToken,"%d",&self->toRead);
|
||||
|
||||
a->wrPos = 0;
|
||||
self->readCount = 0;
|
||||
}
|
||||
/*------------------------------------------------------------------*/
|
||||
static int GenBinHandler(Ascon *a)
|
||||
{
|
||||
pGenBin self = (pGenBin)a->private;
|
||||
unsigned int toWrite;
|
||||
int ret;
|
||||
char chr;
|
||||
|
||||
switch(a->state){
|
||||
case AsconWriteStart:
|
||||
AsconReadGarbage(a->fd);
|
||||
initGenBin(a);
|
||||
a->state = AsconWriting;
|
||||
break;
|
||||
case AsconWriting:
|
||||
toWrite = self->toWrite - a->wrPos;
|
||||
if(toWrite == 0){
|
||||
a->state = AsconWriteDone;
|
||||
} else {
|
||||
ret = AsconWriteChars(a->fd, self->writePointer+a->wrPos, toWrite);
|
||||
if (ret < 0) {
|
||||
if (errno != EINTR && errno != EAGAIN) {
|
||||
AsconError(a, "send failed:", errno);
|
||||
}
|
||||
} else {
|
||||
a->wrPos += ret;
|
||||
if(a->wrPos >= self->toWrite){
|
||||
a->state = AsconWriteDone;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case AsconReading:
|
||||
if(self->readCount >= self->toRead){
|
||||
a->state = AsconReadDone;
|
||||
DynStringCopy(a->rdBuffer,"OK");
|
||||
} else {
|
||||
ret = AsconReadChar(a->fd, &chr);
|
||||
if (ret < 0) {
|
||||
/* EINTR means we must retry */
|
||||
if (errno != EINTR && errno != EAGAIN) {
|
||||
AsconError(a, "AsconReadChar failed:", errno);
|
||||
}
|
||||
return 1;
|
||||
} else if (ret > 0) {
|
||||
a->start = DoubleTime();
|
||||
self->readPointer[self->readCount] = chr;
|
||||
self->readCount++;
|
||||
} 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;
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
static int GenBinInit(Ascon * a, SConnection * con, int argc, char *argv[])
|
||||
{
|
||||
pGenBin priv = NULL;
|
||||
|
||||
priv = calloc(sizeof(GenBin), 1);
|
||||
a->fd = -1;
|
||||
a->state = AsconConnectStart;
|
||||
a->reconnectInterval = 10;
|
||||
a->hostport = strdup(argv[1]);
|
||||
if (argc > 2) {
|
||||
a->timeout = atof(argv[2]);
|
||||
} else {
|
||||
a->timeout = 2.0; /* sec */
|
||||
}
|
||||
a->private = priv;
|
||||
a->killPrivate = free;
|
||||
return 1;
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
void AddGenBinProtocoll()
|
||||
{
|
||||
AsconProtocol *prot = NULL;
|
||||
|
||||
prot = calloc(sizeof(AsconProtocol), 1);
|
||||
prot->name = strdup("genbin");
|
||||
prot->init = GenBinInit;
|
||||
prot->handler = GenBinHandler;
|
||||
AsconInsertProtocol(prot);
|
||||
}
|
Reference in New Issue
Block a user