From ad0e70ba83d3b7d08127b0a32b73d977dff0dac5 Mon Sep 17 00:00:00 2001 From: Jonathan Rose Date: Thu, 14 Nov 2013 20:32:45 +0000 Subject: [PATCH] Say: If SAY_DTMF_INTERRUPT is set to an ast_true value, jump on DTMF Similar to how background works, if a say application is called with this variable set to 'true', 'yes', 'on', etc. then using DTMF while the say action is in progress will result in the channel jumping to that extension in the dialplan. Review: https://reviewboard.asterisk.org/r/3011/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@402819 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- CHANGES | 9 ++++ apps/app_sayunixtime.c | 14 +++++- main/pbx.c | 101 +++++++++++++++++++++++++++++++++++------ 3 files changed, 108 insertions(+), 16 deletions(-) diff --git a/CHANGES b/CHANGES index 381de61bb8..f2bd97e738 100644 --- a/CHANGES +++ b/CHANGES @@ -21,6 +21,15 @@ ConfBridge menus, bridge settings, and user settings that have been applied by the CONFBRIDGE dialplan function. +Say +-------------------------- + * If a channel variable SAY_DTMF_INTERRUPT is present on a channel and set + to 'true' (case insensitive), then any Say application (SayNumber, + SayDigits, SayAlpha, SayAlphaCase, SayUnixTime, and SayCounted) will + anticipate DTMF. If DTMF is received, these applications will behave like + the background application and jump to the received extension once a match + is established or after a short period of inactivity. + ------------------------------------------------------------------------------ --- Functionality changes from Asterisk 11 to Asterisk 12 -------------------- ------------------------------------------------------------------------------ diff --git a/apps/app_sayunixtime.c b/apps/app_sayunixtime.c index 7d34ed9cda..3b4d2b51e7 100644 --- a/apps/app_sayunixtime.c +++ b/apps/app_sayunixtime.c @@ -59,7 +59,10 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") @@ -129,6 +132,7 @@ static int sayunixtime_exec(struct ast_channel *chan, const char *data) const char * haltondigits = AST_DIGIT_NONE; struct ast_flags64 opts = { 0, }; char *opt_args[OPT_ARG_ARRAY_SIZE]; + const char *interrupt_string; if (!data) { return 0; @@ -146,6 +150,14 @@ static int sayunixtime_exec(struct ast_channel *chan, const char *data) } } + /* Check if 'SAY_DTMF_INTERRUPT' is true and apply the same behavior as the j flag. */ + ast_channel_lock(chan); + interrupt_string = pbx_builtin_getvar_helper(chan, "SAY_DTMF_INTERRUPT"); + if (ast_true(interrupt_string)) { + haltondigits = AST_DIGIT_ANY; + } + ast_channel_unlock(chan); + ast_get_time_t(ast_strlen_zero(args.timeval) ? NULL : args.timeval, &unixtime, time(NULL), NULL); if (ast_channel_state(chan) != AST_STATE_UP) { diff --git a/main/pbx.c b/main/pbx.c index 5c29a0c422..99c686371d 100644 --- a/main/pbx.c +++ b/main/pbx.c @@ -491,8 +491,11 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") - This application will play the sounds that correspond to the letters of the - given string. + This application will play the sounds that correspond to the letters + of the given string. If the channel variable + SAY_DTMF_INTERRUPT is set to 'true' (case insensitive), + then this application will react to DTMF in the same way as + Background. SayDigits @@ -531,7 +534,9 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") This application will play the sounds that correspond to the letters of the given string. Optionally, a casetype may be - specified. This will be used for case-insensitive or case-sensitive pronunciations. + specified. This will be used for case-insensitive or case-sensitive pronunciations. If the channel + variable SAY_DTMF_INTERRUPT is set to 'true' (case insensitive), then this + application will react to DTMF in the same way as Background. SayDigits @@ -550,7 +555,10 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") This application will play the sounds that correspond to the digits of - the given number. This will use the language that is currently set for the channel. + the given number. This will use the language that is currently set for the channel. + If the channel variable SAY_DTMF_INTERRUPT is set to 'true' + (case insensitive), then this application will react to DTMF in the same way as + Background. SayAlpha @@ -568,9 +576,12 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") - This application will play the sounds that correspond to the given digits. - Optionally, a gender may be specified. This will use the language that is currently - set for the channel. See the CHANNEL() function for more information on setting the language for the channel. + This application will play the sounds that correspond to the given + digits. Optionally, a gender may be + specified. This will use the language that is currently set for the channel. See the CHANNEL() + function for more information on setting the language for the channel. If the channel variable + SAY_DTMF_INTERRUPT is set to 'true' (case insensitive), then this + application will react to DTMF in the same way as Background. SayAlpha @@ -588,7 +599,9 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") This application will play the sounds from the phonetic alphabet that correspond to the - letters in the given string. + letters in the given string. If the channel variable + SAY_DTMF_INTERRUPT is set to 'true' (case insensitive), then this + application will react to DTMF in the same way as Background. SayAlpha @@ -11288,7 +11301,18 @@ static int pbx_builtin_saynumber(struct ast_channel *chan, const char *data) { char tmp[256]; char *number = tmp; + 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); if (ast_strlen_zero(data)) { ast_log(LOG_WARNING, "SayNumber requires an argument (number)\n"); @@ -11296,6 +11320,12 @@ static int pbx_builtin_saynumber(struct ast_channel *chan, const char *data) } ast_copy_string(tmp, data, sizeof(tmp)); strsep(&number, ","); + + if (sscanf(tmp, "%d", &number_val) != 1) { + ast_log(LOG_WARNING, "argument '%s' to SayNumber could not be parsed as a number.\n", tmp); + return 0; + } + options = strsep(&number, ","); if (options) { if ( strcasecmp(options, "f") && strcasecmp(options, "m") && @@ -11305,19 +11335,32 @@ static int pbx_builtin_saynumber(struct ast_channel *chan, const char *data) } } - if (ast_say_number(chan, atoi(tmp), "", ast_channel_language(chan), options)) { + res = ast_say_number(chan, number_val, interrupt ? AST_DIGIT_ANY : "", ast_channel_language(chan), options); + + if (res < 0) { ast_log(LOG_WARNING, "We were unable to say the number %s, is it too large?\n", tmp); } - return 0; + return interrupt ? res : 0; } 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)); + } - if (data) - res = ast_say_digit_str(chan, data, "", ast_channel_language(chan)); return res; } @@ -11326,11 +11369,21 @@ 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; @@ -11362,7 +11415,7 @@ static int pbx_builtin_saycharacters_case(struct ast_channel *chan, const char * return 0; } - res = ast_say_character_str(chan, args.characters, "", ast_channel_language(chan), sensitivity); + res = ast_say_character_str(chan, args.characters, interrupt ? AST_DIGIT_ANY : "", ast_channel_language(chan), sensitivity); return res; } @@ -11370,9 +11423,18 @@ 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, "", ast_channel_language(chan), AST_SAY_CASE_NONE); + res = ast_say_character_str(chan, data, interrupt ? AST_DIGIT_ANY : "", ast_channel_language(chan), AST_SAY_CASE_NONE); } return res; @@ -11381,9 +11443,18 @@ 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; + } + ast_channel_unlock(chan); if (data) - res = ast_say_phonetic_str(chan, data, "", ast_channel_language(chan)); + res = ast_say_phonetic_str(chan, data, interrupt ? AST_DIGIT_ANY : "", ast_channel_language(chan)); return res; }