[Asterisk-code-review] chan dahdi.c: Flush the DAHDI write buffer after starting DTMF. (asterisk[13])

Richard Mudgett asteriskteam at digium.com
Tue Aug 11 16:55:15 CDT 2015


Richard Mudgett has uploaded a new change for review.

  https://gerrit.asterisk.org/1065

Change subject: chan_dahdi.c: Flush the DAHDI write buffer after starting DTMF.
......................................................................

chan_dahdi.c: Flush the DAHDI write buffer after starting DTMF.

Pressing DTMF digits on a phone to go out on a DAHDI channel can result in
the digit not being recognized or even heard by the peer.

Phone -> Asterisk -> DAHDI/channel

Turns out the DAHDI behavior with DTMF generation (and any other generated
tones) is exposed by the "buffers=" setting in chan_dahdi.conf.  When
Asterisk requests to start sending DTMF then DAHDI waits until its write
buffer is empty before generating any samples for the DTMF tones.  When
Asterisk subsequently requests DAHDI to stop sending DTMF then DAHDI
immediately stops generating the DTMF samples.  As a result, the more
samples there are in the DAHDI write buffer the shorter the time DTMF
actually gets sent on the wire.  If there are more samples in the write
buffer than the time DTMF is supposed to be sent then no DTMF gets sent on
the wire.  With the "buffers=12,half" setting and each buffer representing
20 ms of samples then the DAHDI write buffer is going to contain around
120 ms of samples.  For DTMF to be recognized by the peer the actual sent
DTMF duration needs to be a minimum of 40 ms.  Therefore, the intended
duration needs to be a minimum of 160 ms for the peer to receive the
minimum DTMF digit duration to recognize it.

A simple and effective solution to work around the DAHDI behavior is for
Asterisk to flush the DAHDI write buffer when sending DTMF so the full
duration of DTMF is actually sent on the wire.  When someone is going to
send DTMF they are not likely to be talking before sending the tones so
the flushed write samples are expected to just contain silence.

* Made dahdi_digit_begin() flush the DAHDI write buffer after requesting
to send a DTMF digit.

ASTERISK-25315 #close
Reported by John Hardin

Change-Id: Ib56262c708cb7858082156bfc70ebd0a220efa6a
---
M channels/chan_dahdi.c
1 file changed, 16 insertions(+), 4 deletions(-)


  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/65/1065/1

diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c
index 0949463..248a7fd 100644
--- a/channels/chan_dahdi.c
+++ b/channels/chan_dahdi.c
@@ -4199,7 +4199,7 @@
 {
 	struct dahdi_pvt *pvt;
 	int idx;
-	int dtmf = -1;
+	int dtmf;
 	int res;
 
 	pvt = ast_channel_tech_pvt(chan);
@@ -4222,8 +4222,11 @@
 		break;
 	}
 #endif
-	if ((dtmf = digit_to_dtmfindex(digit)) == -1)
+	dtmf = digit_to_dtmfindex(digit);
+	if (dtmf == -1) {
+		/* Not a valid DTMF digit */
 		goto out;
+	}
 
 	if (pvt->pulse || ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SENDTONE, &dtmf)) {
 		char dial_str[] = { 'T', digit, '\0' };
@@ -4233,10 +4236,19 @@
 			pvt->dialing = 1;
 		}
 	} else {
-		ast_debug(1, "Channel %s started VLDTMF digit '%c'\n",
-			ast_channel_name(chan), digit);
 		pvt->dialing = 1;
 		pvt->begindigit = digit;
+
+		/* Flush the write buffer in DAHDI to start sending the digit immediately. */
+		dtmf = DAHDI_FLUSH_WRITE;
+		res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_FLUSH, &dtmf);
+		if (res) {
+			ast_log(LOG_WARNING, "Unable to flush the DAHDI write buffer to send DTMF on channel %d: %s\n",
+				pvt->channel, strerror(errno));
+		}
+
+		ast_debug(1, "Channel %s started VLDTMF digit '%c'\n",
+			ast_channel_name(chan), digit);
 	}
 
 out:

-- 
To view, visit https://gerrit.asterisk.org/1065
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ib56262c708cb7858082156bfc70ebd0a220efa6a
Gerrit-PatchSet: 1
Gerrit-Project: asterisk
Gerrit-Branch: 13
Gerrit-Owner: Richard Mudgett <rmudgett at digium.com>



More information about the asterisk-code-review mailing list