diff --git a/site_ansto/hardsup/knauer_asyncprotocol.c b/site_ansto/hardsup/knauer_asyncprotocol.c new file mode 100644 index 00000000..aada3c97 --- /dev/null +++ b/site_ansto/hardsup/knauer_asyncprotocol.c @@ -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; + } +} + + diff --git a/site_ansto/hardsup/knauer_asyncprotocol.h b/site_ansto/hardsup/knauer_asyncprotocol.h new file mode 100644 index 00000000..eda10893 --- /dev/null +++ b/site_ansto/hardsup/knauer_asyncprotocol.h @@ -0,0 +1,5 @@ +#ifndef KNAUER_ASYNCPROTOCOL_H +#define KNAUER_ASYNCPROTOCOL_H +#include "sics.h" +void KNAUERInitProtocol(SicsInterp *pSics); +#endif diff --git a/site_ansto/hardsup/loader_asyncprotocol.c b/site_ansto/hardsup/loader_asyncprotocol.c new file mode 100644 index 00000000..cb1c7441 --- /dev/null +++ b/site_ansto/hardsup/loader_asyncprotocol.c @@ -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); +} diff --git a/site_ansto/hardsup/loader_asyncprotocol.h b/site_ansto/hardsup/loader_asyncprotocol.h new file mode 100644 index 00000000..a61d5925 --- /dev/null +++ b/site_ansto/hardsup/loader_asyncprotocol.h @@ -0,0 +1,5 @@ +#ifndef LOADER_ASYNCPROTOCOL_H +#define LOADER_ASYNCPROTOCOL_H +#include "sics.h" +void LOADERInitProtocol(SicsInterp *pSics); +#endif diff --git a/site_ansto/hardsup/makefile b/site_ansto/hardsup/makefile index b7196508..dcac1541 100644 --- a/site_ansto/hardsup/makefile +++ b/site_ansto/hardsup/makefile @@ -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 diff --git a/site_ansto/site_ansto.c b/site_ansto/site_ansto.c index 8d2715bc..f67feef4 100644 --- a/site_ansto/site_ansto.c +++ b/site_ansto/site_ansto.c @@ -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);