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

Frank van Dijk f.v.dijk at home.nl
Sat Feb 26 12:50:07 MST 2005


Brian West wrote:

> Example:
>
> Got RTP packet from 65.38.28.157:22114 (type 101, seq 61705, ts 
> 313955536, len 4)
> Got RTP packet from 65.38.28.157:22114 (type 0, seq 61706, ts 
> 313955536, len 160)
> Sent RTP packet to 65.38.28.157:22114 (type 0, seq 34061, ts 104824, 
> len 160)
> Got RTP packet from 65.38.28.157:22114 (type 101, seq 61707, ts 
> 313955536, len 4)
> Got RTP packet from 65.38.28.157:22114 (type 0, seq 61708, ts 
> 313955696, len 160)
> Sent RTP packet to 65.38.28.157:22114 (type 0, seq 34062, ts 104984, 
> len 160)
>
<...>

> If you notice the type 101 sent from my cisco to asterisk.  The 
> timestamp is always the same.  the seq is all the increases.
>
> This is how everything else works and is expected to work.  Your patch 
> would break this.

It would not break this. your example shows the 1 digit being sent. The 
timestamp is constant, but asterisk+patch would also have sent constant 
time stamps there (I tested it, can send an ethereal trace if you like). 
What's puzzling me is that the asterisk minus your patch 2928 would 
*also* have sent constant time stamps there, as far as I can see (the 
timestamp modification is outside the for loop that resends the packets).

The only difference I can see between my patch and asterisk minus 
patch-2928 is that the latter modifies rtp->txcore when sending a digit 
(I was not sure whether that would be bad, so I preferred safe over sorry).

If my reasoning is correct here, then the question is (1) why then did 
patch-2928 fix your problem and (2) would my patch break it ?  Any 
chance you still have a trace of your problem lying around somewhere, or 
would it be possible to retest ?

By the way, the cisco equipment from your example sends lots of voice 
packets intermixed with the rfc2833 packets, so it would never trigger 
the issue I'm experiencing. The cisco GW I talk to seems to be 
configured to stop sending voice packets while sending  rfc2833 packets.


>   Now what I think you're needing and the RFC isn't very clear on is 
> if events come in too fast or too close together.  You "might" have to 
> in these cases increase the timestamp.  But outright increasing the 
> timestamp on every single dtmf frame would totally break it.
>
> /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