summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorLuigi Rizzo <rizzo@icir.org>2006-11-04 00:01:40 +0000
committerLuigi Rizzo <rizzo@icir.org>2006-11-04 00:01:40 +0000
commit1385b6f047f38fe02971fb69543ac44dfb376d81 (patch)
treee8570ae61d0bfe31a6e003c27b399cc0e275fa96 /apps
parent65beb9dc10ae2feece436a9797e1566979f691ee (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.c176
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);