say.c: Honor requests for DTMF interruption.

SayAlpha, SayAlphaCase, SayDigits, SayMoney, SayNumber, SayOrdinal,
and SayPhonetic all claim to allow DTMF interruption if the
SAY_DTMF_INTERRUPT channel variable is set to a truthy value, but we
are failing to break out of a given 'say' application if DTMF actually
occurs.

ASTERISK-29816 #close

Change-Id: I6a96e0130560831d2cb45164919862b9bcb6287e
This commit is contained in:
Sean Bright 2021-12-23 16:57:59 -05:00 committed by Friendly Automation
parent 9eacfda84d
commit c1d0e23b10
2 changed files with 37 additions and 67 deletions

View File

@ -1323,6 +1323,28 @@ static int pbx_builtin_gotoif(struct ast_channel *chan, const char *data)
return pbx_builtin_goto(chan, branch);
}
/*!
* \brief Determine if DTMF interruption was requested.
*
* If the SAY_DTMF_INTERRUPT channel variable is truthy, the caller has
* requested DTMF interruption be enabled.
*
* \param chan the channel to examine
*
* \retval -1 if DTMF interruption was requested
* \retval 0 if DTMF interruption was not requested
*/
static int permit_dtmf_interrupt(struct ast_channel *chan)
{
int interrupt;
ast_channel_lock(chan);
interrupt = ast_true(pbx_builtin_getvar_helper(chan, "SAY_DTMF_INTERRUPT"));
ast_channel_unlock(chan);
return interrupt;
}
static int pbx_builtin_saynumber(struct ast_channel *chan, const char *data)
{
char tmp[256];
@ -1330,15 +1352,7 @@ static int pbx_builtin_saynumber(struct ast_channel *chan, const char *data)
int number_val;
char *options;
int res;
int interrupt = 0;
const char *interrupt_string;
ast_channel_lock(chan);
interrupt_string = pbx_builtin_getvar_helper(chan, "SAY_DTMF_INTERRUPT");
if (ast_true(interrupt_string)) {
interrupt = 1;
}
ast_channel_unlock(chan);
int interrupt = permit_dtmf_interrupt(chan);
if (ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "SayNumber requires an argument (number)\n");
@ -1377,15 +1391,7 @@ static int pbx_builtin_sayordinal(struct ast_channel *chan, const char *data)
int number_val;
char *options;
int res;
int interrupt = 0;
const char *interrupt_string;
ast_channel_lock(chan);
interrupt_string = pbx_builtin_getvar_helper(chan, "SAY_DTMF_INTERRUPT");
if (ast_true(interrupt_string)) {
interrupt = 1;
}
ast_channel_unlock(chan);
int interrupt = permit_dtmf_interrupt(chan);
if (ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "SayOrdinal requires an argument (number)\n");
@ -1420,18 +1426,9 @@ static int pbx_builtin_sayordinal(struct ast_channel *chan, const char *data)
static int pbx_builtin_saydigits(struct ast_channel *chan, const char *data)
{
int res = 0;
int interrupt = 0;
const char *interrupt_string;
ast_channel_lock(chan);
interrupt_string = pbx_builtin_getvar_helper(chan, "SAY_DTMF_INTERRUPT");
if (ast_true(interrupt_string)) {
interrupt = 1;
}
ast_channel_unlock(chan);
if (data) {
res = ast_say_digit_str(chan, data, interrupt ? AST_DIGIT_ANY : "", ast_channel_language(chan));
res = ast_say_digit_str(chan, data, permit_dtmf_interrupt(chan) ? AST_DIGIT_ANY : "", ast_channel_language(chan));
}
return res;
@ -1440,18 +1437,9 @@ static int pbx_builtin_saydigits(struct ast_channel *chan, const char *data)
static int pbx_builtin_saymoney(struct ast_channel *chan, const char *data)
{
int res = 0;
int interrupt = 0;
const char *interrupt_string;
ast_channel_lock(chan);
interrupt_string = pbx_builtin_getvar_helper(chan, "SAY_DTMF_INTERRUPT");
if (ast_true(interrupt_string)) {
interrupt = 1;
}
ast_channel_unlock(chan);
if (data) {
res = ast_say_money_str(chan, data, interrupt ? AST_DIGIT_ANY : "", ast_channel_language(chan));
res = ast_say_money_str(chan, data, permit_dtmf_interrupt(chan) ? AST_DIGIT_ANY : "", ast_channel_language(chan));
}
return res;
@ -1462,21 +1450,12 @@ static int pbx_builtin_saycharacters_case(struct ast_channel *chan, const char *
int res = 0;
int sensitivity = 0;
char *parse;
int interrupt = 0;
const char *interrupt_string;
AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(options);
AST_APP_ARG(characters);
);
ast_channel_lock(chan);
interrupt_string = pbx_builtin_getvar_helper(chan, "SAY_DTMF_INTERRUPT");
if (ast_true(interrupt_string)) {
interrupt = 1;
}
ast_channel_unlock(chan);
if (ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "SayAlphaCase requires two arguments (options, characters)\n");
return 0;
@ -1508,7 +1487,7 @@ static int pbx_builtin_saycharacters_case(struct ast_channel *chan, const char *
return 0;
}
res = ast_say_character_str(chan, args.characters, interrupt ? AST_DIGIT_ANY : "", ast_channel_language(chan), sensitivity);
res = ast_say_character_str(chan, args.characters, permit_dtmf_interrupt(chan) ? AST_DIGIT_ANY : "", ast_channel_language(chan), sensitivity);
return res;
}
@ -1516,18 +1495,9 @@ static int pbx_builtin_saycharacters_case(struct ast_channel *chan, const char *
static int pbx_builtin_saycharacters(struct ast_channel *chan, const char *data)
{
int res = 0;
int interrupt = 0;
const char *interrupt_string;
ast_channel_lock(chan);
interrupt_string = pbx_builtin_getvar_helper(chan, "SAY_DTMF_INTERRUPT");
if (ast_true(interrupt_string)) {
interrupt = 1;
}
ast_channel_unlock(chan);
if (data) {
res = ast_say_character_str(chan, data, interrupt ? AST_DIGIT_ANY : "", ast_channel_language(chan), AST_SAY_CASE_NONE);
res = ast_say_character_str(chan, data, permit_dtmf_interrupt(chan) ? AST_DIGIT_ANY : "", ast_channel_language(chan), AST_SAY_CASE_NONE);
}
return res;
@ -1536,18 +1506,11 @@ static int pbx_builtin_saycharacters(struct ast_channel *chan, const char *data)
static int pbx_builtin_sayphonetic(struct ast_channel *chan, const char *data)
{
int res = 0;
int interrupt = 0;
const char *interrupt_string;
ast_channel_lock(chan);
interrupt_string = pbx_builtin_getvar_helper(chan, "SAY_DTMF_INTERRUPT");
if (ast_true(interrupt_string)) {
interrupt = 1;
if (data) {
res = ast_say_phonetic_str(chan, data, permit_dtmf_interrupt(chan) ? AST_DIGIT_ANY : "", ast_channel_language(chan));
}
ast_channel_unlock(chan);
if (data)
res = ast_say_phonetic_str(chan, data, interrupt ? AST_DIGIT_ANY : "", ast_channel_language(chan));
return res;
}

View File

@ -189,6 +189,13 @@ static int say_filenames(struct ast_channel *chan, const char *ints, const char
res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
else
res = ast_waitstream(chan, ints);
if (res > 0) {
/* We were interrupted by a digit */
ast_stopstream(chan);
ast_free(filenames);
return res;
}
}
ast_stopstream(chan);
}