[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