#include "fsm.h" #include "nwatch.h" char* fsm_textify(const char* pInp, int inp_len, char* pOut, int out_len) { int iInp = 0; int iOut = 0; for (iInp = 0; iInp < inp_len; ++iInp) { if ((pInp[iInp] < 32 || pInp[iInp] > 126)) { if (iOut < out_len - 4) { const char hex[] = "0123456789abcdef"; pOut[iOut++] = '\\'; pOut[iOut++] = hex[(pInp[iInp] >> 4) & 0xf]; pOut[iOut++] = hex[pInp[iInp] & 0xf]; } else if (iOut < out_len - 1) pOut[iOut++] = '.'; } else if (iOut < out_len - 1) pOut[iOut++] = pInp[iInp]; } if (iOut < out_len) pOut[iOut++] = '\0'; return pOut; } static void report_event(pStateMachine self, pEvtEvent event) { char line[132]; char text[132]; snprintf(line, sizeof(line), "StateMachine=%s, State=%s(%d), event=%s", self->name ? self->name : "", self->state_name ? self->state_name(self->myState) : "", self->mySubState, self->event_name ? self->event_name(event, text, sizeof(text)) : ""); SICSLogWrite(line, eStatus); } static void handle_event(pStateMachine self, pEvtEvent event) { if (self->debug) report_event(self, event); if (self->myState) self->myState(self, event); } int fsm_msg_callback(pAsyncTxn pCmd) { pStateMachine self = (pStateMachine) pCmd->cntx; EvtEvent event; if (pCmd->txn_status == ATX_TIMEOUT) { if (self->debug) { char line[1024]; fsm_textify(pCmd->out_buf, pCmd->out_len, line, sizeof(line)); SICSLogWrite(line, eStatus); SICSLogWrite("", eStatus); } event.event_type = eTimeoutEvent; event.event.msg.cmd = pCmd; } else { if (self->debug) { char line[1024]; fsm_textify(pCmd->out_buf, pCmd->out_len, line, sizeof(line)); SICSLogWrite(line, eStatus); fsm_textify(pCmd->inp_buf, pCmd->inp_idx, line, sizeof(line)); SICSLogWrite(line, eStatus); } event.event_type = eMessageEvent; event.event.msg.cmd = pCmd; } handle_event(self, &event); return 0; } int fsm_tmr_callback(void* ctx, int mode) { pStateMachine self = (pStateMachine) ctx; EvtEvent event; pNWTimer timer; event.event_type = eTimerEvent; timer = NetWatchGetActiveTimer(); event.event.tmr.timerValue = NetWatchGetTimerDelay(timer); handle_event(self, &event); return 0; } int fsm_cmd_execute(pStateMachine self, const void* cmd) { EvtEvent event; event.event_type = eCommandEvent; event.event.cmd.cmd_text = cmd; handle_event(self, &event); return 0; } void fsm_change_state(pStateMachine self, StateFunc func) { if (self->debug) { char line[132]; snprintf(line, sizeof(line), "StateMachine=%s, OldState=%s(%d), NewState=%s", self->name ? self->name : "", self->state_name ? self->state_name(self->myState) : "", self->mySubState, self->state_name ? self->state_name(func) : ""); SICSLogWrite(line, eStatus); } self->myPrevState = self->myState; self->myState = func; self->mySubState = 0; EvtEvent evt; evt.event_type = eStateEvent; if (self->myState) self->myState(self, &evt); } void fsm_unhandled_event(pStateMachine self, pEvtEvent event) { char line[132]; char text[132]; snprintf(line, sizeof(line), "StateMachine=%s, State=%s(%d), unhandled event=%s", self->name ? self->name : "", self->state_name ? self->state_name(self->myState) : "", self->mySubState, self->event_name ? self->event_name(event, text, sizeof(text)) : ""); SICSLogWrite(line, eError); }