[Asterisk-code-review] core: Add digit filtering to ast waitfordigit full (asterisk[master])
Corey Farrell
asteriskteam at digium.com
Wed Jul 12 18:20:14 CDT 2017
Corey Farrell has uploaded this change for review. ( https://gerrit.asterisk.org/6007
Change subject: core: Add digit filtering to ast_waitfordigit_full
......................................................................
core: Add digit filtering to ast_waitfordigit_full
This adds a parameter to ast_waitfordigit_full which can be used to only
stop waiting when certain expected digits are received. Any unexpected
DTMF digits are simply ignored.
This also creates a new dialplan application WaitDigit.
ASTERISK-27129 #close
Change-Id: Id233935ea3d13e71c75a0861834c5936c3700ef9
---
M include/asterisk/channel.h
M main/channel.c
M main/pbx_builtins.c
M res/res_agi.c
4 files changed, 92 insertions(+), 10 deletions(-)
git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/07/6007/1
diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h
index 197cc99..cb2e0e6 100644
--- a/include/asterisk/channel.h
+++ b/include/asterisk/channel.h
@@ -2219,11 +2219,12 @@
* 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 811826f..27efb2e 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -3160,7 +3160,7 @@
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 @@
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 @@
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:
@@ -6351,11 +6354,11 @@
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 bc27b0d..9d43c10 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.
@@ -951,6 +987,47 @@
if (!ast_app_parse_timelen(data, &ms, TIMELEN_SECONDS) && ms > 0) {
return ast_safe_sleep(chan, ms);
}
+ return 0;
+}
+
+/*!
+ * \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;
}
@@ -1410,6 +1487,7 @@
{ "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 e8497f7..4660635 100644
--- a/res/res_agi.c
+++ b/res/res_agi.c
@@ -2393,7 +2393,7 @@
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 @@
/* 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;
--
To view, visit https://gerrit.asterisk.org/6007
To unsubscribe, visit https://gerrit.asterisk.org/settings
Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: Id233935ea3d13e71c75a0861834c5936c3700ef9
Gerrit-Change-Number: 6007
Gerrit-PatchSet: 1
Gerrit-Owner: Corey Farrell <git at cfware.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20170712/6d5813f3/attachment-0001.html>
More information about the asterisk-code-review
mailing list