Handle extremely out of order RFC 2833 DTMF
authorMatthew Jordan <mjordan@digium.com>
Thu, 19 Jul 2012 21:45:20 +0000 (21:45 +0000)
committerMatthew Jordan <mjordan@digium.com>
Thu, 19 Jul 2012 21:45:20 +0000 (21:45 +0000)
commit245f6538e733a46f754a01619bd08eb36a4b1b2b
tree02bcca0ce9b9423b33765cf0920d1e96cf82c1a5
parentded09e368240150145bf29d919ff84dec9f91d2b
Handle extremely out of order RFC 2833 DTMF

The current implementation of RFC 2833 DTMF handling in res_rtp_asterisk will,
if a packet arrives out of order, drop the packet.  This is to prevent
duplicate ton generation in the Asterisk core.  Since the RTP layer does not
buffer data itself, this is the only option the RTP layer currently has for
handling packets that arrive out of order.

For the most part, this doesn't matter.  For a particular digit, so long as a
BEGIN packet arrives before the first END packet, the digit will be produced.
If subsequent BEGIN packets arrive interleaved with the ENDs, they will be
dropped; likewise, if the BEGIN or END packets themselves are out of order,
those packets are dropped but sufficient information is conveyed to the
Asterisk core to produce the appropriate digit.

For certain sequences of DTMF packets - most notably when, for a particular
digit, an END packet arrives before any BEGIN packet for that digit - this
is a real problem.  When an END arrives before any BEGINs, the END packet is
dropped - but at the same time, it causes subsequent BEGIN packets for that
digit to be ignored.  When the next in order END packet arrives, it too is
dropped - Asterisk believes that there was no initial BEGIN.

The solution this patch provides is to trust the END packet to convey the
information needed for the Asterisk core to produce the DTMF digit.  If we
receive an END packet, and it:
  * Has a timestamp greater then the last timestamp received from an END
    packet
  * Does not have the same sequence number as the last received sequence
    number (and is thus not an END packet retransmission)
Then we send the END frame up to the Asterisk core.  It contains enough
DTMF information for Asterisk to produce the digit.

On the other hand, if we receive a BEGIN or continuation packet that occurs
with a timestamp equal to or less then the last END timestamp, then we've
received something out of order - but we already have received enough
information to produce the digit.  These packets are dropped.

Much thanks goes to Olle Johansson (oej) for providing the idea for this
solution.

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

(closes issue ASTERISK-18404)
Reported by: Stephane Chazelas
Tested by: Matt Jordan
........

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

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

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