summaryrefslogtreecommitdiff
path: root/channels/chan_dahdi.c
diff options
context:
space:
mode:
authorRichard Mudgett <rmudgett@digium.com>2015-08-10 13:43:19 -0500
committerRichard Mudgett <rmudgett@digium.com>2015-08-11 16:58:32 -0500
commit87c92d2aee60cc3396f0ccab64801e41b37dd33d (patch)
tree913cdd9313cc8c579b31790f960efd54fd53e9b2 /channels/chan_dahdi.c
parente188192ad10a8570785986a46666b91d7a448b75 (diff)
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
Diffstat (limited to 'channels/chan_dahdi.c')
-rw-r--r--channels/chan_dahdi.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c
index fe613097c..ac159527b 100644
--- a/channels/chan_dahdi.c
+++ b/channels/chan_dahdi.c
@@ -4198,7 +4198,7 @@ static int dahdi_digit_begin(struct ast_channel *chan, char digit)
{
struct dahdi_pvt *pvt;
int idx;
- int dtmf = -1;
+ int dtmf;
int res;
pvt = ast_channel_tech_pvt(chan);
@@ -4221,8 +4221,11 @@ static int dahdi_digit_begin(struct ast_channel *chan, char digit)
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' };
@@ -4232,10 +4235,19 @@ static int dahdi_digit_begin(struct ast_channel *chan, char digit)
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: