diff options
Diffstat (limited to 'main/features.c')
-rw-r--r-- | main/features.c | 59 |
1 files changed, 52 insertions, 7 deletions
diff --git a/main/features.c b/main/features.c index 6e3570e63..6c15f258d 100644 --- a/main/features.c +++ b/main/features.c @@ -1377,6 +1377,9 @@ static int builtin_blindtransfer(struct ast_channel *chan, struct ast_channel *p /* Set the channel's new extension, since it exists, using transferer context */ ast_set_flag(transferee, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */ ast_log(LOG_DEBUG,"ABOUT TO AST_ASYNC_GOTO, have a pbx... set HANGUP_DONT on chan=%s\n", transferee->name); + if (ast_channel_connected_line_macro(transferee, transferer, &transferer->connected, 1, 0)) { + ast_channel_update_connected_line(transferee, &transferer->connected); + } set_c_e_p(transferee, transferer_real_context, xferto, 0); } check_goto_on_transfer(transferer); @@ -1635,13 +1638,43 @@ static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, st /* Due to a limitation regarding when callerID is set on a Local channel, * we use the transferer's connected line information here. */ + + /* xferchan is transferee, and newchan is the transfer target + * So...in a transfer, who is the caller and who is the callee? + * + * When the call is originally made, it is clear who is caller and callee. + * When a transfer occurs, it is my humble opinion that the transferee becomes + * the caller, and the transfer target is the callee. + * + * The problem is that these macros were set with the intention of the original + * caller and callee taking those roles. A transfer can totally mess things up, + * to be technical. What sucks even more is that you can't effectively change + * the macros in the dialplan during the call from the transferer to the transfer + * target because the transferee is stuck with whatever role he originally had. + * + * I think the answer here is just to make sure that it is well documented that + * during a transfer, the transferee is the "caller" and the transfer target + * is the "callee." + * + * This means that if party A calls party B, and party A transfers party B to + * party C, then B has switched roles for the call. Now party B will have the + * caller macro called on his channel instead of the callee macro. + * + * Luckily, the method by which the bridge is launched here ensures that the + * transferee is the "chan" on the bridge and the transfer target is the "peer," + * so my idea for the roles post-transfer does not require extensive code changes. + */ connected_line.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER; - ast_channel_update_connected_line(xferchan, &connected_line); + if (ast_channel_connected_line_macro(newchan, xferchan, &connected_line, 1, 0)) { + ast_channel_update_connected_line(xferchan, &connected_line); + } ast_channel_lock(xferchan); ast_connected_line_copy_from_caller(&connected_line, &xferchan->cid); ast_channel_unlock(xferchan); connected_line.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER; - ast_channel_update_connected_line(newchan, &connected_line); + if (ast_channel_connected_line_macro(xferchan, newchan, &connected_line, 0, 0)) { + ast_channel_update_connected_line(newchan, &connected_line); + } ast_party_connected_line_free(&connected_line); if (ast_stream_and_wait(newchan, xfersound, "")) @@ -1749,12 +1782,16 @@ static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, st ast_connected_line_copy_from_caller(&connected_line, &newchan->cid); ast_channel_unlock(newchan); connected_line.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER; - ast_channel_update_connected_line(xferchan, &connected_line); + if (ast_channel_connected_line_macro(newchan, xferchan, &connected_line, 1, 0)) { + ast_channel_update_connected_line(xferchan, &connected_line); + } ast_channel_lock(xferchan); ast_connected_line_copy_from_caller(&connected_line, &xferchan->cid); ast_channel_unlock(xferchan); connected_line.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER; - ast_channel_update_connected_line(newchan, &connected_line); + if (ast_channel_connected_line_macro(xferchan, newchan, &connected_line, 0, 0)) { + ast_channel_update_connected_line(newchan, &connected_line); + } ast_party_connected_line_free(&connected_line); @@ -2370,7 +2407,9 @@ static struct ast_channel *feature_request_and_dial(struct ast_channel *caller, ready=1; break; } else if (f->subclass == AST_CONTROL_CONNECTED_LINE) { - ast_indicate_data(caller, AST_CONTROL_CONNECTED_LINE, f->data.ptr, f->datalen); + if (ast_channel_connected_line_macro(chan, caller, f, 1, 1)) { + ast_indicate_data(caller, AST_CONTROL_CONNECTED_LINE, f->data.ptr, f->datalen); + } } else if (f->subclass != -1) { ast_log(LOG_NOTICE, "Don't know what to do about control frame: %d\n", f->subclass); } @@ -2766,9 +2805,13 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast case -1: ast_indicate(other, f->subclass); break; + case AST_CONTROL_CONNECTED_LINE: + if (!ast_channel_connected_line_macro(who, other, f, who != chan, 1)) { + break; + } + /* The implied "else" falls through purposely */ case AST_CONTROL_HOLD: case AST_CONTROL_UNHOLD: - case AST_CONTROL_CONNECTED_LINE: ast_indicate_data(other, f->subclass, f->data.ptr, f->datalen); break; case AST_CONTROL_OPTION: @@ -4546,7 +4589,9 @@ int ast_pickup_call(struct ast_channel *chan) connected_caller = cur->connected; connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER; - ast_channel_update_connected_line(chan, &connected_caller); + if (ast_channel_connected_line_macro(NULL, chan, &connected_caller, 0, 0)) { + ast_channel_update_connected_line(chan, &connected_caller); + } ast_party_connected_line_collect_caller(&connected_caller, &chan->cid); connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER; |