[asterisk-users] DTMF digits falsely detected

Matthew Jordan mjordan at digium.com
Sat Sep 15 18:28:08 CDT 2012


----- Original Message -----
> From: "Vladimir Mikhelson" <vlad at mikhelson.com>
> To: "Asterisk Users Mailing List - Non-Commercial Discussion" <asterisk-users at lists.digium.com>
> Sent: Saturday, September 15, 2012 1:11:14 PM
> Subject: Re: [asterisk-users] DTMF digits falsely detected

<snip>

> Can you please quote the appropriate RFC here?  It looks like the UA
> just uses the real time of an event for time stamping.  I still would
> like to understand the logic and the math here as 121920+2400=124320,
> not 122080 or 122240.

Asterisk claims to follow RFC 2833 for DTMF events over RTP.  That is the RFC
that I'll refer to here.

Yes, your UA is incrementing the source timestamp for each packet it sends
corresponding to the same event, and that is incorrect.  RFC 2833 defines the
usage of the RTP timestamp and the duration field as follows in Section 3.4:

Timestamp: The RTP timestamp reflects the measurement point for
   the current packet. The event duration described in Section
   3.5 extends forwards from that time. The receiver calculates
   jitter for RTCP receiver reports based on all packets with a
   given timestamp. Note: The jitter value should primarily be
   used as a means for comparing the reception quality between
   two users or two time-periods, not as an absolute measure.

duration: Duration of this digit, in timestamp units. Thus, the
   event began at the instant identified by the RTP timestamp
   and has so far lasted as long as indicated by this parameter.
   The event may or may not have ended.

   For a sampling rate of 8000 Hz, this field is sufficient to
   express event durations of up to approximately 8 seconds.

Section 3.6 specifically states how these two fields are used when an event
spans more than a single packet:

If an event continues for more than one period, the source generating
   the events should send a new event packet with the RTP timestamp
   value corresponding to the beginning of the event and the duration of
   the event increased correspondingly. (The RTP sequence number is
   incremented by one for each packet.) If there has been no new event
   in the last interval, the event SHOULD be retransmitted three times
   or until the next event is recognized. This ensures that the duration
   of the event can be recognized correctly even if the last packet for
   an event is lost.

Why is the timestamp handled this way?  

Consider the following RTP packets denoting a DTMF event:

Seq No | Timestamp | Event | Duration | End of Event | 
 7991  | 13280     |  1    |   0      |    0         |
 7992  | 13280     |  1    |  160     |    0         |
 7993  | 13280     |  1    |  320     |    0         |

Why does the RFC require the timestamp to be the same for all three packets?
Well, what would happen if the first two packets were dropped?  In that case,
we'd still know how to construct the DTMF digit - we know the relative source
time denoting the beginning of the DTMF event (13280), and we know the
duration (320) - which is 40 ms.  So we can start the DTMF digit at our
appropriate relative time, and we can continue it for the appropriate length
of time.

What would happen instead if the timestamp increased in each RTP packet?

Seq No | Timestamp | Event | Duration | End of Event | 
 7991  | 13280     |  1    |   0      |    0         |
 7992  | 13440     |  1    |  160     |    0         |
 7993  | 13600     |  1    |  320     |    0         |

Now if the first two packets are dropped, we would begin generating the DTMF
tone at the wrong time - we'd think it was supposed to start at the source
relative time of t=13600, when it should have started at t=13280.  This could
cause a delay in the tone generation by 40 ms.

This answers two of your questions:

> 
> >   Because RTP packets can arrive out of order, Asterisk is using
> > the timestamp to determine if the packets correspond to the same
> > DTMF event.
> 
> Is that something mandated by the respective RFC?  In other words is
> it
> "MUST" or "MAY" per RFC?  Or is it not there at all?

It happens because the RFC specifically says the timestamp should be the same
for all event packets corresponding to the same event.  Its not really a MAY,
MUST, SHOULD, or SHALL.  Its just how the RTP timestamp is supposed to be used.

I'll explain the out of order scenario I alluded to later.

> Why does the retransmission happen at all?  Maybe something else is
> broken?

