[svn-commits] rmudgett: branch rmudgett/q931_fsm r2245 - /team/rmudgett/q931_fsm/

SVN commits to the Digium repositories svn-commits at lists.digium.com
Sun Mar 6 15:56:39 CST 2011


Author: rmudgett
Date: Sun Mar  6 15:56:34 2011
New Revision: 2245

URL: http://svnview.digium.com/svn/libpri?view=rev&rev=2245
Log:
Eliminate FSM_EV_INIT.  FSM_EV_PROLOG return now returns the default substate.

Modified:
    team/rmudgett/q931_fsm/pri_fsm.c
    team/rmudgett/q931_fsm/pri_fsm.h

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=2245&r1=2244&r2=2245
==============================================================================
--- team/rmudgett/q931_fsm/pri_fsm.c (original)
+++ team/rmudgett/q931_fsm/pri_fsm.c Sun Mar  6 15:56:34 2011
@@ -58,8 +58,6 @@
 		return "FSM_EV_GET_EV_NAME";
 	case FSM_EV_GET_DEBUG:
 		return "FSM_EV_GET_DEBUG";
-	case FSM_EV_INIT:
-		return "FSM_EV_INIT";
 	case FSM_EV_PROLOG:
 		return "FSM_EV_PROLOG";
 	case FSM_EV_EPILOG:
@@ -88,7 +86,7 @@
 
 	state = event->fsm->state;
 
