Merge "core: Add digit filtering to ast_waitfordigit_full"
This commit is contained in:
commit
f43fc91911
4 changed files with 92 additions and 10 deletions
|
@ -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.
|
* 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 c channel to wait for a digit on
|
||||||
* \param ms how many milliseconds to wait (<0 for indefinite).
|
* \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 audiofd audio file descriptor to write to if audio frames are received
|
||||||
* \param ctrlfd control file descriptor to monitor for reading
|
* \param ctrlfd control file descriptor to monitor for reading
|
||||||
* \return Returns 1 if ctrlfd becomes available
|
* \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
|
* \brief Reads multiple digits
|
||||||
|
|
|
@ -3160,7 +3160,7 @@ int ast_waitfor(struct ast_channel *c, int ms)
|
||||||
|
|
||||||
int ast_waitfordigit(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)
|
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;
|
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();
|
struct timeval start = ast_tvnow();
|
||||||
int ms;
|
int ms;
|
||||||
|
@ -3273,9 +3273,12 @@ int ast_waitfordigit_full(struct ast_channel *c, int timeout_ms, int audiofd, in
|
||||||
break;
|
break;
|
||||||
case AST_FRAME_DTMF_END:
|
case AST_FRAME_DTMF_END:
|
||||||
res = f->subclass.integer;
|
res = f->subclass.integer;
|
||||||
|
if (!breakon || strchr(breakon, res)) {
|
||||||
ast_frfree(f);
|
ast_frfree(f);
|
||||||
ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
|
ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
|
||||||
return res;
|
return res;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case AST_FRAME_CONTROL:
|
case AST_FRAME_CONTROL:
|
||||||
switch (f->subclass.integer) {
|
switch (f->subclass.integer) {
|
||||||
case AST_CONTROL_HANGUP:
|
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);
|
silgen = ast_channel_start_silence_generator(c);
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
if (!d)
|
if (!d)
|
||||||
d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
|
d = ast_waitfordigit_full(c, to, NULL, audiofd, ctrlfd);
|
||||||
} else {
|
} else {
|
||||||
if (!silgen && ast_opt_transmit_silence)
|
if (!silgen && ast_opt_transmit_silence)
|
||||||
silgen = ast_channel_start_silence_generator(c);
|
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) {
|
if (d < 0) {
|
||||||
ast_channel_stop_silence_generator(c, silgen);
|
ast_channel_stop_silence_generator(c, silgen);
|
||||||
|
|
|
@ -580,6 +580,42 @@
|
||||||
<para>This application waits for a specified number of <replaceable>seconds</replaceable>.</para>
|
<para>This application waits for a specified number of <replaceable>seconds</replaceable>.</para>
|
||||||
</description>
|
</description>
|
||||||
</application>
|
</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">
|
<application name="WaitExten" language="en_US">
|
||||||
<synopsis>
|
<synopsis>
|
||||||
Waits for an extension to be entered.
|
Waits for an extension to be entered.
|
||||||
|
@ -954,6 +990,47 @@ static int pbx_builtin_wait(struct ast_channel *chan, const char *data)
|
||||||
return 0;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \ingroup applications
|
* \ingroup applications
|
||||||
*/
|
*/
|
||||||
|
@ -1410,6 +1487,7 @@ struct pbx_builtin {
|
||||||
{ "SayPhonetic", pbx_builtin_sayphonetic },
|
{ "SayPhonetic", pbx_builtin_sayphonetic },
|
||||||
{ "SetAMAFlags", pbx_builtin_setamaflags },
|
{ "SetAMAFlags", pbx_builtin_setamaflags },
|
||||||
{ "Wait", pbx_builtin_wait },
|
{ "Wait", pbx_builtin_wait },
|
||||||
|
{ "WaitDigit", pbx_builtin_waitdigit },
|
||||||
{ "WaitExten", pbx_builtin_waitexten }
|
{ "WaitExten", pbx_builtin_waitexten }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2393,7 +2393,7 @@ static int handle_waitfordigit(struct ast_channel *chan, AGI *agi, int argc, con
|
||||||
return RESULT_SHOWUSAGE;
|
return RESULT_SHOWUSAGE;
|
||||||
if (sscanf(argv[3], "%30d", &to) != 1)
|
if (sscanf(argv[3], "%30d", &to) != 1)
|
||||||
return RESULT_SHOWUSAGE;
|
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);
|
ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
|
||||||
return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE;
|
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 the user didnt press a key, wait for digitTimeout*/
|
||||||
if (res == 0 ) {
|
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 */
|
/* Make sure the new result is in the escape digits of the GET OPTION */
|
||||||
if ( !strchr(edigits,res) )
|
if ( !strchr(edigits,res) )
|
||||||
res=0;
|
res=0;
|
||||||
|
|
Loading…
Reference in a new issue