Index: apps/app_voicemail.c =================================================================== --- apps/app_voicemail.c (revision 84404) +++ apps/app_voicemail.c (working copy) @@ -243,6 +243,7 @@ OPT_RECORDGAIN = (1 << 3), OPT_PREPEND_MAILBOX = (1 << 4), OPT_AUTOPLAY = (1 << 6), + OPT_DTMF_EXIT = (1 << 7), } vm_option_flags; enum { @@ -255,6 +256,7 @@ AST_APP_OPTIONS(vm_app_options, { AST_APP_OPTION('s', OPT_SILENT), AST_APP_OPTION('b', OPT_BUSY_GREETING), + AST_APP_OPTION('d', OPT_DTMF_EXIT), AST_APP_OPTION('u', OPT_UNAVAIL_GREETING), AST_APP_OPTION_ARG('g', OPT_RECORDGAIN, OPT_ARG_RECORDGAIN), AST_APP_OPTION('p', OPT_PREPEND_MAILBOX), @@ -500,6 +502,10 @@ " SUCCESS | USEREXIT | FAILED\n\n" " Options:\n" " b - Play the 'busy' greeting to the calling party.\n" + " d - Allow the caller to dial a 1 digit extension while listening to\n" + " the voicemail greeting or recording a voicemail message. Exit to\n" + " that extension if it exists in the current context, or the context\n" + " defined in the VMEXITCONTEXT variable, if it exists.\n" " g(#) - Use the specified amount of gain when recording the voicemail\n" " message. The units are whole-number decibels (dB).\n" " s - Skip the playback of instructions for leaving a message to the\n" @@ -2997,6 +3003,9 @@ struct ast_vm_user *vmu; struct ast_vm_user svm; const char *category = NULL; + int vm_exit_ext = 0; + char str_vm_exit_ext[2]; + char str_vm_exit_exts[10] = ""; ast_copy_string(tmp, ext, sizeof(tmp)); ext = tmp; @@ -3067,6 +3076,29 @@ ausemacro = 1; } + /* vm_exit setup */ + if (ast_test_flag(options, OPT_DTMF_EXIT)) { + + for (vm_exit_ext = 1; vm_exit_ext <= 9; vm_exit_ext++) { + snprintf(str_vm_exit_ext, sizeof(str_vm_exit_ext), "%d", vm_exit_ext); + + if (!ast_strlen_zero(vmu->exit)) { // check default exit context + if (ast_exists_extension(chan, vmu->exit, str_vm_exit_ext, 1, chan->cid.cid_num)) + strncat(str_vm_exit_exts, str_vm_exit_ext, sizeof(str_vm_exit_exts) - strlen(str_vm_exit_exts) - 1); + } else if (ast_exists_extension(chan, chan->context, str_vm_exit_ext, 1, chan->cid.cid_num)) // then check actual context + strncat(str_vm_exit_exts, str_vm_exit_ext, sizeof(str_vm_exit_exts) - strlen(str_vm_exit_exts) - 1); + else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, str_vm_exit_ext, 1, chan->cid.cid_num)) { // then check macro context + strncat(str_vm_exit_exts, str_vm_exit_ext, sizeof(str_vm_exit_exts) - strlen(str_vm_exit_exts) - 1); + } + } + + strncat(ecodes, str_vm_exit_exts, sizeof(ecodes) - strlen(ecodes) - 1); + + ast_log(LOG_WARNING, "Voicemail: ecodes: '%s'\n", ecodes); + ast_log(LOG_WARNING, "Voicemail: searched in the following contexts:\n"); + ast_log(LOG_WARNING, " %s,%s,%s\n", vmu->exit, chan->context, chan->macrocontext); + } + /* Play the beginning intro if desired */ if (!ast_strlen_zero(prefile)) { #ifdef ODBC_STORAGE @@ -3125,6 +3157,21 @@ return 0; } + /* Check for 1-9 here*/ + switch (res) { + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + vm_exit_ext = res; + goto exit_to_extension; + } + /* Check for a '0' here */ if (res == '0') { transfer: @@ -3356,8 +3403,23 @@ } if (res == '0') { goto transfer; - } else if (res > 0) - res = 0; + } else { + switch (res) { // check to see if we hit a button from 1-9 to exit + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + vm_exit_ext = res; + goto exit_to_extension; + default: + res = 0; + } + } if (duration < vmminsecs) /* XXX We should really give a prompt too short/option start again, with leave_vm_out called only after a timeout XXX */ @@ -3366,6 +3428,25 @@ pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); } else ast_log(LOG_WARNING, "No format for saving voicemail?\n"); + + goto leave_vm_out; + +exit_to_extension: + chan->exten[0] = vm_exit_ext; + chan->exten[1] = '\0'; + //if (!ast_strlen_zero(vm_exit_context)) { + // ast_copy_string(chan->context, vm_exit_context, sizeof(chan->context)); + if (!ast_strlen_zero(vmu->exit)) { + ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); + } else if (!ast_strlen_zero(chan->macrocontext)) { + ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); + } + chan->priority = 0; + free_user(vmu); + pbx_builtin_setvar_helper(chan, "VMMAILBOX", vmu->mailbox); + pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); + return 0; + leave_vm_out: free_user(vmu);