[svn-commits] nadi: branch group/trunk-cm-csel-hash r47429 - /team/group/trunk-cm-csel-hash...

svn-commits at lists.digium.com svn-commits at lists.digium.com
Fri Nov 10 08:53:35 MST 2006


Author: nadi
Date: Fri Nov 10 09:53:34 2006
New Revision: 47429

URL: http://svn.digium.com/view/asterisk?view=rev&rev=47429
Log:
state machine handler function returns a touple of state and event

Modified:
    team/group/trunk-cm-csel-hash/channels/chan_misdn.c

Modified: team/group/trunk-cm-csel-hash/channels/chan_misdn.c
URL: http://svn.digium.com/view/asterisk/team/group/trunk-cm-csel-hash/channels/chan_misdn.c?view=diff&rev=47429&r1=47428&r2=47429
==============================================================================
--- team/group/trunk-cm-csel-hash/channels/chan_misdn.c (original)
+++ team/group/trunk-cm-csel-hash/channels/chan_misdn.c Fri Nov 10 09:53:34 2006
@@ -238,12 +238,17 @@
 	char *ok;
 };
 
+struct state_machine_handle_retval {
+	int      state;
+	int      event;
+};
+
 struct state_machine_transition {
 	int      state;
 	int      event;
 	int      state_next;
 	int      event_out;
-	int      (*handle)(void *p, int state, int event);
+	struct state_machine_handle_retval (*handle)(void *p, int state, int event);
 };
 
 struct state_machine {
@@ -685,9 +690,10 @@
 }
 
 /* State Machine: Generic */
-#define STATE_CONTINUE  -1 /*!< use this in state_next if there exists a following transition */
-#define STATE_KEEP      -2 /*!< use this in state_next if you want to keep the current state */
-#define STATE_ANY       -3 /*!< wildcard for the state field in struct state_machine_transision */
+#define STATE_DEFAULT   -1 /*!< return value of handle(): the next state is the default one specified in the transition table */
+#define STATE_CONTINUE  -2 /*!< use this in state_next if there exists a following transition */
+#define STATE_KEEP      -3 /*!< use this in state_next if you want to keep the current state */
+#define STATE_ANY       -4 /*!< wildcard for the state field in struct state_machine_transision */
 
 #define EVENT_DEFAULT   -1 /*!< return value of handle(): statemachine will send the event as read from the transition table */
 #define EVENT_BREAK     -2 /*!< return value of handle(): no event will be sent out, state_machine_run returns success */
@@ -696,6 +702,14 @@
 
 #define LOG_RECEIVE      0 /*!< passed to log callback when receiving events */
 #define LOG_TRANSMIT     1 /*!< passed to log callback when transmitting events */
+
+#define RE_STATE_EVENT(state,event) ({ struct state_machine_handle_retval rv = { (state), (event) }; rv; })
+#define RE_DEFAULT                  RE_STATE_EVENT(STATE_DEFAULT, EVENT_DEFAULT)
+#define RE_EVENT(event)             RE_STATE_EVENT(STATE_DEFAULT, (event))
+#define RE_STATE_DEFEVENT(state)    RE_STATE_EVENT((state), EVENT_DEFAULT)
+#define RE_STATE_NOEVENT(state)     RE_STATE_EVENT((state), EVENT_NONE)
+#define RE_BREAK                    RE_STATE_EVENT(STATE_DEFAULT, EVENT_BREAK)
+#define RE_NONE                     RE_STATE_EVENT(STATE_DEFAULT, EVENT_NONE)
 
 static struct state_machine * state_machine_create (void *p,
 													int state,
@@ -731,11 +745,13 @@
 static int state_machine_run (struct state_machine *sm, int event)
 {
 	struct state_machine_transition *t;
+	struct state_machine_handle_retval handle_retval;
 	int i = 0,
 		event_out = EVENT_DEFAULT,
 		err,
 		retval = -1,
-		state = sm->state;
+		state = sm->state,
+		leave = 0;
 
 	if (sm->log_event)
 		sm->log_event(sm->p, LOG_RECEIVE, sm->state, event);
@@ -744,9 +760,16 @@
 		t = &sm->table[i];
 		if ((t->state == state || t->state == STATE_ANY) &&
 			(t->event == event || t->event == EVENT_ANY)) {
-			if (t->handle)
-				event_out = t->handle(sm->p, sm->state, event);
-			if (event_out == EVENT_DEFAULT)
+			if (t->handle) {
+				handle_retval = t->handle(sm->p, sm->state, event);
+				event_out = handle_retval.event == EVENT_DEFAULT ? t->event_out : handle_retval.event;
+				if (handle_retval.state != STATE_DEFAULT) {
+					if (handle_retval.state != STATE_KEEP)
+						sm->state = handle_retval.state;
+					retval = 0;
+					leave = 1;
+				}
+			} else
 				event_out = t->event_out;
 			switch (event_out) {
 			case EVENT_BREAK:
@@ -763,6 +786,8 @@
 					goto out;
 				}
 			}
+			if (leave)
+				goto out;
 			event_out = EVENT_DEFAULT;
 			if (t->state_next == STATE_CONTINUE)
 				continue;
@@ -774,7 +799,6 @@
 	}
 
 out:
-	chan_misdn_log(2, 0, "state_machine_run: Returning with value %d ...\n", retval);
 	return retval;
 }
 
