[asterisk-users] DTMF digits falsely detected

Vladimir Mikhelson vlad at mikhelson.com
Mon Sep 17 00:47:39 CDT 2012


On 9/15/2012 6:28 PM, Matthew Jordan wrote:
> ----- 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
>

Matt,

I appreciate you taking time to explain the application logic in detail
along with interpreting the RFC logic.  That BTW finally gave me a push
to read RFC 2833.

It sounds like the soft phone I used did not implement the RFC
requirements precisely as the requirement to keep the same time stamp on
the three (3) redundant packets is "SHOULD."

On the other hand the RFC leaves the room open for the far end
reassembly algorithms.

As you have mentioned one of the objectives of the Asterisk development
is to not break the old behavior, a.k.a. "backwards compatibility."  If
no more elegant solution to satisfy both DTMF transmission scenarios
will be found a per-client setting can be introduced to the effect of
following the "new" or "old' algorithm.  I will be happy to help you
with testing.

Thank you,
Vladimir







More information about the asterisk-users mailing list