- Adapted indenation to new agreed upon system
- Fixed bad status in poldi zug driver
This commit is contained in:
245
pmacprot.c
245
pmacprot.c
@@ -23,7 +23,7 @@
|
||||
#include <dynstring.h>
|
||||
|
||||
#define ETHERNET_DATA_SIZE 1492
|
||||
#define INPUT_SIZE (ETHERNET_DATA_SIZE+1) /* +1 to allow space to add terminating ACK */
|
||||
#define INPUT_SIZE (ETHERNET_DATA_SIZE+1) /* +1 to allow space to add terminating ACK */
|
||||
#define STX '\2'
|
||||
#define CTRLB '\2'
|
||||
#define CTRLC '\3'
|
||||
@@ -37,14 +37,13 @@
|
||||
|
||||
/* PMAC ethernet command structure */
|
||||
#pragma pack(1)
|
||||
typedef struct tagEthernetCmd
|
||||
{
|
||||
unsigned char RequestType;
|
||||
unsigned char Request;
|
||||
unsigned short wValue;
|
||||
unsigned short wIndex;
|
||||
unsigned short wLength; /* length of bData */
|
||||
unsigned char bData[ETHERNET_DATA_SIZE];
|
||||
typedef struct tagEthernetCmd {
|
||||
unsigned char RequestType;
|
||||
unsigned char Request;
|
||||
unsigned short wValue;
|
||||
unsigned short wIndex;
|
||||
unsigned short wLength; /* length of bData */
|
||||
unsigned char bData[ETHERNET_DATA_SIZE];
|
||||
} ethernetCmd;
|
||||
#pragma pack()
|
||||
|
||||
@@ -76,129 +75,133 @@ typedef struct tagEthernetCmd
|
||||
* a private data structurli to keep track of the PMAC
|
||||
*---------------------------------------------------------------------------*/
|
||||
typedef struct {
|
||||
ethernetCmd cmd;
|
||||
char *ptr;
|
||||
int bytesToWrite;
|
||||
int expectACK;
|
||||
}PMACPrivate, *pPMACPrivate;
|
||||
ethernetCmd cmd;
|
||||
char *ptr;
|
||||
int bytesToWrite;
|
||||
int expectACK;
|
||||
} PMACPrivate, *pPMACPrivate;
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int PMACHandler(Ascon *a){
|
||||
char *data = NULL;
|
||||
int ret, l;
|
||||
char chr;
|
||||
pPMACPrivate priv = NULL;
|
||||
|
||||
priv = a->private;
|
||||
|
||||
switch(a->state){
|
||||
case AsconWriteStart:
|
||||
data = GetCharArray(a->wrBuffer);
|
||||
memset(priv,0,sizeof(PMACPrivate));
|
||||
priv->cmd.RequestType = VR_DOWNLOAD;
|
||||
priv->cmd.Request = VR_PMAC_GETRESPONSE;
|
||||
priv->cmd.wValue = 0;
|
||||
priv->cmd.wIndex = 0;
|
||||
priv->cmd.wLength = htons(strlen(data)); /* may be one more */
|
||||
priv->bytesToWrite = strlen(data) + 1 + ETHERNET_CMD_HEADER;
|
||||
strcpy((char *)priv->cmd.bData,data);
|
||||
priv->expectACK = 1;
|
||||
priv->ptr = (char *)&priv->cmd;
|
||||
a->state = AsconWriting;
|
||||
a->wrPos = 0;
|
||||
break;
|
||||
case AsconWriting:
|
||||
AsconReadGarbage(a->fd);
|
||||
l = priv->bytesToWrite - a->wrPos;
|
||||
ret = AsconWriteChars(a->fd, priv->ptr, l);
|
||||
if (ret < 0) {
|
||||
if(errno != EINTR && errno != EAGAIN){
|
||||
AsconError(a, "send failed:", errno);
|
||||
}
|
||||
/*
|
||||
* Ooops: which state shall we go to after a write fail?
|
||||
* This seems to retry.
|
||||
*/
|
||||
} else {
|
||||
a->wrPos += ret;
|
||||
if (a->wrPos >= priv->bytesToWrite) {
|
||||
a->state = AsconWriteDone;
|
||||
} else {
|
||||
priv->ptr += ret;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case AsconReading:
|
||||
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();
|
||||
if(chr == STX || chr == BELL){
|
||||
priv->expectACK = 0;
|
||||
return 1;
|
||||
}
|
||||
if(priv->expectACK && chr == ACK){
|
||||
if(GetDynStringLength(a->rdBuffer) == 0){
|
||||
DynStringConcat(a->rdBuffer,"ACK");
|
||||
}
|
||||
DynStringConcatChar(a->rdBuffer, '\0');
|
||||
a->state = AsconReadDone;
|
||||
break;
|
||||
}
|
||||
if(priv->expectACK == 0 && chr == '\r'){
|
||||
DynStringConcatChar(a->rdBuffer, '\0');
|
||||
a->state = AsconReadDone;
|
||||
break;
|
||||
}
|
||||
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;
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
static int PMACInit(Ascon *a, SConnection *con,
|
||||
int argc, char *argv[]) {
|
||||
static int PMACHandler(Ascon * a)
|
||||
{
|
||||
char *data = NULL;
|
||||
int ret, l;
|
||||
char chr;
|
||||
pPMACPrivate priv = NULL;
|
||||
|
||||
|
||||
priv = a->private;
|
||||
|
||||
switch (a->state) {
|
||||
case AsconWriteStart:
|
||||
data = GetCharArray(a->wrBuffer);
|
||||
memset(priv, 0, sizeof(PMACPrivate));
|
||||
priv->cmd.RequestType = VR_DOWNLOAD;
|
||||
priv->cmd.Request = VR_PMAC_GETRESPONSE;
|
||||
priv->cmd.wValue = 0;
|
||||
priv->cmd.wIndex = 0;
|
||||
priv->cmd.wLength = htons(strlen(data)); /* may be one more */
|
||||
priv->bytesToWrite = strlen(data) + 1 + ETHERNET_CMD_HEADER;
|
||||
strcpy((char *) priv->cmd.bData, data);
|
||||
priv->expectACK = 1;
|
||||
priv->ptr = (char *) &priv->cmd;
|
||||
a->state = AsconWriting;
|
||||
a->wrPos = 0;
|
||||
break;
|
||||
case AsconWriting:
|
||||
AsconReadGarbage(a->fd);
|
||||
l = priv->bytesToWrite - a->wrPos;
|
||||
ret = AsconWriteChars(a->fd, priv->ptr, l);
|
||||
if (ret < 0) {
|
||||
if (errno != EINTR && errno != EAGAIN) {
|
||||
AsconError(a, "send failed:", errno);
|
||||
}
|
||||
/*
|
||||
* Ooops: which state shall we go to after a write fail?
|
||||
* This seems to retry.
|
||||
*/
|
||||
} else {
|
||||
a->wrPos += ret;
|
||||
if (a->wrPos >= priv->bytesToWrite) {
|
||||
a->state = AsconWriteDone;
|
||||
} else {
|
||||
priv->ptr += ret;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case AsconReading:
|
||||
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();
|
||||
if (chr == STX || chr == BELL) {
|
||||
priv->expectACK = 0;
|
||||
return 1;
|
||||
}
|
||||
if (priv->expectACK && chr == ACK) {
|
||||
if (GetDynStringLength(a->rdBuffer) == 0) {
|
||||
DynStringConcat(a->rdBuffer, "ACK");
|
||||
}
|
||||
DynStringConcatChar(a->rdBuffer, '\0');
|
||||
a->state = AsconReadDone;
|
||||
break;
|
||||
}
|
||||
if (priv->expectACK == 0 && chr == '\r') {
|
||||
DynStringConcatChar(a->rdBuffer, '\0');
|
||||
a->state = AsconReadDone;
|
||||
break;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
static int PMACInit(Ascon * a, SConnection * con, int argc, char *argv[])
|
||||
{
|
||||
pPMACPrivate priv = NULL;
|
||||
|
||||
priv = calloc(sizeof(PMACPrivate), 1);
|
||||
a->fd = -1;
|
||||
a->state = AsconConnectStart;
|
||||
a->reconnectInterval = 10;
|
||||
a->hostport = strdup(argv[1]);
|
||||
if(argc > 2){
|
||||
a->timeout = atof(argv[2]);
|
||||
if (argc > 2) {
|
||||
a->timeout = atof(argv[2]);
|
||||
} else {
|
||||
a->timeout = 2.0; /* sec */
|
||||
a->timeout = 2.0; /* sec */
|
||||
}
|
||||
a->private = priv;
|
||||
a->killPrivate = free;
|
||||
a->private = priv;
|
||||
a->killPrivate = free;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
void AddPMACProtocoll(){
|
||||
AsconProtocol *prot = NULL;
|
||||
|
||||
prot = calloc(sizeof(AsconProtocol), 1);
|
||||
prot->name = strdup("pmac");
|
||||
prot->init = PMACInit;
|
||||
prot->handler = PMACHandler;
|
||||
AsconInsertProtocol(prot);
|
||||
void AddPMACProtocoll()
|
||||
{
|
||||
AsconProtocol *prot = NULL;
|
||||
|
||||
prot = calloc(sizeof(AsconProtocol), 1);
|
||||
prot->name = strdup("pmac");
|
||||
prot->init = PMACInit;
|
||||
prot->handler = PMACHandler;
|
||||
AsconInsertProtocol(prot);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user