app_queue.c: Force COLP update if outgoing channel name changed.

* When a call is answered and the outgoing channel name has changed then
force a connected line update because the channel is no longer the same.
The channel was masqueraded into by another channel.  This is usually
because of a call pickup.

Note: Forwarded calls are handled in a controlled manner so the original
channel name is replaced with the forwarded channel.

ASTERISK-25423 #close
Reported by: John Hardin

Change-Id: Ie275ea9e99c092ad369db23e0feb08c44498c172
changes/29/1329/1
Richard Mudgett 10 years ago
parent bd43638622
commit 00be2f6b4f

@ -1439,6 +1439,8 @@ struct callattempt {
/*! TRUE if the call is still active */ /*! TRUE if the call is still active */
unsigned int stillgoing:1; unsigned int stillgoing:1;
struct ast_aoc_decoded *aoc_s_rate_list; struct ast_aoc_decoded *aoc_s_rate_list;
/*! Original channel name. Must be freed. Could be NULL if allocation failed. */
char *orig_chan_name;
}; };
@ -3942,6 +3944,7 @@ static void callattempt_free(struct callattempt *doomed)
ao2_ref(doomed->member, -1); ao2_ref(doomed->member, -1);
} }
ast_party_connected_line_free(&doomed->connected); ast_party_connected_line_free(&doomed->connected);
ast_free(doomed->orig_chan_name);
ast_free(doomed); ast_free(doomed);
} }
@ -4273,6 +4276,9 @@ static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies
ast_channel_exten_set(tmp->chan, ast_channel_exten(qe->chan)); ast_channel_exten_set(tmp->chan, ast_channel_exten(qe->chan));
} }
/* Save the original channel name to detect call pickup masquerading in. */
tmp->orig_chan_name = ast_strdup(ast_channel_name(tmp->chan));
ast_channel_unlock(tmp->chan); ast_channel_unlock(tmp->chan);
ast_channel_unlock(qe->chan); ast_channel_unlock(qe->chan);
@ -4694,7 +4700,14 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte
if (o->stillgoing && (o->chan) && (ast_channel_state(o->chan) == AST_STATE_UP)) { if (o->stillgoing && (o->chan) && (ast_channel_state(o->chan) == AST_STATE_UP)) {
if (!peer) { if (!peer) {
ast_verb(3, "%s answered %s\n", ochan_name, inchan_name); ast_verb(3, "%s answered %s\n", ochan_name, inchan_name);
if (!o->block_connected_update) { if (o->orig_chan_name
&& strcmp(o->orig_chan_name, ochan_name)) {
/*
* The channel name changed so we must generate COLP update.
* Likely because a call pickup channel masqueraded in.
*/
update_connected_line_from_peer(in, o->chan, 1);
} else if (!o->block_connected_update) {
if (o->pending_connected_update) { if (o->pending_connected_update) {
if (ast_channel_connected_line_sub(o->chan, in, &o->connected, 0) && if (ast_channel_connected_line_sub(o->chan, in, &o->connected, 0) &&
ast_channel_connected_line_macro(o->chan, in, &o->connected, 1, 0)) { ast_channel_connected_line_macro(o->chan, in, &o->connected, 1, 0)) {
@ -4782,6 +4795,9 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte
ast_party_connected_line_copy(&o->connected, ast_channel_connected(in)); ast_party_connected_line_copy(&o->connected, ast_channel_connected(in));
} }
ast_free(o->orig_chan_name);
o->orig_chan_name = ast_strdup(ast_channel_name(o->chan));
ast_channel_req_accountcodes(o->chan, in, AST_CHANNEL_REQUESTOR_BRIDGE_PEER); ast_channel_req_accountcodes(o->chan, in, AST_CHANNEL_REQUESTOR_BRIDGE_PEER);
if (!ast_channel_redirecting(o->chan)->from.number.valid if (!ast_channel_redirecting(o->chan)->from.number.valid
@ -4857,7 +4873,14 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte
ast_verb(3, "%s answered %s\n", ochan_name, inchan_name); ast_verb(3, "%s answered %s\n", ochan_name, inchan_name);
ast_channel_publish_dial(qe->chan, o->chan, on, "ANSWER"); ast_channel_publish_dial(qe->chan, o->chan, on, "ANSWER");
publish_dial_end_event(qe->chan, outgoing, o->chan, "CANCEL"); publish_dial_end_event(qe->chan, outgoing, o->chan, "CANCEL");
if (!o->block_connected_update) { if (o->orig_chan_name
&& strcmp(o->orig_chan_name, ochan_name)) {
/*
* The channel name changed so we must generate COLP update.
* Likely because a call pickup channel masqueraded in.
*/
update_connected_line_from_peer(in, o->chan, 1);
} else if (!o->block_connected_update) {
if (o->pending_connected_update) { if (o->pending_connected_update) {
if (ast_channel_connected_line_sub(o->chan, in, &o->connected, 0) && if (ast_channel_connected_line_sub(o->chan, in, &o->connected, 0) &&
ast_channel_connected_line_macro(o->chan, in, &o->connected, 1, 0)) { ast_channel_connected_line_macro(o->chan, in, &o->connected, 1, 0)) {

Loading…
Cancel
Save