Merge branch 'RELEASE-3_1' into RELEASE-3_2

This commit is contained in:
Douglas Clowes
2014-08-20 13:45:59 +10:00
13 changed files with 255 additions and 70 deletions

View File

@ -26,6 +26,12 @@ typedef enum {
ATX_DISCO = 3
} ATX_STATUS;
#define AQU_TIMEOUT -1
#define AQU_DISCONNECT -2
#define AQU_RECONNECT -3
#define AQU_RETRY_CMD -4
#define AQU_POP_CMD -5
struct __async_txn {
pAsyncUnit unit; /**< unit that transaction is associated with */
int txn_state; /**< protocol handler transaction parse state */
@ -38,6 +44,8 @@ struct __async_txn {
int inp_len; /**< length of input buffer */
int inp_idx; /**< index of next character (number already received) */
AsyncTxnHandler handleResponse; /**< Txn response handler of command sender */
void *proto_private; /**< Protocol Private structure */
void (*kill_private) (struct __async_txn *pTxn); /**< if it needs killing */
void *cntx; /**< opaque context used by command sender */
/* The cntx field may be used by protocol handler from sendCommand
* as long as it is restored when response is complete

View File

@ -167,6 +167,11 @@ static void AQ_Purge(pAsyncQueue self)
self->command_head = self->command_tail = NULL;
free(myCmd->tran->out_buf);
free(myCmd->tran->inp_buf);
if (myCmd->tran->proto_private)
if (myCmd->tran->kill_private)
myCmd->tran->kill_private(myCmd->tran);
else
free(myCmd->tran->proto_private);
free(myCmd->tran);
free(myCmd);
myCmd = self->command_head;
@ -455,6 +460,11 @@ static int PopCommand(pAsyncQueue self)
self->command_head = self->command_tail = NULL;
free(myCmd->tran->out_buf);
free(myCmd->tran->inp_buf);
if (myCmd->tran->proto_private)
if (myCmd->tran->kill_private)
myCmd->tran->kill_private(myCmd->tran);
else
free(myCmd->tran->proto_private);
free(myCmd->tran);
free(myCmd);
return 1;
@ -531,7 +541,7 @@ static int MyCallback(void *context, int mode)
for (i = 0; i < nchars; ++i) {
iRet =
self->protocol->handleInput(self->protocol, myCmd->tran,
reply[i]);
reply[i] & 0xFF);
if (iRet == 0 || iRet == AQU_POP_CMD) { /* end of command */
if (self->trace) {
struct timeval tv;
@ -666,6 +676,7 @@ pAsyncTxn AsyncUnitPrepareTxn(pAsyncUnit unit,
}
if (unit->queue->protocol->prepareTxn) {
int iRet;
myTxn->inp_len = rsp_len; /* allowing protocol to change it */
iRet =
unit->queue->protocol->prepareTxn(unit->queue->protocol, myTxn,
command, cmd_len, rsp_len);
@ -673,6 +684,7 @@ pAsyncTxn AsyncUnitPrepareTxn(pAsyncUnit unit,
free(myTxn);
return NULL;
}
rsp_len = myTxn->inp_len; /* allowed protocol to change it */
} else {
myTxn->out_buf = (char *) malloc(cmd_len + 5);
if (myTxn->out_buf == NULL) {

View File

@ -11,12 +11,6 @@
#include "asyncprotocol.h"
#define AQU_TIMEOUT -1
#define AQU_DISCONNECT -2
#define AQU_RECONNECT -3
#define AQU_RETRY_CMD -4
#define AQU_POP_CMD -5
typedef struct __AsyncQueue AsyncQueue, *pAsyncQueue;

View File

@ -1,4 +1,4 @@
#include "sics.h"
#include "huber_asyncprotocol.h"
#include "asyncprotocol.h"
#include "asyncqueue.h"
@ -10,16 +10,16 @@
* Protocol transmit function
* Called by AsyncQueue to transmit a line
*/
static int HUBER_Tx(pAsyncProtocol p, pAsyncTxn myCmd) {
static int HUBER_Tx(pAsyncProtocol p, pAsyncTxn pTxn) {
int iRet = 1;
if (myCmd) {
myCmd->txn_status = ATX_ACTIVE;
iRet = AsyncUnitWrite(myCmd->unit, myCmd->out_buf, myCmd->out_len);
if (pTxn) {
pTxn->txn_status = ATX_ACTIVE;
iRet = AsyncUnitWrite(pTxn->unit, pTxn->out_buf, pTxn->out_len);
/* TODO handle errors */
if (iRet < 0) { /* TODO: EOF */
/*
iRet = AsyncUnitReconnect(myCmd->unit);
iRet = AsyncUnitReconnect(pTxn->unit);
if (iRet == 0)
*/
return 0;
@ -31,39 +31,38 @@ static int HUBER_Tx(pAsyncProtocol p, pAsyncTxn myCmd) {
/*
* Protocol receive character - characater by character
*/
static int HUBER_Rx(pAsyncProtocol p, pAsyncTxn ctx, int rxchar) {
static int HUBER_Rx(pAsyncProtocol p, pAsyncTxn pTxn, int rxchar) {
int iRet = 1;
pAsyncTxn myCmd = (pAsyncTxn) ctx;
switch (myCmd->txn_state) {
switch (pTxn->txn_state) {
case 0: /* first character */
if (rxchar != LBRACE) {
/* TODO: error */
myCmd->txn_state = 99;
myCmd->txn_status = ATX_COMPLETE;
pTxn->txn_state = 99;
pTxn->txn_status = ATX_COMPLETE;
break;
}
/* normal data */
myCmd->txn_state = 1;
pTxn->txn_state = 1;
/* note fallthrough */
case 1: /* receiving reply */
if (myCmd->inp_idx < myCmd->inp_len)
myCmd->inp_buf[myCmd->inp_idx++] = rxchar;
if (pTxn->inp_idx < pTxn->inp_len)
pTxn->inp_buf[pTxn->inp_idx++] = rxchar;
if (rxchar == CR)
myCmd->txn_state = 2;
pTxn->txn_state = 2;
break;
case 2: /* receiving LF */
if (myCmd->inp_idx < myCmd->inp_len)
myCmd->inp_buf[myCmd->inp_idx++] = rxchar;
if (pTxn->inp_idx < pTxn->inp_len)
pTxn->inp_buf[pTxn->inp_idx++] = rxchar;
if (rxchar != LF) {
/* TODO: error */
}
myCmd->txn_state = 99;
myCmd->inp_idx -= 3;
memmove(myCmd->inp_buf, myCmd->inp_buf + 1, myCmd->inp_idx);
pTxn->txn_state = 99;
pTxn->inp_idx -= 3;
memmove(pTxn->inp_buf, pTxn->inp_buf + 1, pTxn->inp_idx);
break;
}
if (myCmd->txn_state == 99) {
if (pTxn->txn_state == 99) {
iRet = 0;
}
if (iRet == 0) { /* end of command */
@ -84,18 +83,18 @@ static int HUBER_Ev(pAsyncProtocol p, pAsyncTxn pTxn, int event) {
return AQU_POP_CMD;
}
static int HUBER_PrepareTxn(pAsyncProtocol p, pAsyncTxn txn, const char* cmd, int cmd_len, int rsp_len) {
static int HUBER_PrepareTxn(pAsyncProtocol p, pAsyncTxn pTxn, const char* cmd, int cmd_len, int rsp_len) {
int i, bcc;
txn->out_buf = (char*) malloc(cmd_len + 3);
if (txn->out_buf == NULL) {
pTxn->out_buf = (char*) malloc(cmd_len + 3);
if (pTxn->out_buf == NULL) {
SICSLogWrite("ERROR: Out of memory in HUBER_PrepareTxn", eError);
return 0;
}
memcpy(txn->out_buf + 1, cmd, cmd_len);
txn->out_buf[0] = LBRACE;
txn->out_buf[cmd_len + 1] = CR;
txn->out_buf[cmd_len + 2] = LF;
txn->out_len = cmd_len + 3;
memcpy(pTxn->out_buf + 1, cmd, cmd_len);
pTxn->out_buf[0] = LBRACE;
pTxn->out_buf[cmd_len + 1] = CR;
pTxn->out_buf[cmd_len + 2] = LF;
pTxn->out_len = cmd_len + 3;
return 1;
}

View File

@ -1,4 +1,5 @@
#ifndef HUBER_ASYNCPROTOCOL_H
#define HUBER_ASYNCPROTOCOL_H
#include "sics.h"
void HUBERInitProtocol(SicsInterp *pSics);
#endif

View File

@ -0,0 +1,148 @@
#include "knauer_asyncprotocol.h"
#include "asyncprotocol.h"
#include "asyncqueue.h"
#define SYN1 0x55
#define SYN2 0xAA
#define CR '\r'
#define LF '\n'
/* Sample Messages
55 aa 00 08 52 45 4d 4f 54 45 3a 30
55 aa 00 16 45 52 52 4f 52 3a 34 38 2c 4e 6f 74 20 73 75 70 70 6f 72 74 65 64
55 aa 00 18 45 52 52 4f 52 3a 31 36 2c 49 6e 76 61 6c 69 64 20 63 6f 6d 6d 61 6e 64
*/
typedef struct knauer_private_t Private, *pPrivate;
struct knauer_private_t {
int len;
};
/*
* Protocol transmit function
* Called by AsyncQueue to transmit a line
*/
static int KNAUER_Tx(pAsyncProtocol p, pAsyncTxn pTxn) {
int iRet = 1;
if (pTxn) {
pTxn->txn_status = ATX_ACTIVE;
iRet = AsyncUnitWrite(pTxn->unit, pTxn->out_buf, pTxn->out_len);
/* TODO handle errors */
if (iRet < 0) { /* TODO: EOF */
/*
iRet = AsyncUnitReconnect(pTxn->unit);
if (iRet == 0)
*/
return 0;
}
}
return 1;
}
/*
* Protocol receive character - characater by character
*/
static int KNAUER_Rx(pAsyncProtocol p, pAsyncTxn pTxn, int rxchar) {
int iRet = 1;
pPrivate myPriv = (pPrivate) pTxn->proto_private;
rxchar &= 0xFF;
switch (pTxn->txn_state) {
case 0: /* first SYN byte */
if (rxchar != SYN1) {
/* TODO: error */
pTxn->txn_state = 99;
pTxn->txn_status = ATX_COMPLETE;
break;
}
pTxn->txn_state = 1;
break;
case 1: /* second SYN byte */
if (rxchar != SYN2) {
/* TODO: error */
pTxn->txn_state = 99;
pTxn->txn_status = ATX_COMPLETE;
break;
}
pTxn->txn_state = 2;
break;
case 2: /* MS length byte */
myPriv->len = 256 * rxchar;
pTxn->txn_state = 3;
break;
case 3: /* LS length byte */
myPriv->len += rxchar;
pTxn->txn_state = 4;
break;
case 4: /* receiving text */
if (pTxn->inp_idx < pTxn->inp_len)
pTxn->inp_buf[pTxn->inp_idx++] = rxchar;
if (pTxn->inp_idx >= myPriv->len) {
pTxn->txn_state = 99;
pTxn->txn_status = ATX_COMPLETE;
}
break;
}
if (pTxn->txn_state == 99) {
iRet = 0;
}
if (iRet == 0) { /* end of command */
free(pTxn->proto_private);
pTxn->proto_private = NULL;
return AQU_POP_CMD;
}
return iRet;
}
/*
* AsyncProtocol Event callback
*/
static int KNAUER_Ev(pAsyncProtocol p, pAsyncTxn pTxn, int event) {
free(pTxn->proto_private);
pTxn->proto_private = NULL;
if (event == AQU_TIMEOUT) {
/* handle command timeout */
pTxn->txn_status = ATX_TIMEOUT;
return AQU_POP_CMD;
}
return AQU_POP_CMD;
}
static int KNAUER_PrepareTxn(pAsyncProtocol p, pAsyncTxn pTxn, const char* cmd, int cmd_len, int rsp_len) {
pPrivate myPriv = (pPrivate) malloc(sizeof(Private));
if (myPriv == NULL) {
SICSLogWrite("ERROR: Out of memory in KNAUER_PrepareTxn", eError);
return 0;
}
myPriv->len = 0;
pTxn->out_buf = (char*) malloc(cmd_len + 1);
if (pTxn->out_buf == NULL) {
SICSLogWrite("ERROR: Out of memory in KNAUER_PrepareTxn", eError);
free(myPriv);
return 0;
}
pTxn->proto_private = myPriv;
memcpy(pTxn->out_buf, cmd, cmd_len);
pTxn->out_buf[cmd_len] = CR;
pTxn->out_len = cmd_len + 1;
return 1;
}
static pAsyncProtocol KNAUER_Protocol = NULL;
/*
* Protocol Initialisation
*/
void KNAUERInitProtocol(SicsInterp *pSics) {
if (KNAUER_Protocol == NULL) {
KNAUER_Protocol = AsyncProtocolCreate(pSics, "KNAUER_AP", NULL, NULL);
KNAUER_Protocol->sendCommand = KNAUER_Tx;
KNAUER_Protocol->handleInput = KNAUER_Rx;
KNAUER_Protocol->handleEvent = KNAUER_Ev;
KNAUER_Protocol->prepareTxn = KNAUER_PrepareTxn;
KNAUER_Protocol->killPrivate = NULL;
}
}

View File

@ -0,0 +1,5 @@
#ifndef KNAUER_ASYNCPROTOCOL_H
#define KNAUER_ASYNCPROTOCOL_H
#include "sics.h"
void KNAUERInitProtocol(SicsInterp *pSics);
#endif

View File

@ -0,0 +1,12 @@
#include "loader_asyncprotocol.h"
#include "huber_asyncprotocol.h"
#include "knauer_asyncprotocol.h"
#include "omron_asyncprotocol.h"
#include "sics.h"
void LOADERInitProtocol(SicsInterp *pSics)
{
HUBERInitProtocol(pSics);
KNAUERInitProtocol(pSics);
OMRONInitProtocol(pSics);
}

View File

@ -0,0 +1,5 @@
#ifndef LOADER_ASYNCPROTOCOL_H
#define LOADER_ASYNCPROTOCOL_H
#include "sics.h"
void LOADERInitProtocol(SicsInterp *pSics);
#endif

View File

@ -37,6 +37,8 @@ HOBJ += sct_asyncqueue.o
HOBJ += aqp_opalstatus.o
HOBJ += omron_asyncprotocol.o
HOBJ += huber_asyncprotocol.o
HOBJ += knauer_asyncprotocol.o
HOBJ += loader_asyncprotocol.o
libhlib.a: $(HOBJ)
rm -f libhlib.a

View File

@ -1,4 +1,4 @@
#include "sics.h"
#include "omron_asyncprotocol.h"
#include "asyncprotocol.h"
#include "asyncqueue.h"
@ -30,16 +30,16 @@ static int calc_bcc(const char* text)
* Protocol transmit function
* Called by AsyncQueue to transmit a line
*/
static int OMRON_Tx(pAsyncProtocol p, pAsyncTxn myCmd) {
static int OMRON_Tx(pAsyncProtocol p, pAsyncTxn pTxn) {
int iRet = 1;
if (myCmd) {
myCmd->txn_status = ATX_ACTIVE;
iRet = AsyncUnitWrite(myCmd->unit, myCmd->out_buf, myCmd->out_len);
if (pTxn) {
pTxn->txn_status = ATX_ACTIVE;
iRet = AsyncUnitWrite(pTxn->unit, pTxn->out_buf, pTxn->out_len);
/* TODO handle errors */
if (iRet < 0) { /* TODO: EOF */
/*
iRet = AsyncUnitReconnect(myCmd->unit);
iRet = AsyncUnitReconnect(pTxn->unit);
if (iRet == 0)
*/
return 0;
@ -51,44 +51,43 @@ static int OMRON_Tx(pAsyncProtocol p, pAsyncTxn myCmd) {
/*
* Protocol receive character - characater by character
*/
static int OMRON_Rx(pAsyncProtocol p, pAsyncTxn ctx, int rxchar) {
static int OMRON_Rx(pAsyncProtocol p, pAsyncTxn pTxn, int rxchar) {
int iRet = 1;
pAsyncTxn myCmd = (pAsyncTxn) ctx;
switch (myCmd->txn_state) {
switch (pTxn->txn_state) {
case 0: /* first character */
if (rxchar != STX) { /* STX */
/* TODO: error */
myCmd->txn_state = 99;
myCmd->txn_status = ATX_COMPLETE;
pTxn->txn_state = 99;
pTxn->txn_status = ATX_COMPLETE;
break;
}
/* normal data */
myCmd->txn_state = 1;
pTxn->txn_state = 1;
/* note fallthrough */
case 1: /* receiving reply */
if (myCmd->inp_idx < myCmd->inp_len)
myCmd->inp_buf[myCmd->inp_idx++] = rxchar;
if (pTxn->inp_idx < pTxn->inp_len)
pTxn->inp_buf[pTxn->inp_idx++] = rxchar;
if (rxchar == ETX)
myCmd->txn_state = 2;
pTxn->txn_state = 2;
break;
case 2: /* receiving bcc */
if (myCmd->inp_idx < myCmd->inp_len)
myCmd->inp_buf[myCmd->inp_idx++] = rxchar;
if (calc_bcc(myCmd->inp_buf) != rxchar) {
if (pTxn->inp_idx < pTxn->inp_len)
pTxn->inp_buf[pTxn->inp_idx++] = rxchar;
if (calc_bcc(pTxn->inp_buf) != rxchar) {
/* TODO: fail bcc */
int bcc = calc_bcc(myCmd->inp_buf);
int bcc = calc_bcc(pTxn->inp_buf);
SICSLogPrintf(eError,
"Omron BCC mismatch, expected %02X but received %02X on message:",
bcc, rxchar);
SICSLogWriteHex(myCmd->inp_buf, myCmd->inp_idx, eError);
SICSLogWriteHex(pTxn->inp_buf, pTxn->inp_idx, eError);
}
myCmd->txn_state = 99;
myCmd->inp_idx -= 3;
memmove(myCmd->inp_buf, myCmd->inp_buf + 1, myCmd->inp_idx);
pTxn->txn_state = 99;
pTxn->inp_idx -= 3;
memmove(pTxn->inp_buf, pTxn->inp_buf + 1, pTxn->inp_idx);
break;
}
if (myCmd->txn_state == 99) {
if (pTxn->txn_state == 99) {
iRet = 0;
}
if (iRet == 0) { /* end of command */
@ -109,18 +108,18 @@ static int OMRON_Ev(pAsyncProtocol p, pAsyncTxn pTxn, int event) {
return AQU_POP_CMD;
}
static int OMRON_PrepareTxn(pAsyncProtocol p, pAsyncTxn txn, const char* cmd, int cmd_len, int rsp_len) {
static int OMRON_PrepareTxn(pAsyncProtocol p, pAsyncTxn pTxn, const char* cmd, int cmd_len, int rsp_len) {
int i, bcc;
txn->out_buf = (char*) malloc(cmd_len + 3);
if (txn->out_buf == NULL) {
pTxn->out_buf = (char*) malloc(cmd_len + 3);
if (pTxn->out_buf == NULL) {
SICSLogWrite("ERROR: Out of memory in OMRON_PrepareTxn", eError);
return 0;
}
memcpy(txn->out_buf + 1, cmd, cmd_len);
txn->out_buf[0] = STX;
txn->out_buf[cmd_len + 1] = ETX;
txn->out_buf[cmd_len + 2] = calc_bcc(txn->out_buf);
txn->out_len = cmd_len + 3;
memcpy(pTxn->out_buf + 1, cmd, cmd_len);
pTxn->out_buf[0] = STX;
pTxn->out_buf[cmd_len + 1] = ETX;
pTxn->out_buf[cmd_len + 2] = calc_bcc(pTxn->out_buf);
pTxn->out_len = cmd_len + 3;
return 1;
}

View File

@ -1,4 +1,5 @@
#ifndef OMRON_ASYNCPROTOCOL_H
#define OMRON_ASYNCPROTOCOL_H
#include "sics.h"
void OMRONInitProtocol(SicsInterp *pSics);
#endif

View File

@ -383,8 +383,7 @@ static void AddCommands(SicsInterp *pInter)
LS340InitProtocol(pInter);
CameraInitProtocol(pInter);
OpalStatusInitProtocol(pInter);
OMRONInitProtocol(pInter);
HUBERInitProtocol(pInter);
LOADERInitProtocol(pInter);
AddCommand(pInter,"InstallProtocolHandler", InstallProtocol,NULL,NULL);
AddCommand(pInter,"hostnam",hostNamCmd,NULL,NULL);
AddCommand(pInter,"portnum",portNumCmd,NULL,NULL);