diff --git a/conf/autoload_configs/ivr.conf.xml b/conf/autoload_configs/ivr.conf.xml index b747f4d525..635dac9732 100644 --- a/conf/autoload_configs/ivr.conf.xml +++ b/conf/autoload_configs/ivr.conf.xml @@ -10,6 +10,7 @@ timeout ="10000" inter-digit-timeout="2000" max-failures="3" + max-timeouts="3" digit-len="4"> @@ -26,7 +27,8 @@ invalid-sound="ivr/ivr-that_was_an_invalid_entry.wav" exit-sound="voicemail/vm-goodbye.wav" timeout="15000" - max-failures="3"> + max-failures="3" + max-timeouts="3"> diff --git a/src/include/switch_ivr.h b/src/include/switch_ivr.h index 28af6b1f17..6b9cc3ef16 100644 --- a/src/include/switch_ivr.h +++ b/src/include/switch_ivr.h @@ -680,7 +680,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_digit_stream_parser_set_terminator(sw const char *confirm_macro, const char *confirm_key, int confirm_attempts, - int inter_timeout, int digit_len, int timeout, int max_failures, switch_memory_pool_t *pool); + int inter_timeout, int digit_len, int timeout, int max_failures, + int max_timeouts, switch_memory_pool_t *pool); /*! *\brief switch_ivr_menu_bind_action: Bind a keystroke to an action. diff --git a/src/switch_ivr_menu.c b/src/switch_ivr_menu.c index eff415876d..922bfdcffc 100644 --- a/src/switch_ivr_menu.c +++ b/src/switch_ivr_menu.c @@ -47,6 +47,7 @@ struct switch_ivr_menu { int confirm_attempts; int digit_len; int max_failures; + int max_timeouts; int timeout; int inter_timeout; switch_size_t inlen; @@ -102,6 +103,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_menu_init(switch_ivr_menu_t ** new_me int inter_timeout, int digit_len, int timeout, int max_failures, + int max_timeouts, switch_memory_pool_t *pool) { switch_ivr_menu_t *menu; @@ -167,6 +169,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_menu_init(switch_ivr_menu_t ** new_me menu->max_failures = max_failures; + menu->max_timeouts = max_timeouts; + menu->timeout = timeout; menu->inter_timeout = inter_timeout; @@ -345,7 +349,7 @@ static switch_status_t play_and_collect(switch_core_session_t *session, switch_i SWITCH_DECLARE(switch_status_t) switch_ivr_menu_execute(switch_core_session_t *session, switch_ivr_menu_t * stack, char *name, void *obj) { - int reps = 0, errs = 0, match = 0, running = 1; + int reps = 0, errs = 0, timeouts = 0, match = 0, running = 1; char *greeting_sound = NULL, *aptr = NULL; char arg[512]; switch_ivr_action_t todo = SWITCH_IVR_ACTION_DIE; @@ -372,11 +376,22 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_menu_execute(switch_core_session_t *s } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Executing IVR menu %s\n", menu->name); + switch_channel_set_variable(channel, "ivr_menu_status", "success"); - for (reps = 0; (running && status == SWITCH_STATUS_SUCCESS && errs < menu->max_failures); reps++) { + for (reps = 0; running && status == SWITCH_STATUS_SUCCESS; reps++) { if (!switch_channel_ready(channel)) { break; } + if (errs == menu->max_failures) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Maximum failures\n"); + switch_channel_set_variable(channel, "ivr_menu_status", "failure"); + break; + } + if (timeouts == menu->max_timeouts) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Maximum timeouts\n"); + switch_channel_set_variable(channel, "ivr_menu_status", "timeout"); + break; + } if (reps > 0 && menu->short_greeting_sound) { greeting_sound = menu->short_greeting_sound; @@ -390,7 +405,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_menu_execute(switch_core_session_t *s memset(arg, 0, sizeof(arg)); memset(menu->buf, 0, menu->inlen + 1); - status = play_and_collect(session, menu, greeting_sound, menu->inlen); + + if (play_and_collect(session, menu, greeting_sound, menu->inlen) == SWITCH_STATUS_TIMEOUT) { + timeouts++; + continue; + } if (*menu->buf != '\0') { @@ -494,17 +513,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_menu_execute(switch_core_session_t *s if (*menu->buf) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IVR menu '%s' caught invalid input '%s'\n", menu->name, menu->buf); if (menu->invalid_sound) { - status = play_and_collect(session, menu, menu->invalid_sound, 0); + play_and_collect(session, menu, menu->invalid_sound, 0); } } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IVR menu '%s' no input detected\n", menu->name); } errs++; - - if (status == SWITCH_STATUS_TIMEOUT) { - status = SWITCH_STATUS_SUCCESS; - } - if (status == SWITCH_STATUS_SUCCESS) { status = switch_ivr_sleep(session, 1000, NULL); } @@ -693,6 +707,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_menu_stack_xml_build(switch_ivr_menu_ const char *exit_sound = switch_xml_attr(xml_menu, "exit-sound"); /* if the attr doesn't exist, return NULL */ const char *timeout = switch_xml_attr_soft(xml_menu, "timeout"); /* if the attr doesn't exist, return "" */ const char *max_failures = switch_xml_attr_soft(xml_menu, "max-failures"); /* if the attr doesn't exist, return "" */ + const char *max_timeouts = switch_xml_attr_soft(xml_menu, "max-timeouts"); const char *confirm_macro= switch_xml_attr(xml_menu, "confirm-macro"); const char *confirm_key= switch_xml_attr(xml_menu, "confirm-key"); const char *confirm_attempts = switch_xml_attr_soft(xml_menu, "confirm-attempts"); @@ -701,6 +716,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_menu_stack_xml_build(switch_ivr_menu_ switch_ivr_menu_t *menu = NULL; + if (switch_strlen_zero(max_timeouts)) { + max_timeouts = max_failures; + } + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "building menu '%s'\n", menu_name); status = switch_ivr_menu_init(&menu, @@ -716,7 +735,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_menu_stack_xml_build(switch_ivr_menu_ atoi(inter_timeout), atoi(digit_len), atoi(timeout), - atoi(max_failures), + strlen(max_failures)? atoi(max_failures): 1, + strlen(max_timeouts)? atoi(max_timeouts): 1, xml_menu_ctx->pool); /* set the menu_stack for the caller */ if (status == SWITCH_STATUS_SUCCESS && *menu_stack == NULL) {