[Asterisk-Dev] DTMF when transferring calls - not handled well?

Vahan Yerkanian vahan at arminco.com
Sat May 21 00:02:21 MST 2005


Greetings,

I've encountered this same problem and by measuring the duration on the 
gateway device I found out that Asterisk sends 3 rtp packets with the 
DTFM payload for each digit, and 3 rtp packets with DTFM mute. Looking 
into the source of rtp.c you can find that Asterisk sends those 6 
packets in a very interesting way. Anyhow this fast cludge piece of 
patch fixed that for me. Also note about 800ms of silence / mute after 
pressing the digit, not sure why it's so big. Well if you don't press 
digits and talk simultaneously/right away, no bigie.

Again, this is an ugly hack over a hack.

patch-rtp.c is patched version for the freebsd ports version for 1.0.7, 
to be copied over the original in /usr/ports/net/asterisk/files

rtp.c.patch is just a diff -u.

Both are for STABLE. I think this was "corrected" in the CVS last week.

HTH,
Vahan

Bryan Field-Elliot wrote:
> I am using the current release of Asterisk (1.0.7).
> 
> When either a SIP user or a IAX2 user is transferred to a SIP extension, 
> DTMF doesn't seem to be handled very well. Specifically, when the caller 
> presses DTMF digits (even if they hold them down), the recipient of the 
> call (SIP) only hears the briefest DTMF pulse imaginable (e.g. 50 
> milliseconds or so).
> 
> Is this a bug in Asterisk? When the caller holds down a DTMF digit, I 
> need the callee to hear the full duration of the tone.
> 
> We are using RFC2833 everywhere.
> 
> Thank you,
> 
> Bryan
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> 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
-------------- next part --------------
--- rtp.c.orig	Sun May 15 16:33:19 2005
+++ rtp.c	Sun May 15 16:33:15 2005
@@ -127,7 +127,7 @@
 {
 	switch(buf & TYPE_MASK) {
 	case TYPE_DONTSEND:
-		return 0;
+		return 2;
 		break;
 	case TYPE_SILENCE:
 		return 4;
@@ -351,9 +351,7 @@
 					0, (struct sockaddr *)&sin, &len);
 	
 	if (res < 0) {
-		if (errno == EAGAIN)
-			ast_log(LOG_NOTICE, "RTP: Received packet with bad UDP checksum\n");
-		else
+		if (errno != EAGAIN)
 			ast_log(LOG_WARNING, "RTP Read error: %s\n", strerror(errno));
 		if (errno == EBADF)
 			CRASH;
@@ -431,9 +429,7 @@
 
 	rtpheader = (unsigned int *)(rtp->rawdata + AST_FRIENDLY_OFFSET);
 	if (res < 0) {
-		if (errno == EAGAIN)
-			ast_log(LOG_NOTICE, "RTP: Received packet with bad UDP checksum\n");
-		else
+		if (errno != EAGAIN)
 			ast_log(LOG_WARNING, "RTP Read error: %s\n", strerror(errno));
 		if (errno == EBADF)
 			CRASH;
@@ -862,8 +858,10 @@
 		/* Must be an even port number by RTP spec */
 		rtp->us.sin_port = htons(x);
 		rtp->us.sin_addr = addr;
-		if (rtp->rtcp)
+		if (rtp->rtcp) {
 			rtp->rtcp->us.sin_port = htons(x + 1);
+			rtp->rtcp->us.sin_addr = addr;
+		}
 		if (!(first = bind(rtp->s, (struct sockaddr *)&rtp->us, sizeof(rtp->us))) &&
 			(!rtp->rtcp || !bind(rtp->rtcp->s, (struct sockaddr *)&rtp->rtcp->us, sizeof(rtp->rtcp->us))))
 			break;
@@ -1037,7 +1035,7 @@
 	rtpheader[1] = htonl(rtp->lastts);
 	rtpheader[2] = htonl(rtp->ssrc); 
 	rtpheader[3] = htonl((digit << 24) | (0xa << 16) | (0));
-	for (x=0;x<6;x++) {
+	for (x=0;x<20;x++) {
 		if (rtp->them.sin_port && rtp->them.sin_addr.s_addr) {
 			res = sendto(rtp->s, (void *)rtpheader, hdrlen + 4, 0, (struct sockaddr *)&rtp->them, sizeof(rtp->them));
 			if (res <0) 
@@ -1046,14 +1044,14 @@
 		printf("Sent %d bytes of RTP data to %s:%d\n", res, ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr), ntohs(rtp->them.sin_port));
 	#endif		
 		}
-		if (x == 2) {
+		if (x == 17) {
 			/* Clear marker bit and increment seqno */
 			rtpheader[0] = htonl((2 << 30)  | (payload << 16) | (rtp->seqno++));
 			/* Make duration 800 (100ms) */
 			rtpheader[3] |= htonl((800));
 			/* Set the End bit for the last 3 */
 			rtpheader[3] |= htonl((1 << 23));
-		} else if ( x < 5) {
+		} else if ( x < 19) {
 			rtpheader[0] = htonl((2 << 30) | (payload << 16) | (rtp->seqno++));
 		}
 	}
-------------- next part --------------
--- rtp.c	Sun May 15 15:41:40 2005
+++ rtp.c.orig	Sun May 15 12:34:11 2005
@@ -1035,7 +1035,7 @@
 	rtpheader[1] = htonl(rtp->lastts);
 	rtpheader[2] = htonl(rtp->ssrc); 
 	rtpheader[3] = htonl((digit << 24) | (0xa << 16) | (0));
-	for (x=0;x<20;x++) {
+	for (x=0;x<6;x++) {
 		if (rtp->them.sin_port && rtp->them.sin_addr.s_addr) {
 			res = sendto(rtp->s, (void *)rtpheader, hdrlen + 4, 0, (struct sockaddr *)&rtp->them, sizeof(rtp->them));
 			if (res <0) 
@@ -1044,14 +1044,14 @@
 		printf("Sent %d bytes of RTP data to %s:%d\n", res, ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr), ntohs(rtp->them.sin_port));
 	#endif		
 		}
-		if (x == 17) {
+		if (x == 2) {
 			/* Clear marker bit and increment seqno */
 			rtpheader[0] = htonl((2 << 30)  | (payload << 16) | (rtp->seqno++));
 			/* Make duration 800 (100ms) */
 			rtpheader[3] |= htonl((800));
 			/* Set the End bit for the last 3 */
 			rtpheader[3] |= htonl((1 << 23));
-		} else if ( x < 19) {
+		} else if ( x < 5) {
 			rtpheader[0] = htonl((2 << 30) | (payload << 16) | (rtp->seqno++));
 		}
 	}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: vahan.vcf
Type: text/x-vcard
Size: 297 bytes
Desc: not available
Url : http://lists.digium.com/pipermail/asterisk-dev/attachments/20050521/2ad1d8ce/vahan.vcf


More information about the asterisk-dev mailing list