[svn-commits] mmichelson: branch mmichelson/atxfer_features r392770 - /team/mmichelson/atxf...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Mon Jun 24 15:34:49 CDT 2013


Author: mmichelson
Date: Mon Jun 24 15:34:47 2013
New Revision: 392770

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=392770
Log:
Switch move and merge operations for attended transfers.

The bridges involved in an attended transfer have merges inhibited,
which would make ast_bridge_merge() and ast_bridge_move() fail to
work. Instead, I need to go the direct approach and perform the
moves/merges with the private functions that do no integrity checking
of the bridges.


Modified:
    team/mmichelson/atxfer_features/main/bridging_basic.c

Modified: team/mmichelson/atxfer_features/main/bridging_basic.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/atxfer_features/main/bridging_basic.c?view=diff&rev=392770&r1=392769&r2=392770
==============================================================================
--- team/mmichelson/atxfer_features/main/bridging_basic.c (original)
+++ team/mmichelson/atxfer_features/main/bridging_basic.c Mon Jun 24 15:34:47 2013
@@ -41,6 +41,7 @@
 #include "asterisk/pbx.h"
 #include "asterisk/file.h"
 #include "asterisk/app.h"
+#include "asterisk/bridging_private.h"
 
 #define NORMAL_FLAGS	AST_BRIDGE_FLAG_DISSOLVE_HANGUP | AST_BRIDGE_FLAG_DISSOLVE_EMPTY \
 			| AST_BRIDGE_FLAG_SMART
@@ -436,6 +437,47 @@
 	ast_bridge_channel_write_unhold(bridge_channel);
 }
 
+static int bridge_move(struct ast_bridge *dest, struct ast_bridge *src, struct ast_channel *channel, struct ast_channel *swap)
+{
+	int res;
+	struct ast_bridge_channel *bridge_channel;
+	SCOPED_LOCK(lock, dest, ast_bridge_lock, ast_bridge_unlock);
+
+	ast_channel_lock(channel);
+	bridge_channel = ast_channel_get_bridge_channel(channel);
+	ast_channel_unlock(channel);
+
+	ast_assert(bridge_channel != NULL);
+
+	ao2_lock(bridge_channel);
+	bridge_channel->swap = swap;
+	res = bridge_move_do(dest, bridge_channel, 1);
+	ao2_unlock(bridge_channel);
+
+	return res;
+}
+
+static void bridge_merge(struct ast_bridge *dest, struct ast_bridge *src, struct ast_channel **kick_me, unsigned int num_kick)
+{
+	struct ast_bridge_channel **kick_bridge_channels = NULL;
+	int i;
+
+	ast_bridge_lock_both(dest, src);
+
+	if (num_kick) {
+		kick_bridge_channels = ast_alloca(num_kick * sizeof(*kick_bridge_channels));
+		for (i = 0; i < num_kick; ++i) {
+			ast_channel_lock(kick_me[i]);
+			kick_bridge_channels[i] = ast_channel_get_bridge_channel(kick_me[i]);
+			ast_channel_unlock(kick_me[i]);
+		}
+	}
+
+	bridge_merge_do(dest, src, kick_bridge_channels, num_kick);
+	ast_bridge_unlock(dest);
+	ast_bridge_unlock(src);
+}
+
 /*!
  * \brief enter callback for TRANSFER_CALLING_TARGET state
  *
@@ -444,7 +486,7 @@
  */
 static int calling_target_enter(struct attended_transfer_properties *props)
 {
-	return ast_bridge_move(props->target_bridge, props->transferee_bridge, props->transferer, NULL, 1);
+	return bridge_move(props->target_bridge, props->transferee_bridge, props->transferer, NULL);
 }
 
 static enum attended_transfer_state calling_target_next(struct attended_transfer_properties *props,
@@ -480,7 +522,7 @@
 
 static int hesitant_enter(struct attended_transfer_properties *props)
 {
-	if (ast_bridge_move(props->transferee_bridge, props->target_bridge, props->transferer, NULL, 1)) {
+	if (bridge_move(props->transferee_bridge, props->target_bridge, props->transferer, NULL)) {
 		return -1;
 	}
 
@@ -517,8 +559,8 @@
 
 static int rebridge_enter(struct attended_transfer_properties *props)
 {
-	if (ast_bridge_move(props->transferee_bridge, props->target_bridge,
-			props->transferer, NULL, 1)) {
+	if (bridge_move(props->transferee_bridge, props->target_bridge,
+			props->transferer, NULL)) {
 		return -1;
 	}
 
@@ -534,9 +576,7 @@
 
 static int threeway_enter(struct attended_transfer_properties *props)
 {
-	if (ast_bridge_merge(props->transferee_bridge, props->target_bridge, 0, NULL, 0)) {
-		return -1;
-	}
+	bridge_merge(props->transferee_bridge, props->target_bridge, NULL, 0);
 
 	/* XXX After the bridge merge, the transferee_bridge will be a softmix
 	 * bridge. If one of the involved bridges was a simple bridge and the
@@ -561,7 +601,7 @@
 		return 0;
 	}
 
-	if (ast_bridge_move(props->target_bridge, props->transferee_bridge, props->transferer, NULL, 1)) {
+	if (bridge_move(props->target_bridge, props->transferee_bridge, props->transferer, NULL)) {
 		return -1;
 	}
 	unhold(props->transferer);
@@ -608,7 +648,7 @@
 	if (transferer_bridge == props->transferee_bridge) {
 		return 0;
 	}
-	if (ast_bridge_move(props->transferee_bridge, props->target_bridge, props->transferer, NULL, 1)) {
+	if (bridge_move(props->transferee_bridge, props->target_bridge, props->transferer, NULL)) {
 		return -1;
 	}
 	unhold(props->transferer);
@@ -643,16 +683,10 @@
 
 static int complete_enter(struct attended_transfer_properties *props)
 {
-	int res;
-
 	if (props->transferer) {
-		res = ast_bridge_merge(props->transferee_bridge, props->target_bridge, 0, &props->transferer, 1);
+		bridge_merge(props->transferee_bridge, props->target_bridge, &props->transferer, 1);
 	} else {
-		res = ast_bridge_merge(props->transferee_bridge, props->target_bridge, 0, NULL, 0);
-	}
-
-	if (res) {
-		return -1;
+		bridge_merge(props->transferee_bridge, props->target_bridge, NULL, 0);
 	}
 
 	/* XXX Same unhold concern here as in the threeway state. However, there




More information about the svn-commits mailing list