diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 2181c6d872e58c53661ae2807bf29e89a1f301fd..9fe9eb5e82b6fabcd332d23dbb0f7745e884985c 100755 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -6946,54 +6946,76 @@ static int sip_park(struct ast_channel *chan1, struct ast_channel *chan2, struct return -1; } +static void ast_quiet_chan(struct ast_channel *chan) { + if(chan && chan->_state == AST_STATE_UP) { + if(chan->generatordata) + ast_deactivate_generator(chan); + + } +} /*--- attempt_transfer: Attempt transfer of SIP call ---*/ static int attempt_transfer(struct sip_pvt *p1, struct sip_pvt *p2) { + int res = 0; + struct ast_channel + *chana = NULL, + *chanb = NULL, + *bridgea = NULL, + *bridgeb = NULL, + *peera = NULL, + *peerb = NULL, + *peerc = NULL; + if (!p1->owner || !p2->owner) { ast_log(LOG_WARNING, "Transfer attempted without dual ownership?\n"); return -1; } - if (ast_bridged_channel(p1->owner)) { - if (ast_bridged_channel(p2->owner)) - ast_moh_stop(ast_bridged_channel(p2->owner)); - ast_moh_stop(ast_bridged_channel(p1->owner)); - ast_moh_stop(ast_bridged_channel(p1->owner)); - ast_moh_stop(ast_bridged_channel(p2->owner)); - if (p1->owner->cdr) { - p2->owner->cdr = ast_cdr_append(p2->owner->cdr, p1->owner->cdr); - p1->owner->cdr = NULL; - } - if (ast_bridged_channel(p1->owner)->cdr) { - p2->owner->cdr = ast_cdr_append(p2->owner->cdr, ast_bridged_channel(p1->owner)->cdr); - ast_bridged_channel(p1->owner)->cdr = NULL; - } - if (ast_channel_masquerade(p2->owner, ast_bridged_channel(p1->owner))) { - ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", p2->owner->name, ast_bridged_channel(p1->owner)->name); - return -1; - } - } else if (ast_bridged_channel(p2->owner)) { - ast_moh_stop(ast_bridged_channel(p2->owner)); - ast_moh_stop(p2->owner); - ast_moh_stop(p1->owner); - if (p2->owner->cdr) { - p1->owner->cdr = ast_cdr_append(p1->owner->cdr, p2->owner->cdr); - p2->owner->cdr = NULL; + chana = p1->owner; + chanb = p2->owner; + bridgea = ast_bridged_channel(chana); + bridgeb = ast_bridged_channel(chanb); + + if (bridgea) { + peera = chana; + peerb = chanb; + peerc = bridgea; + } else if(bridgeb) { + peera = chanb; + peerb = chana; + peerc = bridgeb; + } + + if(peera && peerb && peerc) { + ast_quiet_chan(peera); + ast_quiet_chan(peerb); + ast_quiet_chan(peerc); + + if (peera->cdr && peerb->cdr) { + peerb->cdr = ast_cdr_append(peerb->cdr, peera->cdr); + } else if(peera->cdr) { + peerb->cdr = peera->cdr; } - if (ast_bridged_channel(p2->owner)->cdr) { - p1->owner->cdr = ast_cdr_append(p1->owner->cdr, ast_bridged_channel(p2->owner)->cdr); - ast_bridged_channel(p2->owner)->cdr = NULL; + peera->cdr = NULL; + + if (peerb->cdr && peerc->cdr) { + peerb->cdr = ast_cdr_append(peerb->cdr, peerc->cdr); + } else if(peerc->cdr) { + peerb->cdr = peerc->cdr; } - if (ast_channel_masquerade(p1->owner, ast_bridged_channel(p2->owner))) { - ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", p1->owner->name, ast_bridged_channel(p2->owner)->name); - return -1; + peerc->cdr = NULL; + + if (ast_channel_masquerade(peerb, peerc)) { + ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name); + res = -1; } + return res; } else { ast_log(LOG_NOTICE, "Transfer attempted with no bridged calls to transfer\n"); - if (p1->owner) - ast_softhangup_nolock(p1->owner, AST_SOFTHANGUP_DEV); - if (p2->owner) - ast_softhangup_nolock(p2->owner, AST_SOFTHANGUP_DEV); + if (chana) + ast_softhangup_nolock(chana, AST_SOFTHANGUP_DEV); + if (chanb) + ast_softhangup_nolock(chanb, AST_SOFTHANGUP_DEV); return -1; } return 0; diff --git a/res/res_features.c b/res/res_features.c index 273246ccc5771ce699e3eeae805270f9ae3c256e..bc10ca5a8d245f7ac83319430279919ef67a1c59 100755 --- a/res/res_features.c +++ b/res/res_features.c @@ -304,6 +304,12 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast int allowdisconnect_in,allowdisconnect_out,allowredirect_in,allowredirect_out; char *monitor_exec; + if (chan && peer) { + pbx_builtin_setvar_helper(chan, "BRIDGEPEER", peer->name); + pbx_builtin_setvar_helper(peer, "BRIDGEPEER", chan->name); + } else if (chan) + pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", NULL); + if (monitor_ok) { if (!monitor_app) { if (!(monitor_app = pbx_findapp("Monitor"))) @@ -482,6 +488,8 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast } /* XXX Maybe we should have another message here instead of invalid extension XXX */ } else if (ast_exists_extension(transferee, transferer_real_context, newext, 1, transferer->cid.cid_num)) { + pbx_builtin_setvar_helper(peer, "BLINDTRANSFER", chan->name); + pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", peer->name); ast_moh_stop(transferee); res=ast_autoservice_stop(transferee); if (!transferee->pbx) {