-	//dbg_event.fsm = event->fsm;
+	dbg_event.fsm = event->fsm;
 	dbg_event.code = FSM_EV_GET_DEBUG;
 	if (state(ctrl, &dbg_event)) {
 		dbg_event.code = FSM_EV_GET_EV_NAME;
@@ -132,7 +130,7 @@
 
 	state = event->fsm->state;
 
-	//dbg_event.fsm = event->fsm;
+	dbg_event.fsm = event->fsm;
 	dbg_event.code = FSM_EV_GET_DEBUG;
 	if (state(ctrl, &dbg_event)) {
 		dbg_event.code = FSM_EV_GET_EV_NAME;
@@ -166,25 +164,27 @@
  *
  * \return The value has various meanings depending upon what
  * event was passed in.
- * \see enum fsm_ev event descriptions.
- *
- * \retval NULL For normal events: The state handled the event.
- *
- * \retval non-NULL For normal events: The superstate to pass
- * the event to next.
+ * \see enum fsm_ev event descriptions for return value.
  */
 void *fsm_top_state(struct pri *ctrl, struct fsm_event *event)
 {
 	switch (event->code) {
+	case FSM_EV_GET_SUPERSTATE:
+		break;
 	case FSM_EV_GET_STATE_NAME:
 		return (void *) __PRETTY_FUNCTION__;
 	case FSM_EV_GET_EV_NAME:
+		/* This is not the best state to use to get an event name. */
 		return (void *) fsm_ev2str(event->parms.num);
 	case FSM_EV_GET_DEBUG:
 		/* Noone should be doing this since how are we to know? */
 		pri_error(ctrl, DBGHEAD "Asking for FSM debug output enable!\n", DBGINFO);
 		return (void *) 1;
+	case FSM_EV_PROLOG:
+	case FSM_EV_EPILOG:
 	default:
+		pri_error(ctrl, DBGHEAD "%s: Unhandled event: %s(%d)!\n", DBGINFO,
+			event->fsm->name, fsm_ev2str(event->code), event->code);
 		break;
 	}
 	return NULL;
@@ -196,21 +196,20 @@
  * \param ctrl D channel controller.
  * \param debug TRUE if FSM debug output enabled.
  * \param fsm FSM that is transitioning states.
- * \param from Transitioning from state. (NULL if initial)
- * \param to Transitioning to state. (NULL if terminal)
- *
- * \return Nothing
- */
-void fsm_transition(struct pri *ctrl, int debug, struct fsm_ctrl *fsm, fsm_state from, fsm_state to)
+ * \param dest Transitioning to state. (NULL if terminal)
+ * \param src Transitioning from state. (NULL if initial)
+ *
+ * \return Nothing
+ */
+void fsm_transition(struct pri *ctrl, int debug, struct fsm_ctrl *fsm, fsm_state dest, fsm_state src)
 {
 	struct fsm_event local_event;
 	fsm_state epilog_state[FSM_MAX_SUPERSTATE_NESTING];
 	fsm_state prolog_state[FSM_MAX_SUPERSTATE_NESTING];
 	const char *epilog_name;
 	const char *prolog_name;
-	const char *init_name;
-	const char *from_name;
-	const char *to_name;
+	const char *src_name;
+	const char *dest_name;
 	int epilog_index;
 	int prolog_index;
 	int idx;
@@ -219,48 +218,52 @@
 
 	/* Get original state names. */
 	local_event.code = FSM_EV_GET_STATE_NAME;
-	if (from) {
-		from_name = from(ctrl, &local_event);
-	} else {
+	if (src && src != fsm_top_state) {
+		src_name = src(ctrl, &local_event);
+	} else {
+		/* This is the initial transition to start the FSM. */
 		fsm->state = fsm_top_state;
-		from_name = "*";
-	}
-	if (to) {
-		to_name = to(ctrl, &local_event);
-	} else {
-		to_name = "*";
+		src_name = fsm_top_state(ctrl, &local_event);
+		src = NULL;
+	}
+	if (dest && dest != fsm_top_state) {
+		dest_name = dest(ctrl, &local_event);
+	} else {
+		/* This is the terminal transition to end the FSM. */
+		dest_name = fsm_top_state(ctrl, &local_event);
+		dest = NULL;
 	}
 
 	if (debug) {
-		pri_message(ctrl, "%s:  Next-state %s\n", fsm->name, to_name);
+		pri_message(ctrl, "%s:  Next-state %s\n", fsm->name, dest_name);
 	}
 
 	local_event.code = FSM_EV_GET_SUPERSTATE;
 
-	/* Build from superstate nesting stack. */
+	/* Build src superstate nesting stack. */
 	epilog_index = 0;
-	epilog_state[epilog_index++] = from;
-	while (from) {
+	epilog_state[epilog_index++] = src;
+	while (src && src != fsm_top_state) {
 		if (FSM_MAX_SUPERSTATE_NESTING <= epilog_index) {
-			pri_error(ctrl, "%s: FSM 'from' state %s nested too deep!\n", fsm->name,
-				from_name);
+			pri_error(ctrl, "%s: FSM source state %s nested too deep!\n", fsm->name,
+				src_name);
 			return;
 		}
-		from = from(ctrl, &local_event);
-		epilog_state[epilog_index++] = from;
-	}
-
-	/* Build to superstate nesting stack. */
+		src = src(ctrl, &local_event);
+		epilog_state[epilog_index++] = src;
+	}
+
+	/* Build dest superstate nesting stack. */
 	prolog_index = 0;
-	prolog_state[prolog_index++] = to;
-	while (to) {
+	prolog_state[prolog_index++] = dest;
+	while (dest && dest != fsm_top_state) {
 		if (FSM_MAX_SUPERSTATE_NESTING <= prolog_index) {
-			pri_error(ctrl, "%s: FSM 'to' state %s nested too deep!\n", fsm->name,
-				to_name);
+			pri_error(ctrl, "%s: FSM destination state %s nested too deep!\n", fsm->name,
+				dest_name);
 			return;
 		}
-		to = to(ctrl, &local_event);
-		prolog_state[prolog_index++] = to;
+		dest = dest(ctrl, &local_event);
+		prolog_state[prolog_index++] = dest;
 	}
 
 	/* Find first non-common superstate level. */
@@ -281,16 +284,16 @@
 		epilog_name = fsm_ev2str(FSM_EV_EPILOG);
 
 		for (idx = 0; idx <= epilog_index; ++idx) {
-			from = epilog_state[idx];
+			src = epilog_state[idx];
 			if (debug) {
 				local_event.code = FSM_EV_GET_STATE_NAME;
-				from_name = (const char *) from(ctrl, &local_event);
+				src_name = (const char *) src(ctrl, &local_event);
 
 				pri_message(ctrl, "%s: Event %s in state %s\n", fsm->name, epilog_name,
-					from_name);
+					src_name);
 			}
 			local_event.code = FSM_EV_EPILOG;
-			from(ctrl, &local_event);
+			src(ctrl, &local_event);
 		}
 	}
 
@@ -299,16 +302,16 @@
 		prolog_name = fsm_ev2str(FSM_EV_PROLOG);
 
 		for (idx = prolog_index; 0 <= idx; --idx) {
-			to = prolog_state[idx];
+			dest = prolog_state[idx];
 			if (debug) {
 				local_event.code = FSM_EV_GET_STATE_NAME;
-				to_name = (const char *) to(ctrl, &local_event);
+				dest_name = (const char *) dest(ctrl, &local_event);
 
 				pri_message(ctrl, "%s: Event %s in state %s\n", fsm->name, prolog_name,
-					to_name);
+					dest_name);
 			}
 			local_event.code = FSM_EV_PROLOG;
-			to(ctrl, &local_event);
+			dest = dest(ctrl, &local_event);
 		}
 	} else {
 		/* Termination transition. */
@@ -321,35 +324,28 @@
 		return;
 	}
 
-	/* Drill down into possible further nested states. */
-	init_name = fsm_ev2str(FSM_EV_INIT);
-	to = prolog_state[0];
-	for (;;) {
+	if (!dest) {
+		/* The original dest state is a leaf state. */
+		fsm->state = prolog_state[0];
+		return;
+	}
+
+	/* Drill into nested states for the final destination state. */
+	do {
+		src = dest;
 		if (debug) {
 			local_event.code = FSM_EV_GET_STATE_NAME;
-			to_name = (const char *) to(ctrl, &local_event);
-
-			pri_message(ctrl, "%s: Event %s in state %s\n", fsm->name, init_name,
-				to_name);
-		}
-		local_event.code = FSM_EV_INIT;
-		to = to(ctrl, &local_event);
-		if (!to) {
-			/* We made it to a leaf state. */
-			fsm->state = prolog_state[0];
-			break;
-		}
-		prolog_state[0] = to;
-		if (debug) {
-			local_event.code = FSM_EV_GET_STATE_NAME;
-			to_name = (const char *) to(ctrl, &local_event);
+			dest_name = (const char *) dest(ctrl, &local_event);
 
 			pri_message(ctrl, "%s: Event %s in state %s\n", fsm->name, prolog_name,
-				to_name);
+				dest_name);
 		}
 		local_event.code = FSM_EV_PROLOG;
-		to(ctrl, &local_event);
-	}
+		dest = dest(ctrl, &local_event);
+	} while (dest);
+
+	/* We made it to a leaf state. */
+	fsm->state = src;
 }
 
 /*!
@@ -370,7 +366,7 @@
 
 	state = event->fsm->state;
 
-	//local_event.fsm = event->fsm;
+	local_event.fsm = event->fsm;
 	local_event.code = FSM_EV_GET_DEBUG;
 	if (state(ctrl, &local_event)) {
 		debug = 1;
@@ -446,7 +442,7 @@
 	if (debug) {
 		pri_message(ctrl, "%s: Initial transition\n", fsm->name);
 	}
-	fsm_transition(ctrl, debug, fsm, NULL, fsm->state);
+	fsm_transition(ctrl, debug, fsm, fsm->state, NULL);
 }
 
 /* ------------------------------------------------------------------- */

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=2245&r1=2244&r2=2245
==============================================================================
--- team/rmudgett/q931_fsm/pri_fsm.h (original)
+++ team/rmudgett/q931_fsm/pri_fsm.h Sun Mar  6 15:56:34 2011
@@ -57,28 +57,38 @@
 	 * \note
 	 * Used to determine which PROLOG/EPILOG events need to run in a
 	 * state transition.
