summaryrefslogtreecommitdiff
path: root/cesar/cp2/fsm/src/fsm.c
diff options
context:
space:
mode:
Diffstat (limited to 'cesar/cp2/fsm/src/fsm.c')
-rw-r--r--cesar/cp2/fsm/src/fsm.c33
1 files changed, 30 insertions, 3 deletions
diff --git a/cesar/cp2/fsm/src/fsm.c b/cesar/cp2/fsm/src/fsm.c
index 1605dec6f9..4c673e2bf4 100644
--- a/cesar/cp2/fsm/src/fsm.c
+++ b/cesar/cp2/fsm/src/fsm.c
@@ -24,6 +24,9 @@ cp_fsm_init (cp_t *ctx)
dbg_assert (ctx);
for (i = 0; i < CP_FSM_INITIAL_NB; i++)
ctx->fsm.active_states[i] = cp_fsm_initials_table[i];
+ for (i = 0; i < CP_FSM_INITIAL_NB; i++)
+ if (cp_fsm_enter_table[i])
+ cp_fsm_enter_table[i] (ctx);
ctx->fsm.handled_event = NULL;
ctx->fsm.head = NULL;
ctx->fsm.tail = NULL;
@@ -44,6 +47,27 @@ cp_fsm_uninit (cp_t *ctx)
}
/**
+ * Execute callbacks attached to enter and leave action of states.
+ * \param ctx control plane context
+ * \param i active state index
+ * \param to state entered
+ */
+static void
+cp_fsm_leave_enter (cp_t *ctx, uint i, cp_fsm_state_t to)
+{
+ dbg_assert (ctx);
+ dbg_assert (i < CP_FSM_INITIAL_NB);
+ dbg_assert (to < CP_FSM_STATE_NB);
+ cp_fsm_state_t from = ctx->fsm.active_states[i];
+ dbg_assert (from < CP_FSM_STATE_NB);
+ if (cp_fsm_leave_table[from])
+ cp_fsm_leave_table[from] (ctx);
+ ctx->fsm.active_states[i] = to;
+ if (cp_fsm_enter_table[to])
+ cp_fsm_enter_table[to] (ctx);
+}
+
+/**
* Handle event for one active state.
* \param ctx control plane context
* \param e event to handle
@@ -52,6 +76,9 @@ cp_fsm_uninit (cp_t *ctx)
static void
cp_fsm_handled_event (cp_t *ctx, cp_fsm_event_t *e, uint i)
{
+ dbg_assert (ctx);
+ dbg_assert (e);
+ dbg_assert (i < CP_FSM_INITIAL_NB);
cp_fsm_transition_t t =
cp_fsm_transition_table[ctx->fsm.active_states[i]][e->type];
if (t)
@@ -71,7 +98,7 @@ cp_fsm_handled_event (cp_t *ctx, cp_fsm_event_t *e, uint i)
"no branch selected");
dbg_assert (to < CP_FSM_STATE_NB);
if (to != CP_FSM_STATE_NB) /* Be clement for errors. */
- ctx->fsm.active_states[i] = to;
+ cp_fsm_leave_enter (ctx, i, to);
ctx->fsm.handled_event = NULL;
}
}
@@ -83,7 +110,7 @@ cp_fsm_handled_event (cp_t *ctx, cp_fsm_event_t *e, uint i)
if (to != CP_FSM_STATE_NB)
{
dbg_assert (to < CP_FSM_STATE_NB);
- ctx->fsm.active_states[i] = to;
+ cp_fsm_leave_enter (ctx, i, to);
ctx->fsm.handled_event = NULL;
}
}
@@ -153,7 +180,7 @@ cp_fsm_branch_ (cp_t *ctx, cp_fsm_branch_t branch)
"bad branch");
/* Select this branch. */
cp_fsm_state_t to = ((uint) branch) & 0xff;
- ctx->fsm.active_states[i] = to;
+ cp_fsm_leave_enter (ctx, i, to);
ctx->fsm.handled_event = NULL;
}