aboutsummaryrefslogtreecommitdiffstats
path: root/channels/chan_misdn.c
diff options
context:
space:
mode:
authorcrichter <crichter@f38db490-d61c-443f-a65b-d21fe96a405b>2007-06-05 15:39:43 +0000
committercrichter <crichter@f38db490-d61c-443f-a65b-d21fe96a405b>2007-06-05 15:39:43 +0000
commit186dcfa4946e3f6f039bda095f6e4d70aa5df642 (patch)
tree57a0bc2d1e577a87a84216085aee71113171b0c8 /channels/chan_misdn.c
parent54e98e92f7630545b2faa8669d9af58cf3bd24fb (diff)
simplified the EVENT_SETUP handling in the cb_events function a lot. Commented the different possibilities a bit and made functions of shared code. When the dialed extension does not exist in the extensions.conf we'll jump into the 'i' extension if this does exist, else we disconnect the call with the cause:1 = No Route to Destination.
git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@67306 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels/chan_misdn.c')
-rw-r--r--channels/chan_misdn.c330
1 files changed, 155 insertions, 175 deletions
diff --git a/channels/chan_misdn.c b/channels/chan_misdn.c
index b421e37d2..faa1b9552 100644
--- a/channels/chan_misdn.c
+++ b/channels/chan_misdn.c
@@ -3505,6 +3505,26 @@ void export_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_
}
+static void start_pbx(struct chan_list *ch, struct misdn_bchannel *bc, struct ast_channel *chan) {
+ 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, EVENT_RELEASE_COMPLETE );
+ } else
+ misdn_lib_send_event(bc, EVENT_RELEASE);
+ }
+}
+
+static void wait_for_digits(struct chan_list *ch, struct misdn_bchannel *bc, struct ast_channel *chan) {
+ ch->state=MISDN_WAITING4DIGS;
+ misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
+ if (bc->nt)
+ dialtone_indicate(ch);
+}
+
+
/************************************************************/
/* Receive Events from isdn_lib here */
@@ -3633,41 +3653,30 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
case EVENT_INFORMATION:
{
- int stop_tone;
- misdn_cfg_get( 0, MISDN_GEN_STOP_TONE, &stop_tone, sizeof(int));
+ int l;
- if ( (ch->state != MISDN_CONNECTED) && stop_tone ) {
+ if ( ch->state != MISDN_CONNECTED )
stop_indicate(ch);
- }
if (!ch->ast) break;
if (ch->state == MISDN_WAITING4DIGS ) {
/* Ok, incomplete Setup, waiting till extension exists */
-
if (ast_strlen_zero(bc->info_dad) && ! ast_strlen_zero(bc->keypad)) {
chan_misdn_log(1, bc->port, " --> using keypad as info\n");
strcpy(bc->info_dad,bc->keypad);
}
- {
- int l = sizeof(bc->dad);
- strncat(bc->dad,bc->info_dad, l);
- bc->dad[l-1] = 0;
- }
-
-
- {
- int l = sizeof(ch->ast->exten);
- strncpy(ch->ast->exten, bc->dad, l);
- ch->ast->exten[l-1] = 0;
- }
-/* chan_misdn_log(5, bc->port, "Can Match Extension: dad:%s oad:%s\n",bc->dad,bc->oad);*/
-
+ l = sizeof(bc->dad);
+ strncat(bc->dad,bc->info_dad, l);
+ bc->dad[l-1] = 0;
+
+ l = sizeof(ch->ast->exten);
+ strncpy(ch->ast->exten, bc->dad, l);
+ ch->ast->exten[l-1] = 0;
+
/* Check for Pickup Request first */
if (!strcmp(ch->ast->exten, ast_pickup_ext())) {
- int ret;/** Sending SETUP_ACK**/
- ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
if (ast_pickup_call(ch->ast)) {
hangup_chan(ch);
} else {
@@ -3681,15 +3690,23 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
}
if(!ast_canmatch_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
+ if (ast_exists_extension(ch->ast, ch->context, "i", 1, bc->oad)) {
+ ast_log(LOG_WARNING, "Extension can never match, So jumping to 'i' extension. port(%d)\n",bc->port);
+ strcpy(ch->ast->exten, "i");
+ start_pbx(ch, bc, ch->ast);
+ break;
+ }
+
+ ast_log(LOG_WARNING, "Extension can never match, so disconnecting on port(%d)."
+ "maybe you want to add an 'i' extension to catch this case.\n",
+ bc->port);
- chan_misdn_log(-1, bc->port, "Extension can never match, so disconnecting\n");
if (bc->nt)
hanguptone_indicate(ch);
ch->state=MISDN_EXTCANTMATCH;
bc->out_cause=1;
misdn_lib_send_event(bc, EVENT_DISCONNECT );
-
break;
}
@@ -3704,21 +3721,8 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
break;
}
- if (ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
- ch->state=MISDN_DIALING;
-
- stop_indicate(ch);
-/* chan_misdn_log(1, bc->port, " --> * Starting Ast ctx:%s\n", ch->context);*/
- if (pbx_start_chan(ch)<0) {
- hangup_chan(ch);
-
- chan_misdn_log(-1, bc->port, "ast_pbx_start returned < 0 in INFO\n");
- if (bc->nt) hanguptone_indicate(ch);
-
- misdn_lib_send_event(bc, EVENT_DISCONNECT );
- }
- }
-
+ if (ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad))
+ start_pbx(ch, bc, ch->ast);
} else {
/* sending INFOS as DTMF-Frames :) */
struct ast_frame fr;
@@ -3766,30 +3770,29 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
}
}
}
-
- int msn_valid = misdn_cfg_is_msn_valid(bc->port, bc->dad);
- if (!bc->nt && ! msn_valid) {
- chan_misdn_log(1, 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");
- int cause;
- misdn_cfg_get( bc->port, MISDN_CFG_REJECT_CAUSE, &cause, sizeof(cause));
- bc->out_cause=cause?cause:16;
- return RESPONSE_RELEASE_SETUP;
- }
-
- print_bearer(bc);
-
{
+ int msn_valid = misdn_cfg_is_msn_valid(bc->port, bc->dad);
+ if (!bc->nt && ! msn_valid) {
+ chan_misdn_log(1, 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");
+ int cause;
+ misdn_cfg_get( bc->port, MISDN_CFG_REJECT_CAUSE, &cause, sizeof(cause));
+ bc->out_cause=cause?cause:16;
+ return RESPONSE_RELEASE_SETUP;
+ }
+
+ print_bearer(bc);
+
struct chan_list *ch=init_chan_list(ORG_MISDN);
struct ast_channel *chan;
if (!ch) { chan_misdn_log(-1, bc->port, "cb_events: malloc for chan_list failed!\n"); return 0;}
-
+
ch->bc = bc;
ch->l3id=bc->l3_id;
ch->addr=bc->addr;
@@ -3799,7 +3802,7 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
ch->ast = chan;
read_config(ch, ORG_MISDN);
-
+
export_ch(chan, bc, ch);
ch->ast->rings=1;
@@ -3809,49 +3812,48 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
switch (bc->pres) {
case 1:
- pres=AST_PRES_RESTRICTED; chan_misdn_log(2,bc->port," --> PRES: Restricted (1)\n");
- break;
+ pres=AST_PRES_RESTRICTED; chan_misdn_log(2,bc->port," --> PRES: Restricted (1)\n");
+ break;
case 2:
- pres=AST_PRES_UNAVAILABLE; chan_misdn_log(2,bc->port," --> PRES: Restricted (2)\n");
- break;
+ pres=AST_PRES_UNAVAILABLE; chan_misdn_log(2,bc->port," --> PRES: Restricted (2)\n");
+ break;
default:
- pres=AST_PRES_ALLOWED; chan_misdn_log(2,bc->port," --> PRES: Restricted (%d)\n", bc->pres);
+ pres=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;
+ 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;
+ 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;
+ 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;
+ 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);
+ 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;
-
+
switch (bc->capability) {
- case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
- pbx_builtin_setvar_helper(chan,"CALLTYPE","DIGITAL");
- break;
- default:
- pbx_builtin_setvar_helper(chan,"CALLTYPE","SPEECH");
+ case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
+ pbx_builtin_setvar_helper(chan,"CALLTYPE","DIGITAL");
+ break;
+ default:
+ pbx_builtin_setvar_helper(chan,"CALLTYPE","SPEECH");
}
/** queue new chan **/
cl_queue_chan(&cl_te, ch) ;
-
if (!strstr(ch->allowed_bearers,"all")) {
int i;
for (i=0; i< sizeof(allowed_bearers_array)/sizeof(struct allowed_bearers); i++) {
@@ -3859,16 +3861,16 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
if ( !strstr( ch->allowed_bearers, allowed_bearers_array[i].name)) {
chan_misdn_log(0,bc->port,"Bearer Not allowed\b");
bc->out_cause=88;
-
+
ch->state=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())) {
if (!ch->noautorespond_on_setup) {
@@ -3887,41 +3889,43 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
break;
}
}
-
+
/*
- added support for s extension hope it will help those poor cretains
- which haven't overlap dial.
- */
- {
- int ai;
- misdn_cfg_get( bc->port, MISDN_CFG_ALWAYS_IMMEDIATE, &ai, sizeof(ai));
- if ( ai ) {
- do_immediate_setup(bc, ch , chan);
- break;
- }
-
-
-
+ added support for s extension hope it will help those poor cretains
+ which haven't overlap dial.
+ */
+ int ai;
+ misdn_cfg_get( bc->port, MISDN_CFG_ALWAYS_IMMEDIATE, &ai, sizeof(ai));
+ if ( ai ) {
+ do_immediate_setup(bc, ch , chan);
+ break;
}
/* check if we should jump into s when we have no dad */
- {
- int im;
- misdn_cfg_get( bc->port, MISDN_CFG_IMMEDIATE, &im, sizeof(im));
- if ( im && ast_strlen_zero(bc->dad) ) {
- do_immediate_setup(bc, ch , chan);
- break;
- }
+ int im;
+ misdn_cfg_get( bc->port, MISDN_CFG_IMMEDIATE, &im, sizeof(im));
+ 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");
+ chan_misdn_log(5,bc->port,"CONTEXT:%s\n",ch->context);
+ if(!ast_canmatch_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
+ if (ast_exists_extension(ch->ast, ch->context, "i", 1, bc->oad)) {
+ ast_log(LOG_WARNING, "Extension can never match, So jumping to 'i' extension. port(%d)\n",bc->port);
+ strcpy(ch->ast->exten, "i");
+ misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE);
+ ch->state=MISDN_DIALING;
+ start_pbx(ch, bc, chan);
+ break;
+ }
+ ast_log(LOG_WARNING, "Extension can never match, so disconnecting on port(%d)."
+ "maybe you want to add an 'i' extension to catch this case.\n",
+ bc->port);
if (bc->nt)
hanguptone_indicate(ch);
+
ch->state=MISDN_EXTCANTMATCH;
bc->out_cause=1;
@@ -3929,90 +3933,66 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE );
else
misdn_lib_send_event(bc, EVENT_RELEASE );
-
+
break;
}
-
- if (!ch->overlap_dial && ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
-
+
+ /* Whatever happens, when sending_complete is set or we are PTMP TE, we will definitely
+ * jump into the dialplan, when the dialed extension does not exist, the 's' extension
+ * will be used by Asterisk automatically. */
+ if (bc->sending_complete || (!bc->nt && !misdn_lib_is_ptp(bc->port))) {
if (!ch->noautorespond_on_setup) {
ch->state=MISDN_DIALING;
-
- if (!bc->sending_complete &&
- (bc->nt || (bc->need_more_infos && misdn_lib_is_ptp(bc->port)))) {
- int ret;
- ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
- } else {
- int ret;
- ret= misdn_lib_send_event(bc, EVENT_PROCEEDING );
- }
+ misdn_lib_send_event(bc, EVENT_PROCEEDING );
} else {
ch->state = MISDN_INCOMING_SETUP;
}
-
- if (pbx_start_chan(ch)<0) {
- hangup_chan(ch);
+ start_pbx(ch, bc, chan);
+ break;
+ }
- chan_misdn_log(-1, bc->port, "ast_pbx_start returned <0 in SETUP\n");
- chan=NULL;
+ /*
+ * If overlapdial we will definitely send a SETUP_ACKNOWLEDGE and wait for more
+ * Infos with a Interdigit Timeout.
+ * */
+ if (ch->overlap_dial) {
+ ast_mutex_lock(&ch->overlap_tv_lock);
+ ch->overlap_tv = ast_tvnow();
+ ast_mutex_unlock(&ch->overlap_tv_lock);
- if (bc->nt) {
- hanguptone_indicate(ch);
- misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE );
- } else
- misdn_lib_send_event(bc, EVENT_RELEASE);
- }
- } else {
+ if (ch->overlap_dial_task == -1)
+ ch->overlap_dial_task =
+ misdn_tasks_add_variable(ch->overlap_dial, misdn_overlap_dial_task, ch);
- if (bc->sending_complete) {
- ch->state=MISDN_EXTCANTMATCH;
- bc->out_cause=1;
+ wait_for_digits(ch, bc, chan);
+ break;
+ }
- if (bc->nt) {
- chan_misdn_log(0,bc->port," --> sending_complete so we never match ..\n");
- misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
- } else {
- chan_misdn_log(0,bc->port," --> sending_complete so we never match ..\n");
- misdn_lib_send_event(bc, EVENT_RELEASE);
- }
+ /* If the extension does not exist and we're not TE_PTMP we wait for more digis
+ * without interdigit timeout.
+ * */
+ if (!ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
+ wait_for_digits(ch, bc, chan);
+ break;
+ }
- } else {
- int ret= misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
- if (ret == -ENOCHAN) {
- ast_log(LOG_WARNING,"Channel was catched, before we could Acknowledge\n");
- misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
- }
- /* send tone to phone :) */
-
- /** ADD IGNOREPAT **/
-
- ch->state=MISDN_WAITING4DIGS;
- int stop_tone, dad_len;
- misdn_cfg_get( 0, MISDN_GEN_STOP_TONE, &stop_tone, sizeof(int));
+ /*
+ * If the extension exists let's just jump into it.
+ * */
+ if (ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
+ if (bc->need_more_infos)
+ misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
+ else
+ misdn_lib_send_event(bc, EVENT_PROCEEDING);
- dad_len = ast_strlen_zero(bc->dad);
-
- if ( !dad_len && stop_tone )
- stop_indicate(ch);
- else {
- if (bc->nt)
- dialtone_indicate(ch);
- }
-
- 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);
- }
- }
- }
+ ch->state=MISDN_DIALING;
+ start_pbx(ch, bc, chan);
+ break;
}
-
+
}
break;
+
case EVENT_SETUP_ACKNOWLEDGE:
{
ch->state = MISDN_CALLING_ACKNOWLEDGE;