summaryrefslogtreecommitdiff
path: root/channels
diff options
context:
space:
mode:
authorMatthew Jordan <mjordan@digium.com>2014-02-14 12:41:13 +0000
committerMatthew Jordan <mjordan@digium.com>2014-02-14 12:41:13 +0000
commitf0019818629c546ecc59a76c680cef0619e4c68f (patch)
treee6f54a5b0ee95b9662645e6a1404d35f41891044 /channels
parent199c7de764d0d6b9acb3b6f3e990f8923c14ca02 (diff)
chnan_sip: Set SIP_DEFER_BYE_ON_TRANSFER prior to calling bridge blind transfer
This patch moves setting SIP_DEFER_BY_ON_TRANSFER prior to calling ast_bridge_transfer_blind. This prevents a BYE from being sent prior to the NOTIFY request that informs the transferor if the transfer succeeded or failed. This patch also clears said flag from the off nominal NOTIFY paths in the local_attended_transfer code, as once we've sent the NOTIFY request it is safe to send by the BYE request. This was caught by the blind-transfer-accountcode test in the Asterisk Test Suite. (closes issue ASTERISK-23290) Reported by: Matt Jordan Review: https://reviewboard.asterisk.org/r/3214/ ........ Merged revisions 408069 from http://svn.asterisk.org/svn/asterisk/branches/12 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@408070 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels')
-rw-r--r--channels/chan_sip.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index ab8ff17e3..a54437a53 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -25960,16 +25960,19 @@ static int local_attended_transfer(struct sip_pvt *transferer, struct ast_channe
transferer->refer->status = REFER_FAILED;
transmit_notify_with_sipfrag(transferer, seqno, "500 Internal Server Error", TRUE);
append_history(transferer, "Xfer", "Refer failed (internal error)");
+ ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER);
return -1;
case AST_BRIDGE_TRANSFER_INVALID:
transferer->refer->status = REFER_FAILED;
transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE);
append_history(transferer, "Xfer", "Refer failed (invalid bridge state)");
+ ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER);
return -1;
case AST_BRIDGE_TRANSFER_NOT_PERMITTED:
transferer->refer->status = REFER_FAILED;
transmit_notify_with_sipfrag(transferer, seqno, "403 Forbidden", TRUE);
append_history(transferer, "Xfer", "Refer failed (operation not permitted)");
+ ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER);
return -1;
default:
break;
@@ -26253,6 +26256,7 @@ static int handle_request_refer(struct sip_pvt *p, struct sip_request *req, uint
*nounlock = 1;
}
+ ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER);
sip_pvt_unlock(p);
transfer_res = ast_bridge_transfer_blind(1, transferer, refer_to, refer_to_context, blind_transfer_cb, &cb_data);
sip_pvt_lock(p);
@@ -26263,24 +26267,26 @@ static int handle_request_refer(struct sip_pvt *p, struct sip_request *req, uint
p->refer->status = REFER_FAILED;
transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE);
append_history(p, "Xfer", "Refer failed (only bridged calls).");
+ ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER);
break;
case AST_BRIDGE_TRANSFER_NOT_PERMITTED:
res = -1;
p->refer->status = REFER_FAILED;
transmit_notify_with_sipfrag(p, seqno, "403 Forbidden", TRUE);
append_history(p, "Xfer", "Refer failed (bridge does not permit transfers)");
+ ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER);
break;
case AST_BRIDGE_TRANSFER_FAIL:
res = -1;
p->refer->status = REFER_FAILED;
transmit_notify_with_sipfrag(p, seqno, "500 Internal Server Error", TRUE);
append_history(p, "Xfer", "Refer failed (internal error)");
+ ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER);
break;
case AST_BRIDGE_TRANSFER_SUCCESS:
res = 0;
p->refer->status = REFER_200OK;
transmit_notify_with_sipfrag(p, seqno, "200 OK", TRUE);
- ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER);
append_history(p, "Xfer", "Refer succeeded.");
break;
default: