[asterisk-commits] mmichelson: branch mmichelson/atxfer_features r392770 - /team/mmichelson/atxf...
SVN commits to the Asterisk project
asterisk-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 asterisk-commits
mailing list