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
This commit is contained in:
parent
65beb9dc10
commit
1385b6f047
176
apps/app_dial.c
176
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);
|
||||
|
|
Loading…
Reference in New Issue