From b787b1b3bfb49899414809d56225a417222c17ac Mon Sep 17 00:00:00 2001 From: tilghman Date: Thu, 20 Mar 2008 05:06:12 +0000 Subject: Upgrade the sounds version; add several directory enhancements: 1) Number of digits to enter can now be configured 2) The digits can now match on both first AND last name, instead of only one or the other (Closes issue #7151) git-svn-id: http://svn.digium.com/svn/asterisk/trunk@110237 f38db490-d61c-443f-a65b-d21fe96a405b --- apps/app_directory.c | 139 +++++++++++++++++++++++++++++++++++++++++---------- sounds/Makefile | 2 +- 2 files changed, 113 insertions(+), 28 deletions(-) diff --git a/apps/app_directory.c b/apps/app_directory.c index 86a2c842a..03f8dbbe2 100644 --- a/apps/app_directory.c +++ b/apps/app_directory.c @@ -37,6 +37,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/module.h" #include "asterisk/say.h" #include "asterisk/app.h" +#include "asterisk/utils.h" #ifdef ODBC_STORAGE #include @@ -66,28 +67,54 @@ static char *descrip = " extension that the user has selected, or when jumping to the\n" " 'o' or 'a' extension.\n\n" " Options:\n" -" e - In addition to the name, also read the extension number to the\n" -" caller before presenting dialing options.\n" -" f - Allow the caller to enter the first name of a user in the directory\n" -" instead of using the last name.\n" -" m - Instead of reading each name sequentially and asking for confirmation,\n" -" create a menu of up to 8 names.\n"; +" e In addition to the name, also read the extension number to the\n" +" caller before presenting dialing options.\n" +" f[()] Allow the caller to enter the first name of a user in the\n" +" directory instead of using the last name. If specified, the\n" +" optional number argument will be used for the number of\n" +" characters the user should enter.\n" +" l[()] Allow the caller to enter the last name of a user in the\n" +" directory. This is the default. If specified, the\n" +" optional number argument will be used for the number of\n" +" characters the user should enter.\n" +" b[()] Allow the caller to enter either the first or the last name\n" +" of a user in the directory. If specified, the optional number\n" +" argument will be used for the number of characters the user\n" +" should enter.\n" +" m Instead of reading each name sequentially and asking for\n" +" confirmation, create a menu of up to 8 names.\n" +" p() Pause for n milliseconds after the digits are typed. This is\n" +" helpful for people with cellphones, who are not holding the\n" +" receiver to their ear while entering DTMF.\n" +"\n" +" Only one of the f, l, or b options may be specified. If more than one is\n" +" specified, then Directory will act as if 'b' was specified. The number\n" +" of characters for the user to type defaults to 3.\n"; /* For simplicity, I'm keeping the format compatible with the voicemail config, but i'm open to suggestions for isolating it */ #define VOICEMAIL_CONFIG "voicemail.conf" -/* How many digits to read in */ -#define NUMDIGITS 3 - enum { OPT_LISTBYFIRSTNAME = (1 << 0), OPT_SAYEXTENSION = (1 << 1), OPT_FROMVOICEMAIL = (1 << 2), OPT_SELECTFROMMENU = (1 << 3), + OPT_LISTBYLASTNAME = (1 << 4), + OPT_LISTBYEITHER = OPT_LISTBYFIRSTNAME | OPT_LISTBYLASTNAME, + OPT_PAUSE = (1 << 5), } directory_option_flags; +enum { + OPT_ARG_FIRSTNAME = 0, + OPT_ARG_LASTNAME = 1, + OPT_ARG_EITHER = 2, + OPT_ARG_PAUSE = 3, + /* This *must* be the last value in this enum! */ + OPT_ARG_ARRAY_SIZE = 4, +}; + struct directory_item { char exten[AST_MAX_EXTENSION + 1]; char name[AST_MAX_EXTENSION + 1]; @@ -97,7 +124,10 @@ struct directory_item { }; AST_APP_OPTIONS(directory_app_options, { - AST_APP_OPTION('f', OPT_LISTBYFIRSTNAME), + AST_APP_OPTION_ARG('f', OPT_LISTBYFIRSTNAME, OPT_ARG_FIRSTNAME), + AST_APP_OPTION_ARG('l', OPT_LISTBYLASTNAME, OPT_ARG_LASTNAME), + AST_APP_OPTION_ARG('b', OPT_LISTBYEITHER, OPT_ARG_EITHER), + AST_APP_OPTION_ARG('p', OPT_PAUSE, OPT_ARG_PAUSE), AST_APP_OPTION('e', OPT_SAYEXTENSION), AST_APP_OPTION('v', OPT_FROMVOICEMAIL), AST_APP_OPTION('m', OPT_SELECTFROMMENU), @@ -500,10 +530,11 @@ static struct ast_config *realtime_directory(char *context) mailbox = NULL; while ( (mailbox = ast_category_browse(rtdata, mailbox)) ) { fullname = ast_variable_retrieve(rtdata, mailbox, "fullname"); - hidefromdir = ast_variable_retrieve(rtdata, mailbox, "hidefromdir"); - snprintf(tmp, sizeof(tmp), "no-password,%s,hidefromdir=%s", - fullname ? fullname : "", - hidefromdir ? hidefromdir : "no"); + if (ast_true((hidefromdir = ast_variable_retrieve(rtdata, mailbox, "hidefromdir")))) { + /* Skip hidden */ + continue; + } + snprintf(tmp, sizeof(tmp), "no-password,%s", S_OR(fullname, "")); var = ast_variable_new(mailbox, tmp, ""); if (var) ast_variable_append(cat, var); @@ -556,7 +587,7 @@ static int check_match(struct directory_item **result, const char *item_fullname typedef AST_LIST_HEAD_NOLOCK(, directory_item) itemlist; -static int search_directory(const char *context, struct ast_config *vmcfg, struct ast_config *ucfg, const char *ext, int use_first_name, itemlist *alist) +static int search_directory(const char *context, struct ast_config *vmcfg, struct ast_config *ucfg, const char *ext, struct ast_flags flags, itemlist *alist) { struct ast_variable *v; char buf[AST_MAX_EXTENSION + 1], *pos, *bufptr, *cat; @@ -578,7 +609,14 @@ static int search_directory(const char *context, struct ast_config *vmcfg, struc strsep(&bufptr, ","); pos = strsep(&bufptr, ","); - res = check_match(&item, pos, v->name, ext, use_first_name); + res = 0; + if (ast_test_flag(&flags, OPT_LISTBYLASTNAME)) { + res = check_match(&item, pos, v->name, ext, 0 /* use_first_name */); + } + if (!res && ast_test_flag(&flags, OPT_LISTBYFIRSTNAME)) { + res = check_match(&item, pos, v->name, ext, 1 /* use_first_name */); + } + if (!res) continue; else if (res < 0) @@ -601,7 +639,14 @@ static int search_directory(const char *context, struct ast_config *vmcfg, struc if (!pos) continue; - res = check_match(&item, pos, cat, ext, use_first_name); + res = 0; + if (ast_test_flag(&flags, OPT_LISTBYLASTNAME)) { + res = check_match(&item, pos, v->name, ext, 0 /* use_first_name */); + } + if (!res && ast_test_flag(&flags, OPT_LISTBYFIRSTNAME)) { + res = check_match(&item, pos, v->name, ext, 1 /* use_first_name */); + } + if (!res) continue; else if (res < 0) @@ -649,14 +694,14 @@ static int goto_exten(struct ast_channel *chan, const char *dialcontext, char *e } } -static int do_directory(struct ast_channel *chan, struct ast_config *vmcfg, struct ast_config *ucfg, char *context, char *dialcontext, char digit, struct ast_flags *flags) +static int do_directory(struct ast_channel *chan, struct ast_config *vmcfg, struct ast_config *ucfg, char *context, char *dialcontext, char digit, int digits, struct ast_flags *flags) { /* Read in the first three digits.. "digit" is the first digit, already read */ int res = 0; itemlist alist = AST_LIST_HEAD_NOLOCK_INIT_VALUE; struct directory_item *item, **ptr, **sorted = NULL; int count, i; - char ext[NUMDIGITS + 1] = ""; + char ext[10] = ""; if (ast_strlen_zero(context)) { ast_log(LOG_WARNING, @@ -674,10 +719,10 @@ static int do_directory(struct ast_channel *chan, struct ast_config *vmcfg, stru } ext[0] = digit; - if (ast_readstring(chan, ext + 1, NUMDIGITS - 1, 3000, 3000, "#") < 0) + if (ast_readstring(chan, ext + 1, digits - 1, 3000, 3000, "#") < 0) return -1; - res = search_directory(context, vmcfg, ucfg, ext, ast_test_flag(flags, OPT_LISTBYFIRSTNAME), &alist); + res = search_directory(context, vmcfg, ucfg, ext, *flags, &alist); if (res) goto exit; @@ -735,12 +780,14 @@ exit: static int directory_exec(struct ast_channel *chan, void *data) { - int res = 0; + int res = 0, digit = 3; struct ast_config *cfg, *ucfg; const char *dirintro; - char *parse, *opts[0]; + char *parse, *opts[OPT_ARG_ARRAY_SIZE]; struct ast_flags flags = { 0 }; struct ast_flags config_flags = { 0 }; + enum { FIRST, LAST, BOTH } which = LAST; + char digits[9] = "digits/3"; AST_DECLARE_APP_ARGS(args, AST_APP_ARG(vmcontext); AST_APP_ARG(dialcontext); @@ -773,15 +820,53 @@ static int directory_exec(struct ast_channel *chan, void *data) dirintro = ast_variable_retrieve(cfg, args.vmcontext, "directoryintro"); if (ast_strlen_zero(dirintro)) dirintro = ast_variable_retrieve(cfg, "general", "directoryintro"); - if (ast_strlen_zero(dirintro)) - dirintro = ast_test_flag(&flags, OPT_LISTBYFIRSTNAME) ? "dir-intro-fn" : "dir-intro"; + + if (ast_test_flag(&flags, OPT_LISTBYFIRSTNAME) && ast_test_flag(&flags, OPT_LISTBYLASTNAME)) { + if (!ast_strlen_zero(opts[OPT_ARG_EITHER])) { + digit = atoi(opts[OPT_ARG_EITHER]); + } + which = BOTH; + } else if (ast_test_flag(&flags, OPT_LISTBYFIRSTNAME)) { + if (!ast_strlen_zero(opts[OPT_ARG_FIRSTNAME])) { + digit = atoi(opts[OPT_ARG_FIRSTNAME]); + } + which = FIRST; + } else { + if (!ast_strlen_zero(opts[OPT_ARG_LASTNAME])) { + digit = atoi(opts[OPT_ARG_LASTNAME]); + } + which = LAST; + } + + /* If no options specified, search by last name */ + if (!ast_test_flag(&flags, OPT_LISTBYFIRSTNAME) && !ast_test_flag(&flags, OPT_LISTBYLASTNAME)) { + ast_set_flag(&flags, OPT_LISTBYLASTNAME); + which = LAST; + } + + if (digit > 9) { + digit = 9; + } else if (digit < 1) { + digit = 3; + } + digits[7] = digit + '0'; if (chan->_state != AST_STATE_UP) res = ast_answer(chan); for (;;) { - if (!res) + if (!ast_strlen_zero(dirintro) && !res) { res = ast_stream_and_wait(chan, dirintro, AST_DIGIT_ANY); + } else if (!res) { + res = ast_stream_and_wait(chan, "dir-welcome", AST_DIGIT_ANY) || + ast_stream_and_wait(chan, "dir-pls-enter", AST_DIGIT_ANY) || + ast_stream_and_wait(chan, digits, AST_DIGIT_ANY) || + ast_stream_and_wait(chan, + which == FIRST ? "dir-first" : + which == LAST ? "dir-last" : + "dir-firstlast", AST_DIGIT_ANY) || + ast_stream_and_wait(chan, "dir-usingkeypad", AST_DIGIT_ANY); + } ast_stopstream(chan); if (!res) res = ast_waitfordigit(chan, 5000); @@ -789,7 +874,7 @@ static int directory_exec(struct ast_channel *chan, void *data) if (res <= 0) break; - res = do_directory(chan, cfg, ucfg, args.vmcontext, args.dialcontext, res, &flags); + res = do_directory(chan, cfg, ucfg, args.vmcontext, args.dialcontext, res, digit, &flags); if (res) break; diff --git a/sounds/Makefile b/sounds/Makefile index 5ea2beebe..d8261e770 100644 --- a/sounds/Makefile +++ b/sounds/Makefile @@ -17,7 +17,7 @@ SOUNDS_DIR:=$(DESTDIR)$(ASTDATADIR)/sounds MOH_DIR:=$(DESTDIR)$(ASTDATADIR)/moh -CORE_SOUNDS_VERSION:=1.4.9 +CORE_SOUNDS_VERSION:=1.4.10 EXTRA_SOUNDS_VERSION:=1.4.7 SOUNDS_URL:=http://downloads.digium.com/pub/telephony/sounds/releases MCS:=$(subst -EN-,-en-,$(MENUSELECT_CORE_SOUNDS)) -- cgit v1.2.3