[asterisk-commits] nadi: branch group/trunk-cm-csel-hash r47722 - in /team/group/trunk-cm-csel-h...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Thu Nov 16 04:43:20 MST 2006


Author: nadi
Date: Thu Nov 16 05:43:19 2006
New Revision: 47722

URL: http://svn.digium.com/view/asterisk?view=rev&rev=47722
Log:
extended the transition table

Modified:
    team/group/trunk-cm-csel-hash/channels/chan_misdn.c
    team/group/trunk-cm-csel-hash/channels/misdn/isdn_lib.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=47722&r1=47721&r2=47722
==============================================================================
--- team/group/trunk-cm-csel-hash/channels/chan_misdn.c (original)
+++ team/group/trunk-cm-csel-hash/channels/chan_misdn.c Thu Nov 16 05:43:19 2006
@@ -210,6 +210,8 @@
 	int other_pid;
 	struct chan_list *other_ch;
 	const struct tone_zone_sound *ts;
+
+	int destroy_me;
 
 	struct chan_list *next;
 };
@@ -688,6 +690,11 @@
 static struct statemachine_handle_retval handle_mevent_release_complete (void *p, int state, int event);
 static struct statemachine_handle_retval handle_mevent_cleanup (void *p, int state, int event);
 static struct statemachine_handle_retval handle_mevent_facility (void *p, int state, int event);
