]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
res_rtp_asterisk: More robust timestamp checking
authorSean Bright <sean.bright@gmail.com>
Tue, 27 Apr 2021 17:31:30 +0000 (13:31 -0400)
committerJoshua Colp <jcolp@sangoma.com>
Fri, 30 Apr 2021 14:03:39 +0000 (09:03 -0500)
We assume that a timestamp value of 0 represents an 'uninitialized'
timestamp, but 0 is a valid value. Add a simple wrapper to be able to
differentiate between whether the value is set or not.

This also removes the fix for ASTERISK~28812 which should not be
needed if we are checking the last timestamp appropriately.

ASTERISK-29030 #close

Change-Id: Ie70d657d580d9a1f2877e25a6ef161c5ad761cf7

res/res_rtp_asterisk.c

index 607fd91c6633580a7c69a58a9ca073abddbe6cf4..20504cbb3fbc6eb3389bf44f5139e12a58070a52 100644 (file)
@@ -356,6 +356,11 @@ struct rtp_transport_wide_cc_statistics {
        int schedid;
 };
 
+typedef struct {
+       unsigned int ts;
+       unsigned char is_set;
+} optional_ts;
+
 /*! \brief RTP session description */
 struct ast_rtp {
        int s;
@@ -392,7 +397,7 @@ struct ast_rtp {
        /* DTMF Reception Variables */
        char resp;                        /*!< The current digit being processed */
        unsigned int last_seqno;          /*!< The last known sequence number for any DTMF packet */
-       unsigned int last_end_timestamp;  /*!< The last known timestamp received from an END packet */
+       optional_ts last_end_timestamp;   /*!< The last known timestamp received from an END packet */
        unsigned int dtmf_duration;       /*!< Total duration in samples since the digit start event */
        unsigned int dtmf_timeout;        /*!< When this timestamp is reached we consider END frame lost and forcibly abort digit */
        unsigned int dtmfsamples;
@@ -5536,12 +5541,13 @@ static void process_dtmf_rfc2833(struct ast_rtp_instance *instance, unsigned cha
        }
 
        if (ast_rtp_instance_get_prop(instance, AST_RTP_PROPERTY_DTMF_COMPENSATE)) {
-               if ((rtp->last_end_timestamp != timestamp) || (rtp->resp && rtp->resp != resp)) {
+               if (!rtp->last_end_timestamp.is_set || rtp->last_end_timestamp.ts != timestamp || (rtp->resp && rtp->resp != resp)) {
                        rtp->resp = resp;
                        rtp->dtmf_timeout = 0;
                        f = ast_frdup(create_dtmf_frame(instance, AST_FRAME_DTMF_END, ast_rtp_instance_get_prop(instance, AST_RTP_PROPERTY_DTMF_COMPENSATE)));
                        f->len = 0;
-                       rtp->last_end_timestamp = timestamp;
+                       rtp->last_end_timestamp.ts = timestamp;
+                       rtp->last_end_timestamp.is_set = 1;
                        AST_LIST_INSERT_TAIL(frames, f, frame_list);
                }
        } else {
@@ -5560,8 +5566,9 @@ static void process_dtmf_rfc2833(struct ast_rtp_instance *instance, unsigned cha
 
                if (event_end & 0x80) {
                        /* End event */
-                       if ((rtp->last_seqno != seqno) && ((timestamp > rtp->last_end_timestamp) || ((timestamp == 0) && (rtp->last_end_timestamp == 0)))) {
-                               rtp->last_end_timestamp = timestamp;
+                       if (rtp->last_seqno != seqno && (!rtp->last_end_timestamp.is_set || timestamp > rtp->last_end_timestamp.ts)) {
+                               rtp->last_end_timestamp.ts = timestamp;
+                               rtp->last_end_timestamp.is_set = 1;
                                rtp->dtmf_duration = new_duration;
                                rtp->resp = resp;
                                f = ast_frdup(create_dtmf_frame(instance, AST_FRAME_DTMF_END, 0));
@@ -5581,7 +5588,8 @@ static void process_dtmf_rfc2833(struct ast_rtp_instance *instance, unsigned cha
                         * 65535.
                         */
                        if ((rtp->last_seqno > seqno && rtp->last_seqno - seqno < 50)
-                               || timestamp <= rtp->last_end_timestamp) {
+                          || (rtp->last_end_timestamp.is_set
+                                 && timestamp <= rtp->last_end_timestamp.ts)) {
                                /* Out of order frame. Processing this can cause us to
                                 * improperly duplicate incoming DTMF, so just drop
                                 * this.
@@ -6671,7 +6679,7 @@ static int bridge_p2p_rtp_write(struct ast_rtp_instance *instance,
         * 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) {
+       if (rtp->last_end_timestamp.is_set && rtp->last_end_timestamp.ts == timestamp) {
                ast_debug_rtp(1, "(%p, %p) RTP feeding packet with duplicate timestamp to core\n", instance, instance1);
                return -1;
        }
@@ -7279,7 +7287,8 @@ static struct ast_frame *ast_rtp_interpret(struct ast_rtp_instance *instance, st
                        rtp->cycles = 0;
                        prev_seqno = 0;
                        rtp->last_seqno = 0;
-                       rtp->last_end_timestamp = 0;
+                       rtp->last_end_timestamp.ts = 0;
+                       rtp->last_end_timestamp.is_set = 0;
                        if (rtp->rtcp) {
                                rtp->rtcp->expected_prior = 0;
                                rtp->rtcp->received_prior = 0;
@@ -8518,7 +8527,8 @@ static void ast_rtp_remote_address_set(struct ast_rtp_instance *instance, struct
 
        /* Need to reset the DTMF last sequence number and the timestamp of the last END packet */
        rtp->last_seqno = 0;
-       rtp->last_end_timestamp = 0;
+       rtp->last_end_timestamp.ts = 0;
+       rtp->last_end_timestamp.is_set = 0;
 
        if (strictrtp && rtp->strict_rtp_state != STRICT_RTP_OPEN
                && !ast_sockaddr_isnull(addr) && ast_sockaddr_cmp(addr, &rtp->strict_rtp_address)) {