Handle AST_CONTROL_UPDATE_RTP_PEER frames in local bridge loop
authorMatthew Jordan <mjordan@digium.com>
Thu, 29 Dec 2011 15:16:46 +0000 (15:16 +0000)
committerMatthew Jordan <mjordan@digium.com>
Thu, 29 Dec 2011 15:16:46 +0000 (15:16 +0000)
Failing to handle AST_CONTROL_UPDATE_RTP_PEER frames in the local bridge loop
causes the loop to exit prematurely.  This causes a variety of negative side
effects, depending on when the loop exits.  This patch handles the frame by
essentially swallowing the frame in the local loop, as the current channel
drivers expect the RTP bridge to handle the frame, and, in the case of the
local bridge loop, no additional action is necessary.

(issue ASTERISK-19040)
(issue ASTERISK-19128)
(issue ASTERISK-17725)
(issue ASTERISK-18340)
(closes issue ASTERISK-19095)
Reported by: Stefan Schmidt
Tested by: Matt Jordan

Review: https://reviewboard.asterisk.org/r/1640/
........

Merged revisions 349339 from http://svn.asterisk.org/svn/asterisk/branches/1.8
........

Merged revisions 349340 from http://svn.asterisk.org/svn/asterisk/branches/10

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

main/rtp_engine.c

index 730fdcd..4f28bb9 100644 (file)
@@ -889,7 +889,8 @@ static enum ast_bridge_result local_bridge_loop(struct ast_channel *c0, struct a
                            (fr->subclass.integer == AST_CONTROL_UNHOLD) ||
                            (fr->subclass.integer == AST_CONTROL_VIDUPDATE) ||
                            (fr->subclass.integer == AST_CONTROL_SRCUPDATE) ||
-                           (fr->subclass.integer == AST_CONTROL_T38_PARAMETERS)) {
+                           (fr->subclass.integer == AST_CONTROL_T38_PARAMETERS) ||
+                           (fr->subclass.integer == AST_CONTROL_UPDATE_RTP_PEER)) {
                                /* If we are going on hold, then break callback mode and P2P bridging */
                                if (fr->subclass.integer == AST_CONTROL_HOLD) {
                                        if (instance0->engine->local_bridge) {
@@ -910,7 +911,10 @@ static enum ast_bridge_result local_bridge_loop(struct ast_channel *c0, struct a
                                        instance0->bridged = instance1;
                                        instance1->bridged = instance0;
                                }
-                               ast_indicate_data(other, fr->subclass.integer, fr->data.ptr, fr->datalen);
+                               /* Since UPDATE_BRIDGE_PEER is only used by the bridging code, don't forward it */
+                               if (fr->subclass.integer != AST_CONTROL_UPDATE_RTP_PEER) {
+                                       ast_indicate_data(other, fr->subclass.integer, fr->data.ptr, fr->datalen);
+                               }
                                ast_frfree(fr);
                        } else if (fr->subclass.integer == AST_CONTROL_CONNECTED_LINE) {
                                if (ast_channel_connected_line_macro(who, other, fr, other == c0, 1)) {