mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-05 12:16:00 +00:00
Make the ast_read_noaudio API call behave better under circumstances where DTMF emulation was happening and a generator was setup. (issue #10065 reported by stevefeinstein)
git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@72148 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -2127,6 +2127,36 @@ int ast_waitfordigit_full(struct ast_channel *c, int ms, int audiofd, int cmdfd)
|
||||
return 0; /* Time is up */
|
||||
}
|
||||
|
||||
static void ast_read_generator_actions(struct ast_channel *chan, struct ast_frame *f)
|
||||
{
|
||||
if (chan->generatordata && !ast_internal_timing_enabled(chan)) {
|
||||
void *tmp = chan->generatordata;
|
||||
int res;
|
||||
|
||||
if (chan->timingfunc) {
|
||||
if (option_debug > 1)
|
||||
ast_log(LOG_DEBUG, "Generator got voice, switching to phase locked mode\n");
|
||||
ast_settimeout(chan, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
chan->generatordata = NULL; /* reset, to let writes go through */
|
||||
res = chan->generator->generate(chan, tmp, f->datalen, f->samples);
|
||||
chan->generatordata = tmp;
|
||||
if (res) {
|
||||
if (option_debug > 1)
|
||||
ast_log(LOG_DEBUG, "Auto-deactivating generator\n");
|
||||
ast_deactivate_generator(chan);
|
||||
}
|
||||
|
||||
} else if (f->frametype == AST_FRAME_CNG) {
|
||||
if (chan->generator && !chan->timingfunc && (chan->timingfd > -1)) {
|
||||
if (option_debug > 1)
|
||||
ast_log(LOG_DEBUG, "Generator got CNG, switching to timed mode\n");
|
||||
ast_settimeout(chan, 160, generator_force, chan);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
|
||||
{
|
||||
struct ast_frame *f = NULL; /* the return value */
|
||||
@@ -2382,9 +2412,13 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
|
||||
}
|
||||
|
||||
if (dropaudio || ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
|
||||
if (dropaudio)
|
||||
ast_read_generator_actions(chan, f);
|
||||
ast_frfree(f);
|
||||
f = &ast_null_frame;
|
||||
} else if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) {
|
||||
}
|
||||
|
||||
if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
|
||||
struct timeval now = ast_tvnow();
|
||||
if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) {
|
||||
chan->emulate_dtmf_duration = 0;
|
||||
@@ -2399,14 +2433,14 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
|
||||
ast_frfree(f);
|
||||
f = &ast_null_frame;
|
||||
}
|
||||
} else if (!(f->subclass & chan->nativeformats)) {
|
||||
} else if ((f->frametype == AST_FRAME_VOICE) && !(f->subclass & chan->nativeformats)) {
|
||||
/* This frame can't be from the current native formats -- drop it on the
|
||||
floor */
|
||||
ast_log(LOG_NOTICE, "Dropping incompatible voice frame on %s of format %s since our native format has changed to %s\n",
|
||||
chan->name, ast_getformatname(f->subclass), ast_getformatname(chan->nativeformats));
|
||||
ast_frfree(f);
|
||||
f = &ast_null_frame;
|
||||
} else {
|
||||
} else if ((f->frametype == AST_FRAME_VOICE)) {
|
||||
if (chan->spies)
|
||||
queue_frame_to_spies(chan, f, SPY_READ);
|
||||
|
||||
@@ -2441,32 +2475,7 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
|
||||
|
||||
/* Run generator sitting on the line if timing device not available
|
||||
* and synchronous generation of outgoing frames is necessary */
|
||||
if (chan->generatordata && !ast_internal_timing_enabled(chan)) {
|
||||
void *tmp = chan->generatordata;
|
||||
int res;
|
||||
|
||||
if (chan->timingfunc) {
|
||||
if (option_debug > 1)
|
||||
ast_log(LOG_DEBUG, "Generator got voice, switching to phase locked mode\n");
|
||||
ast_settimeout(chan, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
chan->generatordata = NULL; /* reset, to let writes go through */
|
||||
res = chan->generator->generate(chan, tmp, f->datalen, f->samples);
|
||||
chan->generatordata = tmp;
|
||||
if (res) {
|
||||
if (option_debug > 1)
|
||||
ast_log(LOG_DEBUG, "Auto-deactivating generator\n");
|
||||
ast_deactivate_generator(chan);
|
||||
}
|
||||
|
||||
} else if (f->frametype == AST_FRAME_CNG) {
|
||||
if (chan->generator && !chan->timingfunc && (chan->timingfd > -1)) {
|
||||
if (option_debug > 1)
|
||||
ast_log(LOG_DEBUG, "Generator got CNG, switching to timed mode\n");
|
||||
ast_settimeout(chan, 160, generator_force, chan);
|
||||
}
|
||||
}
|
||||
ast_read_generator_actions(chan, f);
|
||||
}
|
||||
default:
|
||||
/* Just pass it on! */
|
||||
|
Reference in New Issue
Block a user