[asterisk-commits] jrose: branch 12 r403781 - in /branches/12: include/asterisk/ main/ res/parking/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Dec 13 14:04:43 CST 2013


Author: jrose
Date: Fri Dec 13 14:04:41 2013
New Revision: 403781

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=403781
Log:
Transfers: Make Asterisk set ATTENDEDTRANSFER/BLINDTRANSFER more reliably

There were still a few cases in which ATTENDEDTRANSFER and BLINDTRANSFER
wouldn't be set on channels involved with blind and attended transfers.
This would happen with features that were initialized by channel driver
specific mechanisms in multiparty calls. This patch resolves those cases
while attempted to keep the behavior for setting those variables as
consistent as possible.

(closes issue AFS-24)
Review: https://reviewboard.asterisk.org/r/3040/

Modified:
    branches/12/include/asterisk/bridge.h
    branches/12/main/bridge.c
    branches/12/main/bridge_basic.c
    branches/12/res/parking/parking_bridge_features.c
    branches/12/res/parking/parking_manager.c

Modified: branches/12/include/asterisk/bridge.h
URL: http://svnview.digium.com/svn/asterisk/branches/12/include/asterisk/bridge.h?view=diff&rev=403781&r1=403780&r2=403781
==============================================================================
--- branches/12/include/asterisk/bridge.h (original)
+++ branches/12/include/asterisk/bridge.h Fri Dec 13 14:04:41 2013
@@ -955,6 +955,19 @@
 		struct ast_channel *to_transfer_target);
 
 /*!
+ * \brief Set the relevant transfer variables for a single channel
+ *
+ * Sets either the ATTENDEDTRANSFER or BLINDTRANSFER variable for a channel while clearing
+ * the opposite.
+ *
+ * \param chan Channel the variable is being set for
+ * \param value Value the variable is being set to
+ * \param is_attended false  set BLINDTRANSFER and unset ATTENDEDTRANSFER
+ *                    true   set ATTENDEDTRANSFER and unset BLINDTRANSFER
+ */
+void ast_bridge_set_transfer_variables(struct ast_channel *chan, const char *value, int is_attended);
+
+/*!
  * \brief Get a container of all channels in the bridge
  * \since 12.0.0
  *

Modified: branches/12/main/bridge.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/main/bridge.c?view=diff&rev=403781&r1=403780&r2=403781
==============================================================================
--- branches/12/main/bridge.c (original)
+++ branches/12/main/bridge.c Fri Dec 13 14:04:41 2013
@@ -122,6 +122,12 @@
 /* Grow rate of bridge array of channels */
 #define BRIDGE_ARRAY_GROW 32
 
+/* Variable name - stores peer information about the most recent blind transfer */
+#define BLINDTRANSFER "BLINDTRANSFER"
+
+/* Variable name - stores peer information about the most recent attended transfer */
+#define ATTENDEDTRANSFER "ATTENDEDTRANSFER"
+
 static void cleanup_video_mode(struct ast_bridge *bridge);
 static int bridge_make_compatible(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel);
 
@@ -3688,6 +3694,8 @@
 		return AST_BRIDGE_TRANSFER_FAIL;
 	}
 
+	pbx_builtin_setvar_helper(local, BLINDTRANSFER, ast_channel_name(transferer));
+
 	if (new_channel_cb) {
 		new_channel_cb(local, user_data, AST_BRIDGE_TRANSFER_MULTI_PARTY);
 	}
@@ -3850,6 +3858,8 @@
 		return AST_BRIDGE_TRANSFER_FAIL;
 	}
 
+	pbx_builtin_setvar_helper(local_chan, ATTENDEDTRANSFER, ast_channel_name(chan1));
+
 	if (bridge2) {
 		res = ast_local_setup_bridge(local_chan, bridge2, chan2, NULL);
 	} else {
@@ -3945,19 +3955,38 @@
 	return AST_BRIDGE_TRANSFER_SUCCESS;
 }
 
-/*!
- * \internal
- * \brief Set the BLINDTRANSFER variable as appropriate on channels involved in the transfer
- *
- * The transferer channel will have its BLINDTRANSFER variable set the same as its BRIDGEPEER
+void ast_bridge_set_transfer_variables(struct ast_channel *chan, const char *value, int attended)
+{
+	char *writevar;
+	char *erasevar;
+
+	if (attended) {
+		writevar = ATTENDEDTRANSFER;
+		erasevar = BLINDTRANSFER;
+	} else {
+		writevar = BLINDTRANSFER;
+		erasevar = ATTENDEDTRANSFER;
+	}
+
+	pbx_builtin_setvar_helper(chan, writevar, value);
+	pbx_builtin_setvar_helper(chan, erasevar, value);
+}
+
+/*!
+ * \internal
+ * \brief Set the transfer variable as appropriate on channels involved in the transfer
+ *
+ * The transferer channel will have its variable set the same as its BRIDGEPEER
  * variable. This will account for all channels that it is bridged to. The other channels
- * involved in the transfer will have their BLINDTRANSFER variable set to the transferer
+ * involved in the transfer will have their variable set to the transferer
  * channel's name.
  *
- * \param transferer The channel performing the blind transfer
+ * \param transferer The channel performing the transfer
  * \param channels The channels belonging to the bridge
- */
-static void set_blind_transfer_variables(struct ast_channel *transferer, struct ao2_container *channels)
+ * \param is_attended false  set BLINDTRANSFER and unset ATTENDEDTRANSFER
+ *                    true   set ATTENDEDTRANSFER and unset BLINDTRANSFER
+ */
+static void set_transfer_variables_all(struct ast_channel *transferer, struct ao2_container *channels, int is_attended)
 {
 	struct ao2_iterator iter;
 	struct ast_channel *chan;
@@ -3973,9 +4002,9 @@
 			(chan = ao2_iterator_next(&iter));
 			ao2_cleanup(chan)) {
 		if (chan == transferer) {
-			pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", transferer_bridgepeer);
+			ast_bridge_set_transfer_variables(chan, transferer_bridgepeer, is_attended);
 		} else {
-			pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", transferer_name);
+			ast_bridge_set_transfer_variables(chan, transferer_name, is_attended);
 		}
 	}
 
