[asterisk-commits] mmichelson: branch mmichelson/more_transfer r389565 - in /team/mmichelson/mor...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Thu May 23 13:07:01 CDT 2013
Author: mmichelson
Date: Thu May 23 13:06:57 2013
New Revision: 389565
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=389565
Log:
Latest findings blah blah blah
Modified:
team/mmichelson/more_transfer/include/asterisk/bridging.h
team/mmichelson/more_transfer/main/bridging.c
Modified: team/mmichelson/more_transfer/include/asterisk/bridging.h
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/more_transfer/include/asterisk/bridging.h?view=diff&rev=389565&r1=389564&r2=389565
==============================================================================
--- team/mmichelson/more_transfer/include/asterisk/bridging.h (original)
+++ team/mmichelson/more_transfer/include/asterisk/bridging.h Thu May 23 13:06:57 2013
@@ -902,6 +902,7 @@
*
* \param chan_bridge First bridge being tested
* \param peer_bridge Second bridge being tested
+ * \param unreal_in_bridges True if unreal channels to be optimzed out are already in the bridges
*
* This determines if two bridges allow for unreal channel optimization
* to occur between them. The function does not require for unreal channels
@@ -917,7 +918,7 @@
* \returns Optimization allowability for the bridges
*/
enum ast_bridge_optimization ast_bridges_allow_optimization(struct ast_bridge *chan_bridge,
- struct ast_bridge *peer_bridge);
+ struct ast_bridge *peer_bridge, int unreal_in_bridges);
/*!
* \brief Try locking the bridge_channel.
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=389565&r1=389564&r2=389565
==============================================================================
--- team/mmichelson/more_transfer/main/bridging.c (original)
+++ team/mmichelson/more_transfer/main/bridging.c Thu May 23 13:06:57 2013
@@ -3874,7 +3874,7 @@
* \brief Indicates allowability of a swap optimization
*/
enum bridge_allow_swap {
- /*! Bridges cannot allow for a swap optimization to occure */
+ /*! Bridges cannot allow for a swap optimization to occur */
SWAP_PROHIBITED,
/*! Bridge swap optimization can occur into the chan_bridge */
SWAP_TO_CHAN_BRIDGE,
@@ -3897,9 +3897,11 @@
int peer_priority;
if (!ast_test_flag(&chan_bridge->feature_flags,
- AST_BRIDGE_FLAG_SWAP_INHIBIT_TO | AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM)
+ AST_BRIDGE_FLAG_SWAP_INHIBIT_TO | AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM |
+ AST_BRIDGE_FLAG_TRANSFER_BRIDGE_ONLY)
&& !ast_test_flag(&peer_bridge->feature_flags,
- AST_BRIDGE_FLAG_SWAP_INHIBIT_TO | AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM)) {
+ AST_BRIDGE_FLAG_SWAP_INHIBIT_TO | AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM |
+ AST_BRIDGE_FLAG_TRANSFER_BRIDGE_ONLY)) {
/*
* Can swap either way. Swap to the higher priority merge
* bridge.
@@ -4121,7 +4123,7 @@
}
enum ast_bridge_optimization ast_bridges_allow_optimization(struct ast_bridge *chan_bridge,
- struct ast_bridge *peer_bridge)
+ struct ast_bridge *peer_bridge, int unreal_in_bridges)
{
struct merge_direction merge;
@@ -4139,7 +4141,7 @@
break;
}
- if (bridges_allow_merge_optimization(chan_bridge, peer_bridge, 2, &merge) != MERGE_ALLOWED) {
+ if (bridges_allow_merge_optimization(chan_bridge, peer_bridge, unreal_in_bridges ? 2 : 0, &merge) != MERGE_ALLOWED) {
return AST_BRIDGE_OPTIMIZE_PROHIBITED;
}
@@ -5467,11 +5469,18 @@
static struct ast_bridge *acquire_bridge(struct ast_channel *chan)
{
struct ast_bridge *bridge;
+ int bridge_invalid_for_transfer;
ast_channel_lock(chan);
bridge = ast_channel_get_bridge(chan);
ast_channel_unlock(chan);
- if (ast_test_flag(&bridge->feature_flags, AST_BRIDGE_FLAG_MASQUERADE_ONLY)) {
+
+ ast_bridge_lock(bridge);
+ bridge_invalid_for_transfer = ast_test_flag(&bridge->feature_flags, AST_BRIDGE_FLAG_MASQUERADE_ONLY) ||
+ ast_test_flag(&bridge->feature_flags, AST_BRIDGE_FLAG_TRANSFER_PROHIBITED);
+ ast_bridge_unlock(bridge);
+
+ if (bridge_invalid_for_transfer) {
ao2_ref(bridge, -1);
bridge = NULL;
}
@@ -5484,25 +5493,24 @@
* \brief Performs an attended transfer by moving a channel from one bridge to another
*
* The channel that is bridged to the source_channel is moved into the dest_bridge from
- * the source_bridge. The swap_channel is swapped out of the dest_bridge and placed in
- * the source_bridge.
- *
- * \note dest_bridge and source_bridge MUST be locked before calling this function.
+ * the source_bridge_channel's bridge. The swap_channel is swapped out of the dest_bridge and placed in
+ * the source_bridge_channel's bridge.
+ *
+ * \note dest_bridge and source_bridge_channel's bridge MUST be locked before calling this function.
*
* \param dest_bridge The final bridge for the attended transfer
- * \param source_bridge The bridge from which a channel is moved
* \param source_channel Channel who is bridged to the channel that will move
* \param swap_channel Channel to be swapped out of the dest_bridge
* \return The success or failure of the swap attempt
*/
static enum ast_transfer_result bridge_swap_attended_transfer(struct ast_bridge *dest_bridge,
- struct ast_bridge *source_bridge, struct ast_bridge_channel *source_bridge_channel,
- struct ast_channel *swap_channel)
+ struct ast_bridge_channel *source_bridge_channel, struct ast_channel *swap_channel)
{
struct ast_bridge_channel *bridged_to_source;
bridged_to_source = ast_bridge_channel_peer(source_bridge_channel);
- if (bridged_to_source && bridged_to_source->state == AST_BRIDGE_CHANNEL_STATE_WAIT) {
+ if (bridged_to_source && bridged_to_source->state == AST_BRIDGE_CHANNEL_STATE_WAIT
+ && !ast_test_flag(&bridged_to_source->features->feature_flags, AST_BRIDGE_CHANNEL_FLAG_IMMOVABLE)) {
bridged_to_source->swap = swap_channel;
return bridge_move_do(dest_bridge, bridged_to_source, 1) ?
AST_BRIDGE_TRANSFER_FAIL : AST_BRIDGE_TRANSFER_SUCCESS;
@@ -5541,11 +5549,11 @@
to_target_bridge_channel,
};
- switch (ast_bridges_allow_optimization(to_transferee_bridge, to_target_bridge)) {
+ switch (ast_bridges_allow_optimization(to_transferee_bridge, to_target_bridge, 0)) {
case AST_BRIDGE_OPTIMIZE_SWAP_TO_CHAN_BRIDGE:
- return bridge_swap_attended_transfer(to_transferee_bridge, to_target_bridge, to_target_bridge_channel, to_transferee);
+ return bridge_swap_attended_transfer(to_transferee_bridge, to_target_bridge_channel, to_transferee);
case AST_BRIDGE_OPTIMIZE_SWAP_TO_PEER_BRIDGE:
- return bridge_swap_attended_transfer(to_target_bridge, to_transferee_bridge, to_transferee_bridge_channel, to_transfer_target);
+ return bridge_swap_attended_transfer(to_target_bridge, to_transferee_bridge_channel, to_transfer_target);
case AST_BRIDGE_OPTIMIZE_MERGE_TO_CHAN_BRIDGE:
bridge_merge_do(to_transferee_bridge, to_target_bridge, kick_me, ARRAY_LEN(kick_me));
return AST_BRIDGE_TRANSFER_SUCCESS;
@@ -5554,6 +5562,14 @@
return AST_BRIDGE_TRANSFER_SUCCESS;
case AST_BRIDGE_OPTIMIZE_PROHIBITED:
default:
+ /* Just because optimization wasn't doable doesn't necessarily mean
+ * that we can actually perform the transfer. Some reasons for non-optimization
+ * indicate bridge invalidity, so let's check those before proceeding.
+ */
+ if (to_transferee_bridge->inhibit_merge || to_transferee_bridge->dissolved ||
+ to_target_bridge->inhibit_merge || to_target_bridge->dissolved) {
+ return AST_BRIDGE_TRANSFER_INVALID;
+ }
return attended_transfer_bridge(to_transferee, to_transfer_target,
to_transferee_bridge, to_target_bridge);
}
More information about the asterisk-commits
mailing list