[Asterisk-Dev] Re: rfc2833 DTMFs sent with bad timestamps (patch)

Frank van Dijk f.v.dijk at home.nl
Sat Feb 26 11:44:32 MST 2005


Brian,

Thanks for your explanation. That explains why I found bug reports but 
no fix. ...But I would like to make sure that we are talking about the 
same thing here:

You talk about 'the first and each following DTMF frame' having to have 
the same stamp. I agree if by 'frame' you mean the RTP packets that get 
resent but that describe the same instance of the dtmf tone being 
generated (the 6 packets that ast_rtp_senddigit() sends in a for loop): 
they must all have the same stamp.

But when a new dtmf tone is detected, the set of 6 (4 in 1.0.3) packets 
that are generated from that should have a different time stamp from the 
previous set of 6, otherwise you lose information (you don't know how 
far apart the two dtmf tones were).

So, if user presses '1' and then '2' on his phone, we should see 12 RTP 
telephone-event packets, 6 of them having one timestamp, 6 of them 
having another. The cisco ISDN-VOIP GW where the DTMFs come from from 
the POV of the asterisk does it that way. Actually it sends 8+8 packets, 
but each member of a group of 8 has the same timestamp, and each group 
has its own unique stamp.

I hope this clarifies things a bit.


Brian West wrote:

