From f0019818629c546ecc59a76c680cef0619e4c68f Mon Sep 17 00:00:00 2001 From: Matthew Jordan Date: Fri, 14 Feb 2014 12:41:13 +0000 Subject: 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 --- channels/chan_sip.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'channels') 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: -- cgit v1.2.3