diff --git a/apps/app_directory.c b/apps/app_directory.c index c3e2f1a153..091a42aa9f 100644 --- a/apps/app_directory.c +++ b/apps/app_directory.c @@ -39,6 +39,7 @@ #include "asterisk/say.h" #include "asterisk/app.h" #include "asterisk/utils.h" +#include "asterisk/adsi.h" /*** DOCUMENTATION @@ -111,12 +112,17 @@ Skip calling the extension, instead set it in the DIRECTORY_EXTEN channel variable. + Only one of the f, l, or b options may be specified. If more than one is specified, then Directory will act as if b was specified. The number of characters for the user to type defaults to 3. - @@ -167,6 +173,7 @@ enum { OPT_ALIAS = (1 << 7), OPT_CONFIG_FILE = (1 << 8), OPT_SKIP = (1 << 9), + OPT_ADSI = (1 << 10), }; enum { @@ -200,8 +207,72 @@ AST_APP_OPTIONS(directory_app_options, { AST_APP_OPTION('a', OPT_ALIAS), AST_APP_OPTION_ARG('c', OPT_CONFIG_FILE, OPT_ARG_FILENAME), AST_APP_OPTION('s', OPT_SKIP), + AST_APP_OPTION('d', OPT_ADSI), /* (Would've used 'a', but that was taken already) */ }); +static int adsi_search_input(struct ast_channel *chan) +{ + unsigned char buf[256]; + int bytes = 0; + unsigned char keys[6]; + + memset(keys, 0, sizeof(keys)); + + bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, " ", ""); + bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ", ""); + bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); + bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Query: ***", ""); + bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 1, 1, ADSI_JUST_LEFT); + bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Search", "Search", "#", 1); + bytes += ast_adsi_set_keys(buf + bytes, keys); + bytes += ast_adsi_voice_mode(buf + bytes, 0); + + ast_debug(3, "Sending ADSI search input screen on %s\n", ast_channel_name(chan)); + + return ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); +} + +static int adsi_confirm_match(struct ast_channel *chan, int seq, int total, const char *exten, const char *name, int showexten) +{ + unsigned char buf[4096]; + int alignments[5] = {ADSI_JUST_CENT, ADSI_JUST_CENT, ADSI_JUST_CENT, ADSI_JUST_CENT}; + char *lines[5] = {NULL, NULL, NULL, NULL, NULL}; + int x, bytes = 0; + unsigned char keys[8]; + char matchbuf[32]; + + snprintf(matchbuf, sizeof(matchbuf), "%d of %d", seq + 1, total); /* Make it 1-indexed for user consumption */ + + lines[0] = " "; /* Leave the first line empty so the following lines stand out more */ + lines[1] = matchbuf; + lines[2] = (char*) name; + + if (showexten) { + /* If say extension option is set, show it for ADSI as well */ + lines[3] = (char*) exten; + } + + /* Don't use ast_adsi_print here, this way we can send it all at once instead of in 2 transmissions */ + for (x = 0; lines[x]; x++) { + bytes += ast_adsi_display(buf + bytes, ADSI_INFO_PAGE, x + 1, alignments[x], 0, lines[x], ""); + } + bytes += ast_adsi_set_line(buf + bytes, ADSI_INFO_PAGE, 1); + + keys[3] = ADSI_KEY_APPS + 3; + keys[4] = ADSI_KEY_APPS + 4; + keys[5] = ADSI_KEY_APPS + 5; + /* You might think we only need to set the keys up the first time, but nope, we've got to do it each time. */ + bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Dial", "Dial", "1", 0); + bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 4, "Next", "Next", "*", 0); + bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 5, "Exit", "Exit", "#", 0); + bytes += ast_adsi_set_keys(buf + bytes, keys); + bytes += ast_adsi_voice_mode(buf + bytes, 0); + + ast_debug(3, "Sending ADSI confirmation menu for %s\n", name); + + return ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); +} + static int compare(const char *text, const char *template) { char digit; @@ -374,6 +445,10 @@ static int select_item_seq(struct ast_channel *chan, struct directory_item **ite for (ptr = items, i = 0; i < count; i++, ptr++) { item = *ptr; + if (ast_test_flag(flags, OPT_ADSI) && adsi_confirm_match(chan, i, count, item->exten, item->name, ast_test_flag(flags, OPT_SAYEXTENSION))) { + return -1; + } + for (loop = 3 ; loop > 0; loop--) { if (!res) res = play_mailbox_owner(chan, item->context, item->exten, item->name, flags); @@ -933,6 +1008,18 @@ static int directory_exec(struct ast_channel *chan, const char *data) } digits[7] = digit + '0'; + if (ast_test_flag(&flags, OPT_ADSI)) { + if (!ast_adsi_available(chan)) { + ast_log(LOG_WARNING, "ADSI not available on %s\n", ast_channel_name(chan)); + ast_clear_flag(&flags, OPT_ADSI); + } else { + res = ast_adsi_load_session(chan, NULL, 0, 1); + if (res < 0) { + return res; + } + } + } + if (ast_channel_state(chan) != AST_STATE_UP) { if (!ast_test_flag(&flags, OPT_NOANSWER)) { /* Otherwise answer unless we're supposed to read while on-hook */ @@ -940,6 +1027,9 @@ static int directory_exec(struct ast_channel *chan, const char *data) } } for (;;) { + if (ast_test_flag(&flags, OPT_ADSI) && adsi_search_input(chan)) { + return -1; + } if (!ast_strlen_zero(dirintro) && !res) { res = ast_stream_and_wait(chan, dirintro, AST_DIGIT_ANY); } else if (!res) {