> Frank,
>     The RFC states that the timestamp you send on RFC2833 SHOULD NOT 
> increment from the first one sent and each following dtmf frame sent 
> should use the exact same timestamp as the first one.  Only sequence 
> number should increment.  If you use RTP debug in asterisk and 
> compare  how say a Cisco 7960 or a Sipura send DTMF they act in the 
> same manner.  If you increase the timestamp on the DTMP packet you'll 
> break it and the gateways such as a Lucent TNT or cisco will totally 
> ignore the digits being dialed and all you'll hear is a clipy missing 
> dtmf frame.  I know this because i'm the one that spent 3 hours 
> reading the mind warping RFC and talking to mark.  I think your 
> gateway is what is broken.
>
> http://bugs.digium.com/bug_view_page.php?bug_id=0002928
>
> /b
>
>
> On Feb 26, 2005, at 11:45 AM, Frank van Dijk wrote:
>
>> Hi
>>
>> I ran into an issue with the way asterisk sends rfc2833 DTMF events. 
>> As my days of experience with asterisk can be counted on one hand I 
>> would like to hear your expert opinion on the attached patch that 
>> solves the problem for me, or maybe your opinion on other ways to 
>> solve the problem.
>>
>> I ran into the issue using 1.0.3 on BSD, but looking at the latest 
>> rtp.c the issue is still there. I have an asterisk forwarding RTP 
>> streams between a cisco ISDN/VOIP gateway and an intel HMP. When a 
>> caller (in the PSTN) enters some DTMFs in quick succession, asterisk 
>> sends the digits without voice packets in between. That is ok, except 
>> that it re-uses the timestamp of the first digit for the following 
>> digits. The HMP box receives digits that claim to have occurred 
>> simultaneously and it ignores all but the first one. I've seen 
>> mention of this issue in some bug reports, but it seems the problem 
>> persists (CMIIW).
>>
>> The cause of the issue is the fact that ast_rtp_senddigit() in rtp.c 
>> uses rtp->lastts as the timestamp. lastts is the timestamp of the 
>> latest voice packet. If no voice packets are sent, lastts does not 
>> change. The patch below uses (lastts + number of ms elapsed since 
>> then) as timestamp for sending DTMF events. The diff is against rtp.c 
>> from cvs-head.
>>
>> thanks for your time.
>>
>> -- 
>>
>> mvrgr Frank van Dijk
>>
>> --- rtp.c.orig    2005-02-26 04:01:11.000000000 +0100
>> +++ rtp.c    2005-02-26 16:47:17.854001472 +0100
>> @@ -1036,6 +1036,14 @@
>>      free(rtp);
>>  }
>>
>> +static inline unsigned int timeofdaydiff_ms(const struct timeval 
>> *nw,const struct timeval *old)
>> +{
>> +    unsigned int ms;
>> +    ms = (nw->tv_sec - old->tv_sec) * 1000;
>> +    ms += (1000000 + nw->tv_usec - old->tv_usec) / 1000 - 1000;
>> +    return ms;
>> +}
>> +
>>  static unsigned int calc_txstamp(struct ast_rtp *rtp, struct timeval 
>> *delivery)
>>  {
>>      struct timeval now;
>> @@ -1047,14 +1055,12 @@
>>      }
>>      if (delivery && (delivery->tv_sec || delivery->tv_usec)) {
>>          /* Use previous txcore */
>> -        ms = (delivery->tv_sec - rtp->txcore.tv_sec) * 1000;
>> -        ms += (1000000 + delivery->tv_usec - rtp->txcore.tv_usec) / 
>> 1000 - 1000;
>> +        ms = timeofdaydiff_ms(delivery,&rtp->txcore);
>>          rtp->txcore.tv_sec = delivery->tv_sec;
>>          rtp->txcore.tv_usec = delivery->tv_usec;
>>      } else {
>>          gettimeofday(&now, NULL);
>> -        ms = (now.tv_sec - rtp->txcore.tv_sec) * 1000;
>> -        ms += (1000000 + now.tv_usec - rtp->txcore.tv_usec) / 1000 - 
>> 1000;
>> +        ms = timeofdaydiff_ms(&now,&rtp->txcore);
>>          /* Use what we just got for next time */
>>          rtp->txcore.tv_sec = now.tv_sec;
>>          rtp->txcore.tv_usec = now.tv_usec;
>> @@ -1069,6 +1075,7 @@
>>      int res;
>>      int x;
>>      int payload;
>> +    unsigned int timestamp;
>>      char data[256];
>>      char iabuf[INET_ADDRSTRLEN];
>>
>> @@ -1093,6 +1100,11 @@
>>          return 0;
>>
>>      gettimeofday(&rtp->dtmfmute, NULL);
>> +
>> +    /* make distinct digits have distinct timestamps */
>> +    timestamp = timeofdaydiff_ms(&rtp->dtmfmute,&rtp->txcore) * 8
>> +      + rtp->lastts;
>> +
>>      rtp->dtmfmute.tv_usec += (500 * 1000);
>>      if (rtp->dtmfmute.tv_usec > 1000000) {
>>          rtp->dtmfmute.tv_usec -= 1000000;
>> @@ -1102,7 +1114,7 @@
>>      /* Get a pointer to the header */
>>      rtpheader = (unsigned int *)data;
>>      rtpheader[0] = htonl((2 << 30) | (1 << 23) | (payload << 16) | 
>> (rtp->seqno++));
>> -    rtpheader[1] = htonl(rtp->lastts);
>> +    rtpheader[1] = htonl(timestamp);
>>      rtpheader[2] = htonl(rtp->ssrc);
>>      rtpheader[3] = htonl((digit << 24) | (0xa << 16) | (0));
>>      for (x=0;x<6;x++) {
>> _______________________________________________
>> Asterisk-Dev mailing list
>> Asterisk-Dev at lists.digium.com
>> http://lists.digium.com/mailman/listinfo/asterisk-dev
>> To UNSUBSCRIBE or update options visit:
>>    http://lists.digium.com/mailman/listinfo/asterisk-dev
>
>
> _______________________________________________
> Asterisk-Dev mailing list
> Asterisk-Dev at lists.digium.com
> http://lists.digium.com/mailman/listinfo/asterisk-dev
> To UNSUBSCRIBE or update options visit:
>   http://lists.digium.com/mailman/listinfo/asterisk-dev
>




More information about the asterisk-dev mailing list