--- asterisk-11.17.1/apps/app_read.c 2015-07-22 20:39:54.814831867 +0200 +++ asterisk-11.17.1-w1/apps/app_read.c 2015-07-22 21:15:51.021981514 +0200 @@ -21,14 +21,14 @@ * \brief Trivial application to read a variable * * \author Mark Spencer - * + * * \ingroup applications */ /*** MODULEINFO core ***/ - + #include "asterisk.h" ASTERISK_FILE_VERSION(__FILE__, "$Revision$") @@ -77,6 +77,12 @@ + @@ -116,12 +122,14 @@ OPT_SKIP = (1 << 0), OPT_INDICATION = (1 << 1), OPT_NOANSWER = (1 << 2), + OPT_HASH = (1 << 3), }; AST_APP_OPTIONS(read_app_options, { AST_APP_OPTION('s', OPT_SKIP), AST_APP_OPTION('i', OPT_INDICATION), AST_APP_OPTION('n', OPT_NOANSWER), + AST_APP_OPTION('h', OPT_HASH), }); static char *app = "Read"; @@ -146,13 +154,13 @@ AST_APP_ARG(attempts); AST_APP_ARG(timeout); ); - + pbx_builtin_setvar_helper(chan, "READSTATUS", status); if (ast_strlen_zero(data)) { ast_log(LOG_WARNING, "Read requires an argument (variable)\n"); return 0; } - + argcopy = ast_strdupa(data); AST_STANDARD_APP_ARGS(arglist, argcopy); @@ -160,7 +168,7 @@ if (!ast_strlen_zero(arglist.options)) { ast_app_parse_options(read_app_options, &flags, NULL, arglist.options); } - + if (!ast_strlen_zero(arglist.attempts)) { tries = atoi(arglist.attempts); if (tries <= 0) @@ -185,6 +193,12 @@ } else ast_verb(3, "Accepting a maximum of %d digits.\n", maxdigits); } + + if (ast_test_flag(&flags, OPT_HASH) && to == 0 && ast_strlen_zero(arglist.maxdigits)) { + ast_log(LOG_ERROR, "Read(): option h requires setting timeout or maxdigits"); + return 0; + } + if (ast_strlen_zero(arglist.variable)) { ast_log(LOG_WARNING, "Invalid! Usage: Read(variable[,filename][,maxdigits][,option][,attempts][,timeout])\n\n"); return 0; @@ -208,37 +222,44 @@ if (!res) { while (tries && !res) { ast_stopstream(chan); + if (!to) { + to = ast_channel_pbx(chan) ? ast_channel_pbx(chan)->rtimeoutms : 6000; + } + + x = 0; if (ts && ts->data[0]) { - if (!to) - to = ast_channel_pbx(chan) ? ast_channel_pbx(chan)->rtimeoutms : 6000; res = ast_playtones_start(chan, 0, ts->data, 0); - for (x = 0; x < maxdigits; ) { - res = ast_waitfordigit(chan, to); - ast_playtones_stop(chan); - if (res < 1) { - if (res == 0) - status = "TIMEOUT"; - tmp[x]='\0'; - break; - } - tmp[x++] = res; - if (tmp[x-1] == '#') { - tmp[x-1] = '\0'; - status = "OK"; - break; - } - if (x >= maxdigits) { - status = "OK"; - } - } } else { res = ast_app_getdata(chan, arglist.filename, tmp, maxdigits, to); - if (res == AST_GETDATA_COMPLETE || res == AST_GETDATA_EMPTY_END_TERMINATED) + if (res == AST_GETDATA_COMPLETE || res == AST_GETDATA_EMPTY_END_TERMINATED) { status = "OK"; - else if (res == AST_GETDATA_TIMEOUT) + x = strlen(tmp); + if (x < maxdigits && ast_test_flag(&flags, OPT_HASH)) { + res = tmp[x++] = '#'; + } + } + else if (res == AST_GETDATA_TIMEOUT) { status = "TIMEOUT"; - else if (res == AST_GETDATA_INTERRUPTED) + } + else if (res == AST_GETDATA_INTERRUPTED) { status = "INTERRUPTED"; + } + } + + while (x < maxdigits && ast_test_flag(&flags, OPT_HASH) && res) { + res = ast_waitfordigit(chan, to); + if (x == 0) { + ast_playtones_stop(chan); + } + if (res < 1) { + if (res == 0) status = "TIMEOUT"; + tmp[x] = '\0'; + break; + } + tmp[x++] = res; + if (x >= maxdigits) { + status = "OK"; + } } if (res > -1) { pbx_builtin_setvar_helper(chan, arglist.variable, tmp); @@ -247,10 +268,7 @@ tries = 0; } else { tries--; - if (tries) - ast_verb(3, "User entered nothing, %d chance%s left\n", tries, (tries != 1) ? "s" : ""); - else - ast_verb(3, "User entered nothing.\n"); + ast_verb(3, "User entered nothing, %d chance%s left\n", tries, (tries != 1) ? "s" : ""); } res = 0; } else {