+static struct statemachine_handle_retval handle_mevent_retrieve (void *p, int state, int event);
+static struct statemachine_handle_retval handle_mevent_restart (void *p, int state, int event);
+static struct statemachine_handle_retval handle_mevent_hold (void *p, int state, int event);
+static struct statemachine_handle_retval handle_mevent_timeout_1 (void *p, int state, int event);
+static struct statemachine_handle_retval handle_mevent_timeout_2 (void *p, int state, int event);
 
 static struct statemachine_transition misdn_state_table[] = {
 	/*
@@ -726,6 +733,28 @@
 	{ STATE_ANY,                  EVENT_CONNECT,              STATE_CONTINUE,              EVENT_CONNECT_ACKNOWLEDGE,   handle_mevent_connect },
 	{ STATE_ANY,                  EVENT_CONNECT,              MISDN_CONNECTED,             AEVENT_CANSWER,              NULL },
 	{ STATE_ANY,                  EVENT_DISCONNECT,           MISDN_DISCONNECTED,          EVENT_NONE,                  handle_mevent_disconnect },
+	{ STATE_ANY,                  EVENT_RETRIEVE,             MISDN_CONNECTED,             EVENT_RETRIEVE_ACKNOWLEDGE,  handle_mevent_retrieve },
+	{ STATE_ANY,                  EVENT_HOLD,                 MISDN_HOLDED,                EVENT_HOLD_ACKNOWLEDGE,      handle_mevent_hold },
+
+	{ MISDN_DIALING,              EVENT_TIMEOUT,              STATE_KEEP,                  EVENT_DISCONNECT,            handle_mevent_timeout_1 },
+	{ MISDN_PROGRESS,             EVENT_TIMEOUT,              STATE_KEEP,                  EVENT_DISCONNECT,            handle_mevent_timeout_1 },
+	{ MISDN_CALLING,              EVENT_TIMEOUT,              STATE_KEEP,                  EVENT_DISCONNECT,            handle_mevent_timeout_1 },
+	{ MISDN_ALERTING,             EVENT_TIMEOUT,              STATE_KEEP,                  EVENT_DISCONNECT,            handle_mevent_timeout_1 },
+	{ MISDN_PROCEEDING,           EVENT_TIMEOUT,              STATE_KEEP,                  EVENT_DISCONNECT,            handle_mevent_timeout_1 },
+	{ MISDN_CALLING_ACKNOWLEDGE,  EVENT_TIMEOUT,              STATE_KEEP,                  EVENT_DISCONNECT,            handle_mevent_timeout_1 },
+	{ MISDN_WAITING4DIGS,         EVENT_TIMEOUT,              STATE_KEEP,                  EVENT_DISCONNECT,            handle_mevent_timeout_2 },
+	{ MISDN_CLEANING,             EVENT_TIMEOUT,              STATE_KEEP,                  EVENT_NONE,                  NULL },
+	{ STATE_ANY,                  EVENT_TIMEOUT,              STATE_KEEP,                  EVENT_RELEASE_COMPLETE,      NULL },
+
+	{ MISDN_DIALING,              EVENT_BCHAN_ERROR,          STATE_KEEP,                  EVENT_DISCONNECT,            handle_mevent_timeout_1 },
+	{ MISDN_PROGRESS,             EVENT_BCHAN_ERROR,          STATE_KEEP,                  EVENT_DISCONNECT,            handle_mevent_timeout_1 },
+	{ MISDN_CALLING,              EVENT_BCHAN_ERROR,          STATE_KEEP,                  EVENT_DISCONNECT,            handle_mevent_timeout_1 },
+	{ MISDN_ALERTING,             EVENT_BCHAN_ERROR,          STATE_KEEP,                  EVENT_DISCONNECT,            handle_mevent_timeout_1 },
+	{ MISDN_PROCEEDING,           EVENT_BCHAN_ERROR,          STATE_KEEP,                  EVENT_DISCONNECT,            handle_mevent_timeout_1 },
+	{ MISDN_CALLING_ACKNOWLEDGE,  EVENT_BCHAN_ERROR,          STATE_KEEP,                  EVENT_DISCONNECT,            handle_mevent_timeout_1 },
+	{ MISDN_WAITING4DIGS,         EVENT_BCHAN_ERROR,          STATE_KEEP,                  EVENT_DISCONNECT,            handle_mevent_timeout_2 },
+	{ MISDN_CLEANING,             EVENT_BCHAN_ERROR,          STATE_KEEP,                  EVENT_NONE,                  NULL },
+	{ STATE_ANY,                  EVENT_BCHAN_ERROR,          STATE_KEEP,                  EVENT_RELEASE_COMPLETE,      NULL },
 
 	/* state keeping events */
 	{ STATE_ANY,                  EVENT_PORT_ALARM,           STATE_KEEP,                  EVENT_NONE,                  handle_mevent_port_alarm },
@@ -735,6 +764,7 @@
 	{ STATE_ANY,                  EVENT_RELEASE,              STATE_KEEP,                  EVENT_RELEASE_COMPLETE,      handle_mevent_release },
 	{ STATE_ANY,                  EVENT_CLEANUP,              STATE_KEEP,                  EVENT_NONE,                  handle_mevent_cleanup },
 	{ STATE_ANY,                  EVENT_FACILITY,             STATE_KEEP,                  EVENT_NONE,                  handle_mevent_facility },
+	{ STATE_ANY,                  EVENT_RESTART,              STATE_KEEP,                  EVENT_NONE,                  handle_mevent_restart },
 
 	/* noop events */
 	{ STATE_ANY,                  EVENT_BCHAN_ACTIVATED,      STATE_KEEP,                  EVENT_NONE,                  NULL},
@@ -857,8 +887,11 @@
 	int first = 0;
 	char tmpbuf[256];
 
+	if (!num)
+		return;
+
 #define IF_INFO(i,fmt,parm) \
-	if (*elems & (i) && num) { \
+	if (*elems & (i)) { \
 		*elems &= ~(i); \
 		snprintf(tmpbuf, sizeof(tmpbuf), "%s" fmt, !(first--) ? "" : " ", parm); \
 		strncat(buf, tmpbuf, bufsize); \
@@ -916,10 +949,17 @@
 static int send_event (void *p, int event)
 {
 	struct chan_list *ch = p;
+	struct misdn_bchannel *bc = ch->bc;
 	int re = 0;
 
 	if (event > EVENT_NOTHING && event < EVENT_UNKNOWN) {
-		misdn_lib_send_event(ch->bc, event);
+		misdn_lib_send_event(bc, event);
+		if (event == EVENT_HOLD_ACKNOWLEDGE) {
+			/*forget the channel now*/
+			ch->bc = NULL;
+			ch->hold_info.port = bc->port;
+			ch->hold_info.channel = bc->channel;
+		}
 	} else {
 		switch (event) {
 		case AEVENT_CPROCEEDING:
@@ -1788,13 +1828,13 @@
 }
 
 /* Isdn asks us to release channel, pendant to misdn_hangup */
-static void release_chan (struct misdn_bchannel *bc)
+static void release_chan (struct chan_list *ch)
 {
 	struct ast_channel *ast;
-	struct chan_list *ch = find_chan_by_bc(cl_te, bc);
+	struct misdn_bchannel *bc = ch->bc;
 
 	if (!ch) {
-		chan_misdn_log(2, bc->port, "release_chan: Ch not found!\n");
+		chan_misdn_log(2, bc->port, "release_chan: No ch!\n");
 		return;
 	}
 	ast = ch->ast;
@@ -3835,6 +3875,7 @@
 
 	ch->bc->out_cause = 16;
 	hangup_chan(ch);
+	ch->destroy_me = 1;
 
 	return ch->bc->need_release_complete ? RE_DEFAULT : RE_NONE;
 }
@@ -3845,6 +3886,7 @@
 	
 	stop_bc_tones(ch);
 	hangup_chan(ch);
+	ch->destroy_me = 1;
 	
 	return RE_DEFAULT;
 }
@@ -3857,6 +3899,7 @@
 	if (state == MISDN_CALLING)
 		ch->bc->cause = 27; /* Destination out of order */
 	hangup_chan(ch);
+	ch->destroy_me = 1;
 
 	return RE_DEFAULT;
 }
@@ -3895,6 +3938,89 @@
 	return RE_DEFAULT;
 }
 
+static struct statemachine_handle_retval handle_mevent_retrieve (void *p, int state, int event)
+{
+	struct chan_list *ch = p;
+	struct ast_channel *hold_ast;
+
+	hold_ast = AST_BRIDGED_P(ch->ast);
+	if (hold_ast)
+		ast_moh_stop(hold_ast);
+
+	return RE_DEFAULT;
+}
+
+static struct statemachine_handle_retval handle_mevent_restart (void *p, int state, int event)
+{
+	struct chan_list *ch = p;
+
+	stop_bc_tones(ch);
+	ch->destroy_me = 1;
+
+	return RE_DEFAULT;
+}
+
+static struct statemachine_handle_retval handle_mevent_hold (void *p, int state, int event)
+{
+	struct chan_list *ch = p;
+	struct misdn_bchannel *bc = ch->bc;
+	struct ast_channel *bridged;
+	int hold_allowed = 0;
+
+	cm_get_int(misdn_cm, hold_allowed, PORT, MCFG_HOLDALLOWED, bc->port);
+	if (!hold_allowed) {
+		chan_misdn_log(-1, bc->port, "Hold not allowed for this port.\n");
+		return RE_STATE_EVENT(STATE_KEEP, EVENT_HOLD_REJECT);
+	}
+			
+	bridged = AST_BRIDGED_P(ch->ast);
+	if (bridged) {
+		chan_misdn_log(2, bc->port, "Bridge partner is of type: %s\n", bridged->tech->type);
+		ch->l3id = bc->l3_id;
+		
+		/* XXX This should queue an AST_CONTROL_HOLD frame on this channel
+		 * instead of starting moh on the bridged channel directly */
+		ast_moh_start(bridged, NULL, NULL);
+		return RE_DEFAULT;
+	} else {
+		chan_misdn_log(0, bc->port, "We aren't bridged to anybody\n");
+		return RE_STATE_EVENT(STATE_KEEP, EVENT_HOLD_REJECT);
+	}
+}
+
+static struct statemachine_handle_retval handle_mevent_timeout_1 (void *p, int state, int event)
+{
+	struct chan_list *ch = p;
+	struct misdn_bchannel *bc = ch->bc;
+
+	if ((state == MISDN_DIALING || state == MISDN_PROGRESS) && bc->nt && !ch->nttimeout)
+		return RE_NONE;
+
+	if (bc->nt) {
+		bc->progress_indicator = 8;
+		hanguptone_indicate(ch);
+	}
+	bc->out_cause = 1;
+
+	return RE_DEFAULT;
+}
+
+static struct statemachine_handle_retval handle_mevent_timeout_2 (void *p, int state, int event)
+{
+	struct chan_list *ch = p;
+	struct misdn_bchannel *bc = ch->bc;
+
+	if (bc->nt) {
+		bc->progress_indicator = 8;
+		bc->out_cause = 1;
+		hanguptone_indicate(ch);
+		return RE_DEFAULT;
+	} else {
+		bc->out_cause = 16;
+		return RE_EVENT(EVENT_RELEASE);
+	}
+}
+
 /* 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)
 {
@@ -3930,9 +4056,17 @@
 		}
 	} else {
 		switch (event) {
+		case EVENT_RETRIEVE:
+			ch = find_holded_l3(cl_te, bc->l3_id, 1);
+			if (!ch) {
+				ast_log(LOG_WARNING, "Found no holded channel, cannot retrieve\n");
+				misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT);
+				return RESPONSE_OK;
+			}
+			ch->bc = bc;
+			break;
 		case EVENT_SETUP:
 		case EVENT_PORT_ALARM:
-		case EVENT_RETRIEVE:
 		case EVENT_NEW_BC:
 		case EVENT_FACILITY:
 			break;
@@ -4087,118 +4221,15 @@
 	 * run the statemachine and return if the event could be handled
 	 */
 	if (ch && !statemachine_run(ch->sm, event)) {
-		if (event == EVENT_RELEASE || event == EVENT_RELEASE_COMPLETE || event == EVENT_CLEANUP)
-			release_chan(ch->bc);
+		if (ch->destroy_me)
+			release_chan(ch);
 		return RESPONSE_OK;
 	}
 
 	/*
 	 * this is for events not (yet) handled by our statemachine
 	 */
-	switch (event) {
-	case EVENT_BCHAN_ERROR:
-	case EVENT_TIMEOUT:
-		if (ch && bc)
-			chan_misdn_log(2, bc->port, "--> state: %s\n", get_state_string(statemachine_get_state(ch->sm)));
-		switch (statemachine_get_state(ch->sm)) {
-		case MISDN_DIALING:
-		case MISDN_PROGRESS:
-			if (bc->nt && !ch->nttimeout)
-				break;
-		case MISDN_CALLING:
-		case MISDN_ALERTING:
-		case MISDN_PROCEEDING:
-		case MISDN_CALLING_ACKNOWLEDGE:
-			if (bc->nt) {
-				bc->progress_indicator = 8;
-				hanguptone_indicate(ch);
-			}
-			bc->out_cause = 1;
-			misdn_lib_send_event(bc, EVENT_DISCONNECT);
-			break;
-		case MISDN_WAITING4DIGS:
-			if (bc->nt) {
-				bc->progress_indicator = 8;
-				bc->out_cause = 1;
-				hanguptone_indicate(ch);
-				misdn_lib_send_event(bc, EVENT_DISCONNECT);
-			} else {
-				bc->out_cause = 16;
-				misdn_lib_send_event(bc, EVENT_RELEASE);
-			}
-			break;
-		case MISDN_CLEANING: 
-			chan_misdn_log(2, bc->port, " --> in state cleaning .. so ingoring, the stack should clean it for us\n");
-			break;
-		default:
-			misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
-		}
-		break;
-
-		/***************************/
-		/** Supplementary Services **/
-		/***************************/
-	case EVENT_RETRIEVE:
-		{
-			struct ast_channel *hold_ast;
-
-			ch = find_holded_l3(cl_te, bc->l3_id, 1);
-			if (!ch) {
-				ast_log(LOG_WARNING, "Found no Holded channel, cannot Retrieve\n");
-				misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT);
-				break;
-			}
-			
-			/*remember the channel again*/
-			ch->bc = bc;
-			statemachine_set_state(ch->sm, MISDN_CONNECTED);
-			
-			hold_ast = AST_BRIDGED_P(ch->ast);
-			if (hold_ast)
-				ast_moh_stop(hold_ast);
-			if (misdn_lib_send_event(bc, EVENT_RETRIEVE_ACKNOWLEDGE) < 0)
-				misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT);
-		}
-		break;
-	case EVENT_HOLD:
-		{
-			int hold_allowed = 0;
-			struct ast_channel *bridged;
-
-			cm_get_int(misdn_cm, hold_allowed, PORT, MCFG_HOLDALLOWED, bc->port);
-			if (!hold_allowed) {
-				chan_misdn_log(-1, bc->port, "Hold not allowed this port.\n");
-				misdn_lib_send_event(bc, EVENT_HOLD_REJECT);
-				break;
-			}
-			bridged = AST_BRIDGED_P(ch->ast);
-			if (bridged){
-				chan_misdn_log(2, bc->port, "Bridge Partner is of type: %s\n", bridged->tech->type);
-				statemachine_set_state(ch->sm, MISDN_HOLDED);
-				ch->l3id = bc->l3_id;
-				misdn_lib_send_event(bc, EVENT_HOLD_ACKNOWLEDGE);
-				/* XXX This should queue an AST_CONTROL_HOLD frame on this channel
-				 * instead of starting moh on the bridged channel directly */
-				ast_moh_start(bridged, NULL, NULL);
-
-				/*forget the channel now*/
-				ch->bc = NULL;
-				ch->hold_info.port = bc->port;
-				ch->hold_info.channel = bc->channel;
-			} else {
-				misdn_lib_send_event(bc, EVENT_HOLD_REJECT);
-				chan_misdn_log(0, bc->port, "We aren't bridged to anybody\n");
-			}
-		} 
-		break;
-	case EVENT_RESTART:
-		stop_bc_tones(ch);
-		release_chan(bc);
-		break;
-	default:
-		ast_log(LOG_NOTICE, "Got Unknown Event\n");
-		break;
-	}
+	ast_log(LOG_NOTICE, "Got Unknown Event\n");
 
 	return RESPONSE_OK;
 }

Modified: team/group/trunk-cm-csel-hash/channels/misdn/isdn_lib.c
URL: http://svn.digium.com/view/asterisk/team/group/trunk-cm-csel-hash/channels/misdn/isdn_lib.c?view=diff&rev=47722&r1=47721&r2=47722
==============================================================================
--- team/group/trunk-cm-csel-hash/channels/misdn/isdn_lib.c (original)
+++ team/group/trunk-cm-csel-hash/channels/misdn/isdn_lib.c Thu Nov 16 05:43:19 2006
@@ -3213,9 +3213,8 @@
 			if (bc->channel <=0 ) { /*  else we have the channel already */
 				if (!find_free_chan_in_stack(stack, bc, 0)) {
 					cb_log(0, stack->port, " No free channel at the moment\n");
-					
-					err=-ENOCHAN;
-					goto ERR;
+					event = EVENT_RETRIEVE_REJECT;
+					break;
 				}
 			}
 			/* Its that i generate channels */



More information about the asterisk-commits mailing list