#include "huber_asyncprotocol.h" #include "asyncprotocol.h" #include "asyncqueue.h" #define LBRACE '{' #define CR '\r' #define LF '\n' /* * Protocol transmit function * Called by AsyncQueue to transmit a line */ static int HUBER_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 HUBER_Rx(pAsyncProtocol p, pAsyncTxn pTxn, int rxchar) { int iRet = 1; switch (pTxn->txn_state) { case 0: /* first character */ if (rxchar != LBRACE) { /* TODO: error */ pTxn->txn_state = 99; pTxn->txn_status = ATX_COMPLETE; break; } /* 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 */ } pTxn->txn_state = 99; pTxn->inp_idx -= 3; memmove(pTxn->inp_buf, pTxn->inp_buf + 1, pTxn->inp_idx); break; } if (pTxn->txn_state == 99) { iRet = 0; } if (iRet == 0) { /* end of command */ return AQU_POP_CMD; } return iRet; } /* * AsyncProtocol Event callback */ static int HUBER_Ev(pAsyncProtocol p, pAsyncTxn pTxn, int event) { if (event == AQU_TIMEOUT) { /* handle command timeout */ pTxn->txn_status = ATX_TIMEOUT; return AQU_POP_CMD; } 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); 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; return 1; } static pAsyncProtocol HUBER_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; } }