#include "sics.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 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 */ static int HUBER_Rx(pAsyncProtocol p, pAsyncTxn ctx, int rxchar) { int iRet = 1; pAsyncTxn myCmd = (pAsyncTxn) ctx; switch (myCmd->txn_state) { case 0: /* first character */ if (rxchar != LBRACE) { /* TODO: error */ myCmd->txn_state = 99; myCmd->txn_status = ATX_COMPLETE; break; } /* normal data */ myCmd->txn_state = 1; /* note fallthrough */ case 1: /* receiving reply */ if (myCmd->inp_idx < myCmd->inp_len) myCmd->inp_buf[myCmd->inp_idx++] = rxchar; if (rxchar == CR) myCmd->txn_state = 2; break; case 2: /* receiving LF */ if (myCmd->inp_idx < myCmd->inp_len) myCmd->inp_buf[myCmd->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); break; } if (myCmd->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 txn, 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) { 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; 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; } }