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

svn-commits at lists.digium.com svn-commits at lists.digium.com
Thu Nov 9 08:41:57 MST 2006


Author: nadi
Date: Thu Nov  9 09:41:56 2006
New Revision: 47365

URL: http://svn.digium.com/view/asterisk?view=rev&rev=47365
Log:
connect and disconnect through state machine

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=47365&r1=47364&r2=47365
==============================================================================
--- team/group/trunk-cm-csel-hash/channels/chan_misdn.c (original)
+++ team/group/trunk-cm-csel-hash/channels/chan_misdn.c Thu Nov  9 09:41:56 2006
@@ -706,14 +706,15 @@
 	int i = 0,
 		event_out = EVENT_DEFAULT,
 		err,
-		retval = -1;
+		retval = -1,
+		state = sm->state;
 
 	if (sm->log_event)
 		sm->log_event(sm->p, LOG_RECEIVE, sm->state, event);
 
 	for (; i < sm->num_rows; ++i) {
 		t = &sm->table[i];
-		if ((t->state == sm->state || t->state == STATE_ANY) &&
+		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);
@@ -761,12 +762,15 @@
 
 /* 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_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_setup_acknowledge (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);
@@ -777,42 +781,47 @@
 	/*
 	 * ASTERISK EVENTS
 	 */
-	{ MISDN_NOTHING,              AEVENT_CALL,             MISDN_CALLING,               EVENT_SETUP,                 NULL },
-
-	{ MISDN_CALLING,              AEVENT_HANGUP,           MISDN_CLEANING,              EVENT_RELEASE_COMPLETE,      NULL },
-	{ MISDN_DISCONNECTED,         AEVENT_HANGUP,           MISDN_CLEANING,              EVENT_RELEASE,               NULL },
-	{ MISDN_RELEASED,             AEVENT_HANGUP,           MISDN_CLEANING,              EVENT_NONE,                  NULL },
-	{ MISDN_CLEANING,             AEVENT_HANGUP,           MISDN_CLEANING,              EVENT_NONE,                  NULL },
-	{ MISDN_BUSY,                 AEVENT_HANGUP,           MISDN_CLEANING,              EVENT_NONE,                  NULL },
-	{ MISDN_HOLD_DISCONNECT,      AEVENT_HANGUP,           MISDN_CLEANING,              EVENT_RELEASE,               handle_aevent_hangup },
-	{ MISDN_CLEANING,             AEVENT_HANGUP,           MISDN_CLEANING,              EVENT_NONE,                  handle_aevent_hangup },
-	{ STATE_ANY,                  AEVENT_HANGUP,           MISDN_CLEANING,              EVENT_DISCONNECT,            handle_aevent_hangup },
-
-	{ STATE_ANY,                  AEVENT_ANSWER,           MISDN_CONNECTED,             EVENT_CONNECT,               NULL },
-
-	{ STATE_ANY,                  AEVENT_CBUSY,            MISDN_CLEANING,              EVENT_DISCONNECT,            NULL },
+	{ MISDN_NOTHING,              AEVENT_CALL,                MISDN_CALLING,               EVENT_SETUP,                 NULL },
+
+	{ MISDN_CALLING,              AEVENT_HANGUP,              MISDN_CLEANING,              EVENT_RELEASE_COMPLETE,      NULL },
+	{ MISDN_DISCONNECTED,         AEVENT_HANGUP,              MISDN_CLEANING,              EVENT_RELEASE,               NULL },
+	{ MISDN_WAITING4DIGS,         AEVENT_HANGUP,              MISDN_CLEANING,              EVENT_RELEASE,               NULL },
+	{ MISDN_RELEASED,             AEVENT_HANGUP,              MISDN_CLEANING,              EVENT_NONE,                  NULL },
+	{ MISDN_CLEANING,             AEVENT_HANGUP,              MISDN_CLEANING,              EVENT_NONE,                  NULL },
+	{ MISDN_BUSY,                 AEVENT_HANGUP,              MISDN_CLEANING,              EVENT_NONE,                  NULL },
+	{ MISDN_HOLD_DISCONNECT,      AEVENT_HANGUP,              MISDN_CLEANING,              EVENT_RELEASE,               handle_aevent_hangup },
+	{ MISDN_CLEANING,             AEVENT_HANGUP,              MISDN_CLEANING,              EVENT_NONE,                  handle_aevent_hangup },
+	{ STATE_ANY,                  AEVENT_HANGUP,              MISDN_CLEANING,              EVENT_DISCONNECT,            handle_aevent_hangup },
+
+	{ STATE_ANY,                  AEVENT_ANSWER,              MISDN_CONNECTED,             EVENT_CONNECT,               NULL },
+
+	{ STATE_ANY,                  AEVENT_CBUSY,               MISDN_CLEANING,              EVENT_DISCONNECT,            NULL },
 
 	/*
 	 * MISDN EVENTS
 	 */
-	{ STATE_ANY,                  EVENT_PROCEEDING,        MISDN_PROCEEDING,            AEVENT_CPROCEEDING,          handle_mevent_proceeding_progress },
-	{ STATE_ANY,                  EVENT_PROGRESS,          MISDN_PROGRESS,              AEVENT_CPROGRESS,            handle_mevent_proceeding_progress },
-	{ STATE_ANY,                  EVENT_SETUP_ACKNOWLEDGE, MISDN_CALLING_ACKNOWLEDGE,   EVENT_NONE,                  handle_mevent_setup_acknowledge },
-	{ STATE_ANY,                  EVENT_ALERTING,          MISDN_ALERTING,              AEVENT_CRINGING,             handle_mevent_alerting },
-	{ STATE_ANY,                  EVENT_CONNECT_ACKNOWLEDGE, MISDN_CONNECTED,           AEVENT_CANSWER,              handle_mevent_connect_acknowledge },
-	{ STATE_ANY,                  EVENT_RELEASE_COMPLETE,  MISDN_CLEANING,              EVENT_NONE,                  handle_mevent_release_complete },
+	{ STATE_ANY,                  EVENT_SETUP,                MISDN_DIALING,               EVENT_SETUP_ACKNOWLEDGE,     handle_mevent_setup },
+	{ STATE_ANY,                  EVENT_SETUP_ACKNOWLEDGE,    MISDN_CALLING_ACKNOWLEDGE,   EVENT_NONE,                  handle_mevent_setup_acknowledge },
+	{ STATE_ANY,                  EVENT_PROCEEDING,           MISDN_PROCEEDING,            AEVENT_CPROCEEDING,          handle_mevent_proceeding_progress },
+	{ STATE_ANY,                  EVENT_PROGRESS,             MISDN_PROGRESS,              AEVENT_CPROGRESS,            handle_mevent_proceeding_progress },
+	{ STATE_ANY,                  EVENT_ALERTING,             MISDN_ALERTING,              AEVENT_CRINGING,             handle_mevent_alerting },
+	{ STATE_ANY,                  EVENT_CONNECT_ACKNOWLEDGE,  MISDN_CONNECTED,             AEVENT_CANSWER,              handle_mevent_connect_acknowledge },
+	{ STATE_ANY,                  EVENT_RELEASE_COMPLETE,     MISDN_CLEANING,              EVENT_NONE,                  handle_mevent_release_complete },
+	{ 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 keeping events */
-	{ STATE_ANY,                  EVENT_PORT_ALARM,        STATE_KEEP,                  EVENT_NONE,                  handle_mevent_port_alarm },
-	{ STATE_ANY,                  EVENT_NEW_CHANNEL,       STATE_KEEP,                  EVENT_NONE,                  handle_mevent_new_channel },
-	{ STATE_ANY,                  EVENT_NEW_L3ID,          STATE_KEEP,                  EVENT_NONE,                  handle_mevent_new_l3id },
-	{ STATE_ANY,                  EVENT_DTMF_TONE,         STATE_KEEP,                  EVENT_NONE,                  handle_mevent_dtmf_tone },
-	{ 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_PORT_ALARM,           STATE_KEEP,                  EVENT_NONE,                  handle_mevent_port_alarm },
+	{ STATE_ANY,                  EVENT_NEW_CHANNEL,          STATE_KEEP,                  EVENT_NONE,                  handle_mevent_new_channel },
+	{ STATE_ANY,                  EVENT_NEW_L3ID,             STATE_KEEP,                  EVENT_NONE,                  handle_mevent_new_l3id },
+	{ STATE_ANY,                  EVENT_DTMF_TONE,            STATE_KEEP,                  EVENT_NONE,                  handle_mevent_dtmf_tone },
+	{ STATE_ANY,                  EVENT_RELEASE,              STATE_KEEP,                  EVENT_RELEASE_COMPLETE,      handle_mevent_release },
+	{ STATE_ANY,                  EVENT_CLEANUP,              STATE_KEEP,                  EVENT_NONE,                  handle_mevent_cleanup },
 
 	/* noop events */
-	{ STATE_ANY,                  EVENT_BCHAN_ACTIVATED,   STATE_KEEP,                  EVENT_NONE,                  NULL},
-	{ STATE_ANY,                  EVENT_STATUS,            STATE_KEEP,                  EVENT_NONE,                  NULL},
+	{ STATE_ANY,                  EVENT_BCHAN_ACTIVATED,      STATE_KEEP,                  EVENT_NONE,                  NULL},
+	{ STATE_ANY,                  EVENT_STATUS,               STATE_KEEP,                  EVENT_NONE,                  NULL},
 };
 
 static const char * event2str (int event)
@@ -1687,7 +1696,7 @@
 		"!852+1633/100, !0/100",	/* C */
 		"!941+1633/100, !0/100",	/* D */
 		"!941+1209/100, !0/100",	/* * */
-		"!941+1477/100, !0/100"	/* # */
+		"!941+1477/100, !0/100"		/* # */
 	};
 
 	if (digit >= '0' && digit <= '9')
