diff options
author | Joshua Colp <jcolp@digium.com> | 2017-07-19 13:09:56 -0500 |
---|---|---|
committer | Gerrit Code Review <gerrit2@gerrit.digium.api> | 2017-07-19 13:09:56 -0500 |
commit | f43fc9191132d93918a2e4c173c876dd1cbfe4d2 (patch) | |
tree | 788868ae28128a2586c2996ad160a67076ffbd5f | |
parent | 66b8c454d139cd51ededad78ec34fef99c7e2dd6 (diff) | |
parent | 6b138046e7db59e975fc06ee3aea54fe0c143f5d (diff) |
Merge "core: Add digit filtering to ast_waitfordigit_full"
-rw-r--r-- | include/asterisk/channel.h | 3 | ||||
-rw-r--r-- | main/channel.c | 17 | ||||
-rw-r--r-- | main/pbx_builtins.c | 78 | ||||
-rw-r--r-- | res/res_agi.c | 4 |
4 files changed, 92 insertions, 10 deletions
diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h index 55126b472..f0fe5b212 100644 --- a/include/asterisk/channel.h +++ b/include/asterisk/channel.h @@ -2239,11 +2239,12 @@ int ast_waitfordigit(struct ast_channel *c, int ms); * Same as ast_waitfordigit() with audio fd for outputting read audio and ctrlfd to monitor for reading. * \param c channel to wait for a digit on * \param ms how many milliseconds to wait (<0 for indefinite). + * \param breakon string of DTMF digits to break upon or NULL for any. * \param audiofd audio file descriptor to write to if audio frames are received * \param ctrlfd control file descriptor to monitor for reading * \return Returns 1 if ctrlfd becomes available */ -int ast_waitfordigit_full(struct ast_channel *c, int ms, int audiofd, int ctrlfd); +int ast_waitfordigit_full(struct ast_channel *c, int ms, const char *breakon, int audiofd, int ctrlfd); /*! * \brief Reads multiple digits diff --git a/main/channel.c b/main/channel.c index 23bb74f08..66825559c 100644 --- a/main/channel.c +++ b/main/channel.c @@ -3160,7 +3160,7 @@ int ast_waitfor(struct ast_channel *c, int ms) int ast_waitfordigit(struct ast_channel *c, int ms) { - return ast_waitfordigit_full(c, ms, -1, -1); + return ast_waitfordigit_full(c, ms, NULL, -1, -1); } int ast_settimeout(struct ast_channel *c, unsigned int rate, int (*func)(const void *data), void *data) @@ -3222,7 +3222,7 @@ int ast_settimeout_full(struct ast_channel *c, unsigned int rate, int (*func)(co return res; } -int ast_waitfordigit_full(struct ast_channel *c, int timeout_ms, int audiofd, int cmdfd) +int ast_waitfordigit_full(struct ast_channel *c, int timeout_ms, const char *breakon, int audiofd, int cmdfd) { struct timeval start = ast_tvnow(); int ms; @@ -3273,9 +3273,12 @@ int ast_waitfordigit_full(struct ast_channel *c, int timeout_ms, int audiofd, in break; case AST_FRAME_DTMF_END: res = f->subclass.integer; - ast_frfree(f); - ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY); - return res; + if (!breakon || strchr(breakon, res)) { + ast_frfree(f); + ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY); + return res; + } + break; case AST_FRAME_CONTROL: switch (f->subclass.integer) { case AST_CONTROL_HANGUP: @@ -6356,11 +6359,11 @@ int ast_readstring_full(struct ast_channel *c, char *s, int len, int timeout, in silgen = ast_channel_start_silence_generator(c); usleep(1000); if (!d) - d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); + d = ast_waitfordigit_full(c, to, NULL, audiofd, ctrlfd); } else { if (!silgen && ast_opt_transmit_silence) silgen = ast_channel_start_silence_generator(c); - d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); + d = ast_waitfordigit_full(c, to, NULL, audiofd, ctrlfd); } if (d < 0) { ast_channel_stop_silence_generator(c, silgen); diff --git a/main/pbx_builtins.c b/main/pbx_builtins.c index bc27b0d58..9d43c10ff 100644 --- a/main/pbx_builtins.c +++ b/main/pbx_builtins.c @@ -580,6 +580,42 @@ <para>This application waits for a specified number of <replaceable>seconds</replaceable>.</para> </description> </application> + <application name="WaitDigit" language="en_US"> + <synopsis> + Waits for a digit to be entered. + </synopsis> + <syntax> + <parameter name="seconds"> + <para>Can be passed with fractions of a second. For example, <literal>1.5</literal> will ask the + application to wait for 1.5 seconds.</para> + </parameter> + <parameter name="digits"> + <para>Digits to accept, all others are ignored.</para> + </parameter> + </syntax> + <description> + <para>This application waits for the user to press one of the accepted + <replaceable>digits</replaceable> for a specified number of + <replaceable>seconds</replaceable>.</para> + <variablelist> + <variable name="WAITDIGITSTATUS"> + <para>This is the final status of the command</para> + <value name="ERROR">Parameters are invalid.</value> + <value name="DTMF">An accepted digit was received.</value> + <value name="TIMEOUT">The timeout passed before any acceptable digits were received.</value> + <value name="CANCEL">The channel has hungup or was redirected.</value> + </variable> + <variable name="WAITDIGITRESULT"> + <para>The digit that was received, only set if + <variable>WAITDIGITSTATUS</variable> is <literal>DTMF</literal>.</para> + </variable> + </variablelist> + </description> + <see-also> + <ref type="application">Wait</ref> + <ref type="application">WaitExten</ref> + </see-also> + </application> <application name="WaitExten" language="en_US"> <synopsis> Waits for an extension to be entered. @@ -957,6 +993,47 @@ static int pbx_builtin_wait(struct ast_channel *chan, const char *data) /*! * \ingroup applications */ +static int pbx_builtin_waitdigit(struct ast_channel *chan, const char *data) +{ + int res; + int ms; + char *parse; + AST_DECLARE_APP_ARGS(args, + AST_APP_ARG(timeout); + AST_APP_ARG(digits); + ); + + parse = ast_strdupa(data); + AST_STANDARD_APP_ARGS(args, parse); + + if (ast_app_parse_timelen(args.timeout, &ms, TIMELEN_SECONDS) || ms < 0) { + pbx_builtin_setvar_helper(chan, "WAITDIGITSTATUS", "ERROR"); + return 0; + } + + /* Wait for "n" seconds */ + res = ast_waitfordigit_full(chan, ms, S_OR(args.digits, AST_DIGIT_ANY), -1, -1); + if (res < 0) { + pbx_builtin_setvar_helper(chan, "WAITDIGITSTATUS", "CANCEL"); + return -1; + } + + if (res == 0) { + pbx_builtin_setvar_helper(chan, "WAITDIGITSTATUS", "TIMEOUT"); + } else { + char key[2]; + + snprintf(key, sizeof(key), "%c", res); + pbx_builtin_setvar_helper(chan, "WAITDIGITRESULT", key); + pbx_builtin_setvar_helper(chan, "WAITDIGITSTATUS", "DTMF"); + } + + return 0; +} + +/*! + * \ingroup applications + */ static int pbx_builtin_waitexten(struct ast_channel *chan, const char *data) { int ms, res; @@ -1410,6 +1487,7 @@ struct pbx_builtin { { "SayPhonetic", pbx_builtin_sayphonetic }, { "SetAMAFlags", pbx_builtin_setamaflags }, { "Wait", pbx_builtin_wait }, + { "WaitDigit", pbx_builtin_waitdigit }, { "WaitExten", pbx_builtin_waitexten } }; diff --git a/res/res_agi.c b/res/res_agi.c index e8497f7ca..466063557 100644 --- a/res/res_agi.c +++ b/res/res_agi.c @@ -2393,7 +2393,7 @@ static int handle_waitfordigit(struct ast_channel *chan, AGI *agi, int argc, con return RESULT_SHOWUSAGE; if (sscanf(argv[3], "%30d", &to) != 1) return RESULT_SHOWUSAGE; - res = ast_waitfordigit_full(chan, to, agi->audio, agi->ctrl); + res = ast_waitfordigit_full(chan, to, NULL, agi->audio, agi->ctrl); ast_agi_send(agi->fd, chan, "200 result=%d\n", res); return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; } @@ -2673,7 +2673,7 @@ static int handle_getoption(struct ast_channel *chan, AGI *agi, int argc, const /* If the user didnt press a key, wait for digitTimeout*/ if (res == 0 ) { - res = ast_waitfordigit_full(chan, timeout, agi->audio, agi->ctrl); + res = ast_waitfordigit_full(chan, timeout, NULL, agi->audio, agi->ctrl); /* Make sure the new result is in the escape digits of the GET OPTION */ if ( !strchr(edigits,res) ) res=0; |