Its happening because the RFC in Section 3.6 says that when the DTMF end is
detected, that is, there are no new events detected in the last interval, the
event should be retransmitted three times.  In that regard, your UA is behaving
correctly (note in my previous e-mail that the duration did not increase) - but
the new RTP timestamps denote different times that the event began, which is
incorrect.

So, why did the handling of this change in Asterisk 1.8.16.0 and 10.8.0?

Asterisk used to determine that a new DTMF event was beginning when it received
a non-end event that had a different timestamp and a different digit.  It would
store this event digit value as the current DTMF digit.  It would recognize the
end of a DTMF digit when it received a packet with End of Event set and a digit
value matching the current DTMF digit value.  It would ignore repeated end
events based on a combination of sequence number checking and whether or not
it had detected a DTMF begin or continuation packet.

Take for example the following:

Seq No | Timestamp | Event | Duration | End of Event | 
 7991  | 13280     |  1    |   0      |    0         |
 7992  | 13280     |  1    |  160     |    0         |
 7993  | 13280     |  1    |  320     |    0         |
 7994  | 13280     |  1    |  480     |    1         |
 7995  | 13280     |  1    |  480     |    1         |
 7996  | 13280     |  1    |  480     |    1         |

Asterisk would start a new DTMF digit when it received the first event packet
at sequence number 7991.  It would continue the digit until it received the
first packet marking the End of Event (7994).  At that point, it would create an
DTMF_END frame and end the DTMF digit.  It would use the sequence number (7994)
to know that subsequent reception of End of Event packets (7995, 7996) were
retransmissions.  This was tolerant to your scenario, where the timestamps are
erroneously inrecreasing, as it used the event value (of '1') and the sequence
numbers to know that the repeated End of Event packets were retransmissions.

Unfortunately, this fails in scenarios where packets arrive out of order.
In ASTERISK-18404, various people reported that they would recieve multiple
DTMF digits where the End of Event digits for a subsequent digit with the same
value would arrive before any event begin or continuation packets.  This would
look something like this:

Seq No | Timestamp | Event | Duration | End of Event | 
 7991  | 13280     |  1    |   0      |    0         |
 7992  | 13280     |  1    |  160     |    0         |
 7993  | 13280     |  1    |  320     |    1         |
 7994  | 13280     |  1    |  320     |    1         |
 7995  | 13280     |  1    |  320     |    1         |
 7998  | 14340     |  1    |  320     |    1         |
 7999  | 14340     |  1    |  320     |    1         |
 8000  | 14340     |  1    |  320     |    1         |
 7996  | 14340     |  1    |   0      |    0         |
 7997  | 14340     |  1    |  160     |    0         |

Since the End of Event packets arrive before the begin or continuation, and the
digit value hadn't changed, Asterisk prior to 1.8.16.0/10.8.0 would treat the
packets as retransmissions of the previous DTMF '1' digit.  Because no End of
Event packets would arrive after the begin/continuation packets, the digit would
be dropped completely.  The new implementation in 1.8.16.0/10.8.0 handles this
scenario by using the RTP timestamp - which should denote the beginning of the
DTMF event - to correlate the End of Event packets it has received.  Thus, in
the above scenario, it will properly reconstruct both DTMF digits.

> 
> I need to test with IVR, but my bet results will be the same as with
> Voice Mail.  At least that is how it sounds from your explanation of
> what behavior was modified and where.

Yes, I would expect that any time Asterisk attempts to process a DTMF event sent
from this UA, it would create DTMF frames inside Asterisk corresponding to each
end of event packet sent from the UA.  I would expect it to create three DTMF
digits regardless of the application, as the decoding of the RTP stream into
DTMF frames happens in the RTP implementation (res_rtp_asterisk) registered
to the RTP engine, not at the application level.

There may be a way to handle your endpoint's behavior, as well as maintain
the handling of out of order packets.  We certainly try to not have a new
version of Asterisk break any existing devices, even if those devices are
behaving oddly.

--
Matthew Jordan
Digium, Inc. | Engineering Manager
445 Jan Davis Drive NW - Huntsville, AL 35806 - USA
Check us out at: http://digium.com & http://asterisk.org



More information about the asterisk-users mailing list