Author: jrose
Date: Fri Aug  9 12:22:28 2013
New Revision: 396497

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=396497
Log:
bridge_channel: Support the lonely flag and make ARI use it.

The lonely flag is an optional flag for bridge channels that will
make them leave a bridge when a channel leaves if only lonely
channels are in the bridge at that point. This is useful for things
like ending recording and playback channels when they cease to be
interacting with other channels in the bridge.

(closes issue ASTERISK-22117)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2721/

Modified:
    trunk/include/asterisk/bridge.h
    trunk/include/asterisk/core_unreal.h
    trunk/main/bridge_channel.c
    trunk/main/core_unreal.c
    trunk/res/ari/resource_bridges.c

Modified: trunk/include/asterisk/bridge.h
URL: 
http://svnview.digium.com/svn/asterisk/trunk/include/asterisk/bridge.h?view=diff&rev=396497&r1=396496&r2=396497
==============================================================================
--- trunk/include/asterisk/bridge.h (original)
+++ trunk/include/asterisk/bridge.h Fri Aug  9 12:22:28 2013
@@ -295,6 +295,8 @@
        unsigned int num_channels;
        /*! Number of active channels in the bridge. */
        unsigned int num_active;
+       /*! Number of channels with AST_BRIDGE_CHANNEL_FLAG_LONELY in the 
bridge. */
+       unsigned int num_lonely;
        /*!
         * \brief Count of the active temporary requests to inhibit bridge 
merges.
         * Zero if merges are allowed.

Modified: trunk/include/asterisk/core_unreal.h
URL: 
http://svnview.digium.com/svn/asterisk/trunk/include/asterisk/core_unreal.h?view=diff&rev=396497&r1=396496&r2=396497
==============================================================================
--- trunk/include/asterisk/core_unreal.h (original)
+++ trunk/include/asterisk/core_unreal.h Fri Aug  9 12:22:28 2013
@@ -215,13 +215,14 @@
  *
  * \param ast A member of the unreal channel being pushed
  * \param bridge Which bridge we want to push the channel to
+ * \param flags Feature flags to be set on the bridge channel.
  *
  * \retval 0 if the channel is successfully imparted onto the bridge
  * \retval -1 on failure
  *
  * \note This is equivalent to ast_call() on unreal based channel drivers that 
are designed to use it instead.
  */
-int ast_unreal_channel_push_to_bridge(struct ast_channel *ast, struct 
ast_bridge *bridge);
+int ast_unreal_channel_push_to_bridge(struct ast_channel *ast, struct 
ast_bridge *bridge, unsigned int flags);
 
 /* ------------------------------------------------------------------- */
 

Modified: trunk/main/bridge_channel.c
URL: 
http://svnview.digium.com/svn/asterisk/trunk/main/bridge_channel.c?view=diff&rev=396497&r1=396496&r2=396497
==============================================================================
--- trunk/main/bridge_channel.c (original)
+++ trunk/main/bridge_channel.c Fri Aug  9 12:22:28 2013
@@ -1324,7 +1324,12 @@
        default:
                break;
        }
-/* BUGBUG need to implement AST_BRIDGE_CHANNEL_FLAG_LONELY support here */
+
+       if (bridge->num_lonely && bridge->num_lonely == bridge->num_channels) {
+               /* This will start a chain reaction where each channel leaving 
enters this function and causes
+                * the next to leave as long as there aren't non-lonely 
channels in the bridge. */
+               
ast_bridge_channel_leave_bridge(AST_LIST_FIRST(&bridge->channels), 
BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE);
+       }
 }
 
 void bridge_channel_internal_pull(struct ast_bridge_channel *bridge_channel)
@@ -1360,6 +1365,9 @@
        /* Remove channel from the bridge */
        if (!bridge_channel->suspended) {
                --bridge->num_active;
+       }
+       if (ast_test_flag(&bridge_channel->features->feature_flags, 
AST_BRIDGE_CHANNEL_FLAG_LONELY)) {
+               --bridge->num_lonely;
        }
        --bridge->num_channels;
        AST_LIST_REMOVE(&bridge->channels, bridge_channel, entry);
@@ -1416,6 +1424,9 @@
        bridge_channel->just_joined = 1;
        AST_LIST_INSERT_TAIL(&bridge->channels, bridge_channel, entry);
        ++bridge->num_channels;
+       if (ast_test_flag(&bridge_channel->features->feature_flags, 
AST_BRIDGE_CHANNEL_FLAG_LONELY)) {
+               ++bridge->num_lonely;
+       }
        if (!bridge_channel->suspended) {
                ++bridge->num_active;
        }

Modified: trunk/main/core_unreal.c
URL: 
http://svnview.digium.com/svn/asterisk/trunk/main/core_unreal.c?view=diff&rev=396497&r1=396496&r2=396497
==============================================================================
--- trunk/main/core_unreal.c (original)
+++ trunk/main/core_unreal.c Fri Aug  9 12:22:28 2013
@@ -668,7 +668,7 @@
        ast_channel_datastore_inherit(semi1, semi2);
 }
 
-int ast_unreal_channel_push_to_bridge(struct ast_channel *ast, struct 
ast_bridge *bridge)
+int ast_unreal_channel_push_to_bridge(struct ast_channel *ast, struct 
ast_bridge *bridge, unsigned int flags)
 {
        struct ast_bridge_features *features;
        struct ast_channel *chan;
@@ -741,7 +741,8 @@
                ast_channel_unref(chan);
                return -1;
        }
-       ast_set_flag(&features->feature_flags, 
AST_BRIDGE_CHANNEL_FLAG_IMMOVABLE);
+
+       ast_set_flag(&features->feature_flags, flags);
 
        /* Impart the semi2 channel into the bridge */
        if (ast_bridge_impart(bridge, chan, NULL, features, 1)) {

Modified: trunk/res/ari/resource_bridges.c
URL: 
http://svnview.digium.com/svn/asterisk/trunk/res/ari/resource_bridges.c?view=diff&rev=396497&r1=396496&r2=396497
==============================================================================
--- trunk/res/ari/resource_bridges.c (original)
+++ trunk/res/ari/resource_bridges.c Fri Aug  9 12:22:28 2013
@@ -300,7 +300,8 @@
        }
        ast_debug(1, "Created announcer channel '%s'\n", 
ast_channel_name(play_channel));
 
-       if (ast_unreal_channel_push_to_bridge(play_channel, bridge)) {
+       if (ast_unreal_channel_push_to_bridge(play_channel, bridge,
+               AST_BRIDGE_CHANNEL_FLAG_IMMOVABLE | 
AST_BRIDGE_CHANNEL_FLAG_LONELY)) {
                ast_ari_response_error(
                        response, 500, "Internal Error", "Failed to put 
playback channel into the bridge");
                return;
@@ -394,7 +395,8 @@
                return;
        }
 
-       if (ast_unreal_channel_push_to_bridge(record_channel, bridge)) {
+       if (ast_unreal_channel_push_to_bridge(record_channel, bridge,
+               AST_BRIDGE_CHANNEL_FLAG_IMMOVABLE | 
AST_BRIDGE_CHANNEL_FLAG_LONELY)) {
                ast_ari_response_error(
                        response, 500, "Internal Error", "Failed to put 
recording channel into the bridge");
                return;


--
_____________________________________________________________________
-- Bandwidth and Colocation Provided by http://www.api-digital.com --

svn-commits mailing list
To UNSUBSCRIBE or update options visit:
   http://lists.digium.com/mailman/listinfo/svn-commits

Reply via email to