forward = "";
if (!rewind)
rewind = "";
+
+ /* Switch the channel to end DTMF frame only. waitstream_core doesn't care about the start of DTMF. */
+ ast_set_flag(c, AST_FLAG_END_DTMF_ONLY);
while (c->stream) {
int res;
res = ast_waitfor(c, ms);
if (res < 0) {
ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno));
+ ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
return res;
}
} else {
if (errno == EINTR)
continue;
ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
+ ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
return -1;
} else if (outfd > -1) { /* this requires cmdfd set */
/* The FD we were watching has something waiting */
+ ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
return 1;
}
/* if rchan is set, it is 'c' */
}
if (res > 0) {
struct ast_frame *fr = ast_read(c);
- if (!fr)
+ if (!fr) {
+ ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
return -1;
+ }
switch (fr->frametype) {
case AST_FRAME_DTMF_END:
if (context) {
if (ast_exists_extension(c, context, exten, 1, c->cid.cid_num)) {
res = fr->subclass;
ast_frfree(fr);
+ ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
return res;
}
} else {
ast_stream_rewind(c->stream, skip_ms);
} else if (strchr(breakon, res)) {
ast_frfree(fr);
+ ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
return res;
}
}
case AST_CONTROL_BUSY:
case AST_CONTROL_CONGESTION:
ast_frfree(fr);
+ ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
return -1;
case AST_CONTROL_RINGING:
case AST_CONTROL_ANSWER:
}
ast_sched_runq(c->sched);
}
+
+ ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
+
return (c->_softhangup ? -1 : 0);
}