res_rtp_asterisk: Fix infinite DTMF issue when switching to P2P bridge
authorTorrey Searle <torrey@voxbone.com>
Thu, 29 Sep 2016 17:52:45 +0000 (19:52 +0200)
committerRichard Mudgett <rmudgett@digium.com>
Mon, 10 Oct 2016 22:00:23 +0000 (17:00 -0500)
If a bridge switched to P2P when a DTMF was in progress it
was possible for the DTMF to continue being sent indefinitely.

Change-Id: I7e2a3efe0d59d4b214ed50cd0b5d0317e2d92e29

res/res_rtp_asterisk.c

index d6eea3c..520fd76 100644 (file)
@@ -4284,6 +4284,7 @@ static int bridge_p2p_rtp_write(struct ast_rtp_instance *instance, unsigned int
        int reconstruct = ntohl(rtpheader[0]);
        struct ast_sockaddr remote_address = { {0,} };
        int ice;
+       unsigned int timestamp = ntohl(rtpheader[1]);
 
        /* Get fields from packet */
        payload = (reconstruct & 0x7f0000) >> 16;
@@ -4313,6 +4314,22 @@ static int bridge_p2p_rtp_write(struct ast_rtp_instance *instance, unsigned int
                return -1;
        }
 
+       /* If bridged peer is in dtmf, feed all packets to core until it finishes to avoid infinite dtmf */
+       if (bridged->sending_digit) {
+               ast_debug(1, "Feeding packets to core until DTMF finishes\n");
+               return -1;
+       }
+
+       /*
+        * Even if we are no longer in dtmf, we could still be receiving
+        * re-transmissions of the last dtmf end still.  Feed those to the
+        * core so they can be filtered accordingly.
+        */
+       if (rtp->last_end_timestamp == timestamp) {
+               ast_debug(1, "Feeding packet with duplicate timestamp to core\n");
+               return -1;
+       }
+
        /* If the marker bit has been explicitly set turn it on */
        if (ast_test_flag(rtp, FLAG_NEED_MARKER_BIT)) {
                mark = 1;