aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>2004-10-27 22:01:33 +0000
committermarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>2004-10-27 22:01:33 +0000
commitcbd442675dd984833231770b44f862c7740d5179 (patch)
tree7682421eb154b7d6a817e29f15b35c25f1190d6b
parent15f87a90769e07a89f558e5ae43cc48675457202 (diff)
Transfer improvements and fixes (bug #2741)
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@4113 f38db490-d61c-443f-a65b-d21fe96a405b
-rwxr-xr-xchannels/chan_sip.c92
-rwxr-xr-xres/res_features.c8
2 files changed, 65 insertions, 35 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 2181c6d87..9fe9eb5e8 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 273246ccc..bc10ca5a8 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) {