summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Colp <jcolp@digium.com>2014-10-10 20:48:03 +0000
committerJoshua Colp <jcolp@digium.com>2014-10-10 20:48:03 +0000
commit743ad196991ab9179b8bcbab963002de92549514 (patch)
tree4ca01c05cd7f84211fd7a8345b6e5fab25edc4f8
parentb8aed5b14dd34027ba5dcc372f2ca7a013c67837 (diff)
bridge: During a smart bridge operation provide a more complete bridge to the old technology.
When a smart bridge operation occurs and a bridge transitions from one technology to another the old technology is provided the channels formerly in it and told that they are leaving. Unfortunately the bridge provided along with them is incomplete. The bridge, despite there being channels in it, contains none. This forces technology implementations to have additional logic when channels are leaving or to store their own duplicated state. This change makes the bridge more complete so it contains the expected channels. Now that the bridge is complete special logic within bridge_native_rtp is no longer needed and has been removed. Review: https://reviewboard.asterisk.org/r/4057/ ........ Merged revisions 425242 from http://svn.asterisk.org/svn/asterisk/branches/12 git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/13@425243 65c4cc65-6c06-0410-ace0-fbb531ad65f3
-rw-r--r--bridges/bridge_native_rtp.c41
-rw-r--r--main/bridge.c57
2 files changed, 42 insertions, 56 deletions
diff --git a/bridges/bridge_native_rtp.c b/bridges/bridge_native_rtp.c
index 4655efeae..24873d031 100644
--- a/bridges/bridge_native_rtp.c
+++ b/bridges/bridge_native_rtp.c
@@ -212,10 +212,6 @@ static void native_rtp_bridge_stop(struct ast_bridge *bridge, struct ast_channel
return;
}
- if (!c0 || !c1) {
- return;
- }
-
ast_channel_lock_both(c0->chan, c1->chan);
native_type = native_rtp_bridge_get(c0->chan, c1->chan, &glue0, &glue1, &instance0, &instance1, &vinstance0, &vinstance1);
@@ -457,44 +453,7 @@ static void native_rtp_bridge_unsuspend(struct ast_bridge *bridge, struct ast_br
static void native_rtp_bridge_leave(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
{
- struct ast_rtp_glue *glue;
- RAII_VAR(struct ast_rtp_instance *, instance, NULL, ao2_cleanup);
- RAII_VAR(struct ast_rtp_instance *, vinstance, NULL, ao2_cleanup);
- RAII_VAR(struct ast_rtp_instance *, tinstance, NULL, ao2_cleanup);
-
native_rtp_bridge_framehook_detach(bridge_channel);
-
- glue = ast_rtp_instance_get_glue(ast_channel_tech(bridge_channel->chan)->type);
- if (!glue) {
- return;
- }
-
- glue->get_rtp_info(bridge_channel->chan, &instance);
-
- if (glue->get_vrtp_info) {
- glue->get_vrtp_info(bridge_channel->chan, &vinstance);
- }
-
- if (glue->get_trtp_info) {
- glue->get_trtp_info(bridge_channel->chan, &tinstance);
- }
-
- /* Tear down P2P bridges */
- if (instance) {
- ast_rtp_instance_set_bridged(instance, NULL);
- }
- if (vinstance) {
- ast_rtp_instance_set_bridged(vinstance, NULL);
- }
- if (tinstance) {
- ast_rtp_instance_set_bridged(tinstance, NULL);
- }
-
- if (ast_channel_is_leaving_bridge(bridge_channel->chan)) {
- /* Direct RTP may have occurred, tear it down */
- glue->update_peer(bridge_channel->chan, NULL, NULL, NULL, NULL, 0);
- }
-
native_rtp_bridge_stop(bridge, NULL);
}
diff --git a/main/bridge.c b/main/bridge.c
index 0478e4686..ab3bb17e6 100644
--- a/main/bridge.c
+++ b/main/bridge.c
@@ -1139,28 +1139,55 @@ static int smart_bridge_operation(struct ast_bridge *bridge)
return -1;
}
+ /* To ensure that things are sane for the old technology move the channels it
+ * expects to the dummy bridge
+ */
+ AST_LIST_TRAVERSE_SAFE_BEGIN(&bridge->channels, bridge_channel, entry) {
+ if (bridge_channel->just_joined) {
+ continue;
+ }
+ ast_debug(1, "Bridge %s: moving %p(%s) to dummy bridge temporarily\n",
+ bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan));
+ AST_LIST_REMOVE_CURRENT(entry);
+ AST_LIST_INSERT_TAIL(&dummy_bridge.channels, bridge_channel, entry);
+ dummy_bridge.num_channels++;
+ if (ast_test_flag(&bridge_channel->features->feature_flags, AST_BRIDGE_CHANNEL_FLAG_LONELY)) {
+ dummy_bridge.num_lonely++;
+ }
+ if (!bridge_channel->suspended) {
+ dummy_bridge.num_active++;
+ }
+ }
+ AST_LIST_TRAVERSE_SAFE_END;
+
+ /* Take all the channels out of the old technology */
+ AST_LIST_TRAVERSE_SAFE_BEGIN(&dummy_bridge.channels, bridge_channel, entry) {
+ ast_debug(1, "Bridge %s: %p(%s) is leaving %s technology (dummy)\n",
+ dummy_bridge.uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan),
+ old_technology->name);
+ if (old_technology->leave) {
+ old_technology->leave(&dummy_bridge, bridge_channel);
+ }
+ AST_LIST_REMOVE_CURRENT(entry);
+ AST_LIST_INSERT_TAIL(&bridge->channels, bridge_channel, entry);
+ dummy_bridge.num_channels--;
+ if (ast_test_flag(&bridge_channel->features->feature_flags, AST_BRIDGE_CHANNEL_FLAG_LONELY)) {
+ dummy_bridge.num_lonely--;
+ }
+ if (!bridge_channel->suspended) {
+ dummy_bridge.num_active--;
+ }
+ }
+ AST_LIST_TRAVERSE_SAFE_END;
+
ast_debug(1, "Bridge %s: calling %s technology stop\n",
dummy_bridge.uniqueid, old_technology->name);
if (old_technology->stop) {
old_technology->stop(&dummy_bridge);
}
- /*
- * Move existing channels over to the new technology and
- * complete joining any new channels to the bridge.
- */
+ /* Add any new channels or re-add existing channels to the bridge. */
AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
- if (!bridge_channel->just_joined) {
- /* Take existing channel from the old technology. */
- ast_debug(1, "Bridge %s: %p(%s) is leaving %s technology (dummy)\n",
- dummy_bridge.uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan),
- old_technology->name);
- if (old_technology->leave) {
- old_technology->leave(&dummy_bridge, bridge_channel);
- }
- }
-
- /* Add any new channels or re-add an existing channel to the bridge. */
bridge_channel_complete_join(bridge, bridge_channel);
}