[asterisk-commits] mmichelson: branch mmichelson/more_transfer r388894 - /team/mmichelson/more_t...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed May 15 16:02:44 CDT 2013


Author: mmichelson
Date: Wed May 15 16:02:42 2013
New Revision: 388894

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=388894
Log:
Filling in the attended_transfer_bridge() function.


Modified:
    team/mmichelson/more_transfer/main/bridging.c

Modified: team/mmichelson/more_transfer/main/bridging.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/more_transfer/main/bridging.c?view=diff&rev=388894&r1=388893&r2=388894
==============================================================================
--- team/mmichelson/more_transfer/main/bridging.c (original)
+++ team/mmichelson/more_transfer/main/bridging.c Wed May 15 16:02:42 2013
@@ -59,6 +59,7 @@
 #include "asterisk/features.h"
 #include "asterisk/cli.h"
 #include "asterisk/parking.h"
+#include "asterisk/core_local.h"
 
 /*! All bridges container. */
 static struct ao2_container *bridges;
@@ -4869,22 +4870,55 @@
 	return AST_BRIDGE_TRANSFER_SUCCESS;
 }
 
-static enum ast_transfer_result attended_transfer_bridge(struct ast_channel *chan_bridged,
-		struct ast_channel *chan_unbridged, struct ast_bridge *bridge)
-{
-	/* This needs to do the following:
-	 * 1) Create a local channel
-	 * 2) Masquerade the local ;2 channel into the chan_unbridged channel
-	 * 3) Add the local ;1 channel to the bridge (swapping the chan_bridged out).
-	 *
-	 * The problem is that we've got a bit of a dicey situation with the local
-	 * channel for now. When we request a local channel, all we have is the ;1 channel.
-	 * We don't have the ability to masquerade the ;2 side the way we'd like. For now
-	 * this function is a stub;
-	 */
-
-/* BUGBUG This needs unreal channel support */
-	return AST_BRIDGE_TRANSFER_INVALID;
+/*!
+ * \brief Perform an attended transfer of a bridge
+ *
+ * This performs an attended transfer of an entire bridge to a target.
+ * The target varies, depending on what bridges exist during the transfer
+ * attempt.
+ *
+ * If two bridges exist, then a local channel is created to link the two
+ * bridges together. Local channel optimization may result in the bridges
+ * merging.
+ *
+ * If only one bridge exists, then a local channel is created with one end
+ * placed into the existing bridge and the other end masquerading into
+ * the unbridged channel.
+ *
+ * \param chan1 Transferer channel. Guaranteed to be bridged.
+ * \param chan2 Other transferer channel. May or may not be bridged.
+ * \param bridge1 Bridge that chan1 is in. Guaranteed to be non-NULL.
+ * \param bridge2 Bridge that chan2 is in. If NULL, then chan2 is not bridged.
+ * \retval AST_BRIDGE_TRANSFER_FAIL Internal error occurred
+ * \retval AST_BRIDGE_TRANSFER_SUCCESS Succesfully transferred the bridge
+ */
+static enum ast_transfer_result attended_transfer_bridge(struct ast_channel *chan1,
+		struct ast_channel *chan2, struct ast_bridge *bridge1, struct ast_bridge *bridge2)
+{
+	struct ast_channel *local_chan;
+	int cause;
+
+	local_chan = ast_request("Local", ast_channel_nativeformats(chan1), chan1,
+			"BridgeAttendedTransfer", &cause);
+
+	if (!local_chan) {
+		return AST_BRIDGE_TRANSFER_FAIL;
+	}
+
+	if (bridge2) {
+		ast_local_setup_bridge(local_chan, bridge2, chan2, NULL);
+	} else {
+		ast_local_setup_masquerade(local_chan, chan2);
+	}
+
+	ast_call(local_chan, "BridgeAttendedTransfer", 0);
+
+	if (ast_bridge_impart(bridge1, local_chan, chan1, NULL, 1)) {
+		ast_hangup(local_chan);
+		return AST_BRIDGE_TRANSFER_FAIL;
+	}
+
+	return AST_BRIDGE_TRANSFER_SUCCESS;
 }
 
 /*!
@@ -5162,13 +5196,8 @@
 
 	/* Let's get the easy one out of the way first */
 	if (to_transferee_bridge && to_target_bridge) {
-		/* This needs to do the following:
-		 * 1) Create a local channel
-		 * 2) Impart the local ;1 channel to to_transferee_bridge, swapping out to_transferee
-		 * 3) Impart the local ;2 channel to to_target_bridge, swapping out to_target
-		 */
-/* BUGBUG This needs unreal channel support */
-		return AST_BRIDGE_TRANSFER_INVALID;
+		return attended_transfer_bridge(to_transferee, to_transfer_target,
+				to_transferee_bridge, to_target_bridge);
 	}
 
 	the_bridge = to_transferee_bridge ?: to_target_bridge;
@@ -5199,7 +5228,7 @@
 	}
 
 	if (do_bridge_transfer) {
-		return attended_transfer_bridge(chan_bridged, chan_unbridged, the_bridge);
+		return attended_transfer_bridge(chan_bridged, chan_unbridged, the_bridge, NULL);
 	}
 
 	transferee = get_transferee(channels, chan_bridged);




More information about the asterisk-commits mailing list