diff --git a/asyncqueue.c b/asyncqueue.c index 3a315a0e..e754eb73 100644 --- a/asyncqueue.c +++ b/asyncqueue.c @@ -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 */ diff --git a/site_ansto/hardsup/aqp_opalstatus.c b/site_ansto/hardsup/aqp_opalstatus.c index 7760e910..b0de390b 100644 --- a/site_ansto/hardsup/aqp_opalstatus.c +++ b/site_ansto/hardsup/aqp_opalstatus.c @@ -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 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; diff --git a/site_ansto/hardsup/cameradriver.c b/site_ansto/hardsup/cameradriver.c index 0a1c75df..e77114fb 100644 --- a/site_ansto/hardsup/cameradriver.c +++ b/site_ansto/hardsup/cameradriver.c @@ -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; diff --git a/site_ansto/hardsup/huber_asyncprotocol.c b/site_ansto/hardsup/huber_asyncprotocol.c index 62ed18b7..7ed7c43f 100644 --- a/site_ansto/hardsup/huber_asyncprotocol.c +++ b/site_ansto/hardsup/huber_asyncprotocol.c @@ -1,80 +1,163 @@ #include "huber_asyncprotocol.h" #include "asyncprotocol.h" #include "asyncqueue.h" +#include "ascon.i" +#include "dynstring.h" +#include +#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; } } diff --git a/site_ansto/hardsup/knauer_asyncprotocol.c b/site_ansto/hardsup/knauer_asyncprotocol.c index aada3c97..f8ad2497 100644 --- a/site_ansto/hardsup/knauer_asyncprotocol.c +++ b/site_ansto/hardsup/knauer_asyncprotocol.c @@ -1,105 +1,175 @@ #include "knauer_asyncprotocol.h" #include "asyncprotocol.h" #include "asyncqueue.h" +#include "ascon.i" +#include "dynstring.h" +#include -#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; } } - diff --git a/site_ansto/hardsup/omron_asyncprotocol.c b/site_ansto/hardsup/omron_asyncprotocol.c index 2266d07a..ddd264bf 100644 --- a/site_ansto/hardsup/omron_asyncprotocol.c +++ b/site_ansto/hardsup/omron_asyncprotocol.c @@ -1,105 +1,186 @@ #include "omron_asyncprotocol.h" #include "asyncprotocol.h" #include "asyncqueue.h" +#include "ascon.i" +#include "dynstring.h" +#include +#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; } } diff --git a/site_ansto/ls340.c b/site_ansto/ls340.c index e1d69f55..ef4b9a41 100644 --- a/site_ansto/ls340.c +++ b/site_ansto/ls340.c @@ -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; diff --git a/site_ansto/lssmonitor.c b/site_ansto/lssmonitor.c index 94df0c68..bab86590 100644 --- a/site_ansto/lssmonitor.c +++ b/site_ansto/lssmonitor.c @@ -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; diff --git a/site_ansto/motor_dmc2280.c b/site_ansto/motor_dmc2280.c index c6a4ee71..b625f2ef 100644 --- a/site_ansto/motor_dmc2280.c +++ b/site_ansto/motor_dmc2280.c @@ -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; diff --git a/site_ansto/orhvps.c b/site_ansto/orhvps.c index 03cf129b..88b0e705 100644 --- a/site_ansto/orhvps.c +++ b/site_ansto/orhvps.c @@ -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; diff --git a/site_ansto/safetyplc.c b/site_ansto/safetyplc.c index 5febf900..35486d55 100644 --- a/site_ansto/safetyplc.c +++ b/site_ansto/safetyplc.c @@ -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;