[libpri-commits] rmudgett: branch rmudgett/q931_fsm r2248 - /team/rmudgett/q931_fsm/
SVN commits to the libpri project
libpri-commits at lists.digium.com
Thu Mar 10 12:28:41 CST 2011
Author: rmudgett
Date: Thu Mar 10 12:28:39 2011
New Revision: 2248
URL: http://svnview.digium.com/svn/libpri?view=rev&rev=2248
Log:
* Add test FSM statistics and checks if the statistics match expected
values.
* Minor tweaks to fsm_transition() usage.
Modified:
team/rmudgett/q931_fsm/fsmtest.c
team/rmudgett/q931_fsm/pri_fsm.c
team/rmudgett/q931_fsm/pri_fsm.h
Modified: team/rmudgett/q931_fsm/fsmtest.c
URL: http://svnview.digium.com/svn/libpri/team/rmudgett/q931_fsm/fsmtest.c?view=diff&rev=2248&r1=2247&r2=2248
==============================================================================
--- team/rmudgett/q931_fsm/fsmtest.c (original)
+++ team/rmudgett/q931_fsm/fsmtest.c Thu Mar 10 12:28:39 2011
@@ -105,6 +105,60 @@
}
}
+enum tst_state {
+ TST_S1,
+ TST_S1_1,
+ TST_S1_1_1,
+ TST_S1_1_2,
+ TST_S1_2,
+ TST_S1_3,
+ TST_S1_3_1,
+
+ TST_NUM_STATES
+};
+
+/*!
+ * \internal
+ * \brief Convert the given test FSM state to string.
+ *
+ * \param state Test FSM state to convert.
+ *
+ * \return String equivalent of event code.
+ */
+static const char *tst_state2str(enum tst_state state)
+{
+ switch (state) {
+ case TST_S1:
+ return "TST_S1";
+ case TST_S1_1:
+ return "TST_S1_1";
+ case TST_S1_1_1:
+ return "TST_S1_1_1";
+ case TST_S1_1_2:
+ return "TST_S1_1_2";
+ case TST_S1_2:
+ return "TST_S1_2";
+ case TST_S1_3:
+ return "TST_S1_3";
+ case TST_S1_3_1:
+ return "TST_S1_3_1";
+ case TST_NUM_STATES:
+ break;
+ }
+ return "TST_state_unknown";
+}
+
+struct tst_statistics {
+ struct {
+ /*! How many prolog events. */
+ int prolog;
+ /*! How many epilog events. */
+ int epilog;
+ } visit[TST_NUM_STATES];
+ /*! How many times the FSM was destroyed. */
+ int destroyed;
+};
+
static void *tst_state_1(struct pri *ctrl, struct fsm_ctrl *fsm, struct fsm_event *event);
static void *tst_state_1_1(struct pri *ctrl, struct fsm_ctrl *fsm, struct fsm_event *event);
static void *tst_state_1_1_1(struct pri *ctrl, struct fsm_ctrl *fsm, struct fsm_event *event);
@@ -140,11 +194,13 @@
return FSM_IS_DEBUG(ctrl->debug & PRI_DEBUG_Q931_STATE);
case FSM_EV_PROLOG:
ACT_DEBUG(ctrl, fsm, event);
+ ++((struct tst_statistics *) (fsm->parms))->visit[TST_S1_1_1].prolog;
break;
case FSM_EV_INIT:
return NULL;
case FSM_EV_EPILOG:
ACT_DEBUG(ctrl, fsm, event);
+ ++((struct tst_statistics *) (fsm->parms))->visit[TST_S1_1_1].epilog;
break;
case TST_EV_A:
ACT_DEBUG(ctrl, fsm, event);
@@ -155,249 +211,254 @@
fsm_event_push(ctrl, fsm, TST_EV_D);
fsm_event_push(ctrl, fsm, TST_EV_C);
fsm_event_post(ctrl, fsm, TST_EV_E);
- fsm_transition(ctrl, ctrl->debug & PRI_DEBUG_Q931_STATE, fsm, tst_state_1_1_1);
+ return fsm_transition(ctrl, ctrl->debug & PRI_DEBUG_Q931_STATE, fsm, tst_state_1_1_1);
+ case TST_EV_C:
+ ACT_DEBUG(ctrl, fsm, event);
+ return fsm_transition(ctrl, ctrl->debug & PRI_DEBUG_Q931_STATE, fsm, tst_state_1_1_2);
+ case TST_EV_E:
+ ACT_DEBUG(ctrl, fsm, event);
+ fsm_event_post(ctrl, fsm, TST_EV_F);
+ return fsm_transition(ctrl, ctrl->debug & PRI_DEBUG_Q931_STATE, fsm, tst_state_1_2);
+ default:
+ break;
+ }
+ return tst_state_1_1;
+}
+
+/*!
+ * \internal
+ * \brief State 1.1.2.
+ *
+ * \param ctrl D channel controller.
+ * \param event Event to process.
+ *
+ * \return The value has various meanings depending upon what
+ * event was passed in.
+ * \see enum fsm_ev event descriptions for return value.
+ */
+static void *tst_state_1_1_2(struct pri *ctrl, struct fsm_ctrl *fsm, struct fsm_event *event)
+{
+ switch (event->code) {
+ case FSM_EV_GET_SUPERSTATE:
+ return tst_state_1_1;
+ case FSM_EV_GET_STATE_NAME:
+ return (void *) __PRETTY_FUNCTION__;
+ case FSM_EV_GET_EV_NAME:
+ return (void *) tst_ev2str(event->parms.num);
+ case FSM_EV_GET_DEBUG:
+ return FSM_IS_DEBUG(ctrl->debug & PRI_DEBUG_Q931_STATE);
+ case FSM_EV_PROLOG:
+ ACT_DEBUG(ctrl, fsm, event);
+ ++((struct tst_statistics *) (fsm->parms))->visit[TST_S1_1_2].prolog;
+ break;
+ case FSM_EV_INIT:
return NULL;
- case TST_EV_C:
- ACT_DEBUG(ctrl, fsm, event);
- fsm_transition(ctrl, ctrl->debug & PRI_DEBUG_Q931_STATE, fsm, tst_state_1_1_2);
+ case FSM_EV_EPILOG:
+ ACT_DEBUG(ctrl, fsm, event);
+ ++((struct tst_statistics *) (fsm->parms))->visit[TST_S1_1_2].epilog;
+ break;
+ case TST_EV_D:
+ ACT_DEBUG(ctrl, fsm, event);
+ return fsm_transition(ctrl, ctrl->debug & PRI_DEBUG_Q931_STATE, fsm, tst_state_1_1);
+ case TST_EV_H:
+ ACT_DEBUG(ctrl, fsm, event);
+ return fsm_transition(ctrl, ctrl->debug & PRI_DEBUG_Q931_STATE, fsm, NULL);
+ default:
+ break;
+ }
+ return tst_state_1_1;
+}
+
+/*!
+ * \internal
+ * \brief State 1.1.
+ *
+ * \param ctrl D channel controller.
+ * \param event Event to process.
+ *
+ * \return The value has various meanings depending upon what
+ * event was passed in.
+ * \see enum fsm_ev event descriptions for return value.
+ */
+static void *tst_state_1_1(struct pri *ctrl, struct fsm_ctrl *fsm, struct fsm_event *event)
+{
+ switch (event->code) {
+ case FSM_EV_GET_SUPERSTATE:
+ return tst_state_1;
+ case FSM_EV_GET_STATE_NAME:
+ return (void *) __PRETTY_FUNCTION__;
+ case FSM_EV_GET_EV_NAME:
+ return (void *) tst_ev2str(event->parms.num);
+ case FSM_EV_GET_DEBUG:
+ return FSM_IS_DEBUG(ctrl->debug & PRI_DEBUG_Q931_STATE);
+ case FSM_EV_PROLOG:
+ ACT_DEBUG(ctrl, fsm, event);
+ ++((struct tst_statistics *) (fsm->parms))->visit[TST_S1_1].prolog;
+ break;
+ case FSM_EV_INIT:
+ return tst_state_1_1_1;
+ case FSM_EV_EPILOG:
+ ACT_DEBUG(ctrl, fsm, event);
+ ++((struct tst_statistics *) (fsm->parms))->visit[TST_S1_1].epilog;
+ break;
+ default:
+ break;
+ }
+ return tst_state_1;
+}
+
+/*!
+ * \internal
+ * \brief State 1.2.
+ *
+ * \param ctrl D channel controller.
+ * \param event Event to process.
+ *
+ * \return The value has various meanings depending upon what
+ * event was passed in.
+ * \see enum fsm_ev event descriptions for return value.
+ */
+static void *tst_state_1_2(struct pri *ctrl, struct fsm_ctrl *fsm, struct fsm_event *event)
+{
+ switch (event->code) {
+ case FSM_EV_GET_SUPERSTATE:
+ return tst_state_1;
+ case FSM_EV_GET_STATE_NAME:
+ return (void *) __PRETTY_FUNCTION__;
+ case FSM_EV_GET_EV_NAME:
+ return (void *) tst_ev2str(event->parms.num);
+ case FSM_EV_GET_DEBUG:
+ return FSM_IS_DEBUG(ctrl->debug & PRI_DEBUG_Q931_STATE);
+ case FSM_EV_PROLOG:
+ ACT_DEBUG(ctrl, fsm, event);
+ ++((struct tst_statistics *) (fsm->parms))->visit[TST_S1_2].prolog;
+ break;
+ case FSM_EV_INIT:
return NULL;
- case TST_EV_E:
- ACT_DEBUG(ctrl, fsm, event);
- fsm_event_post(ctrl, fsm, TST_EV_F);
- fsm_transition(ctrl, ctrl->debug & PRI_DEBUG_Q931_STATE, fsm, tst_state_1_2);
+ case FSM_EV_EPILOG:
+ ACT_DEBUG(ctrl, fsm, event);
+ ++((struct tst_statistics *) (fsm->parms))->visit[TST_S1_2].epilog;
+ break;
+ case TST_EV_F:
+ ACT_DEBUG(ctrl, fsm, event);
+ fsm_event_post(ctrl, fsm, TST_EV_G);
+ return fsm_transition(ctrl, ctrl->debug & PRI_DEBUG_Q931_STATE, fsm, tst_state_1_3);
+ default:
+ break;
+ }
+ return tst_state_1;
+}
+
+/*!
+ * \internal
+ * \brief State 1.3.1.
+ *
+ * \param ctrl D channel controller.
+ * \param event Event to process.
+ *
+ * \return The value has various meanings depending upon what
+ * event was passed in.
+ * \see enum fsm_ev event descriptions for return value.
+ */
+static void *tst_state_1_3_1(struct pri *ctrl, struct fsm_ctrl *fsm, struct fsm_event *event)
+{
+ switch (event->code) {
+ case FSM_EV_GET_SUPERSTATE:
+ return tst_state_1_3;
+ case FSM_EV_GET_STATE_NAME:
+ return (void *) __PRETTY_FUNCTION__;
+ case FSM_EV_GET_EV_NAME:
+ return (void *) tst_ev2str(event->parms.num);
+ case FSM_EV_GET_DEBUG:
+ return FSM_IS_DEBUG(ctrl->debug & PRI_DEBUG_Q931_STATE);
+ case FSM_EV_PROLOG:
+ ACT_DEBUG(ctrl, fsm, event);
+ ++((struct tst_statistics *) (fsm->parms))->visit[TST_S1_3_1].prolog;
+ break;
+ case FSM_EV_INIT:
return NULL;
- default:
- break;
- }
- return tst_state_1_1;
-}
-
-/*!
- * \internal
- * \brief State 1.1.2.
- *
- * \param ctrl D channel controller.
- * \param event Event to process.
- *
- * \return The value has various meanings depending upon what
- * event was passed in.
- * \see enum fsm_ev event descriptions for return value.
- */
-static void *tst_state_1_1_2(struct pri *ctrl, struct fsm_ctrl *fsm, struct fsm_event *event)
-{
- switch (event->code) {
- case FSM_EV_GET_SUPERSTATE:
+ case FSM_EV_EPILOG:
+ ACT_DEBUG(ctrl, fsm, event);
+ ++((struct tst_statistics *) (fsm->parms))->visit[TST_S1_3_1].epilog;
+ break;
+ default:
+ break;
+ }
+ return tst_state_1_3;
+}
+
+/*!
+ * \internal
+ * \brief State 1.3.
+ *
+ * \param ctrl D channel controller.
+ * \param event Event to process.
+ *
+ * \return The value has various meanings depending upon what
+ * event was passed in.
+ * \see enum fsm_ev event descriptions for return value.
+ */
+static void *tst_state_1_3(struct pri *ctrl, struct fsm_ctrl *fsm, struct fsm_event *event)
+{
+ switch (event->code) {
+ case FSM_EV_GET_SUPERSTATE:
+ return tst_state_1;
+ case FSM_EV_GET_STATE_NAME:
+ return (void *) __PRETTY_FUNCTION__;
+ case FSM_EV_GET_EV_NAME:
+ return (void *) tst_ev2str(event->parms.num);
+ case FSM_EV_GET_DEBUG:
+ return FSM_IS_DEBUG(ctrl->debug & PRI_DEBUG_Q931_STATE);
+ case FSM_EV_PROLOG:
+ ACT_DEBUG(ctrl, fsm, event);
+ ++((struct tst_statistics *) (fsm->parms))->visit[TST_S1_3].prolog;
+ break;
+ case FSM_EV_INIT:
+ return tst_state_1_3_1;
+ case FSM_EV_EPILOG:
+ ACT_DEBUG(ctrl, fsm, event);
+ ++((struct tst_statistics *) (fsm->parms))->visit[TST_S1_3].epilog;
+ break;
+ case TST_EV_G:
+ ACT_DEBUG(ctrl, fsm, event);
+ return fsm_transition(ctrl, ctrl->debug & PRI_DEBUG_Q931_STATE, fsm, tst_state_1_1_2);
+ default:
+ break;
+ }
+ return tst_state_1;
+}
+
+/*!
+ * \internal
+ * \brief State 1.
+ *
+ * \param ctrl D channel controller.
+ * \param event Event to process.
+ *
+ * \return The value has various meanings depending upon what
+ * event was passed in.
+ * \see enum fsm_ev event descriptions for return value.
+ */
+static void *tst_state_1(struct pri *ctrl, struct fsm_ctrl *fsm, struct fsm_event *event)
+{
+ switch (event->code) {
+ case FSM_EV_GET_SUPERSTATE:
+ return fsm_top_state;
+ case FSM_EV_GET_STATE_NAME:
+ return (void *) __PRETTY_FUNCTION__;
+ case FSM_EV_GET_EV_NAME:
+ return (void *) tst_ev2str(event->parms.num);
+ case FSM_EV_GET_DEBUG:
+ return FSM_IS_DEBUG(ctrl->debug & PRI_DEBUG_Q931_STATE);
+ case FSM_EV_PROLOG:
+ ACT_DEBUG(ctrl, fsm, event);
+ ++((struct tst_statistics *) (fsm->parms))->visit[TST_S1].prolog;
+ break;
+ case FSM_EV_INIT:
return tst_state_1_1;
- case FSM_EV_GET_STATE_NAME:
- return (void *) __PRETTY_FUNCTION__;
- case FSM_EV_GET_EV_NAME:
- return (void *) tst_ev2str(event->parms.num);
- case FSM_EV_GET_DEBUG:
- return FSM_IS_DEBUG(ctrl->debug & PRI_DEBUG_Q931_STATE);
- case FSM_EV_PROLOG:
- ACT_DEBUG(ctrl, fsm, event);
- break;
- case FSM_EV_INIT:
- return NULL;
- case FSM_EV_EPILOG:
- ACT_DEBUG(ctrl, fsm, event);
- break;
- case TST_EV_D:
- ACT_DEBUG(ctrl, fsm, event);
- fsm_transition(ctrl, ctrl->debug & PRI_DEBUG_Q931_STATE, fsm, tst_state_1_1);
- return NULL;
- case TST_EV_H:
- ACT_DEBUG(ctrl, fsm, event);
- fsm_transition(ctrl, ctrl->debug & PRI_DEBUG_Q931_STATE, fsm, NULL);
- return NULL;
- default:
- break;
- }
- return tst_state_1_1;
-}
-
-/*!
- * \internal
- * \brief State 1.1.
- *
- * \param ctrl D channel controller.
- * \param event Event to process.
- *
- * \return The value has various meanings depending upon what
- * event was passed in.
- * \see enum fsm_ev event descriptions for return value.
- */
-static void *tst_state_1_1(struct pri *ctrl, struct fsm_ctrl *fsm, struct fsm_event *event)
-{
- switch (event->code) {
- case FSM_EV_GET_SUPERSTATE:
- return tst_state_1;
- case FSM_EV_GET_STATE_NAME:
- return (void *) __PRETTY_FUNCTION__;
- case FSM_EV_GET_EV_NAME:
- return (void *) tst_ev2str(event->parms.num);
- case FSM_EV_GET_DEBUG:
- return FSM_IS_DEBUG(ctrl->debug & PRI_DEBUG_Q931_STATE);
- case FSM_EV_PROLOG:
- ACT_DEBUG(ctrl, fsm, event);
- break;
- case FSM_EV_INIT:
- return tst_state_1_1_1;
- case FSM_EV_EPILOG:
- ACT_DEBUG(ctrl, fsm, event);
- break;
- default:
- break;
- }
- return tst_state_1;
-}
-
-/*!
- * \internal
- * \brief State 1.2.
- *
- * \param ctrl D channel controller.
- * \param event Event to process.
- *
- * \return The value has various meanings depending upon what
- * event was passed in.
- * \see enum fsm_ev event descriptions for return value.
- */
-static void *tst_state_1_2(struct pri *ctrl, struct fsm_ctrl *fsm, struct fsm_event *event)
-{
- switch (event->code) {
- case FSM_EV_GET_SUPERSTATE:
- return tst_state_1;
- case FSM_EV_GET_STATE_NAME:
- return (void *) __PRETTY_FUNCTION__;
- case FSM_EV_GET_EV_NAME:
- return (void *) tst_ev2str(event->parms.num);
- case FSM_EV_GET_DEBUG:
- return FSM_IS_DEBUG(ctrl->debug & PRI_DEBUG_Q931_STATE);
- case FSM_EV_PROLOG:
- ACT_DEBUG(ctrl, fsm, event);
- break;
- case FSM_EV_INIT:
- return NULL;
- case FSM_EV_EPILOG:
- ACT_DEBUG(ctrl, fsm, event);
- break;
- case TST_EV_F:
- ACT_DEBUG(ctrl, fsm, event);
- fsm_event_post(ctrl, fsm, TST_EV_G);
- fsm_transition(ctrl, ctrl->debug & PRI_DEBUG_Q931_STATE, fsm, tst_state_1_3);
- return NULL;
- default:
- break;
- }
- return tst_state_1;
-}
-
-/*!
- * \internal
- * \brief State 1.3.1.
- *
- * \param ctrl D channel controller.
- * \param event Event to process.
- *
- * \return The value has various meanings depending upon what
- * event was passed in.
- * \see enum fsm_ev event descriptions for return value.
- */
-static void *tst_state_1_3_1(struct pri *ctrl, struct fsm_ctrl *fsm, struct fsm_event *event)
-{
- switch (event->code) {
- case FSM_EV_GET_SUPERSTATE:
- return tst_state_1_3;
- case FSM_EV_GET_STATE_NAME:
- return (void *) __PRETTY_FUNCTION__;
- case FSM_EV_GET_EV_NAME:
- return (void *) tst_ev2str(event->parms.num);
- case FSM_EV_GET_DEBUG:
- return FSM_IS_DEBUG(ctrl->debug & PRI_DEBUG_Q931_STATE);
- case FSM_EV_PROLOG:
- ACT_DEBUG(ctrl, fsm, event);
- break;
- case FSM_EV_INIT:
- return NULL;
- case FSM_EV_EPILOG:
- ACT_DEBUG(ctrl, fsm, event);
- break;
- default:
- break;
- }
- return tst_state_1_3;
-}
-
-/*!
- * \internal
- * \brief State 1.3.
- *
- * \param ctrl D channel controller.
- * \param event Event to process.
- *
- * \return The value has various meanings depending upon what
- * event was passed in.
- * \see enum fsm_ev event descriptions for return value.
- */
-static void *tst_state_1_3(struct pri *ctrl, struct fsm_ctrl *fsm, struct fsm_event *event)
-{
- switch (event->code) {
- case FSM_EV_GET_SUPERSTATE:
- return tst_state_1;
- case FSM_EV_GET_STATE_NAME:
- return (void *) __PRETTY_FUNCTION__;
- case FSM_EV_GET_EV_NAME:
- return (void *) tst_ev2str(event->parms.num);
- case FSM_EV_GET_DEBUG:
- return FSM_IS_DEBUG(ctrl->debug & PRI_DEBUG_Q931_STATE);
- case FSM_EV_PROLOG:
- ACT_DEBUG(ctrl, fsm, event);
- break;
- case FSM_EV_INIT:
- return tst_state_1_3_1;
- case FSM_EV_EPILOG:
- ACT_DEBUG(ctrl, fsm, event);
- break;
- case TST_EV_G:
- ACT_DEBUG(ctrl, fsm, event);
- fsm_transition(ctrl, ctrl->debug & PRI_DEBUG_Q931_STATE, fsm, tst_state_1_1_2);
- return NULL;
- default:
- break;
- }
- return tst_state_1;
-}
-
-/*!
- * \internal
- * \brief State 1.
- *
- * \param ctrl D channel controller.
- * \param event Event to process.
- *
- * \return The value has various meanings depending upon what
- * event was passed in.
- * \see enum fsm_ev event descriptions for return value.
- */
-static void *tst_state_1(struct pri *ctrl, struct fsm_ctrl *fsm, struct fsm_event *event)
-{
- switch (event->code) {
- case FSM_EV_GET_SUPERSTATE:
- return fsm_top_state;
- case FSM_EV_GET_STATE_NAME:
- return (void *) __PRETTY_FUNCTION__;
- case FSM_EV_GET_EV_NAME:
- return (void *) tst_ev2str(event->parms.num);
- case FSM_EV_GET_DEBUG:
- return FSM_IS_DEBUG(ctrl->debug & PRI_DEBUG_Q931_STATE);
- case FSM_EV_PROLOG:
- ACT_DEBUG(ctrl, fsm, event);
- break;
- case FSM_EV_INIT:
- return tst_state_1_1;
- case FSM_EV_EPILOG:
- ACT_DEBUG(ctrl, fsm, event);
+ case FSM_EV_EPILOG:
+ ACT_DEBUG(ctrl, fsm, event);
+ ++((struct tst_statistics *) (fsm->parms))->visit[TST_S1].epilog;
break;
default:
break;
@@ -416,8 +477,11 @@
*/
static void tst_fsm_destructor(struct pri *ctrl, struct fsm_ctrl *fsm, void *parms)
{
+ struct tst_statistics *stats;
+
pri_message(ctrl, DBGHEAD "\n", DBGINFO);
- *(int *) parms = *((int *) parms) + 1;
+ stats = parms;
+ ++stats->destroyed;
}
/*!
@@ -434,7 +498,19 @@
static struct pri dummy_ctrl;
static struct fsm_queue ev_q;
static struct fsm_ctrl fsm;
- static int fsm_destroyed;
+ static struct tst_statistics tst_stats;
+
+ static const int expected_visits[TST_NUM_STATES] = {
+ [TST_S1] = 1,
+ [TST_S1_1] = 2,
+ [TST_S1_1_1] = 3,
+ [TST_S1_1_2] = 2,
+ [TST_S1_2] = 1,
+ [TST_S1_3] = 1,
+ [TST_S1_3_1] = 1,
+ };
+
+ int idx;
pri_set_message(tst_pri_message);
pri_set_error(tst_pri_error);
@@ -448,9 +524,9 @@
/* Setup FSM */
fsm.state = NULL;
fsm.destructor = tst_fsm_destructor;
- fsm.name = "Test FSM";
+ fsm.name = "Test";
fsm.que = &ev_q;
- fsm.parms = &fsm_destroyed;
+ fsm.parms = &tst_stats;
fsm_init(&dummy_ctrl, &fsm, tst_state_1);
/* Nothing to do. */
@@ -464,8 +540,27 @@
fsm_event_post(&dummy_ctrl, &fsm, TST_EV_H);
fsm_run(&dummy_ctrl, &ev_q);
- if (fsm_destroyed != 1) {
- pri_error(&dummy_ctrl, "Test FSM destroyed %d times!\n", fsm_destroyed);
+ /* Display FSM state statistics. */
+ for (idx = 0; idx < ARRAY_LEN(tst_stats.visit); ++idx) {
+ pri_message(&dummy_ctrl, "State %-10s: prologs: %d epilogs: %d\n",
+ tst_state2str(idx),
+ tst_stats.visit[idx].prolog, tst_stats.visit[idx].epilog);
+ }
+
+ /* Check FSM state statistics. */
+ for (idx = 0; idx < ARRAY_LEN(tst_stats.visit); ++idx) {
+ if (tst_stats.visit[idx].prolog != tst_stats.visit[idx].epilog) {
+ pri_error(&dummy_ctrl, "State %s: Prologs do not match epilogs!\n",
+ tst_state2str(idx));
+ }
+ if (tst_stats.visit[idx].prolog != expected_visits[idx]) {
+ pri_error(&dummy_ctrl,
+ "State %s: Did not get the expected number of visits!\n",
+ tst_state2str(idx));
+ }
+ }
+ if (tst_stats.destroyed != 1) {
+ pri_error(&dummy_ctrl, "%s: FSM destroyed %d times!\n", fsm.name, tst_stats.destroyed);
}
return 0;
Modified: team/rmudgett/q931_fsm/pri_fsm.c
URL: http://svnview.digium.com/svn/libpri/team/rmudgett/q931_fsm/pri_fsm.c?view=diff&rev=2248&r1=2247&r2=2248
==============================================================================
--- team/rmudgett/q931_fsm/pri_fsm.c (original)
+++ team/rmudgett/q931_fsm/pri_fsm.c Thu Mar 10 12:28:39 2011
@@ -242,9 +242,11 @@
* \param fsm FSM that is transitioning states.
* \param dest Transitioning to state. (NULL if terminal)
*
- * \return Nothing
- */
-void fsm_transition(struct pri *ctrl, int debug, struct fsm_ctrl *fsm, fsm_state dest)
+ * \return NULL to encourage the use of "return
+ * fsm_transition();". The expression emphasizes the fact that
+ * the state has completed processing an event.
+ */
+void *fsm_transition(struct pri *ctrl, int debug, struct fsm_ctrl *fsm, fsm_state dest)
{
struct fsm_event local_event;
fsm_state epilog_state[FSM_MAX_SUPERSTATE_NESTING + 1];/* Plus top state. */
@@ -261,7 +263,7 @@
src = fsm->state;
if (!src || src == fsm_top_state) {
- /* This is the initial transition to start the FSM. */
+ /* This is the initial event transition to start the FSM. */
fsm->state = fsm_top_state;
src = NULL;
}
@@ -271,7 +273,7 @@
if (dest && dest != fsm_top_state) {
dest_name = dest(ctrl, fsm, &local_event);
} else {
- /* This is the terminal transition to end the FSM. */
+ /* This is the terminal event transition to end the FSM. */
dest_name = fsm_top_state(ctrl, fsm, &local_event);
dest = NULL;
}
@@ -292,7 +294,7 @@
pri_error(ctrl, "%s: FSM source state %s nested too deep!\n", fsm->name,
src_name);
- return;
+ return NULL;
}
src = src(ctrl, fsm, &local_event);
if (src == fsm_top_state) {
@@ -308,7 +310,7 @@
if (FSM_MAX_SUPERSTATE_NESTING <= prolog_index) {
pri_error(ctrl, "%s: FSM destination state %s nested too deep!\n", fsm->name,
dest_name);
- return;
+ return NULL;
}
dest = dest(ctrl, fsm, &local_event);
if (dest == fsm_top_state) {
@@ -320,7 +322,7 @@
if (!epilog_index && !prolog_index) {
pri_error(ctrl, "%s: FSM initial transition is termination transition!\n",
fsm->name);
- return;
+ return NULL;
}
/* Find first non-common superstate level. */
@@ -382,13 +384,13 @@
} else {
/* Termination transition. */
fsm->state = fsm_top_state;
+ if (debug) {
+ pri_message(ctrl, "%s: Terminated\n", fsm->name);
+ }
if (fsm->destructor) {
- if (debug) {
- pri_message(ctrl, "%s: Destroying\n", fsm->name);
- }
fsm->destructor(ctrl, fsm, fsm->parms);
}
- return;
+ return NULL;
}
/* We reached the specified destination state. */
@@ -421,6 +423,8 @@
/* We drilled one level deeper. */
fsm->state = dest;
}
+
+ return NULL;
}
/*!
@@ -494,7 +498,7 @@
}
/*!
- * \brief Do the initial transition to start the FSM.
+ * \brief Do the initial event transition to start the FSM.
*
* \param ctrl D channel controller.
* \param fsm Filled in FSM control structure set to the initial FSM state.
@@ -515,7 +519,7 @@
}
if (debug) {
- pri_message(ctrl, "%s: Initial transition\n", fsm->name);
+ pri_message(ctrl, "%s: Initial event\n", fsm->name);
}
fsm->state = fsm_top_state;
fsm_transition(ctrl, debug, fsm, init);
Modified: team/rmudgett/q931_fsm/pri_fsm.h
URL: http://svnview.digium.com/svn/libpri/team/rmudgett/q931_fsm/pri_fsm.h?view=diff&rev=2248&r1=2247&r2=2248
==============================================================================
--- team/rmudgett/q931_fsm/pri_fsm.h (original)
+++ team/rmudgett/q931_fsm/pri_fsm.h Thu Mar 10 12:28:39 2011
@@ -211,7 +211,7 @@
void fsm_event_push(struct pri *ctrl, struct fsm_ctrl *fsm, int code);
void fsm_event_post(struct pri *ctrl, struct fsm_ctrl *fsm, int code);
void *fsm_top_state(struct pri *ctrl, struct fsm_ctrl *fsm, struct fsm_event *event);
-void fsm_transition(struct pri *ctrl, int debug, struct fsm_ctrl *fsm, fsm_state dest);
+void *fsm_transition(struct pri *ctrl, int debug, struct fsm_ctrl *fsm, fsm_state dest);
void fsm_run(struct pri *ctrl, struct fsm_queue *que);
void fsm_init(struct pri *ctrl, struct fsm_ctrl *fsm, fsm_state init);
More information about the libpri-commits
mailing list