#include #include #include int defaultSendCommand(pAsyncProtocol p, pAsyncTxn txn) { txn->txn_state = 0; /* TODO: anything? */ return AsyncUnitWrite(txn->unit, txn->out_buf, txn->out_len); } int defaultHandleInput(pAsyncProtocol p, pAsyncTxn txn, int ch) { /* TODO: generic terminators */ char term[] = { 0x0D, 0x0A, 0x00 }; if (ch == term[txn->txn_state]) ++txn->txn_state; else txn->txn_state = 0; if (txn->inp_idx < txn->inp_len) txn->inp_buf[txn->inp_idx++] = ch; if (term[txn->txn_state] == 0) { if (txn->inp_idx < txn->inp_len) txn->inp_buf[txn->inp_idx] = '\0'; return AQU_POP_CMD; } return 1; } int defaultHandleEvent(pAsyncProtocol p, pAsyncTxn txn, int event) { /* TODO */ } int defaultPrepareTxn(pAsyncProtocol p, pAsyncTxn txn, const char* cmd, int cmd_len, int rsp_len) { /* TODO: generic terminators */ char term[] = { 0x0D, 0x0A, 0x00 }; int i; int state; state = 0; for (i = 0; i < cmd_len; ++i) { if (cmd[i] == 0x00) { /* end of transmission */ cmd_len = i; break; } else if (cmd[i] == term[state]) { ++state; continue; } state = 0; } if (term[state] == 0) { txn->out_buf = malloc(cmd_len + 1); memcpy(txn->out_buf, cmd, cmd_len + 1); } else { int tlen = strlen(term); txn->out_buf = malloc(cmd_len + tlen + 1); memcpy(txn->out_buf, cmd, cmd_len); memcpy(txn->out_buf + cmd_len, term, tlen + 1); cmd_len += tlen; } txn->out_len = cmd_len; txn->out_idx = 0; txn->inp_buf = malloc(rsp_len); txn->inp_len = rsp_len; txn->inp_idx = 0; txn->txn_state = 0; txn->txn_status = 0; return 1; } int AsyncProtocolNoAction(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]) { char line[132]; pAsyncProtocol self = (pAsyncProtocol) pData; if (argc > 1) { /* TODO: handle parameters like terminators */ } snprintf(line, 132, "%s does not understand %s", argv[0], argv[1]); SCWrite(pCon, line, eError); return 0; } int AsyncProtocolAction(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]) { char line[132]; pAsyncProtocol self = (pAsyncProtocol) pData; /* TODO: terminators */ snprintf(line, 132, "%s does not understand %s", argv[0], argv[1]); SCWrite(pCon, line, eError); return 0; } void defaultKillPrivate(pAsyncProtocol p) { /* TODO: anything? */ } void AsyncProtocolKill(void *pData) { pAsyncProtocol self = (pAsyncProtocol) pData; DeleteDescriptor(self->pDes); /* TODO: more destruction maybe */ if (self->killPrivate) self->killPrivate(self); } pAsyncProtocol AsyncProtocolCreate(SicsInterp *pSics, const char* protocolName, ObjectFunc pFunc, KillFunc pKFunc) { int iRet; pAsyncProtocol self = NULL; /* try to find an existing queue with this name */ self = (pAsyncProtocol) FindCommandData(pServ->pSics, protocolName, "AsyncProtocol"); if (self != NULL) { return self; } self = (pAsyncProtocol) malloc(sizeof(AsyncProtocol)); if (self == NULL) { /* TODO */ return NULL; } memset(self, 0, sizeof(AsyncProtocol)); self->pDes = CreateDescriptor("AsyncProtocol"); if (pFunc == NULL) pFunc = AsyncProtocolNoAction; if (pKFunc == NULL) pKFunc = AsyncProtocolKill; iRet = AddCommand(pSics, protocolName, pFunc, pKFunc, self); if (!iRet ) { /* TODO */ AsyncProtocolKill(self); return NULL; } self->sendCommand = defaultSendCommand; self->handleInput = defaultHandleInput; self->handleEvent = defaultHandleEvent; self->prepareTxn = defaultPrepareTxn; self->killPrivate = defaultKillPrivate; return self; } int AsyncProtocolFactory(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]) { if (argc < 2) { SCWrite(pCon,"ERROR: insufficient arguments to AsyncProtocolFactory", eError); return 0; } pAsyncProtocol pNew = AsyncProtocolCreate(pSics, argv[1], AsyncProtocolAction, AsyncProtocolKill); /* TODO: handle arguments */ pNew->privateData = NULL; return 1; }