[asterisk-commits] nadi: branch group/trunk-cm-csel-hash r47365 -
/team/group/trunk-cm-csel-hash...
asterisk-commits at lists.digium.com
asterisk-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 asterisk-commits
mailing list