]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
bridge: During a smart bridge operation provide a more complete bridge to the old...
authorJoshua Colp <jcolp@digium.com>
Fri, 10 Oct 2014 20:47:21 +0000 (20:47 +0000)
committerJoshua Colp <jcolp@digium.com>
Fri, 10 Oct 2014 20:47:21 +0000 (20:47 +0000)
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/

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/12@425242 65c4cc65-6c06-0410-ace0-fbb531ad65f3

bridges/bridge_native_rtp.c
main/bridge.c

index 2362ad296dc1a8d2ad64c2d86f7c7e7ddf322089..8cf7a4f0af35207e01b8504af294f6c2cd2d690e 100644 (file)
@@ -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);
 
@@ -458,44 +454,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);
 }
 
index b181c8f53b16b18ce641630368905003596a7525..2383c7a9300dff0e257bb9953cdb406b58a7d921 100644 (file)
@@ -1129,28 +1129,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);
        }