@@ -3532,6 +3541,212 @@
 }
 
 /* misdn event handler functions, called by state machine on event */
+static int handle_mevent_setup (void *p, int state, int event)
+{
+	struct chan_list *ch = p;
+	struct misdn_bchannel *bc = ch->bc;
+	int pres,
+		screen,
+		i,
+		im,
+		dad_len;
+
+	ch->ast->rings = 1;
+	ast_setstate(ch->ast, AST_STATE_RINGING);
+
+	pres = bc->pres == 1 ? AST_PRES_RESTRICTED : (bc->pres == 2 ? AST_PRES_UNAVAILABLE : AST_PRES_ALLOWED);
+	chan_misdn_log(2, bc->port, " --> PRES: Restricted (%d)\n", bc->pres);
+	switch (bc->screen) {
+	case 0:
+		screen = AST_PRES_USER_NUMBER_UNSCREENED;
+		chan_misdn_log(2, bc->port, " --> SCREEN: Unscreened (0)\n");
+		break;
+	case 1:
+		screen = AST_PRES_USER_NUMBER_PASSED_SCREEN;
+		chan_misdn_log(2, bc->port, " --> SCREEN: Passed screen (1)\n");
+		break;
+	case 2:
+		screen = AST_PRES_USER_NUMBER_FAILED_SCREEN;
+		chan_misdn_log(2, bc->port, " --> SCREEN: Failed screen (2)\n");
+		break;
+	case 3:
+		screen = AST_PRES_NETWORK_NUMBER;
+		chan_misdn_log(2, bc->port, " --> SCREEN: Network Number (3)\n");
+		break;
+	default:
+		screen = AST_PRES_USER_NUMBER_UNSCREENED;
+		chan_misdn_log(2, bc->port, " --> SCREEN: Unscreened (%d)\n", bc->screen);
+	}
+	ch->ast->cid.cid_pres = pres + screen;
+
+	pbx_builtin_setvar_helper(ch->ast, "TRANSFERCAPABILITY", ast_transfercapability2str(bc->capability));
+	ch->ast->transfercapability = bc->capability;
+	pbx_builtin_setvar_helper(ch->ast, "CALLTYPE", bc->capability == INFO_CAPABILITY_DIGITAL_UNRESTRICTED ? "DIGITAL" : "SPEECH");
+
+	cl_queue_chan(&cl_te, ch) ;
+	if (!strstr(ch->allowed_bearers, "all")) {
+		for (i = 0; i <  sizeof(allowed_bearers) / sizeof(struct allowed_bearer); ++i) {
+			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;
+			}
+		}
+	}
+
+	/* 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))
+			hangup_chan(ch);
+		else {
+			state_machine_set_state(ch->sm, MISDN_CALLING_ACKNOWLEDGE);
+			ast_setstate(ch->ast, AST_STATE_DOWN);
+			hangup_chan(ch);
+			ch->ast = NULL;
+		}
+		return EVENT_BREAK;
+	}
+
+	/* check if we should jump into s when we have no dad */
+	im = 0;
+	cm_get_int(misdn_cm, im, PORT, MCFG_IMMEDIATE, bc->port);
+	if (im && ast_strlen_zero(bc->dad)) {
+		do_immediate_setup(bc, ch , ch->ast);
+		return EVENT_BREAK;
+	}
+
+	chan_misdn_log(5, bc->port, "CONTEXT: %s\n", ch->context);
+	if (!ast_canmatch_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
+		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;
+	}
+
+	if (!ch->overlap_dial && ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
+		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);
+		if (pbx_start_chan(ch) < 0) {
+			hangup_chan(ch);
+			chan_misdn_log(-1, bc->port, "ast_pbx_start returned < 0 in SETUP\n");
+			if (bc->nt)
+				hanguptone_indicate(ch);
+			misdn_lib_send_event(bc, bc->nt ? EVENT_RELEASE_COMPLETE : EVENT_RELEASE);
+		}
+	} 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);
+		} else {
+			if (misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE) == -ENOCHAN) {
+				ast_log(LOG_WARNING, "Channel was catched before we could acknowledge!\n");
+				misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
+			}
+			dad_len = ast_strlen_zero(bc->dad);
+			if (!dad_len)
+				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();
+				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;
+}
+
+static int handle_mevent_setup_acknowledge (void *p, int state, int event)
+{
+	struct chan_list *ch = p;
+	struct misdn_bchannel *bc = ch->bc;
+	
+	if (bc->channel) 
+		update_name(ch->ast, bc->port, bc->channel);
+
+	if (!ast_strlen_zero(bc->infos_pending)) {
+		strncat(bc->dad, bc->infos_pending, sizeof(bc->dad) - strlen(bc->dad));
+		bc->dad[sizeof(bc->dad) - 1] = 0;
+		strncpy(ch->ast->exten, bc->dad, sizeof(ch->ast->exten));
+		ch->ast->exten[sizeof(ch->ast->exten) - 1] = 0;
+		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)
+{
+	struct chan_list *ch = p;
+	struct ast_channel *bridged;
+	struct chan_list *bridged_ch;
+
+	/* we answer when we've got our very new L3 ID from the NT stack */
+	bridged = AST_BRIDGED_P(ch->ast);
+	misdn_lib_echo(ch->bc, 0);
+	stop_indicate(ch);
+	if (bridged && !strcasecmp(bridged->tech->type, "mISDN")) {
+		bridged_ch = MISDN_ASTERISK_TECH_PVT(bridged);
+		chan_misdn_log(2, ch->bc->port, " --> copying cpndialplan:%d and cad:%s to the A-Channel\n",
+					   ch->bc->cpnnumplan, ch->bc->cad);
+		if (bridged_ch) {
+			bridged_ch->bc->cpnnumplan = ch->bc->cpnnumplan;
+			ast_copy_string(bridged_ch->bc->cad, ch->bc->cad, sizeof(ch->bc->cad));
+		}
+	}
+	ch->l3id = ch->bc->l3_id;
+	ch->addr = ch->bc->addr;
+	start_bc_tones(ch);
+	
+	return EVENT_DEFAULT;
+}
+
+static int handle_mevent_disconnect (void *p, int state, int event)
+{
+	struct chan_list *ch = p,
+					 *holded_ch;
+	struct misdn_bchannel *bc = ch->bc;
+
+	/* we might not have an ch->ast ptr here anymore */
+	chan_misdn_log(3, bc->port, " --> org:%d nt:%d, inbandavail:%d state:%d\n",
+				   ch->orginator, bc->nt, misdn_inband_avail(bc), state);
+	
+	if (ch->orginator == ORG_AST && !bc->nt && misdn_inband_avail(bc)) {
+		/* If there's inband information available (e.g. a recorded message saying what was wrong with the
+		 * dialled number, or perhaps even giving an alternative number, then play it instead of
+		 * immediately releasing the call */
+		chan_misdn_log(2, bc->port, " --> Inband Info Avail, not sending RELEASE\n");
+		start_bc_tones(ch);
+		return EVENT_DEFAULT;
+	}
+	/* Check for holded channel, to implement transfer */
+	holded_ch = find_holded(cl_te, bc);
+	if (holded_ch && holded_ch != ch && ch->ast && state_machine_get_state(holded_ch->sm) == MISDN_CONNECTED) {
+		chan_misdn_log(2, bc->port, " --> found holded ch\n");
+		misdn_transfer_bc(ch, holded_ch) ;
+	}
+	stop_bc_tones(ch);
+	hangup_chan(ch);
+	bc->out_cause = -1;
+
+	return EVENT_DEFAULT;
+}
+
 static int handle_mevent_proceeding_progress (void *p, int state, int event)
 {
 	struct chan_list *ch = p;
@@ -3592,28 +3807,6 @@
 	return EVENT_DEFAULT;
 }
 
-static int handle_mevent_setup_acknowledge (void *p, int state, int event)
-{
-	struct chan_list *ch = p;
-	struct misdn_bchannel *bc = ch->bc;
-	
-	if (bc->channel) 
-		update_name(ch->ast, bc->port, bc->channel);
-
-	if (!ast_strlen_zero(bc->infos_pending)) {
-		strncat(bc->dad, bc->infos_pending, sizeof(bc->dad) - strlen(bc->dad));
-		bc->dad[sizeof(bc->dad) - 1] = 0;
-		strncpy(ch->ast->exten, bc->dad, sizeof(ch->ast->exten));
-		ch->ast->exten[sizeof(ch->ast->exten) - 1] = 0;
-		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_alerting (void *p, int state, int event)
 {
 	struct chan_list *ch = p;
@@ -3676,6 +3869,9 @@
 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",
@@ -3708,11 +3904,13 @@
 	} else {
 		switch (event) {
 		case EVENT_SETUP:
-		case EVENT_DISCONNECT:
 		case EVENT_PORT_ALARM:
 		case EVENT_RETRIEVE:
 		case EVENT_NEW_BC:
 		case EVENT_FACILITY:
+			break;
+		case EVENT_DISCONNECT:
+			bc->out_cause = -1;
 			break;
 		case EVENT_RELEASE_COMPLETE:
 			chan_misdn_log(2, bc->port, " --> no Ch, so we've already released.\n");
@@ -3793,6 +3991,68 @@
 		return RESPONSE_OK;
 	}
 
+	if (event == EVENT_SETUP) {
+		char msns[BUFFERSIZE],
+			 tmp[16];
+		int msn_valid = 0,
+			exceed;
+		if (ch) {
+			if (state_machine_get_state(ch->sm) == MISDN_NOTHING)
+				ch = NULL;
+			else {
+				chan_misdn_log(2, bc->port, " --> Ignoring Call we already have one\n");
+				return RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE;
+			}
+		}
+		if (!cm_get(misdn_cm, msns, sizeof(msns), PORT, MCFG_MSNS, bc->port))
+			msn_valid = is_msn_valid(msns, bc->dad);
+		if (!bc->nt && !msn_valid) {
+			chan_misdn_log(2, bc->port, " --> Ignoring Call, its not in our MSN List\n");
+			return RESPONSE_IGNORE_SETUP; /*  Ignore MSNs which are not in our list. */
+		}
+
+		if (bc->cw) {
+			chan_misdn_log(0, bc->port, " --> Call Waiting on PMP sending RELEASE_COMPLETE\n");
+			if (cm_get_int(misdn_cm, bc->out_cause, PORT, MCFG_REJECT_CAUSE, bc->port))
+				bc->out_cause = 0;
+			if (!bc->out_cause)
+				bc->out_cause = 16;
+			return RESPONSE_RELEASE_SETUP;
+		}
+
+		print_bearer(bc);
+
+		ch = init_chan_list(ORG_MISDN);
+		if (!ch) {
+			chan_misdn_log(-1, bc->port, "cb_events: malloc for chan_list failed!\n");
+			return RESPONSE_IGNORE_SETUP;
+		}
+
+		ch->bc = bc;
+		ch->l3id = bc->l3_id;
+		ch->addr = bc->addr;
+		ch->orginator = ORG_MISDN;
+		ch->ast = misdn_new(ch, AST_STATE_RESERVED, bc->dad, bc->oad, AST_FORMAT_ALAW, bc->port, bc->channel);
+
+		if ((exceed = add_in_calls(bc->port))) {
+			snprintf(tmp, sizeof(tmp), "%d", exceed);
+			pbx_builtin_setvar_helper(ch->ast, "MAX_OVERFLOW", tmp);
+		}
+
+		config_ch(ch, ORG_MISDN);
+		export_chan(ch->ast, bc, ch);
+	}
+
+	if (event == EVENT_NEW_BC) {
+		if (!ch)
+			ch = find_holded(cl_te, bc);
+		if (!ch)
+			ast_log(LOG_WARNING, "NEW_BC without chan_list?\n");
+		else if (bc)
+			ch->bc = user_data;
+		return RESPONSE_OK;
+	}
+
 	/*
 	 * run the state machine and return if the event could be handled
 	 */
@@ -3806,14 +4066,6 @@
 	 * this is for events not (yet) handled by our state machine
 	 */
 	switch (event) {
-	case EVENT_NEW_BC:
-		if (!ch)
-			ch = find_holded(cl_te, bc);
-		if (!ch)
-			ast_log(LOG_WARNING, "NEW_BC without chan_list?\n");
-		else if (bc)
-			ch->bc = user_data;
-		break;
 	case EVENT_INFORMATION:
 		{
 			stop_indicate(ch);
@@ -3883,228 +4135,6 @@
 				fr.delivery = ast_tv(0, 0);
 				ast_queue_frame(ch->ast, &fr);
 			}
-		}
-		break;
-	case EVENT_SETUP:
-		{
-			struct ast_channel *chan;
-			char msns[BUFFERSIZE],
-				 tmp[16];
-			int msn_valid = 0,
-				exceed,
-				pres,
-				screen,
-				i,
-				im,
-				dad_len;
-			
-			if (ch) {
-				if (state_machine_get_state(ch->sm) == MISDN_NOTHING)
-					ch = NULL;
-				else {
-					chan_misdn_log(2, bc->port, " --> Ignoring Call we already have one\n");
-					return RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE;
-				}
-			}
-			if (!cm_get(misdn_cm, msns, sizeof(msns), PORT, MCFG_MSNS, bc->port))
-				msn_valid = is_msn_valid(msns, bc->dad);
-			if (!bc->nt && !msn_valid) {
-				chan_misdn_log(2, bc->port, " --> Ignoring Call, its not in our MSN List\n");
-				return RESPONSE_IGNORE_SETUP; /*  Ignore MSNs which are not in our list. */
-			}
-
-			if (bc->cw) {
-				chan_misdn_log(0, bc->port, " --> Call Waiting on PMP sending RELEASE_COMPLETE\n");
-				if (cm_get_int(misdn_cm, bc->out_cause, PORT, MCFG_REJECT_CAUSE, bc->port))
-					bc->out_cause = 0;
-				if (!bc->out_cause)
-					bc->out_cause = 16;
-				return RESPONSE_RELEASE_SETUP;
-			}
-
-			print_bearer(bc);
-			
-			ch = init_chan_list(ORG_MISDN);
-			if (!ch) {
-				chan_misdn_log(-1, bc->port, "cb_events: malloc for chan_list failed!\n");
-				return RESPONSE_IGNORE_SETUP;
-			}
-
-			ch->bc = bc;
-			ch->l3id = bc->l3_id;
-			ch->addr = bc->addr;
-			ch->orginator = ORG_MISDN;
-			chan = misdn_new(ch, AST_STATE_RESERVED, bc->dad, bc->oad, AST_FORMAT_ALAW, bc->port, bc->channel);
-			ch->ast = chan;
-
-			if ((exceed = add_in_calls(bc->port))) {
-				snprintf(tmp, sizeof(tmp), "%d", exceed);
-				pbx_builtin_setvar_helper(chan, "MAX_OVERFLOW", tmp);
-			}
-
-			config_ch(ch, ORG_MISDN);
-			export_chan(chan, bc, ch);
-			ch->ast->rings = 1;
-			ast_setstate(ch->ast, AST_STATE_RINGING);
-
-			pres = bc->pres == 1 ? AST_PRES_RESTRICTED : (bc->pres == 2 ? AST_PRES_UNAVAILABLE : AST_PRES_ALLOWED);
-			chan_misdn_log(2, bc->port, " --> PRES: Restricted (%d)\n", bc->pres);
-			switch (bc->screen) {
-			case 0:
-				screen = AST_PRES_USER_NUMBER_UNSCREENED;
-				chan_misdn_log(2, bc->port, " --> SCREEN: Unscreened (0)\n");
-				break;
-			case 1:
-				screen = AST_PRES_USER_NUMBER_PASSED_SCREEN;
-				chan_misdn_log(2, bc->port, " --> SCREEN: Passed screen (1)\n");
-				break;
-			case 2:
-				screen = AST_PRES_USER_NUMBER_FAILED_SCREEN;
-				chan_misdn_log(2, bc->port, " --> SCREEN: Failed screen (2)\n");
-				break;
-			case 3:
-				screen = AST_PRES_NETWORK_NUMBER;
-				chan_misdn_log(2, bc->port, " --> SCREEN: Network Number (3)\n");
-				break;
-			default:
-				screen = AST_PRES_USER_NUMBER_UNSCREENED;
-				chan_misdn_log(2, bc->port, " --> SCREEN: Unscreened (%d)\n", bc->screen);
-			}
-			chan->cid.cid_pres = pres + screen;
-			
-			pbx_builtin_setvar_helper(chan, "TRANSFERCAPABILITY", ast_transfercapability2str(bc->capability));
-			chan->transfercapability = bc->capability;
-			pbx_builtin_setvar_helper(chan, "CALLTYPE", bc->capability == INFO_CAPABILITY_DIGITAL_UNRESTRICTED ? "DIGITAL" : "SPEECH");
-
-			cl_queue_chan(&cl_te, ch) ;
-			if (!strstr(ch->allowed_bearers, "all"))
-				for (i = 0; i <  sizeof(allowed_bearers) / sizeof(struct allowed_bearer); ++i)
-					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);
-						misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
-						return RESPONSE_OK;
-					}
-
-			/* Check for Pickup Request first */
-			if (!strcmp(chan->exten, ast_pickup_ext())) {
-				misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE);
-				if (ast_pickup_call(chan))
-					hangup_chan(ch);
-				else {
-					state_machine_set_state(ch->sm, MISDN_CALLING_ACKNOWLEDGE);
-					ast_setstate(chan, AST_STATE_DOWN);
-					hangup_chan(ch);
-					ch->ast = NULL;
-				}
-				break;
-			}
-
-			/* check if we should jump into s when we have no dad */
-			im = 0;
-			cm_get_int(misdn_cm, im, PORT, MCFG_IMMEDIATE, bc->port);
-			if (im && ast_strlen_zero(bc->dad)) {
-				do_immediate_setup(bc, ch , chan);
-				break;
-			}
-
-			chan_misdn_log(5, bc->port, "CONTEXT: %s\n", ch->context);
-			if (!ast_canmatch_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
-				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);
-				break;
-			}
-
-			if (!ch->overlap_dial && ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
-				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);
-				if (pbx_start_chan(ch) < 0) {
-					hangup_chan(ch);
-					chan_misdn_log(-1, bc->port, "ast_pbx_start returned < 0 in SETUP\n");
-					chan = NULL;
-					if (bc->nt)
-						hanguptone_indicate(ch);
-					misdn_lib_send_event(bc, bc->nt ? EVENT_RELEASE_COMPLETE : EVENT_RELEASE);
-				}
-			} 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);
-				} else {
-					if (misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE) == -ENOCHAN) {
-						ast_log(LOG_WARNING, "Channel was catched before we could acknowledge!\n");
-						misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
-					}
-					dad_len = ast_strlen_zero(bc->dad);
-					if (!dad_len)
-						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();
-						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);
-					}
-				}
-			}
-		}
-		break;
-	case EVENT_CONNECT:
-		{
-			struct ast_channel *bridged;
-			struct chan_list *bridged_ch;
-			/* we answer when we've got our very new L3 ID from the NT stack */
-			misdn_lib_send_event(bc, EVENT_CONNECT_ACKNOWLEDGE);
-			bridged = AST_BRIDGED_P(ch->ast);
-			misdn_lib_echo(bc, 0);
-			stop_indicate(ch);
-			if (bridged && !strcasecmp(bridged->tech->type, "mISDN")) {
-				bridged_ch = MISDN_ASTERISK_TECH_PVT(bridged);
-				chan_misdn_log(2, bc->port, " --> copying cpndialplan:%d and cad:%s to the A-Channel\n", bc->cpnnumplan, bc->cad);
-				if (bridged_ch) {
-					bridged_ch->bc->cpnnumplan = bc->cpnnumplan;
-					ast_copy_string(bridged_ch->bc->cad, bc->cad, sizeof(bc->cad));
-				}
-			}
-		}
-		/* notice that we don't break here!*/
-	case EVENT_DISCONNECT:
-		{
-			struct chan_list *holded_ch;
-			/* we might not have an ch->ast ptr here anymore */
-			if (ch) {
-				chan_misdn_log(3, bc->port, " --> org:%d nt:%d, inbandavail:%d state:%d\n",
-							   ch->orginator, bc->nt, misdn_inband_avail(bc), state_machine_get_state(ch->sm));
-				state_machine_set_state(ch->sm, MISDN_DISCONNECTED);
-				if (ch->orginator == ORG_AST && !bc->nt && misdn_inband_avail(bc) && state_machine_get_state(ch->sm) != MISDN_CONNECTED) {
-					/* If there's inband information available (e.g. a recorded message saying what was wrong with the
-					 * dialled number, or perhaps even giving an alternative number, then play it instead of
-					 * immediately releasing the call */
-					chan_misdn_log(2, bc->port, " --> Inband Info Avail, not sending RELEASE\n");
-					start_bc_tones(ch);
-					break;
-				}
-				/* Check for holded channel, to implement transfer */
-				holded_ch = find_holded(cl_te, bc);
-				if (holded_ch && holded_ch != ch && ch->ast && state_machine_get_state(ch->sm) == MISDN_CONNECTED) {
-					chan_misdn_log(2, bc->port, " --> found holded ch\n");
-					misdn_transfer_bc(ch, holded_ch) ;
-				}
-				stop_bc_tones(ch);
-				hangup_chan(ch);
-			}
-			bc->out_cause = -1;
 		}
 		break;
 	case EVENT_BCHAN_ERROR:



More information about the svn-commits mailing list