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

Brian West brian.west at mac.com
Sat Feb 26 12:14:36 MST 2005


My Cisco uses the same timestamp for ANY and ALL dtmf events.  If you 
change this and increment this then you break DTMF.

/b

On Feb 26, 2005, at 1:50 PM, Frank van Dijk wrote:

> 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
>>
>
> _______________________________________________
> 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