@@ -789,24 +813,24 @@
 }
 
 /* State Machine: mISDN */
-static int handle_aevent_hangup (void *p, int state, int event);
-static int handle_mevent_setup (void *p, int state, int event);
-static int handle_mevent_setup_followup (void *p, int state, int event);
-static int handle_mevent_information (void *p, int state, int event);
-static int handle_mevent_information_dtmf (void *p, int state, int event);
-static int handle_mevent_setup_acknowledge (void *p, int state, int event);
-static int handle_mevent_connect (void *p, int state, int event);
-static int handle_mevent_disconnect (void *p, int state, int event);
-static int handle_mevent_proceeding_progress (void *p, int state, int event);
-static int handle_mevent_port_alarm (void *p, int state, int event);
-static int handle_mevent_new_channel (void *p, int state, int event);
-static int handle_mevent_new_l3id (void *p, int state, int event);
-static int handle_mevent_dtmf_tone (void *p, int state, int event);
-static int handle_mevent_alerting (void *p, int state, int event);
-static int handle_mevent_connect_acknowledge (void *p, int state, int event);
-static int handle_mevent_release (void *p, int state, int event);
-static int handle_mevent_release_complete (void *p, int state, int event);
-static int handle_mevent_cleanup (void *p, int state, int event);
+static struct state_machine_handle_retval handle_aevent_hangup (void *p, int state, int event);
+static struct state_machine_handle_retval handle_mevent_setup (void *p, int state, int event);
+static struct state_machine_handle_retval handle_mevent_setup_followup (void *p, int state, int event);
+static struct state_machine_handle_retval handle_mevent_information (void *p, int state, int event);
+static struct state_machine_handle_retval handle_mevent_information_dtmf (void *p, int state, int event);
+static struct state_machine_handle_retval handle_mevent_setup_acknowledge (void *p, int state, int event);
+static struct state_machine_handle_retval handle_mevent_connect (void *p, int state, int event);
+static struct state_machine_handle_retval handle_mevent_disconnect (void *p, int state, int event);
+static struct state_machine_handle_retval handle_mevent_proceeding_progress (void *p, int state, int event);
+static struct state_machine_handle_retval handle_mevent_port_alarm (void *p, int state, int event);
+static struct state_machine_handle_retval handle_mevent_new_channel (void *p, int state, int event);
+static struct state_machine_handle_retval handle_mevent_new_l3id (void *p, int state, int event);
+static struct state_machine_handle_retval handle_mevent_dtmf_tone (void *p, int state, int event);
+static struct state_machine_handle_retval handle_mevent_alerting (void *p, int state, int event);
+static struct state_machine_handle_retval handle_mevent_connect_acknowledge (void *p, int state, int event);
+static struct state_machine_handle_retval handle_mevent_release (void *p, int state, int event);
+static struct state_machine_handle_retval handle_mevent_release_complete (void *p, int state, int event);
+static struct state_machine_handle_retval handle_mevent_cleanup (void *p, int state, int event);
 
 static struct state_machine_transition misdn_state_table[] = {
 	/*
@@ -3215,7 +3239,7 @@
 	return 0;
 }
 
-static int handle_aevent_hangup (void *p, int state, int event)
+static struct state_machine_handle_retval handle_aevent_hangup (void *p, int state, int event)
 {
 	struct chan_list *ch = p;
 	struct misdn_bchannel *bc = ch->bc;
@@ -3261,7 +3285,7 @@
 			re = EVENT_RELEASE;
 	}
 
-	return re;
+	return RE_EVENT(re);
 }
 
 static int misdn_answer (struct ast_channel *ast)
@@ -3629,7 +3653,7 @@
 }
 
 /* misdn event handler functions, called by state machine on event */
-static int handle_mevent_setup (void *p, int state, int event)
+static struct state_machine_handle_retval handle_mevent_setup (void *p, int state, int event)
 {
 	struct chan_list *ch = p;
 	struct misdn_bchannel *bc = ch->bc;
@@ -3643,16 +3667,15 @@
 			if (allowed_bearers[i].cap == bc->capability && !strstr(ch->allowed_bearers, allowed_bearers[i].name)) {
 				chan_misdn_log(0, bc->port, "Bearer Not allowed!\b");
 				bc->out_cause = 88;
-				state_machine_set_state(ch->sm, MISDN_EXTCANTMATCH);
-				return EVENT_RELEASE_COMPLETE;
+				return RE_STATE_EVENT(MISDN_EXTCANTMATCH, EVENT_RELEASE_COMPLETE);
 			}
 		}
 	}
 	