@@ -4066,7 +4095,7 @@
 		goto publish;
 	}
 
-	set_blind_transfer_variables(transferer, channels);
+	set_transfer_variables_all(transferer, channels, 0);
 
 	if (do_bridge_transfer) {
 		transfer_result = blind_transfer_bridge(transferer, bridge, exten, context,
@@ -4167,6 +4196,16 @@
 	};
 	enum ast_transfer_result res;
 	struct ast_bridge *final_bridge = NULL;
+	RAII_VAR(struct ao2_container *, channels, NULL, ao2_cleanup);
+
+	channels = ast_bridge_peers_nolock(to_transferee_bridge);
+
+	if (!channels) {
+		res = AST_BRIDGE_TRANSFER_FAIL;
+		goto end;
+	}
+
+	set_transfer_variables_all(to_transferee, channels, 1);
 
 	switch (ast_bridges_allow_optimization(to_transferee_bridge, to_target_bridge)) {
 	case AST_BRIDGE_OPTIMIZE_SWAP_TO_CHAN_BRIDGE:
@@ -4338,6 +4377,8 @@
 		goto end;
 	}
 
+	set_transfer_variables_all(to_transferee, channels, 1);
+
 	if (do_bridge_transfer) {
 		 res = attended_transfer_bridge(chan_bridged, chan_unbridged, the_bridge, NULL, &publication);
 		 goto end;

Modified: branches/12/main/bridge_basic.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/main/bridge_basic.c?view=diff&rev=403781&r1=403780&r2=403781
==============================================================================
--- branches/12/main/bridge_basic.c (original)
+++ branches/12/main/bridge_basic.c Fri Dec 13 14:04:41 2013
@@ -2929,8 +2929,7 @@
 	/* Who is transferring the call. */
 	pbx_builtin_setvar_helper(chan, "TRANSFERERNAME", ast_channel_name(caller));
 
-	/* To work as an analog to BLINDTRANSFER */
-	pbx_builtin_setvar_helper(chan, "ATTENDEDTRANSFER", ast_channel_name(caller));
+	ast_bridge_set_transfer_variables(chan, ast_channel_name(caller), 1);
 
 	/* Before we actually dial out let's inherit appropriate information. */
 	copy_caller_data(chan, caller);

Modified: branches/12/res/parking/parking_bridge_features.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/parking/parking_bridge_features.c?view=diff&rev=403781&r1=403780&r2=403781
==============================================================================
--- branches/12/res/parking/parking_bridge_features.c (original)
+++ branches/12/res/parking/parking_bridge_features.c Fri Dec 13 14:04:41 2013
@@ -220,7 +220,7 @@
 	/* We need to have the parker subscribe to the new local channel before hand. */
 	create_parked_subscription(parker, ast_channel_uniqueid(parkee_side_2));
 
-	pbx_builtin_setvar_helper(parkee_side_2, "BLINDTRANSFER", ast_channel_name(parker));
+	ast_bridge_set_transfer_variables(parkee_side_2, ast_channel_name(parker), 0);
 
 	ast_channel_unref(parkee_side_2);
 
@@ -375,7 +375,7 @@
 		return -1;
 	}
 
-	pbx_builtin_setvar_helper(bridge_channel->chan, "BLINDTRANSFER", ast_channel_name(parker));
+	ast_bridge_set_transfer_variables(bridge_channel->chan, ast_channel_name(parker), 0);
 
 	/* bridge_channel must be locked so we can get a reference to the bridge it is currently on */
 	ao2_lock(bridge_channel);

Modified: branches/12/res/parking/parking_manager.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/parking/parking_manager.c?view=diff&rev=403781&r1=403780&r2=403781
==============================================================================
--- branches/12/res/parking/parking_manager.c (original)
+++ branches/12/res/parking/parking_manager.c Fri Dec 13 14:04:41 2013
@@ -453,7 +453,7 @@
 
 	ast_channel_lock(chan);
 	if (!ast_strlen_zero(timeout_channel)) {
-		pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", timeout_channel);
+		ast_bridge_set_transfer_variables(chan, timeout_channel, 0);
 	}
 	ast_channel_unlock(chan);
 




More information about the asterisk-commits mailing list