/* Cesar project {{{ * * Copyright (C) 2007 Spidcom * * <<>> * * }}} */ /** * \file mac/pbproc/src/fsm.c * \brief FSM engine. * \ingroup mac_pbproc */ #include "common/std.h" #include "mac/pbproc/pbproc.h" #include "mac/pbproc/inc/fsm.h" #include "mac/pbproc/inc/context.h" void pbproc_fsm_init (pbproc_t *ctx) { uint i; dbg_assert (ctx); ctx->fsm.current_state = PBPROC_FSM_STATE_IDLE; for (i = 0; i < PBPROC_FSM_STATE_NB; i++) { ctx->fsm.states[i].rx_fc_cb = (pbproc_fsm_rx_fc_cb_t) pbproc_fsm_unexpected; ctx->fsm.states[i].access_cb = pbproc_fsm_unexpected; ctx->fsm.states[i].access_conf_cb = pbproc_fsm_unexpected; } ctx->fsm.deferred_cb = NULL; } bool pbproc_fsm_handle_rx_fc_event (pbproc_t *ctx, u32 rx_date, const u32 *fc_av) { dbg_assert (ctx); dbg_assert (ctx->fsm.current_state < PBPROC_FSM_STATE_NB); PBPROC_TRACE (FSM_RX_FC, phy_date (ctx->phy), rx_date, fc_av ? fc_av[0] & PBPROC_FC_DT_MASK : PBPROC_FC_DT_MASK + 1); ctx->fsm.states[ctx->fsm.current_state]. rx_fc_cb (ctx, rx_date, (const pbproc_fc_t *) fc_av); return ctx->fsm.deferred_cb != NULL; } bool pbproc_fsm_handle_access_event (pbproc_t *ctx) { dbg_assert (ctx); dbg_assert (ctx->fsm.current_state < PBPROC_FSM_STATE_NB); PBPROC_TRACE (FSM_ACCESS, phy_date (ctx->phy)); ctx->fsm.states[ctx->fsm.current_state].access_cb (ctx); return ctx->fsm.deferred_cb != NULL; } bool pbproc_fsm_handle_access_conf_event (pbproc_t *ctx) { dbg_assert (ctx); dbg_assert (ctx->fsm.current_state < PBPROC_FSM_STATE_NB); PBPROC_TRACE (FSM_ACCESS_CONF, phy_date (ctx->phy)); ctx->fsm.states[ctx->fsm.current_state].access_conf_cb (ctx); return ctx->fsm.deferred_cb != NULL; } bool pbproc_fsm_handle_pbdma_event (pbproc_t *ctx, u32 status_word) { dbg_assert (ctx); dbg_assert (ctx->fsm.current_state < PBPROC_FSM_STATE_NB); PBPROC_TRACE (FSM_PBDMA, phy_date (ctx->phy), status_word); /* Handled as an ACCESS event. */ ctx->pbdma_status = PHY_PBDMA_STATUS (status_word); ctx->fsm.states[ctx->fsm.current_state].access_cb (ctx); return ctx->fsm.deferred_cb != NULL; } bool pbproc_fsm_handle_tx_false_alarm_event (pbproc_t *ctx) { // TODO return false; } void pbproc_fsm_handle_deferred (pbproc_t *ctx) { pbproc_fsm_deferred_cb_t cb; dbg_assert (ctx); dbg_assert (ctx->fsm.deferred_cb); PBPROC_TRACE (FSM_DEFERRED, phy_date (ctx->phy)); cb = ctx->fsm.deferred_cb; ctx->fsm.deferred_cb = NULL; cb (ctx); dbg_assert (!ctx->fsm.deferred_cb); } void pbproc_fsm_change_state (pbproc_t *ctx, pbproc_fsm_state_t state) { dbg_assert (ctx); dbg_assert (state < PBPROC_FSM_STATE_NB); PBPROC_TRACE (FSM_CHANGE_STATE, state); ctx->fsm.current_state = state; } void pbproc_fsm_schedule_deferred (pbproc_t *ctx, pbproc_fsm_deferred_cb_t deferred_cb) { dbg_assert (ctx); dbg_assert (deferred_cb); dbg_assert (!ctx->fsm.deferred_cb); PBPROC_TRACE (FSM_SCHEDULE_DEFERRED); ctx->fsm.deferred_cb = deferred_cb; } void pbproc_fsm_unexpected (pbproc_t *ctx) { PBPROC_TRACE (FSM_UNEXPECTED); dbg_fatal ("unexpected event"); }