-	return EVENT_DEFAULT;
-}
-
-static int handle_mevent_setup_followup (void *p, int state, int event)
+	return RE_DEFAULT;
+}
+
+static struct state_machine_handle_retval handle_mevent_setup_followup (void *p, int state, int event)
 {
 	struct chan_list *ch = p;
 	struct misdn_bchannel *bc = ch->bc;
@@ -3662,15 +3685,15 @@
 	/* Check for Pickup Request first */
 	if (!strcmp(ch->ast->exten, ast_pickup_ext())) {
 		misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE);
-		if (ast_pickup_call(ch->ast))
+		if (ast_pickup_call(ch->ast)) {
 			hangup_chan(ch);
-		else {
-			state_machine_set_state(ch->sm, MISDN_CALLING_ACKNOWLEDGE);
+			return RE_BREAK;
+		} else {
 			ast_setstate(ch->ast, AST_STATE_DOWN);
 			hangup_chan(ch);
 			ch->ast = NULL;
-		}
-		return EVENT_BREAK;
+			return RE_STATE_NOEVENT(MISDN_CALLING_ACKNOWLEDGE);
+		}
 	}
 
 	/* check if we should jump into s when we have no dad */
@@ -3690,10 +3713,8 @@
 		chan_misdn_log(-1, bc->port, "Extension can never match, so disconnecting\n");
 		if (bc->nt)
 			hanguptone_indicate(ch);
-		state_machine_set_state(ch->sm, MISDN_EXTCANTMATCH);
 		bc->out_cause = 1;
-		misdn_lib_send_event(bc, bc->nt ? EVENT_RELEASE_COMPLETE : EVENT_RELEASE);
-		return EVENT_BREAK;
+		return RE_STATE_EVENT(MISDN_EXTCANTMATCH, bc->nt ? EVENT_RELEASE_COMPLETE : EVENT_RELEASE);
 	}
 
 	if (state == MISDN_WAITING4DIGS && ch->overlap_dial) {
@@ -3702,11 +3723,11 @@
 		ast_mutex_unlock(&ch->overlap_tv_lock);
 		if (ch->overlap_dial_task == -1)
 			ch->overlap_dial_task = misdn_tasks_add_variable(ch->overlap_dial, misdn_overlap_dial_task, ch);
-		return EVENT_BREAK;
+		return RE_BREAK;
 	}
 
 	if (!ch->overlap_dial && ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
-		START_PBX:
+START_PBX:
 		state_machine_set_state(ch->sm, MISDN_DIALING);
 		misdn_lib_send_event(bc, (bc->nt || (bc->need_more_infos && misdn_lib_is_ptp(bc->port))) ?
 							 EVENT_SETUP_ACKNOWLEDGE : EVENT_PROCEEDING);
@@ -3717,12 +3738,12 @@
 				hanguptone_indicate(ch);
 			misdn_lib_send_event(bc, bc->nt ? EVENT_RELEASE_COMPLETE : EVENT_RELEASE);
 		}
