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) {