[asterisk-commits] rmudgett: branch rmudgett/bridge_phase r381914 - in /team/rmudgett/bridge_pha...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Sat Feb 23 01:31:31 CST 2013
Author: rmudgett
Date: Sat Feb 23 01:31:27 2013
New Revision: 381914
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=381914
Log:
Add bridge merge inhibit options.
This is intended to prevent local channel optimization and attended
transfers from merging bridges in an inappropriate fashion or time.
Modified:
team/rmudgett/bridge_phase/apps/app_confbridge.c
team/rmudgett/bridge_phase/include/asterisk/bridging.h
team/rmudgett/bridge_phase/include/asterisk/bridging_features.h
team/rmudgett/bridge_phase/main/bridging.c
Modified: team/rmudgett/bridge_phase/apps/app_confbridge.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/bridge_phase/apps/app_confbridge.c?view=diff&rev=381914&r1=381913&r2=381914
==============================================================================
--- team/rmudgett/bridge_phase/apps/app_confbridge.c (original)
+++ team/rmudgett/bridge_phase/apps/app_confbridge.c Sat Feb 23 01:31:27 2013
@@ -1266,7 +1266,8 @@
conf_bridge_profile_copy(&conference_bridge->b_profile, &conference_bridge_user->b_profile);
/* Create an actual bridge that will do the audio mixing */
- if (!(conference_bridge->bridge = ast_bridge_new(AST_BRIDGE_CAPABILITY_MULTIMIX, 0))) {
+ if (!(conference_bridge->bridge = ast_bridge_new(AST_BRIDGE_CAPABILITY_MULTIMIX,
+ AST_BRIDGE_FLAG_MASQUERADE_ONLY))) {
ao2_ref(conference_bridge, -1);
conference_bridge = NULL;
ao2_unlock(conference_bridges);
Modified: team/rmudgett/bridge_phase/include/asterisk/bridging.h
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/bridge_phase/include/asterisk/bridging.h?view=diff&rev=381914&r1=381913&r2=381914
==============================================================================
--- team/rmudgett/bridge_phase/include/asterisk/bridging.h (original)
+++ team/rmudgett/bridge_phase/include/asterisk/bridging.h Sat Feb 23 01:31:27 2013
@@ -225,6 +225,13 @@
int num_channels;
/*! The video mode this bridge is using */
struct ast_bridge_video_mode video_mode;
+ /*!
+ * \brief Count of the active temporary requests to inhibit bridge merges.
+ * Zero if merges are allowed.
+ *
+ * \note Temporary as in try again in a moment.
+ */
+ unsigned int inhibit_merge;
/*! The internal sample rate this bridge is mixed at when multiple channels are being mixed.
* If this value is 0, the bridge technology may auto adjust the internal mixing rate. */
unsigned int internal_sample_rate;
@@ -509,6 +516,19 @@
int ast_bridge_merge(struct ast_bridge *bridge1, struct ast_bridge *bridge2);
/*!
+ * \brief Adjust the bridge merge inhibit request count.
+ * \since 12.0.0
+ *
+ * \param bridge What to operate on.
+ * \param request Inhibit request increment.
+ * (Positive to add requests. Negative to remove requests.)
+ *
+ * \return Nothing
+ */
+
+void ast_bridge_merge_inhibit(struct ast_bridge *bridge, int request);
+
+/*!
* \brief Suspend a channel temporarily from a bridge
*
* \param bridge Bridge to suspend the channel from
Modified: team/rmudgett/bridge_phase/include/asterisk/bridging_features.h
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/bridge_phase/include/asterisk/bridging_features.h?view=diff&rev=381914&r1=381913&r2=381914
==============================================================================
--- team/rmudgett/bridge_phase/include/asterisk/bridging_features.h (original)
+++ team/rmudgett/bridge_phase/include/asterisk/bridging_features.h Sat Feb 23 01:31:27 2013
@@ -36,6 +36,12 @@
AST_BRIDGE_FLAG_SMART = (1 << 1),
/*! This channel leaves the bridge if all participants have this flag set. */
AST_BRIDGE_FLAG_LONELY = (1 << 2),
+ /*! Bridge channels cannot be merged from this bridge. */
+ AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM = (1 << 3),
+ /*! Bridge channels cannot be merged to this bridge. */
+ AST_BRIDGE_FLAG_MERGE_INHIBIT_TO = (1 << 4),
+ /*! Bridge channels can be moved to another bridge only by masquerade (ConfBridge) */
+ AST_BRIDGE_FLAG_MASQUERADE_ONLY = (1 << 5),
};
/*! \brief Built in DTMF features */
Modified: team/rmudgett/bridge_phase/main/bridging.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/bridge_phase/main/bridging.c?view=diff&rev=381914&r1=381913&r2=381914
==============================================================================
--- team/rmudgett/bridge_phase/main/bridging.c (original)
+++ team/rmudgett/bridge_phase/main/bridging.c Sat Feb 23 01:31:27 2013
@@ -2296,9 +2296,50 @@
return 0;
}
+/*!
+ * \internal
+ * \brief Do the merge of two bridges.
+ * \since 12.0.0
+ *
+ * \param bridge1 First bridge
+ * \param bridge2 Second bridge
+ *
+ * \return Nothing
+ *
+ * \note The two bridges are assumed already locked.
+ *
+ * This merges the bridge pointed to by bridge2 into the bridge
+ * pointed to by bridge1. In reality all of the channels in
+ * bridge2 are moved to bridge1.
+ *
+ * \note The second bridge has no active channels in it when
+ * this operation is completed. The caller must explicitly call
+ * ast_bridge_destroy().
+ */
+static void ast_bridge_merge_do(struct ast_bridge *bridge1, struct ast_bridge *bridge2)
+{
+ struct ast_bridge_channel *bridge_channel;
+
+ ast_debug(1, "Merging channels from bridge %p into bridge %p\n", bridge2, bridge1);
+
+ /* Move channels from bridge2 over to bridge1 */
+ while ((bridge_channel = AST_LIST_FIRST(&bridge2->channels))) {
+ ast_bridge_channel_pull(bridge_channel);
+
+ /* Point to new bridge.*/
+ ao2_ref(bridge2, -1);
+ bridge_channel->bridge = bridge1;
+ ao2_ref(bridge1, +1);
+
+ ast_bridge_channel_push(bridge_channel);
+ }
+
+ ast_debug(1, "Merged channels from bridge %p into bridge %p\n", bridge2, bridge1);
+}
+
int ast_bridge_merge(struct ast_bridge *bridge1, struct ast_bridge *bridge2)
{
- struct ast_bridge_channel *bridge_channel;
+ int res = -1;
/* Deadlock avoidance. */
for (;;) {
@@ -2313,45 +2354,42 @@
if (bridge1->dissolved) {
ast_debug(1, "Can't merge bridge %p into bridge %p, destination bridge is dissolved.\n",
bridge2, bridge1);
- ao2_unlock(bridge2);
- ao2_unlock(bridge1);
- return -1;
- }
-
- /*
- * If the first bridge will have more than 2 channels and is not
- * capable of becoming a multimixing bridge we cannot merge.
- */
- if (2 < bridge1->num_channels + bridge2->num_channels
+ } else if (bridge1->inhibit_merge || bridge2->inhibit_merge
+ || ast_test_flag(&bridge1->feature_flags, AST_BRIDGE_FLAG_MASQUERADE_ONLY | AST_BRIDGE_FLAG_MERGE_INHIBIT_TO)
+ || ast_test_flag(&bridge2->feature_flags, AST_BRIDGE_FLAG_MASQUERADE_ONLY | AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM)) {
+ /* Merging is inhibited by either bridge. */
+ ast_debug(1, "Can't merge bridge %p into bridge %p, merging inhibited.\n",
+ bridge2, bridge1);
+ } else if (2 < bridge1->num_channels + bridge2->num_channels
&& !(bridge1->technology->capabilities & AST_BRIDGE_CAPABILITY_MULTIMIX)
&& !ast_test_flag(&bridge1->feature_flags, AST_BRIDGE_FLAG_SMART)) {
- ao2_unlock(bridge2);
- ao2_unlock(bridge1);
ast_debug(1, "Can't merge bridge %p into bridge %p, multimix is needed and it cannot be acquired.\n",
bridge2, bridge1);
- return -1;
- }
-
- ast_debug(1, "Merging channels from bridge %p into bridge %p\n", bridge2, bridge1);
-
- /* Move channels from bridge2 over to bridge1 */
- while ((bridge_channel = AST_LIST_FIRST(&bridge2->channels))) {
- ast_bridge_channel_pull(bridge_channel);
-
- /* Point to new bridge.*/
- ao2_ref(bridge2, -1);
- bridge_channel->bridge = bridge1;
- ao2_ref(bridge1, +1);
-
- ast_bridge_channel_push(bridge_channel);
- }
-
- ast_debug(1, "Merged channels from bridge %p into bridge %p\n", bridge2, bridge1);
+ } else {
+ ++bridge1->inhibit_merge;
+ ++bridge2->inhibit_merge;
+ ast_bridge_merge_do(bridge1, bridge2);
+ --bridge2->inhibit_merge;
+ --bridge1->inhibit_merge;
+ res = 0;
+ }
ao2_unlock(bridge2);
ao2_unlock(bridge1);
-
- return 0;
+ return res;
+}
+
+void ast_bridge_merge_inhibit(struct ast_bridge *bridge, int request)
+{
+ int new_request;
+
+ ao2_lock(bridge);
+ new_request = bridge->inhibit_merge + request;
+ if (new_request < 0) {
+ new_request = 0;
+ }
+ bridge->inhibit_merge = new_request;
+ ao2_unlock(bridge);
}
int ast_bridge_suspend(struct ast_bridge *bridge, struct ast_channel *chan)
More information about the asterisk-commits
mailing list