+		return RE_BREAK;
 	} else {
 		if (bc->sending_complete) {
-			state_machine_set_state(ch->sm, MISDN_EXTCANTMATCH);
 			bc->out_cause = 1;
 			chan_misdn_log(0, bc->port, " --> sending_complete so we never match ..\n");
-			misdn_lib_send_event(bc, bc->nt ? EVENT_RELEASE_COMPLETE : EVENT_RELEASE);
+			return RE_STATE_EVENT(MISDN_EXTCANTMATCH, bc->nt ? EVENT_RELEASE_COMPLETE : EVENT_RELEASE);
 		} else {
 			if (misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE) == -ENOCHAN) {
 				ast_log(LOG_WARNING, "Channel was catched before we could acknowledge!\n");
@@ -3733,7 +3754,6 @@
 				stop_indicate(ch);
 			else
 				dialtone_indicate(ch);
-			state_machine_set_state(ch->sm, MISDN_WAITING4DIGS);
 			if (ch->overlap_dial && !dad_len) {
 				ast_mutex_lock(&ch->overlap_tv_lock);
 				ch->overlap_tv = ast_tvnow();
@@ -3741,13 +3761,12 @@
 				if (ch->overlap_dial_task == -1)
 					ch->overlap_dial_task = misdn_tasks_add_variable(ch->overlap_dial, misdn_overlap_dial_task, ch);
 			}
-		}
-	}
-
-	return EVENT_BREAK;
-}
-
-static int handle_mevent_information (void *p, int state, int event)
+			return RE_STATE_EVENT(MISDN_WAITING4DIGS, EVENT_BREAK);
+		}
+	}
+}
+
+static struct state_machine_handle_retval handle_mevent_information (void *p, int state, int event)
 {
 	struct chan_list *ch = p;
 	struct misdn_bchannel *bc = ch->bc;
@@ -3763,10 +3782,10 @@
 	strncpy(ch->ast->exten, bc->dad, sizeof(ch->ast->exten));
 	ch->ast->exten[sizeof(ch->ast->exten) - 1] = 0;
 
-	return EVENT_DEFAULT;
-}
-
-static int handle_mevent_information_dtmf (void *p, int state, int event)
+	return RE_DEFAULT;
+}
+
+static struct state_machine_handle_retval handle_mevent_information_dtmf (void *p, int state, int event)
 {
 	struct chan_list *ch = p;
 	struct misdn_bchannel *bc = ch->bc;
@@ -3784,10 +3803,10 @@
 	fr.delivery = ast_tv(0, 0);
 	ast_queue_frame(ch->ast, &fr);
 
-	return EVENT_DEFAULT;
-}
-
-static int handle_mevent_setup_acknowledge (void *p, int state, int event)
+	return RE_DEFAULT;
+}
+
+static struct state_machine_handle_retval handle_mevent_setup_acknowledge (void *p, int state, int event)
 {
 	struct chan_list *ch = p;
 	struct misdn_bchannel *bc = ch->bc;
@@ -3803,13 +3822,13 @@
 		strncpy(bc->info_dad, bc->infos_pending, sizeof(bc->info_dad));
 		bc->info_dad[sizeof(bc->info_dad) - 1] = 0;
 		*bc->infos_pending = 0;
-		return EVENT_INFORMATION;
-	}
-
-	return EVENT_DEFAULT;
-}
-
-static int handle_mevent_connect (void *p, int state, int event)
+		return RE_EVENT(EVENT_INFORMATION);
+	}
+
+	return RE_DEFAULT;
+}
+
+static struct state_machine_handle_retval handle_mevent_connect (void *p, int state, int event)
 {
 	struct chan_list *ch = p;
 	struct ast_channel *bridged;
@@ -3832,10 +3851,10 @@
 	ch->addr = ch->bc->addr;
 	start_bc_tones(ch);
 	
-	return EVENT_DEFAULT;
-}
-
-static int handle_mevent_disconnect (void *p, int state, int event)
+	return RE_DEFAULT;
+}
+
+static struct state_machine_handle_retval handle_mevent_disconnect (void *p, int state, int event)
 {
 	struct chan_list *ch = p,
 					 *holded_ch;
@@ -3851,7 +3870,7 @@
 		 * immediately releasing the call */
 		chan_misdn_log(2, bc->port, " --> Inband Info Avail, not sending RELEASE\n");
 		start_bc_tones(ch);
-		return EVENT_DEFAULT;
+		return RE_DEFAULT;
 	}
 	/* Check for holded channel, to implement transfer */
 	holded_ch = find_holded(cl_te, bc);
@@ -3863,20 +3882,20 @@
 	hangup_chan(ch);
 	bc->out_cause = -1;
 
-	return EVENT_DEFAULT;
-}
-
-static int handle_mevent_proceeding_progress (void *p, int state, int event)
+	return RE_DEFAULT;
+}
+
+static struct state_machine_handle_retval handle_mevent_proceeding_progress (void *p, int state, int event)
 {
 	struct chan_list *ch = p;
 
 	if (misdn_cap_is_speech(ch->bc->capability) && misdn_inband_avail(ch->bc))
 		start_bc_tones(ch);
 
-	return EVENT_DEFAULT;
-}
-
-static int handle_mevent_port_alarm (void *p, int state, int event)
+	return RE_DEFAULT;
+}
+
+static struct state_machine_handle_retval handle_mevent_port_alarm (void *p, int state, int event)
 {
 	struct chan_list *ch = p;
 	int boa;
@@ -3888,27 +3907,27 @@
 		misdn_lib_port_block(ch->bc->port); 
 	}
 
