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

Brian West brian.west at mac.com
Sat Feb 26 10:10:37 MST 2005


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




More information about the asterisk-dev mailing list