Merged revisions 180032 via svnmerge from

https://origsvn.digium.com/svn/asterisk/trunk

........
  r180032 | dvossel | 2009-03-03 17:21:18 -0600 (Tue, 03 Mar 2009) | 14 lines
  
  app_read does not break from prompt loop with user terminated empty string
  
  In app.c, ast_app_getdata is called to stream the prompts and receive DTMF input.  If ast_app_getdata() receives an empty string caused by the user inputing the end of string character, in this case '#', it should break from the prompt loop and return to app_read, but instead it cycles through all the prompts.  I've added a return value for this special case in ast_readstring() which uses an enum I've delcared in apps.h.  This enum is now used as a return value for ast_app_getdata().
  
  (closes issue #14279)
  Reported by: Marquis
  Patches:
  	fix_app_read.patch uploaded by Marquis (license 32)
  	read-ampersanmd.patch2 uploaded by dvossel (license 671)
  Tested by: Marquis, dvossel
  Review: http://reviewboard.digium.com/r/177/
........


git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.6.0@180078 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
David Vossel
2009-03-03 23:35:18 +00:00
parent ce5bbc3eb8
commit 9cad0b7e22
4 changed files with 33 additions and 14 deletions

View File

@@ -185,11 +185,11 @@ static int read_exec(struct ast_channel *chan, void *data)
}
} else {
res = ast_app_getdata(chan, arglist.filename, tmp, maxdigits, to);
if (res == 0)
if (res == AST_GETDATA_COMPLETE || res == AST_GETDATA_EMPTY_END_TERMINATED)
status = "OK";
else if (res == 1)
else if (res == AST_GETDATA_TIMEOUT)
status = "TIMEOUT";
else if (res == 2)
else if (res == AST_GETDATA_INTERRUPTED)
status = "INTERRUPTED";
}
if (res > -1) {

View File

@@ -196,6 +196,16 @@ int ast_play_and_record(struct ast_channel *chan, const char *playfile, const ch
'silencethreshold' or use '-1' for either or both parameters for defaults. */
int ast_play_and_prepend(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime_sec, char *fmt, int *duration, int beep, int silencethreshold, int maxsilence_ms);
enum ast_getdata_result {
AST_GETDATA_FAILED = -1,
AST_GETDATA_COMPLETE = 0,
AST_GETDATA_TIMEOUT = 1,
AST_GETDATA_INTERRUPTED = 2,
/*! indicates a user terminated empty string rather than an empty string resulting
* from a timeout or other factors */
AST_GETDATA_EMPTY_END_TERMINATED = 3,
};
enum AST_LOCK_RESULT {
AST_LOCK_SUCCESS = 0,
AST_LOCK_TIMEOUT = -1,

View File

@@ -108,7 +108,7 @@ int ast_app_dtget(struct ast_channel *chan, const char *context, char *collect,
* \param maxlen How many digits to read (maximum)
* \param timeout set timeout to 0 for "standard" timeouts. Set timeout to -1 for
* "ludicrous time" (essentially never times out) */
int ast_app_getdata(struct ast_channel *c, const char *prompt, char *s, int maxlen, int timeout)
enum ast_getdata_result ast_app_getdata(struct ast_channel *c, const char *prompt, char *s, int maxlen, int timeout)
{
int res = 0, to, fto;
char *front, *filename;
@@ -145,10 +145,14 @@ int ast_app_getdata(struct ast_channel *c, const char *prompt, char *s, int maxl
to = c->pbx ? c->pbx->dtimeout * 1000 : 2000;
}
res = ast_readstring(c, s, maxlen, to, fto, "#");
if (!ast_strlen_zero(s))
if (res == AST_GETDATA_EMPTY_END_TERMINATED) {
return res;
}
if (!ast_strlen_zero(s)) {
return res;
}
}
return res;
}

View File

@@ -3692,20 +3692,25 @@ int ast_readstring_full(struct ast_channel *c, char *s, int len, int timeout, in
d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
}
if (d < 0)
return -1;
return AST_GETDATA_FAILED;
if (d == 0) {
s[pos]='\0';
return 1;
s[pos] = '\0';
return AST_GETDATA_TIMEOUT;
}
if (d == 1) {
s[pos]='\0';
return 2;
s[pos] = '\0';
return AST_GETDATA_INTERRUPTED;
}
if (!strchr(enders, d))
if (strchr(enders, d) && (pos == 0)) {
s[pos] = '\0';
return AST_GETDATA_EMPTY_END_TERMINATED;
}
if (!strchr(enders, d)) {
s[pos++] = d;
}
if (strchr(enders, d) || (pos >= len)) {
s[pos]='\0';
return 0;
s[pos] = '\0';
return AST_GETDATA_COMPLETE;
}
to = timeout;
}