-	return EVENT_DEFAULT;
-}
-
-static int handle_mevent_new_channel (void *p, int state, int event)
+	return RE_DEFAULT;
+}
+
+static struct state_machine_handle_retval handle_mevent_new_channel (void *p, int state, int event)
 {
 	struct chan_list *ch = p;
 	update_name(ch->ast, ch->bc->port, ch->bc->channel);
-	return EVENT_DEFAULT;
-}
-
-static int handle_mevent_new_l3id (void *p, int state, int event)
+	return RE_DEFAULT;
+}
+
+static struct state_machine_handle_retval handle_mevent_new_l3id (void *p, int state, int event)
 {
 	struct chan_list *ch = p;
 
 	ch->l3id = ch->bc->l3_id;
 	ch->addr = ch->bc->addr;
 
-	return EVENT_DEFAULT;
-}
-
-static int handle_mevent_dtmf_tone (void *p, int state, int event)
+	return RE_DEFAULT;
+}
+
+static struct state_machine_handle_retval handle_mevent_dtmf_tone (void *p, int state, int event)
 {
 	struct chan_list *ch = p;
 	struct ast_frame fr;
@@ -3923,10 +3942,10 @@
 	} else
 		chan_misdn_log(2, ch->bc->port, " --> Ingoring DTMF:%c due to bridge flags\n", ch->bc->dtmf);
 
-	return EVENT_DEFAULT;
-}
-
-static int handle_mevent_alerting (void *p, int state, int event)
+	return RE_DEFAULT;
+}
+
+static struct state_machine_handle_retval handle_mevent_alerting (void *p, int state, int event)
 {
 	struct chan_list *ch = p;
 	struct misdn_bchannel *bc = ch->bc;
@@ -3938,10 +3957,10 @@
 	} else
 		chan_misdn_log(2, bc->port, "We have no inband Data, the other end must create ringing.\n");
 
-	return EVENT_DEFAULT;
-}
-
-static int handle_mevent_connect_acknowledge (void *p, int state, int event)
+	return RE_DEFAULT;
+}
+
+static struct state_machine_handle_retval handle_mevent_connect_acknowledge (void *p, int state, int event)
 {
 	struct chan_list *ch = p;
 
@@ -3949,30 +3968,30 @@
 	ch->addr = ch->bc->addr;
 	start_bc_tones(ch);
 
-	return EVENT_DEFAULT;
-}
-
-static int handle_mevent_release (void *p, int state, int event)
+	return RE_DEFAULT;
+}
+
+static struct state_machine_handle_retval handle_mevent_release (void *p, int state, int event)
 {
 	struct chan_list *ch = p;
 
 	ch->bc->out_cause = 16;
 	hangup_chan(ch);
 
-	return ch->bc->need_release_complete ? EVENT_DEFAULT : EVENT_NONE;
-}
-
-static int handle_mevent_release_complete (void *p, int state, int event)
+	return ch->bc->need_release_complete ? RE_DEFAULT : RE_NONE;
+}
+
+static struct state_machine_handle_retval handle_mevent_release_complete (void *p, int state, int event)
 {
 	struct chan_list *ch = p;
 	
 	stop_bc_tones(ch);
 	hangup_chan(ch);
 	
-	return EVENT_DEFAULT;
-}
-
-static int handle_mevent_cleanup (void *p, int state, int event)
+	return RE_DEFAULT;
+}
+
+static struct state_machine_handle_retval handle_mevent_cleanup (void *p, int state, int event)
 {
 	struct chan_list *ch = p;
 
@@ -3981,16 +4000,13 @@
 		ch->bc->cause = 27; /* Destination out of order */
 	hangup_chan(ch);
 
-	return EVENT_DEFAULT;
+	return RE_DEFAULT;
 }
 
 /* The big event handler for all events from mISDN (isdn_lib) */
 static enum event_response_e cb_events (enum event_e event, struct misdn_bchannel *bc, void *user_data)
 {
 	struct chan_list *ch = find_chan_by_bc(cl_te, bc);
-
-	if (event == EVENT_SETUP_ACKNOWLEDGE)
-		chan_misdn_log(0,0,"SETUP_ACKNOLEDGE!!\n");
 
 	if (event != EVENT_BCHAN_DATA && event != EVENT_TONE_GENERATE) { /*  Debug Only Non-Bchan */
 		chan_misdn_log((event == EVENT_CLEANUP && !user_data) ? 5 : 2, bc->port, "I IND :%s oad:%s dad:%s pid:%d state:%s\n",



More information about the svn-commits mailing list