diff options
author | Luigi Rizzo <rizzo@icir.org> | 2006-11-04 00:01:40 +0000 |
---|---|---|
committer | Luigi Rizzo <rizzo@icir.org> | 2006-11-04 00:01:40 +0000 |
commit | 1385b6f047f38fe02971fb69543ac44dfb376d81 (patch) | |
tree | e8570ae61d0bfe31a6e003c27b399cc0e275fa96 /apps | |
parent | 65beb9dc10ae2feece436a9797e1566979f691ee (diff) |
move a large block into a separate function.
Mark with XXX a possible bug in previous code which used
the wrong source in case of a forwarded call.
the function do_forward() needs to be split further, as the initial
part is replicated in another places (with some minor differences, most likely
forgotten when updating after the copy).
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@47179 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'apps')
-rw-r--r-- | apps/app_dial.c | 176 |
1 files changed, 93 insertions, 83 deletions
diff --git a/apps/app_dial.c b/apps/app_dial.c index 5e68156e7..14a9476f9 100644 --- a/apps/app_dial.c +++ b/apps/app_dial.c @@ -419,6 +419,97 @@ static void senddialendevent(const struct ast_channel *src, const char *dialstat src->name, dialstatus); } +/* helper function for wait_for_answer() */ +static void do_forward(struct dial_localuser *o, + struct cause_args *num, struct ast_flags *peerflags, int single) +{ + char tmpchan[256]; + struct ast_channel *c = o->chan; /* the winner */ + struct ast_channel *in = num->chan; /* the input channel */ + char *stuff; + char *tech; + int cause; + + ast_copy_string(tmpchan, c->call_forward, sizeof(tmpchan)); + if ((stuff = strchr(tmpchan, '/'))) { + *stuff++ = '\0'; + tech = tmpchan; + } else { + const char *forward_context = pbx_builtin_getvar_helper(c, "FORWARD_CONTEXT"); + snprintf(tmpchan, sizeof(tmpchan), "%s@%s", c->call_forward, forward_context ? forward_context : c->context); + stuff = tmpchan; + tech = "Local"; + } + /* Before processing channel, go ahead and check for forwarding */ + o->forwards++; + if (o->forwards < AST_MAX_FORWARDS) { + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, c->name); + /* If we have been told to ignore forwards, just set this channel to null and continue processing extensions normally */ + if (ast_test_flag(peerflags, OPT_IGNORE_FORWARDING)) { + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "Forwarding %s to '%s/%s' prevented.\n", in->name, tech, stuff); + c = o->chan = NULL; + cause = AST_CAUSE_BUSY; + } else { + /* Setup parameters */ + c = o->chan = ast_request(tech, in->nativeformats, stuff, &cause); + if (!c) + ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause); + else + ast_channel_inherit_variables(in, o->chan); + } + } else { + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "Too many forwards from %s\n", c->name); + cause = AST_CAUSE_CONGESTION; + c = o->chan = NULL; + } + if (!c) { + ast_clear_flag(o, DIAL_STILLGOING); + handle_cause(cause, num); + } else { + char *new_cid_num, *new_cid_name; + struct ast_channel *src; + + ast_rtp_make_compatible(c, in, single); + if (ast_test_flag(o, OPT_FORCECLID)) { + new_cid_num = ast_strdup(S_OR(in->macroexten, in->exten)); + new_cid_name = NULL; /* XXX no name ? */ + src = c; /* XXX possible bug in previous code, which used 'winner' ? it may have changed */ + } else { + new_cid_num = ast_strdup(in->cid.cid_num); + new_cid_name = ast_strdup(in->cid.cid_name); + src = in; + } + ast_string_field_set(c, accountcode, src->accountcode); + c->cdrflags = src->cdrflags; + S_REPLACE(c->cid.cid_num, new_cid_num); + S_REPLACE(c->cid.cid_name, new_cid_name); + + if (in->cid.cid_ani) { /* XXX or maybe unconditional ? */ + S_REPLACE(c->cid.cid_ani, ast_strdup(in->cid.cid_ani)); + } + S_REPLACE(c->cid.cid_rdnis, ast_strdup(S_OR(in->macroexten, in->exten))); + if (ast_call(c, tmpchan, 0)) { + ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan); + ast_clear_flag(o, DIAL_STILLGOING); + ast_hangup(c); + c = o->chan = NULL; + num->nochan++; + } else { + senddialevent(in, c); + /* After calling, set callerid to extension */ + if (!ast_test_flag(peerflags, OPT_ORIGINAL_CLID)) { + char cidname[AST_MAX_EXTENSION]; + ast_set_callerid(c, S_OR(in->macroexten, in->exten), get_cid_name(cidname, sizeof(cidname), in), NULL); + } + } + } + /* Hangup the original channel now, in case we needed it */ + ast_hangup(c); +} + static struct ast_channel *wait_for_answer(struct ast_channel *in, struct dial_localuser *outgoing, int *to, struct ast_flags *peerflags, int *sentringing, char *status, size_t statussize, const struct cause_args *num_in, int priority_jump, int *result) { @@ -495,90 +586,9 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct dial_l } if (c != winner) continue; + /* here, o->chan == c == winner */ if (!ast_strlen_zero(c->call_forward)) { - char tmpchan[256]; - char *stuff; - char *tech; - int cause; - - ast_copy_string(tmpchan, c->call_forward, sizeof(tmpchan)); - if ((stuff = strchr(tmpchan, '/'))) { - *stuff++ = '\0'; - tech = tmpchan; - } else { - const char *forward_context = pbx_builtin_getvar_helper(c, "FORWARD_CONTEXT"); - snprintf(tmpchan, sizeof(tmpchan), "%s@%s", c->call_forward, forward_context ? forward_context : c->context); - stuff = tmpchan; - tech = "Local"; - } - /* Before processing channel, go ahead and check for forwarding */ - o->forwards++; - if (o->forwards < AST_MAX_FORWARDS) { - if (option_verbose > 2) - ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, c->name); - /* If we have been told to ignore forwards, just set this channel to null and continue processing extensions normally */ - if (ast_test_flag(peerflags, OPT_IGNORE_FORWARDING)) { - if (option_verbose > 2) - ast_verbose(VERBOSE_PREFIX_3 "Forwarding %s to '%s/%s' prevented.\n", in->name, tech, stuff); - c = o->chan = NULL; - cause = AST_CAUSE_BUSY; - } else { - /* Setup parameters */ - c = o->chan = ast_request(tech, in->nativeformats, stuff, &cause); - if (!c) - ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause); - else - ast_channel_inherit_variables(in, o->chan); - } - } else { - if (option_verbose > 2) - ast_verbose(VERBOSE_PREFIX_3 "Too many forwards from %s\n", c->name); - cause = AST_CAUSE_CONGESTION; - c = o->chan = NULL; - } - if (!c) { - ast_clear_flag(o, DIAL_STILLGOING); - handle_cause(cause, &num); - } else { - char *new_cid_num, *new_cid_name; - struct ast_channel *src; - - ast_rtp_make_compatible(c, in, single); - if (ast_test_flag(o, OPT_FORCECLID)) { - new_cid_num = ast_strdup(S_OR(in->macroexten, in->exten)); - new_cid_name = NULL; /* XXX no name ? */ - src = winner; - } else { - new_cid_num = ast_strdup(in->cid.cid_num); - new_cid_name = ast_strdup(in->cid.cid_name); - src = in; - } - ast_string_field_set(c, accountcode, src->accountcode); - c->cdrflags = src->cdrflags; - S_REPLACE(c->cid.cid_num, new_cid_num); - S_REPLACE(c->cid.cid_name, new_cid_name); - - if (in->cid.cid_ani) { /* XXX or maybe unconditional ? */ - S_REPLACE(c->cid.cid_ani, ast_strdup(in->cid.cid_ani)); - } - S_REPLACE(c->cid.cid_rdnis, ast_strdup(S_OR(in->macroexten, in->exten))); - if (ast_call(c, tmpchan, 0)) { - ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan); - ast_clear_flag(o, DIAL_STILLGOING); - ast_hangup(c); - c = o->chan = NULL; - num.nochan++; - } else { - senddialevent(in, c); - /* After calling, set callerid to extension */ - if (!ast_test_flag(peerflags, OPT_ORIGINAL_CLID)) { - char cidname[AST_MAX_EXTENSION]; - ast_set_callerid(c, S_OR(in->macroexten, in->exten), get_cid_name(cidname, sizeof(cidname), in), NULL); - } - } - } - /* Hangup the original channel now, in case we needed it */ - ast_hangup(winner); + do_forward(o, &num, peerflags, single); continue; } f = ast_read(winner); |