summaryrefslogtreecommitdiff
path: root/channels
diff options
context:
space:
mode:
authorMark Michelson <mmichelson@digium.com>2015-08-12 13:37:38 -0500
committerGerrit Code Review <gerrit2@gerrit.digium.api>2015-08-12 13:37:39 -0500
commitd37488c7c32f029db46488e7f7687e7a9171fd5a (patch)
treefe2344dbb399bf0fb37df29bd677650d68852f83 /channels
parentf8df3589cd612d4b1d3f0a062e1b9a9bcb6218b2 (diff)
parent256bc52b6684141b100c5018dbf0ad3ce6111585 (diff)
Merge topic 'ASTERISK-25315' into 13
* changes: chan_dahdi.c: Flush the DAHDI write buffer after starting DTMF. chan_dahdi.c: Lock private struct for ast_write().
Diffstat (limited to 'channels')
-rw-r--r--channels/chan_dahdi.c55
1 files changed, 41 insertions, 14 deletions
diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c
index 953561ce4..248a7fd10 100644
--- a/channels/chan_dahdi.c
+++ b/channels/chan_dahdi.c
@@ -4199,7 +4199,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);
@@ -4222,8 +4222,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' };
@@ -4233,10 +4236,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:
@@ -8773,39 +8785,52 @@ static int my_dahdi_write(struct dahdi_pvt *p, unsigned char *buf, int len, int
static int dahdi_write(struct ast_channel *ast, struct ast_frame *frame)
{
- struct dahdi_pvt *p = ast_channel_tech_pvt(ast);
+ struct dahdi_pvt *p;
int res;
int idx;
+
+ /* Write a frame of (presumably voice) data */
+ if (frame->frametype != AST_FRAME_VOICE) {
+ if (frame->frametype != AST_FRAME_IMAGE) {
+ ast_log(LOG_WARNING, "Don't know what to do with frame type '%u'\n",
+ frame->frametype);
+ }
+ return 0;
+ }
+
+ /* Return if it's not valid data */
+ if (!frame->data.ptr || !frame->datalen) {
+ return 0;
+ }
+
+ p = ast_channel_tech_pvt(ast);
+ ast_mutex_lock(&p->lock);
+
idx = dahdi_get_index(ast, p, 0);
if (idx < 0) {
+ ast_mutex_unlock(&p->lock);
ast_log(LOG_WARNING, "%s doesn't really exist?\n", ast_channel_name(ast));
return -1;
}
- /* Write a frame of (presumably voice) data */
- if (frame->frametype != AST_FRAME_VOICE) {
- if (frame->frametype != AST_FRAME_IMAGE)
- ast_log(LOG_WARNING, "Don't know what to do with frame type '%u'\n", frame->frametype);
- return 0;
- }
if (p->dialing) {
+ ast_mutex_unlock(&p->lock);
ast_debug(5, "Dropping frame since I'm still dialing on %s...\n",
ast_channel_name(ast));
return 0;
}
if (!p->owner) {
+ ast_mutex_unlock(&p->lock);
ast_debug(5, "Dropping frame since there is no active owner on %s...\n",
ast_channel_name(ast));
return 0;
}
if (p->cidspill) {
+ ast_mutex_unlock(&p->lock);
ast_debug(5, "Dropping frame since I've still got a callerid spill on %s...\n",
ast_channel_name(ast));
return 0;
}
- /* Return if it's not valid data */
- if (!frame->data.ptr || !frame->datalen)
- return 0;
if (ast_format_cmp(frame->subclass.format, ast_format_slin) == AST_FORMAT_CMP_EQUAL) {
if (!p->subs[idx].linear) {
@@ -8826,10 +8851,12 @@ static int dahdi_write(struct ast_channel *ast, struct ast_frame *frame)
}
res = my_dahdi_write(p, (unsigned char *)frame->data.ptr, frame->datalen, idx, 0);
} else {
+ ast_mutex_unlock(&p->lock);
ast_log(LOG_WARNING, "Cannot handle frames in %s format\n",
ast_format_get_name(frame->subclass.format));
return -1;
}
+ ast_mutex_unlock(&p->lock);
if (res < 0) {
ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
return -1;