Reworked AsyncQueue sendCommand processing

Squashed commit of the following:

commit 42fb7d3cde591d40060cc740ccbc47f1ae7a5a50
Author: Douglas Clowes <dcl@ansto.gov.au>
Date:   Tue Aug 26 13:31:11 2014 +1000

    Get the MODBUS_AP working

commit da785c1434a04c4186d4174eb2dfbaefc850c8e7
Author: Douglas Clowes <dcl@ansto.gov.au>
Date:   Mon Aug 25 18:01:50 2014 +1000

    Bring Modbus protocol closer to Huber, Knauer and Omron

commit ef06ed7b6911cb49b35c19fe73e55f7c57cfd049
Author: Douglas Clowes <dcl@ansto.gov.au>
Date:   Mon Aug 25 18:01:18 2014 +1000

    Make Huber, Knauer and Omron protocols more aligned (diffable)

commit 3ef1bb06b3f865502ad7dffc4bf5dba4814d9334
Author: Douglas Clowes <dcl@ansto.gov.au>
Date:   Fri Aug 22 17:47:50 2014 +1000

    Get the Huber and Knauer protocols to be more alike

commit 2c9932e83f6735e894278648afdcadece654d43b
Author: Douglas Clowes <dcl@ansto.gov.au>
Date:   Fri Aug 22 17:12:31 2014 +1000

    Clean up the Knauer dual-mode protocol and refactor

commit 333300b19b0e61916e261300ac6ae2b6bab5df09
Author: Douglas Clowes <dcl@ansto.gov.au>
Date:   Thu Aug 21 15:38:39 2014 +1000

    Get the Knauer dual-mode protocol working(-ish)

commit b1f9d82f1b9eb8a1ff54694adc3482984b0d3d72
Author: Douglas Clowes <dcl@ansto.gov.au>
Date:   Thu Aug 21 15:37:44 2014 +1000

    Make private functions static (and not duplicated)

commit 0b077414eef9e4351956a2b971d7751cced0d3cd
Author: Douglas Clowes <dcl@ansto.gov.au>
Date:   Thu Aug 21 12:46:10 2014 +1000

    Knauer moving toward dual protocol

commit 13199bea38a1595ce06923e83474b738b10db94d
Author: Douglas Clowes <dcl@ansto.gov.au>
Date:   Thu Aug 21 12:42:48 2014 +1000

    Restructure default sendCommand processing in asyncqueue

commit 99a8ea3174ca0636503b0ce0cdb6016790315558
Author: Douglas Clowes <dcl@ansto.gov.au>
Date:   Thu Aug 21 09:48:50 2014 +1000

    Add a Modbus Protocol handler derived from sct_tcpmodbus

commit 3adf49fb7c8402c8260a0bb20729d551ac88537b
Author: Douglas Clowes <dcl@ansto.gov.au>
Date:   Thu Aug 21 09:43:54 2014 +1000

    Leave the free of private data to the asyncqueue mechanism
This commit is contained in:
Douglas Clowes
2014-08-26 14:30:19 +10:00
parent ee40adceb2
commit a43461b200
11 changed files with 897 additions and 379 deletions

View File

@ -394,7 +394,16 @@ static int StartCommand(pAsyncQueue self)
}
myCmd->tran->txn_status = ATX_ACTIVE;
iRet = self->protocol->sendCommand(self->protocol, myCmd->tran);
if (self->protocol->sendCommand) {
iRet = self->protocol->sendCommand(self->protocol, myCmd->tran);
} else {
pAsyncTxn txn = myCmd->tran;
iRet = AsyncUnitWrite(txn->unit, txn->out_buf, txn->out_len);
if (iRet < 0)
iRet = 0;
else
iRet = 1;
}
/*
* Handle case of no response expected
*/

View File

@ -20,17 +20,6 @@
enum replystates {START, HEADER, CHKHEADEREND, MSG};
static pAsyncProtocol OPAL_Protocol = NULL;
static int OPAL_Tx(pAsyncProtocol p, pAsyncTxn txn) {
if (txn == NULL) {
return 0;
}
txn->txn_status = ATX_ACTIVE;
if (AsyncUnitWrite(txn->unit, txn->out_buf, txn->out_len) < 0) {
return 0;
}
return 1;
}
/* The header and message are followed by the character sequences given below,
* HEADER cr lf cr lf <msg len> cr lf
* MESSAGE cr lf 0x30 cr lf cr lf
@ -137,7 +126,7 @@ static int OPAL_PrepareTxn(pAsyncProtocol p, pAsyncTxn txn, const char* cmd, int
void OpalStatusInitProtocol(SicsInterp *pSics) {
if (OPAL_Protocol == NULL) {
OPAL_Protocol = AsyncProtocolCreate(pSics, "OPALSTAT", NULL, NULL);
OPAL_Protocol->sendCommand = OPAL_Tx;
OPAL_Protocol->sendCommand = NULL;
OPAL_Protocol->handleInput = OPAL_Rx;
OPAL_Protocol->killPrivate = NULL;
OPAL_Protocol->handleEvent = OPAL_Ev;

View File

@ -183,18 +183,6 @@ static void CAM_Notify(void* context, int event) {
return;
}
static int CAM_Tx(pAsyncProtocol p, pAsyncTxn txn) {
if (txn == NULL) {
return 0;
}
txn->txn_status = ATX_ACTIVE;
if (AsyncUnitWrite(txn->unit, txn->out_buf, txn->out_len) < 0) {
return 0;
}
return 1;
}
int defaultHandleInput(pAsyncProtocol p, pAsyncTxn txn, int ch);
static int CAM_Rx(pAsyncProtocol p, pAsyncTxn txn, int ch) {
int ret = 1;
@ -221,7 +209,7 @@ static int CAM_Ev(pAsyncProtocol p, pAsyncTxn pTxn, int event) {
void CameraInitProtocol(SicsInterp *pSics) {
if (CAM_Protocol == NULL) {
CAM_Protocol = AsyncProtocolCreate(pSics, "CAMERA", NULL, NULL);
CAM_Protocol->sendCommand = CAM_Tx;
CAM_Protocol->sendCommand = NULL;
CAM_Protocol->handleInput = CAM_Rx;
CAM_Protocol->prepareTxn = NULL;
CAM_Protocol->killPrivate = NULL;

View File

@ -1,80 +1,163 @@
#include "huber_asyncprotocol.h"
#include "asyncprotocol.h"
#include "asyncqueue.h"
#include "ascon.i"
#include "dynstring.h"
#include <errno.h>
#define PROTOCOL_CONTINUE 0
#define PROTOCOL_COMPLETE 1
#define PROTOCOL_ERROR (-1)
/* Sample Messages
structure:
7B - LEFT BRACE
xx - text
0D 0A - CR LF
*/
#define PROTOCOL_NAME "HUBER_AP"
#define PROTOCOL_INIT HUBERInitProtocol
#define LBRACE '{'
#define CR '\r'
#define LF '\n'
/*
* Protocol transmit function
* Called by AsyncQueue to transmit a line
* Protocol Private data block
*/
static int HUBER_Tx(pAsyncProtocol p, pAsyncTxn pTxn) {
int iRet = 1;
typedef struct proto_private_t {
int state; /**< protocol state machine */
int len; /**< length from the protocol */
pDynString wrBuffer; /**< transmitted message */
pDynString rxBuffer; /**< received message */
} ProtoPrivate;
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;
static ProtoPrivate *makeProtoPrivate()
{
ProtoPrivate *priv = calloc(sizeof(ProtoPrivate), 1);
priv->wrBuffer = CreateDynString(100, 100);
priv->rxBuffer = CreateDynString(100, 100);
return priv;
}
static ProtoPrivate *Proto_KillPrivate(ProtoPrivate *priv)
{
if (priv) {
if (priv->rxBuffer) {
DeleteDynString(priv->rxBuffer);
priv->rxBuffer = NULL;
}
free(priv);
}
return 1;
return NULL;
}
/*
* Protocol Specific Support Functions
*/
/*
* Protocol Prepare Output
*/
static int Proto_Prepare(ProtoPrivate *priv, pDynString wrBuffer)
{
DynStringInsert(wrBuffer, "{", 0);
DynStringConcatChar(wrBuffer, CR);
DynStringConcatChar(wrBuffer, LF);
return PROTOCOL_COMPLETE;
}
/*
* Protocol receive character - characater by character
*/
static int HUBER_Rx(pAsyncProtocol p, pAsyncTxn pTxn, int rxchar) {
int iRet = 1;
switch (pTxn->txn_state) {
case 0: /* first character */
static int Proto_RxChar(ProtoPrivate *priv, int rxchar)
{
enum RX_STATE {
RX_START=0,
RX_TEXT=1,
RX_LAST=2, /* LF */
RX_STOP=99
};
rxchar &= 0xFF;
switch (priv->state) {
case RX_START:
if (rxchar != LBRACE) {
/* TODO: error */
pTxn->txn_state = 99;
pTxn->txn_status = ATX_COMPLETE;
break;
priv->state = RX_STOP;
return PROTOCOL_ERROR;
}
/* normal data */
pTxn->txn_state = 1;
/* note fallthrough */
case 1: /* receiving reply */
if (pTxn->inp_idx < pTxn->inp_len)
pTxn->inp_buf[pTxn->inp_idx++] = rxchar;
if (rxchar == CR)
pTxn->txn_state = 2;
break;
case 2: /* receiving LF */
if (pTxn->inp_idx < pTxn->inp_len)
pTxn->inp_buf[pTxn->inp_idx++] = rxchar;
if (rxchar != LF) {
/* TODO: error */
priv->state = RX_TEXT;
return PROTOCOL_CONTINUE;
case RX_TEXT:
if (rxchar == CR) {
priv->state = RX_LAST;
return PROTOCOL_CONTINUE;
}
pTxn->txn_state = 99;
pTxn->inp_idx -= 3;
memmove(pTxn->inp_buf, pTxn->inp_buf + 1, pTxn->inp_idx);
break;
DynStringConcatChar(priv->rxBuffer, rxchar);
return PROTOCOL_CONTINUE;
case RX_LAST:
if (rxchar == LF) {
priv->state = RX_STOP;
return PROTOCOL_COMPLETE;
} else {
priv->state = RX_STOP;
return PROTOCOL_ERROR;
}
default:
return PROTOCOL_ERROR;
}
if (pTxn->txn_state == 99) {
iRet = 0;
return PROTOCOL_ERROR;
}
/*
* AsyncProtocol handling
* ======================
*/
static void Async_KillPrivate(pAsyncTxn pTxn)
{
Proto_KillPrivate((ProtoPrivate *) pTxn->proto_private);
pTxn->proto_private = NULL;
}
/*
* AsyncProtocol Receive Character
*/
static int Async_Rx(pAsyncProtocol p, pAsyncTxn pTxn, int rxchar) {
int iRet, str_len;
ProtoPrivate *priv = (ProtoPrivate *) pTxn->proto_private;
iRet = Proto_RxChar(priv, rxchar);
/*
* Keep inp_buf and inp_idx up-to-date after each character
*/
str_len = GetDynStringLength(priv->rxBuffer);
if (str_len > pTxn->inp_idx && pTxn->inp_idx < pTxn->inp_len) {
int xfr_len;
char *tgt = &pTxn->inp_buf[pTxn->inp_idx];
char *loc = &GetCharArray(priv->rxBuffer)[pTxn->inp_idx];
if (str_len > pTxn->inp_len)
xfr_len = pTxn->inp_len - pTxn->inp_idx;
else
xfr_len = str_len - pTxn->inp_idx;
memcpy(tgt, loc, xfr_len);
pTxn->inp_idx += xfr_len;
}
if (iRet == 0) { /* end of command */
return AQU_POP_CMD;
if (iRet == PROTOCOL_CONTINUE) {
return 1; /* Keep Going */
}
return iRet;
if (iRet == PROTOCOL_ERROR) {
return -1; /* Error condition */
}
/* Message Complete */
return AQU_POP_CMD;
}
/*
* AsyncProtocol Event callback
*/
static int HUBER_Ev(pAsyncProtocol p, pAsyncTxn pTxn, int event) {
static int Async_Ev(pAsyncProtocol p, pAsyncTxn pTxn, int event) {
if (event == AQU_TIMEOUT) {
/* handle command timeout */
pTxn->txn_status = ATX_TIMEOUT;
@ -83,34 +166,168 @@ static int HUBER_Ev(pAsyncProtocol p, pAsyncTxn pTxn, int event) {
return AQU_POP_CMD;
}
static int HUBER_PrepareTxn(pAsyncProtocol p, pAsyncTxn pTxn, const char* cmd, int cmd_len, int rsp_len) {
int i, bcc;
pTxn->out_buf = (char*) malloc(cmd_len + 3);
if (pTxn->out_buf == NULL) {
SICSLogWrite("ERROR: Out of memory in HUBER_PrepareTxn", eError);
/*
* AsyncProtocol Prepare Transaction
*/
static int Async_PrepareTxn(pAsyncProtocol p, pAsyncTxn pTxn, const char* cmd, int cmd_len, int rsp_len) {
ProtoPrivate *priv;
priv = makeProtoPrivate();
if (priv == NULL) {
SICSLogWrite("ERROR: Out of memory in Async_PrepareTxn", eError);
return 0;
}
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;
priv->state = 0;
priv->len = 0;
DynStringConcatBytes(priv->wrBuffer, cmd, cmd_len);
Proto_Prepare(priv, priv->wrBuffer);
pTxn->out_len = GetDynStringLength(priv->wrBuffer);
pTxn->out_buf = (char*) malloc(pTxn->out_len);
if (pTxn->out_buf == NULL) {
SICSLogPrintf(eError, "ERROR: Out of memory in %s:%s", __FILE__, __FUNCTION__);
Proto_KillPrivate(priv);
return 0;
}
pTxn->proto_private = priv;
pTxn->kill_private = Async_KillPrivate;
memcpy(pTxn->out_buf, GetCharArray(priv->wrBuffer), pTxn->out_len);
return 1;
}
static pAsyncProtocol HUBER_Protocol = NULL;
/*
* Ascon Protocol handling
* =======================
*/
static void Ascon_KillPrivate(void *priv)
{
Proto_KillPrivate((ProtoPrivate *) priv);
}
/*
* Ascon Protocol WriteStart
*/
static int Ascon_Prepare(Ascon *a) {
ProtoPrivate *priv = (ProtoPrivate *) a->private;
Proto_Prepare(priv, a->wrBuffer);
a->wrPos = 0;
a->state = AsconWriting;
return 1;
}
/*
* Ascon Protocol Read Poll
*/
static int Ascon_Rx(Ascon *a) {
int ret, status;
char chr = '\0';
ProtoPrivate *priv = (ProtoPrivate *) a->private;
ret = AsconReadChar(a->fd, &chr);
while (ret > 0) {
a->start = DoubleTime();
status = Proto_RxChar(priv, chr);
if (GetDynStringLength(priv->rxBuffer) > GetDynStringLength(a->rdBuffer)) {
int len_rd = GetDynStringLength(a->rdBuffer);
int len_rx = GetDynStringLength(priv->rxBuffer);
char *loc = &GetCharArray(priv->rxBuffer)[len_rd];
DynStringConcatBytes(a->rdBuffer, loc, len_rx - len_rd);
}
if (status > 0) { /* Complete */
a->state = AsconReadDone;
return 1;
}
else if (status < 0) { /* Error */
AsconError(a, "Protocol Input Error:", status);
/*TODO This hack stops ascon.c:AsconTask() from needlessly closing the connection. Remove this when it's no longer needed */
a->lastReconnect = DoubleTime();
return 1;
}
ret = AsconReadChar(a->fd, &chr);
}
if (ret < 0) {
AsconError(a, "AsconReadChar failed:", errno);
return 1;
}
if (a->state != AsconReadDone) {
if (a->timeout > 0) {
if (DoubleTime() - a->start > a->timeout) {
AsconError(a, "read timeout", 0);
a->state = AsconTimeout;
}
}
}
return 1;
}
/*
* Ascon Protocol Poll Loop
*/
static int AsconProtHandler(Ascon *a) {
ProtoPrivate *priv = (ProtoPrivate *) a->private;
int ret;
switch(a->state){
case AsconWriteStart:
ret = Ascon_Prepare(a);
return ret;
case AsconReadStart:
DynStringClear(priv->rxBuffer);
a->start = DoubleTime();
priv->state = 0;
priv->len = 0;
ret = AsconStdHandler(a);
return ret;
case AsconReading:
ret = Ascon_Rx(a);
return ret;
default:
ret = AsconStdHandler(a);
return ret;
}
return 1;
}
/*
* Ascon Protocol Connection Init
*/
static int AsconInit(Ascon *a, SConnection *con, int argc, char *argv[])
{
int iRet;
ProtoPrivate *priv;
iRet = AsconStdInit(a, con, argc, argv);
priv = makeProtoPrivate();
a->private = priv;
a->killPrivate = Ascon_KillPrivate;
return iRet;
}
static AsyncProtocol *My_Async_Protocol = NULL;
static AsconProtocol *My_Ascon_Protocol = NULL;
/*
* Protocol Initialisation
*/
void HUBERInitProtocol(SicsInterp *pSics) {
if (HUBER_Protocol == NULL) {
HUBER_Protocol = AsyncProtocolCreate(pSics, "HUBER_AP", NULL, NULL);
HUBER_Protocol->sendCommand = HUBER_Tx;
HUBER_Protocol->handleInput = HUBER_Rx;
HUBER_Protocol->handleEvent = HUBER_Ev;
HUBER_Protocol->prepareTxn = HUBER_PrepareTxn;
HUBER_Protocol->killPrivate = NULL;
void PROTOCOL_INIT(SicsInterp *pSics) {
if (My_Async_Protocol == NULL) {
AsyncProtocol *prot;
prot = AsyncProtocolCreate(pSics, PROTOCOL_NAME, NULL, NULL);
prot->sendCommand = NULL;
prot->handleInput = Async_Rx;
prot->handleEvent = Async_Ev;
prot->prepareTxn = Async_PrepareTxn;
My_Async_Protocol = prot;
}
if (My_Ascon_Protocol == NULL) {
AsconProtocol *prot;
prot = calloc(sizeof(AsconProtocol), 1);
prot->name = strdup(PROTOCOL_NAME);
prot->init = AsconInit;
prot->handler = AsconProtHandler;
AsconInsertProtocol(prot);
My_Ascon_Protocol = prot;
}
}

View File

@ -1,105 +1,175 @@
#include "knauer_asyncprotocol.h"
#include "asyncprotocol.h"
#include "asyncqueue.h"
#include "ascon.i"
#include "dynstring.h"
#include <errno.h>
#define SYN1 0x55
#define SYN2 0xAA
#define CR '\r'
#define LF '\n'
#define PROTOCOL_CONTINUE 0
#define PROTOCOL_COMPLETE 1
#define PROTOCOL_ERROR (-1)
/* 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
structure:
55 aa - sync bytes
00 xx - length of following bytes
yy .. zz - count(00 xx) message bytes with no terminator
*/
typedef struct knauer_private_t Private, *pPrivate;
struct knauer_private_t {
int len;
};
#define PROTOCOL_NAME "KNAUER_AP"
#define PROTOCOL_INIT KNAUERInitProtocol
#define SYN1 0x55
#define SYN2 0xAA
#define CR '\r'
#define LF '\n'
/*
* Protocol transmit function
* Called by AsyncQueue to transmit a line
* Protocol Private data block
*/
static int KNAUER_Tx(pAsyncProtocol p, pAsyncTxn pTxn) {
int iRet = 1;
typedef struct proto_private_t {
int state; /**< protocol state machine */
int len; /**< length from the protocol */
pDynString wrBuffer; /**< transmitted message */
pDynString rxBuffer; /**< received message */
} ProtoPrivate;
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;
static ProtoPrivate *makeProtoPrivate()
{
ProtoPrivate *priv = calloc(sizeof(ProtoPrivate), 1);
priv->wrBuffer = CreateDynString(100, 100);
priv->rxBuffer = CreateDynString(100, 100);
return priv;
}
static ProtoPrivate *Proto_KillPrivate(ProtoPrivate *priv)
{
if (priv) {
if (priv->rxBuffer) {
DeleteDynString(priv->rxBuffer);
priv->rxBuffer = NULL;
}
free(priv);
}
return 1;
return NULL;
}
/*
* Protocol Specific Support Functions
*/
/*
* Protocol Prepare Output
*/
static int Proto_Prepare(ProtoPrivate *priv, pDynString wrBuffer)
{
DynStringConcatChar(wrBuffer, CR);
return PROTOCOL_COMPLETE;
}
/*
* 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;
static int Proto_RxChar(ProtoPrivate *priv, int rxchar)
{
enum RX_STATE {
RX_START=0,
RX_TEXT=1,
RX_SYN2=2,
RX_LEN1=3,
RX_LEN2=4,
RX_STOP=99
};
rxchar &= 0xFF;
switch (pTxn->txn_state) {
case 0: /* first SYN byte */
switch (priv->state) {
case RX_START:
if (rxchar != SYN1) {
/* TODO: error */
pTxn->txn_state = 99;
pTxn->txn_status = ATX_COMPLETE;
break;
priv->state = RX_STOP;
return PROTOCOL_ERROR;
}
pTxn->txn_state = 1;
break;
case 1: /* second SYN byte */
priv->state = RX_SYN2;
return PROTOCOL_CONTINUE;
case RX_SYN2:
if (rxchar != SYN2) {
/* TODO: error */
pTxn->txn_state = 99;
pTxn->txn_status = ATX_COMPLETE;
break;
priv->state = RX_STOP;
return PROTOCOL_ERROR;
}
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;
priv->state = RX_LEN1;
return PROTOCOL_CONTINUE;
case RX_LEN1:
priv->len = 256 * rxchar;
priv->state = RX_LEN2;
return PROTOCOL_CONTINUE;
case RX_LEN2:
priv->len += rxchar;
priv->state = RX_TEXT;
return PROTOCOL_CONTINUE;
case RX_TEXT:
DynStringConcatChar(priv->rxBuffer, rxchar);
if (GetDynStringLength(priv->rxBuffer) >= priv->len) {
priv->state = RX_STOP;
return PROTOCOL_COMPLETE;
} else {
return PROTOCOL_CONTINUE;
}
break;
default:
return PROTOCOL_ERROR;
}
if (pTxn->txn_state == 99) {
iRet = 0;
return PROTOCOL_ERROR;
}
/*
* AsyncProtocol handling
* ======================
*/
static void Async_KillPrivate(pAsyncTxn pTxn)
{
Proto_KillPrivate((ProtoPrivate *) pTxn->proto_private);
pTxn->proto_private = NULL;
}
/*
* AsyncProtocol Receive Character
*/
static int Async_Rx(pAsyncProtocol p, pAsyncTxn pTxn, int rxchar) {
int iRet, str_len;
ProtoPrivate *priv = (ProtoPrivate *) pTxn->proto_private;
iRet = Proto_RxChar(priv, rxchar);
/*
* Keep inp_buf and inp_idx up-to-date after each character
*/
str_len = GetDynStringLength(priv->rxBuffer);
if (str_len > pTxn->inp_idx && pTxn->inp_idx < pTxn->inp_len) {
int xfr_len;
char *tgt = &pTxn->inp_buf[pTxn->inp_idx];
char *loc = &GetCharArray(priv->rxBuffer)[pTxn->inp_idx];
if (str_len > pTxn->inp_len)
xfr_len = pTxn->inp_len - pTxn->inp_idx;
else
xfr_len = str_len - pTxn->inp_idx;
memcpy(tgt, loc, xfr_len);
pTxn->inp_idx += xfr_len;
}
if (iRet == 0) { /* end of command */
free(pTxn->proto_private);
pTxn->proto_private = NULL;
return AQU_POP_CMD;
if (iRet == PROTOCOL_CONTINUE) {
return 1; /* Keep Going */
}
return iRet;
if (iRet == PROTOCOL_ERROR) {
return -1; /* Error condition */
}
/* Message Complete */
return AQU_POP_CMD;
}
/*
* AsyncProtocol Event callback
*/
static int KNAUER_Ev(pAsyncProtocol p, pAsyncTxn pTxn, int event) {
free(pTxn->proto_private);
pTxn->proto_private = NULL;
static int Async_Ev(pAsyncProtocol p, pAsyncTxn pTxn, int event) {
if (event == AQU_TIMEOUT) {
/* handle command timeout */
pTxn->txn_status = ATX_TIMEOUT;
@ -108,41 +178,168 @@ static int KNAUER_Ev(pAsyncProtocol p, pAsyncTxn pTxn, int event) {
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);
/*
* AsyncProtocol Prepare Transaction
*/
static int Async_PrepareTxn(pAsyncProtocol p, pAsyncTxn pTxn, const char* cmd, int cmd_len, int rsp_len) {
ProtoPrivate *priv;
priv = makeProtoPrivate();
if (priv == NULL) {
SICSLogWrite("ERROR: Out of memory in Async_PrepareTxn", eError);
return 0;
}
myPriv->len = 0;
pTxn->out_buf = (char*) malloc(cmd_len + 1);
priv->state = 0;
priv->len = 0;
DynStringConcatBytes(priv->wrBuffer, cmd, cmd_len);
Proto_Prepare(priv, priv->wrBuffer);
pTxn->out_len = GetDynStringLength(priv->wrBuffer);
pTxn->out_buf = (char*) malloc(pTxn->out_len);
if (pTxn->out_buf == NULL) {
SICSLogWrite("ERROR: Out of memory in KNAUER_PrepareTxn", eError);
free(myPriv);
SICSLogPrintf(eError, "ERROR: Out of memory in %s:%s", __FILE__, __FUNCTION__);
Proto_KillPrivate(priv);
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;
pTxn->proto_private = priv;
pTxn->kill_private = Async_KillPrivate;
memcpy(pTxn->out_buf, GetCharArray(priv->wrBuffer), pTxn->out_len);
return 1;
}
static pAsyncProtocol KNAUER_Protocol = NULL;
/*
* Ascon Protocol handling
* =======================
*/
static void Ascon_KillPrivate(void *priv)
{
Proto_KillPrivate((ProtoPrivate *) priv);
}
/*
* Ascon Protocol WriteStart
*/
static int Ascon_Prepare(Ascon *a) {
ProtoPrivate *priv = (ProtoPrivate *) a->private;
Proto_Prepare(priv, a->wrBuffer);
a->wrPos = 0;
a->state = AsconWriting;
return 1;
}
/*
* Ascon Protocol Read Poll
*/
static int Ascon_Rx(Ascon *a) {
int ret, status;
char chr = '\0';
ProtoPrivate *priv = (ProtoPrivate *) a->private;
ret = AsconReadChar(a->fd, &chr);
while (ret > 0) {
a->start = DoubleTime();
status = Proto_RxChar(priv, chr);
if (GetDynStringLength(priv->rxBuffer) > GetDynStringLength(a->rdBuffer)) {
int len_rd = GetDynStringLength(a->rdBuffer);
int len_rx = GetDynStringLength(priv->rxBuffer);
char *loc = &GetCharArray(priv->rxBuffer)[len_rd];
DynStringConcatBytes(a->rdBuffer, loc, len_rx - len_rd);
}
if (status > 0) { /* Complete */
a->state = AsconReadDone;
return 1;
}
else if (status < 0) { /* Error */
AsconError(a, "Protocol Input Error:", status);
/*TODO This hack stops ascon.c:AsconTask() from needlessly closing the connection. Remove this when it's no longer needed */
a->lastReconnect = DoubleTime();
return 1;
}
ret = AsconReadChar(a->fd, &chr);
}
if (ret < 0) {
AsconError(a, "AsconReadChar failed:", errno);
return 1;
}
if (a->state != AsconReadDone) {
if (a->timeout > 0) {
if (DoubleTime() - a->start > a->timeout) {
AsconError(a, "read timeout", 0);
a->state = AsconTimeout;
}
}
}
return 1;
}
/*
* Ascon Protocol Poll Loop
*/
static int AsconProtHandler(Ascon *a) {
ProtoPrivate *priv = (ProtoPrivate *) a->private;
int ret;
switch(a->state){
case AsconWriteStart:
ret = Ascon_Prepare(a);
return ret;
case AsconReadStart:
DynStringClear(priv->rxBuffer);
a->start = DoubleTime();
priv->state = 0;
priv->len = 0;
ret = AsconStdHandler(a);
return ret;
case AsconReading:
ret = Ascon_Rx(a);
return ret;
default:
ret = AsconStdHandler(a);
return ret;
}
return 1;
}
/*
* Ascon Protocol Connection Init
*/
static int AsconInit(Ascon *a, SConnection *con, int argc, char *argv[])
{
int iRet;
ProtoPrivate *priv;
iRet = AsconStdInit(a, con, argc, argv);
priv = makeProtoPrivate();
a->private = priv;
a->killPrivate = Ascon_KillPrivate;
return iRet;
}
static AsyncProtocol *My_Async_Protocol = NULL;
static AsconProtocol *My_Ascon_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;
void PROTOCOL_INIT(SicsInterp *pSics) {
if (My_Async_Protocol == NULL) {
AsyncProtocol *prot;
prot = AsyncProtocolCreate(pSics, PROTOCOL_NAME, NULL, NULL);
prot->sendCommand = NULL;
prot->handleInput = Async_Rx;
prot->handleEvent = Async_Ev;
prot->prepareTxn = Async_PrepareTxn;
My_Async_Protocol = prot;
}
if (My_Ascon_Protocol == NULL) {
AsconProtocol *prot;
prot = calloc(sizeof(AsconProtocol), 1);
prot->name = strdup(PROTOCOL_NAME);
prot->init = AsconInit;
prot->handler = AsconProtHandler;
AsconInsertProtocol(prot);
My_Ascon_Protocol = prot;
}
}

View File

@ -1,105 +1,186 @@
#include "omron_asyncprotocol.h"
#include "asyncprotocol.h"
#include "asyncqueue.h"
#include "ascon.i"
#include "dynstring.h"
#include <errno.h>
#define PROTOCOL_CONTINUE 0
#define PROTOCOL_COMPLETE 1
#define PROTOCOL_ERROR (-1)
/* Sample Messages
* structure:
* STX
* data
* ETX
* BCC
*/
#define PROTOCOL_NAME "OMRON_AP"
#define PROTOCOL_INIT OMRONInitProtocol
#define STX 2
#define ETX 3
static int calc_bcc(const char* text)
/*
* Protocol Private data block
*/
typedef struct proto_private_t {
int state; /**< protocol state machine */
int len; /**< length from the protocol */
pDynString wrBuffer; /**< transmitted message */
pDynString rxBuffer; /**< received message */
} ProtoPrivate;
static ProtoPrivate *makeProtoPrivate()
{
int bcc = 0;
int i = 0;
int c;
while (i < 1024) {
c = text[i] & 0xFF;
if (c == STX) {
bcc = 0;
} else {
bcc ^= c;
ProtoPrivate *priv = calloc(sizeof(ProtoPrivate), 1);
priv->wrBuffer = CreateDynString(100, 100);
priv->rxBuffer = CreateDynString(100, 100);
return priv;
}
static ProtoPrivate *Proto_KillPrivate(ProtoPrivate *priv)
{
if (priv) {
if (priv->rxBuffer) {
DeleteDynString(priv->rxBuffer);
priv->rxBuffer = NULL;
}
SICSLogPrintf(eLog, "BCC %02d: char %02X, bcc = %02X", i, c, bcc);
if (c == ETX)
break;
++text;
free(priv);
}
return NULL;
}
/*
* Protocol Specific Support Functions
*/
static int calc_bcc(const char* text, int len)
{
int idx = 0;
int bcc = 0;
int c = 0;
for (idx = 0; idx < len; ++idx) {
c = text[idx] & 0xFF;
bcc ^= c;
}
bcc ^= ETX;
return bcc;
}
/*
* Protocol transmit function
* Called by AsyncQueue to transmit a line
* Protocol Prepare Output
*/
static int OMRON_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;
static int Proto_Prepare(ProtoPrivate *priv, pDynString wrBuffer)
{
int bcc;
char stx[2] = {STX, '\0'};
bcc = calc_bcc(GetCharArray(wrBuffer), GetDynStringLength(wrBuffer));
DynStringInsert(wrBuffer, stx, 0);
DynStringConcatChar(wrBuffer, ETX);
DynStringConcatChar(wrBuffer, bcc);
return PROTOCOL_COMPLETE;
}
/*
* Protocol receive character - characater by character
*/
static int OMRON_Rx(pAsyncProtocol p, pAsyncTxn pTxn, int rxchar) {
int iRet = 1;
switch (pTxn->txn_state) {
case 0: /* first character */
if (rxchar != STX) { /* STX */
/* TODO: error */
pTxn->txn_state = 99;
pTxn->txn_status = ATX_COMPLETE;
break;
static int Proto_RxChar(ProtoPrivate *priv, int rxchar)
{
enum RX_STATE {
RX_START=0,
RX_TEXT=1,
RX_LAST=2, /* BCC */
RX_STOP=99
};
int bcc;
rxchar &= 0xFF;
switch (priv->state) {
case RX_START:
if (rxchar != STX) {
priv->state = RX_STOP;
return PROTOCOL_ERROR;
}
/* normal data */
pTxn->txn_state = 1;
/* note fallthrough */
case 1: /* receiving reply */
if (pTxn->inp_idx < pTxn->inp_len)
pTxn->inp_buf[pTxn->inp_idx++] = rxchar;
if (rxchar == ETX)
pTxn->txn_state = 2;
break;
case 2: /* receiving bcc */
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(pTxn->inp_buf);
priv->state = RX_TEXT;
return PROTOCOL_CONTINUE;
case RX_TEXT:
if (rxchar == ETX) {
priv->state = RX_LAST;
return PROTOCOL_CONTINUE;
}
DynStringConcatChar(priv->rxBuffer, rxchar);
return PROTOCOL_CONTINUE;
case RX_LAST:
bcc = calc_bcc(GetCharArray(priv->rxBuffer), GetDynStringLength(priv->rxBuffer));
if (bcc == rxchar) {
priv->state = RX_STOP;
return PROTOCOL_COMPLETE;
} else {
SICSLogPrintf(eError,
"Omron BCC mismatch, expected %02X but received %02X on message:",
bcc, rxchar);
SICSLogWriteHex(pTxn->inp_buf, pTxn->inp_idx, eError);
SICSLogWriteHex(GetCharArray(priv->rxBuffer), GetDynStringLength(priv->rxBuffer), eError);
priv->state = RX_STOP;
return PROTOCOL_ERROR;
}
pTxn->txn_state = 99;
pTxn->inp_idx -= 3;
memmove(pTxn->inp_buf, pTxn->inp_buf + 1, pTxn->inp_idx);
break;
default:
return PROTOCOL_ERROR;
}
if (pTxn->txn_state == 99) {
iRet = 0;
return PROTOCOL_ERROR;
}
/*
* AsyncProtocol handling
* ======================
*/
static void Async_KillPrivate(pAsyncTxn pTxn)
{
Proto_KillPrivate((ProtoPrivate *) pTxn->proto_private);
pTxn->proto_private = NULL;
}
/*
* AsyncProtocol Receive Character
*/
static int Async_Rx(pAsyncProtocol p, pAsyncTxn pTxn, int rxchar) {
int iRet, str_len;
ProtoPrivate *priv = (ProtoPrivate *) pTxn->proto_private;
iRet = Proto_RxChar(priv, rxchar);
/*
* Keep inp_buf and inp_idx up-to-date after each character
*/
str_len = GetDynStringLength(priv->rxBuffer);
if (str_len > pTxn->inp_idx && pTxn->inp_idx < pTxn->inp_len) {
int xfr_len;
char *tgt = &pTxn->inp_buf[pTxn->inp_idx];
char *loc = &GetCharArray(priv->rxBuffer)[pTxn->inp_idx];
if (str_len > pTxn->inp_len)
xfr_len = pTxn->inp_len - pTxn->inp_idx;
else
xfr_len = str_len - pTxn->inp_idx;
memcpy(tgt, loc, xfr_len);
pTxn->inp_idx += xfr_len;
}
if (iRet == 0) { /* end of command */
return AQU_POP_CMD;
if (iRet == PROTOCOL_CONTINUE) {
return 1; /* Keep Going */
}
return iRet;
if (iRet == PROTOCOL_ERROR) {
return -1; /* Error condition */
}
/* Message Complete */
return AQU_POP_CMD;
}
/*
* AsyncProtocol Event callback
*/
static int OMRON_Ev(pAsyncProtocol p, pAsyncTxn pTxn, int event) {
static int Async_Ev(pAsyncProtocol p, pAsyncTxn pTxn, int event) {
if (event == AQU_TIMEOUT) {
/* handle command timeout */
pTxn->txn_status = ATX_TIMEOUT;
@ -108,34 +189,168 @@ static int OMRON_Ev(pAsyncProtocol p, pAsyncTxn pTxn, int event) {
return AQU_POP_CMD;
}
static int OMRON_PrepareTxn(pAsyncProtocol p, pAsyncTxn pTxn, const char* cmd, int cmd_len, int rsp_len) {
int i, bcc;
pTxn->out_buf = (char*) malloc(cmd_len + 3);
if (pTxn->out_buf == NULL) {
SICSLogWrite("ERROR: Out of memory in OMRON_PrepareTxn", eError);
/*
* AsyncProtocol Prepare Transaction
*/
static int Async_PrepareTxn(pAsyncProtocol p, pAsyncTxn pTxn, const char* cmd, int cmd_len, int rsp_len) {
ProtoPrivate *priv;
priv = makeProtoPrivate();
if (priv == NULL) {
SICSLogWrite("ERROR: Out of memory in Async_PrepareTxn", eError);
return 0;
}
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;
priv->state = 0;
priv->len = 0;
DynStringConcatBytes(priv->wrBuffer, cmd, cmd_len);
Proto_Prepare(priv, priv->wrBuffer);
pTxn->out_len = GetDynStringLength(priv->wrBuffer);
pTxn->out_buf = (char*) malloc(pTxn->out_len);
if (pTxn->out_buf == NULL) {
SICSLogPrintf(eError, "ERROR: Out of memory in %s:%s", __FILE__, __FUNCTION__);
Proto_KillPrivate(priv);
return 0;
}
pTxn->proto_private = priv;
pTxn->kill_private = Async_KillPrivate;
memcpy(pTxn->out_buf, GetCharArray(priv->wrBuffer), pTxn->out_len);
return 1;
}
static pAsyncProtocol OMRON_Protocol = NULL;
/*
* Ascon Protocol handling
* =======================
*/
static void Ascon_KillPrivate(void *priv)
{
Proto_KillPrivate((ProtoPrivate *) priv);
}
/*
* Ascon Protocol WriteStart
*/
static int Ascon_Prepare(Ascon *a) {
ProtoPrivate *priv = (ProtoPrivate *) a->private;
Proto_Prepare(priv, a->wrBuffer);
a->wrPos = 0;
a->state = AsconWriting;
return 1;
}
/*
* Ascon Protocol Read Poll
*/
static int Ascon_Rx(Ascon *a) {
int ret, status;
char chr = '\0';
ProtoPrivate *priv = (ProtoPrivate *) a->private;
ret = AsconReadChar(a->fd, &chr);
while (ret > 0) {
a->start = DoubleTime();
status = Proto_RxChar(priv, chr);
if (GetDynStringLength(priv->rxBuffer) > GetDynStringLength(a->rdBuffer)) {
int len_rd = GetDynStringLength(a->rdBuffer);
int len_rx = GetDynStringLength(priv->rxBuffer);
char *loc = &GetCharArray(priv->rxBuffer)[len_rd];
DynStringConcatBytes(a->rdBuffer, loc, len_rx - len_rd);
}
if (status > 0) { /* Complete */
a->state = AsconReadDone;
return 1;
}
else if (status < 0) { /* Error */
AsconError(a, "Protocol Input Error:", status);
/*TODO This hack stops ascon.c:AsconTask() from needlessly closing the connection. Remove this when it's no longer needed */
a->lastReconnect = DoubleTime();
return 1;
}
ret = AsconReadChar(a->fd, &chr);
}
if (ret < 0) {
AsconError(a, "AsconReadChar failed:", errno);
return 1;
}
if (a->state != AsconReadDone) {
if (a->timeout > 0) {
if (DoubleTime() - a->start > a->timeout) {
AsconError(a, "read timeout", 0);
a->state = AsconTimeout;
}
}
}
return 1;
}
/*
* Ascon Protocol Poll Loop
*/
static int AsconProtHandler(Ascon *a) {
ProtoPrivate *priv = (ProtoPrivate *) a->private;
int ret;
switch(a->state){
case AsconWriteStart:
ret = Ascon_Prepare(a);
return ret;
case AsconReadStart:
DynStringClear(priv->rxBuffer);
a->start = DoubleTime();
priv->state = 0;
priv->len = 0;
ret = AsconStdHandler(a);
return ret;
case AsconReading:
ret = Ascon_Rx(a);
return ret;
default:
ret = AsconStdHandler(a);
return ret;
}
return 1;
}
/*
* Ascon Protocol Connection Init
*/
static int AsconInit(Ascon *a, SConnection *con, int argc, char *argv[])
{
int iRet;
ProtoPrivate *priv;
iRet = AsconStdInit(a, con, argc, argv);
priv = makeProtoPrivate();
a->private = priv;
a->killPrivate = Ascon_KillPrivate;
return iRet;
}
static AsyncProtocol *My_Async_Protocol = NULL;
static AsconProtocol *My_Ascon_Protocol = NULL;
/*
* Protocol Initialisation
*/
void OMRONInitProtocol(SicsInterp *pSics) {
if (OMRON_Protocol == NULL) {
OMRON_Protocol = AsyncProtocolCreate(pSics, "OMRON_AP", NULL, NULL);
OMRON_Protocol->sendCommand = OMRON_Tx;
OMRON_Protocol->handleInput = OMRON_Rx;
OMRON_Protocol->handleEvent = OMRON_Ev;
OMRON_Protocol->prepareTxn = OMRON_PrepareTxn;
OMRON_Protocol->killPrivate = NULL;
void PROTOCOL_INIT(SicsInterp *pSics) {
if (My_Async_Protocol == NULL) {
AsyncProtocol *prot;
prot = AsyncProtocolCreate(pSics, PROTOCOL_NAME, NULL, NULL);
prot->sendCommand = NULL;
prot->handleInput = Async_Rx;
prot->handleEvent = Async_Ev;
prot->prepareTxn = Async_PrepareTxn;
My_Async_Protocol = prot;
}
if (My_Ascon_Protocol == NULL) {
AsconProtocol *prot;
prot = calloc(sizeof(AsconProtocol), 1);
prot->name = strdup(PROTOCOL_NAME);
prot->init = AsconInit;
prot->handler = AsconProtHandler;
AsconInsertProtocol(prot);
My_Ascon_Protocol = prot;
}
}

View File

@ -786,33 +786,6 @@ static void LS340Notify(void* context, int event)
static pAsyncProtocol LS340_Protocol = NULL;
static int LS340_Tx(pAsyncProtocol p, pAsyncTxn ctx)
{
int iRet = 1;
pAsyncTxn myCmd = (pAsyncTxn) ctx;
if (myCmd) {
if (strchr(myCmd->out_buf, '?')) {
myCmd->txn_status = ATX_ACTIVE;
} else {
myCmd->txn_status = ATX_COMPLETE;
}
iRet = AsyncUnitWrite(myCmd->unit, myCmd->out_buf, myCmd->out_len);
/* TODO handle errors */
if (iRet < 0) { /* TODO: EOF */
/*
iRet = AsyncUnitReconnect(myCmd->unit);
if (iRet == 0)
*/
return 0;
}
}
return 1;
}
static int LS340_Rx(pAsyncProtocol p, pAsyncTxn ctx, int rxchar) {
int iRet = 1;
pAsyncTxn myCmd = (pAsyncTxn) ctx;
@ -856,17 +829,22 @@ static int LS340_PrepareTxn(pAsyncProtocol p, pAsyncTxn txn, const char* cmd, in
if (txn->out_buf[txn->out_len-1] != '\r') {
txn->out_buf[txn->out_len++] = '\r';
// txn->out_buf[txn->out_len++] = '\r';
}
// txn->out_buf[txn->out_len++] = '\0';
/*
* If this message does not contain a Question Mark (?)
* Then it does not request a reply
*/
if (!strchr(cmd, '?'))
txn->inp_len = 0;
return 1;
}
void LS340InitProtocol(SicsInterp *pSics) {
if (LS340_Protocol == NULL) {
LS340_Protocol = AsyncProtocolCreate(pSics, "ls340", NULL, NULL);
LS340_Protocol->sendCommand = LS340_Tx;
LS340_Protocol->sendCommand = NULL;
LS340_Protocol->handleInput = LS340_Rx;
LS340_Protocol->handleEvent = LS340_Ev;
LS340_Protocol->prepareTxn = LS340_PrepareTxn;

View File

@ -97,23 +97,6 @@ mxml_node_t *tree;
static int LSS_GetState(void *pData, char *param, LSS_STATUS *retState);
static int LSS_Tx(pAsyncProtocol p, pAsyncTxn myCmd)
{
int iRet = 1;
if (myCmd) {
myCmd->txn_status = ATX_ACTIVE;
iRet = AsyncUnitWrite(myCmd->unit, myCmd->out_buf, myCmd->out_len);
/* TODO handle errors */
if (iRet < 0) { /* TODO: EOF */
iRet = AsyncUnitReconnect(myCmd->unit);
if (iRet == 0)
return 0;
}
}
return 1;
}
static int LSS_Rx(pAsyncProtocol p, pAsyncTxn myCmd, int rxchar)
{
int iRet = 1;
@ -512,7 +495,7 @@ static void LSS_Kill(void* pData)
void LSSInitProtocol(SicsInterp *pSics) {
if (LSS_Protocol == NULL) {
LSS_Protocol = AsyncProtocolCreate(pSics, "LSS", NULL, NULL);
LSS_Protocol->sendCommand = LSS_Tx;
LSS_Protocol->sendCommand = NULL;
LSS_Protocol->handleInput = LSS_Rx;
LSS_Protocol->handleEvent = LSS_Ev;
LSS_Protocol->prepareTxn = NULL;

View File

@ -933,25 +933,6 @@ static int motCreep(pDMC2280Driv self, double target) {
return target_steps;
}
static int DMC_Tx(pAsyncProtocol p, pAsyncTxn ctx) {
int iRet = 1;
pAsyncTxn myCmd = (pAsyncTxn) ctx;
if (myCmd) {
myCmd->txn_status = ATX_ACTIVE;
iRet = AsyncUnitWrite(myCmd->unit, myCmd->out_buf, myCmd->out_len);
/* TODO handle errors */
if (iRet < 0) { /* TODO: EOF */
/*
iRet = AsyncUnitReconnect(myCmd->unit);
if (iRet == 0)
*/
return 0;
}
}
return 1;
}
static int DMC_Rx(pAsyncProtocol p, pAsyncTxn ctx, int rxchar) {
int iRet = 1;
pAsyncTxn myCmd = (pAsyncTxn) ctx;
@ -6367,7 +6348,7 @@ int DMC2280Action(SConnection *pCon, SicsInterp *pSics, void *pData,
void DMC2280InitProtocol(SicsInterp *pSics) {
if (DMC2280_Protocol == NULL) {
DMC2280_Protocol = AsyncProtocolCreate(pSics, "DMC2280", NULL, NULL);
DMC2280_Protocol->sendCommand = DMC_Tx;
DMC2280_Protocol->sendCommand = NULL;
DMC2280_Protocol->handleInput = DMC_Rx;
DMC2280_Protocol->handleEvent = DMC_Ev;
DMC2280_Protocol->prepareTxn = NULL;

View File

@ -778,28 +778,6 @@ static void ORHVPSKillPrivate(void *pData) {
}
}
/*
* Protocol transmit function
* Called by AsyncQueue to transmit a line
*/
static int ORHVPS_Tx(pAsyncProtocol p, pAsyncTxn myCmd) {
int iRet = 1;
if (myCmd) {
myCmd->txn_status = ATX_ACTIVE;
iRet = AsyncUnitWrite(myCmd->unit, myCmd->out_buf, myCmd->out_len);
/* TODO handle errors */
if (iRet < 0) { /* TODO: EOF */
/*
iRet = AsyncUnitReconnect(myCmd->unit);
if (iRet == 0)
*/
return 0;
}
}
return 1;
}
/*
* Protocol receive character - characater by character
*/
@ -907,7 +885,7 @@ static pAsyncProtocol ORHVPS_Protocol = NULL;
void ORHVPSInitProtocol(SicsInterp *pSics) {
if (ORHVPS_Protocol == NULL) {
ORHVPS_Protocol = AsyncProtocolCreate(pSics, "ORHVPS", NULL, NULL);
ORHVPS_Protocol->sendCommand = ORHVPS_Tx;
ORHVPS_Protocol->sendCommand = NULL;
ORHVPS_Protocol->handleInput = ORHVPS_Rx;
ORHVPS_Protocol->handleEvent = ORHVPS_Ev;
ORHVPS_Protocol->prepareTxn = ORHVPS_PrepareTxn;

View File

@ -77,23 +77,6 @@ struct __SafetyPLCController {
static int PLC_GetState(void *pData, char *param, PLC_STATUS *retState);
static int PLC_Tx(pAsyncProtocol p, pAsyncTxn myCmd)
{
int iRet = 1;
if (myCmd) {
myCmd->txn_status = ATX_ACTIVE;
iRet = AsyncUnitWrite(myCmd->unit, myCmd->out_buf, myCmd->out_len);
/* TODO handle errors */
if (iRet < 0) { /* TODO: EOF */
iRet = AsyncUnitReconnect(myCmd->unit);
if (iRet == 0)
return 0;
}
}
return 1;
}
static int PLC_Rx(pAsyncProtocol p, pAsyncTxn myCmd, int rxchar)
{
int iRet = 1;
@ -477,7 +460,7 @@ static void PLC_Kill(void* pData)
void SafetyPLCInitProtocol(SicsInterp *pSics) {
if (PLC_Protocol == NULL) {
PLC_Protocol = AsyncProtocolCreate(pSics, "SafetyPLC", NULL, NULL);
PLC_Protocol->sendCommand = PLC_Tx;
PLC_Protocol->sendCommand = NULL;
PLC_Protocol->handleInput = PLC_Rx;
PLC_Protocol->handleEvent = PLC_Ev;
PLC_Protocol->prepareTxn = NULL;