+	 *
+	 * \return The superstate of the current state.
 	 */
 	FSM_EV_GET_SUPERSTATE,
 	/*! \brief Event to get the __PRETTY_FUNCTION__ string of the FSM state. */
 	FSM_EV_GET_STATE_NAME,
-	/*! \brief Event to get the event name string. */
+	/*!
+	 * \brief Event to get the event name string.
+	 *
+	 * \note This event takes an event code parameter: event.parms.num
+	 */
 	FSM_EV_GET_EV_NAME,
-	/*! \brief Event to get the FSM debug output enable flag. */
+	/*!
+	 * \brief Event to get the FSM debug output enable flag.
+	 *
+	 * \retval NULL if debug output is disabled.
+	 */
 	FSM_EV_GET_DEBUG,
-	/*!
-	 * \brief Event to get the initial sub-state of the FSM state.
-	 *
-	 * \note
-	 * Used to drill down into the FSM to find the initial FSM leaf
-	 * state.
-	 */
-	FSM_EV_INIT,
 	/*!
 	 * \brief Event to construct the FSM state.
 	 *
 	 * \note
 	 * Used to construct the FSM state when an event causes a
 	 * transition into the state.
+	 *
+	 * \note
+	 * The return value is used to drill down into the FSM to find
+	 * the initial FSM leaf state.
+	 *
+	 * \retval NULL The state is a leaf state.  There is no default substate.
+	 *
+	 * \retval substate The default substate to drill down into the FSM.
 	 */
 	FSM_EV_PROLOG,
 	/*!
@@ -87,13 +97,20 @@
 	 * \note
 	 * Used to destroy the FSM state when an event causes a
 	 * transition from the state.
+	 *
+	 * \return The superstate of the current state.
 	 */
 	FSM_EV_EPILOG,
 
 	/*!
-	 * \brief First event code value available for a user defined FSM.
+	 * \brief First normal event code value available for a user defined FSM.
 	 *
 	 * \note MUST be last in the enum.
+	 *
+	 * \retval NULL The state handled the event.
+	 *
+	 * \retval superstate The superstate of the current state to
+	 * pass the event to next.
 	 */
 	FSM_EV_FIRST_USER_EV
 };
@@ -106,12 +123,7 @@
  *
  * \return The value has various meanings depending upon what
  * event was passed in.
- * \see enum fsm_ev event descriptions.
- *
- * \retval NULL For normal events: The state handled the event.
- *
- * \retval non-NULL For normal events: The superstate to pass
- * the event to next.
+ * \see enum fsm_ev event descriptions for return value.
  */
 typedef void *(*fsm_state)(struct pri *ctrl, struct fsm_event *event);
 
@@ -189,7 +201,7 @@
 void fsm_event_push(struct pri *ctrl, struct fsm_event *event);
 void fsm_event_post(struct pri *ctrl, struct fsm_event *event);
 void *fsm_top_state(struct pri *ctrl, struct fsm_event *event);
-void fsm_transition(struct pri *ctrl, int debug, struct fsm_ctrl *fsm, fsm_state from, fsm_state to);
+void fsm_transition(struct pri *ctrl, int debug, struct fsm_ctrl *fsm, fsm_state dest, fsm_state src);
 void fsm_run(struct pri *ctrl, struct fsm_queue *que);
 void fsm_init(struct pri *ctrl, struct fsm_ctrl *fsm);
 




More information about the svn-commits mailing list