[Asterisk-code-review] res pjsip refer/chan sip: Fix INVITE with replaces transfer ... (asterisk[13])

Jenkins2 asteriskteam at digium.com
Wed Apr 11 07:03:21 CDT 2018


Jenkins2 has submitted this change and it was merged. ( https://gerrit.asterisk.org/8737 )

Change subject: res_pjsip_refer/chan_sip: Fix INVITE with replaces transfer to ConfBridge
......................................................................

res_pjsip_refer/chan_sip: Fix INVITE with replaces transfer to ConfBridge

There is a problem when an INVITE-with-Replaces transfer targets a channel
in a ConfBridge.  The transfer will unconditionally swap out the
ConfBridge channel.  Unfortunately, the ConfBridge state will not be aware
of this change.  Unexpected behavior will happen as a result since
ConfBridge channels currently can only be replaced by a masquerade and not
normal bridge channel moves.

* We just need to pretend that the channel isn't in a bridge (like other
transfer methods already do) so the transfer channel will masquerade into
the ConfBridge channel.

Change-Id: I209beb0e748fa4f4b92a576f36afa8f495ba4c82
---
M channels/chan_sip.c
M include/asterisk/bridge.h
M main/bridge.c
M res/res_pjsip_refer.c
4 files changed, 17 insertions(+), 12 deletions(-)

Approvals:
  George Joseph: Looks good to me, but someone else must approve
  Joshua Colp: Looks good to me, approved
  Jenkins2: Approved for Submit



diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 74a978c..b096c33 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -25670,10 +25670,7 @@
 
 	ast_raw_answer(c);
 
-	ast_channel_lock(replaces_chan);
-	bridge = ast_channel_get_bridge(replaces_chan);
-	ast_channel_unlock(replaces_chan);
-
+	bridge = ast_bridge_transfer_acquire_bridge(replaces_chan);
 	if (bridge) {
 		if (ast_bridge_impart(bridge, c, replaces_chan, NULL,
 			AST_BRIDGE_IMPART_CHAN_INDEPENDENT)) {
diff --git a/include/asterisk/bridge.h b/include/asterisk/bridge.h
index 0d43767..e7f9ca6 100644
--- a/include/asterisk/bridge.h
+++ b/include/asterisk/bridge.h
@@ -912,6 +912,17 @@
  */
 const char *ast_bridge_video_mode_to_string(enum ast_bridge_video_mode_type video_mode);
 
+/*!
+ * \brief Acquire the channel's bridge for transfer purposes.
+ * \since 13.21.0
+ *
+ * \param chan Channel involved in a transfer.
+ *
+ * \return The bridge the channel is in or NULL if it either isn't
+ * in a bridge or should not be considered to be in a bridge.
+ */
+struct ast_bridge *ast_bridge_transfer_acquire_bridge(struct ast_channel *chan);
+
 enum ast_transfer_result {
 	/*! The transfer completed successfully */
 	AST_BRIDGE_TRANSFER_SUCCESS,
diff --git a/main/bridge.c b/main/bridge.c
index 2da1d0c..0f3cfb1 100644
--- a/main/bridge.c
+++ b/main/bridge.c
@@ -4355,7 +4355,7 @@
 	ao2_iterator_destroy(&iter);
 }
 
-static struct ast_bridge *acquire_bridge(struct ast_channel *chan)
+struct ast_bridge *ast_bridge_transfer_acquire_bridge(struct ast_channel *chan)
 {
 	struct ast_bridge *bridge;
 
@@ -4396,7 +4396,7 @@
 		return AST_BRIDGE_TRANSFER_FAIL;
 	}
 
-	bridge = acquire_bridge(transferer);
+	bridge = ast_bridge_transfer_acquire_bridge(transferer);
 	if (!bridge) {
 		transfer_result = AST_BRIDGE_TRANSFER_INVALID;
 		goto publish;
@@ -4643,8 +4643,8 @@
 	const char *app = NULL;
 	int hangup_target = 0;
 
-	to_transferee_bridge = acquire_bridge(to_transferee);
-	to_target_bridge = acquire_bridge(to_transfer_target);
+	to_transferee_bridge = ast_bridge_transfer_acquire_bridge(to_transferee);
+	to_target_bridge = ast_bridge_transfer_acquire_bridge(to_transfer_target);
 
 	transfer_msg = ast_attended_transfer_message_create(1, to_transferee, to_transferee_bridge,
 			to_transfer_target, to_target_bridge, NULL, NULL);
diff --git a/res/res_pjsip_refer.c b/res/res_pjsip_refer.c
index 964c231..46beb1c 100644
--- a/res/res_pjsip_refer.c
+++ b/res/res_pjsip_refer.c
@@ -917,10 +917,7 @@
 	ast_channel_ref(invite->session->channel);
 	invite->channel = invite->session->channel;
 
-	ast_channel_lock(invite->channel);
-	invite->bridge = ast_channel_get_bridge(invite->channel);
-	ast_channel_unlock(invite->channel);
-
+	invite->bridge = ast_bridge_transfer_acquire_bridge(invite->channel);
 	return 0;
 }
 

-- 
To view, visit https://gerrit.asterisk.org/8737
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-Project: asterisk
Gerrit-Branch: 13
Gerrit-MessageType: merged
Gerrit-Change-Id: I209beb0e748fa4f4b92a576f36afa8f495ba4c82
Gerrit-Change-Number: 8737
Gerrit-PatchSet: 1
Gerrit-Owner: Richard Mudgett <rmudgett at digium.com>
Gerrit-Reviewer: George Joseph <gjoseph at digium.com>
Gerrit-Reviewer: Jenkins2
Gerrit-Reviewer: Joshua Colp <jcolp at digium.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20180411/a6b5d5e9/attachment-0001.html>


More information about the asterisk-code-review mailing list