summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
authorJonathan Rose <jrose@digium.com>2013-08-09 17:22:28 +0000
committerJonathan Rose <jrose@digium.com>2013-08-09 17:22:28 +0000
commit6fe21ef48eede571957863484a203124a6118d9f (patch)
treea267da3dde4b48ff8065f552958de2026bf9a086 /main
parent6eec8a44e7a9158fff224957ffe93260f513835c (diff)
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/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@396497 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main')
-rw-r--r--main/bridge_channel.c13
-rw-r--r--main/core_unreal.c5
2 files changed, 15 insertions, 3 deletions
diff --git a/main/bridge_channel.c b/main/bridge_channel.c
index c782ec67d..830abb750 100644
--- a/main/bridge_channel.c
+++ b/main/bridge_channel.c
@@ -1324,7 +1324,12 @@ static void bridge_channel_dissolve_check(struct ast_bridge_channel *bridge_chan
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)
@@ -1361,6 +1366,9 @@ void bridge_channel_internal_pull(struct ast_bridge_channel *bridge_channel)
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);
bridge->v_table->pull(bridge, bridge_channel);
@@ -1416,6 +1424,9 @@ int bridge_channel_internal_push(struct ast_bridge_channel *bridge_channel)
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;
}
diff --git a/main/core_unreal.c b/main/core_unreal.c
index 7b7595b87..99ddc5163 100644
--- a/main/core_unreal.c
+++ b/main/core_unreal.c
@@ -668,7 +668,7 @@ void ast_unreal_call_setup(struct ast_channel *semi1, struct ast_channel *semi2)
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 @@ int ast_unreal_channel_push_to_bridge(struct ast_channel *ast, struct ast_bridge
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)) {