diff --git a/src/include/switch_ivr.h b/src/include/switch_ivr.h index 712179d783..00488380ed 100644 --- a/src/include/switch_ivr.h +++ b/src/include/switch_ivr.h @@ -989,6 +989,7 @@ SWITCH_DECLARE(void) switch_ivr_dmachine_destroy(switch_ivr_dmachine_t **dmachin SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_bind(switch_ivr_dmachine_t *dmachine, const char *realm, const char *digits, + switch_byte_t is_priority, int32_t key, switch_ivr_dmachine_callback_t callback, void *user_data); diff --git a/src/mod/applications/mod_conference/conference_member.c b/src/mod/applications/mod_conference/conference_member.c index 064d12edac..71b50984f2 100644 --- a/src/mod/applications/mod_conference/conference_member.c +++ b/src/mod/applications/mod_conference/conference_member.c @@ -85,8 +85,7 @@ void conference_member_do_binding(conference_member_t *member, conference_key_ca } binding->handler = handler; - switch_ivr_dmachine_bind(member->dmachine, "conf", digits, 0, conference_loop_dmachine_dispatcher, binding); - + switch_ivr_dmachine_bind(member->dmachine, "conf", digits, 0, 0, conference_loop_dmachine_dispatcher, binding); } void conference_member_bind_controls(conference_member_t *member, const char *controls) diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index 1ed993574a..01f34dac0e 100644 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -357,6 +357,7 @@ static void bind_to_session(switch_core_session_t *session, switch_ivr_dmachine_t *dmachine; switch_channel_t *channel = switch_core_session_get_channel(session); const char *terminators = NULL; + switch_byte_t is_priority = 0; if (!(dmachine = switch_core_session_get_dmachine(session, target))) { uint32_t digit_timeout = 1500; @@ -383,8 +384,27 @@ static void bind_to_session(switch_core_session_t *session, act->value = switch_core_session_strdup(session, arg3); act->target = bind_target; act->session = session; - switch_ivr_dmachine_bind(dmachine, act->realm, act->input, 0, digit_action_callback, act); + if (!strncasecmp(act->string, "exec", 4) || !strncasecmp(act->string, "api:", 4)) { + char *flags, *e; + char *string = switch_core_session_strdup(session, act->string); + + string += 4; + if (*string == '[') { + flags = string; + if ((e = switch_find_end_paren(flags, '[', ']'))) { + if (e && *(e+1) == ':') { + flags++; + *e = '\0'; + if (strchr(flags, 'P')) + is_priority = 1; + } + } + } + } + + switch_ivr_dmachine_bind(dmachine, act->realm, act->input, is_priority, 0, digit_action_callback, act); + if ((terminators = switch_channel_get_variable(channel, "bda_terminators"))) { switch_ivr_dmachine_set_terminators(dmachine, terminators); } diff --git a/src/mod/applications/mod_httapi/mod_httapi.c b/src/mod/applications/mod_httapi/mod_httapi.c index 70d7e39bd3..59b0148a35 100644 --- a/src/mod/applications/mod_httapi/mod_httapi.c +++ b/src/mod/applications/mod_httapi/mod_httapi.c @@ -563,7 +563,7 @@ static switch_status_t parse_playback(const char *tag_name, client_t *client, sw action_binding->error_file = (char *) error_file; action_binding->parent = top_action_binding; - switch_ivr_dmachine_bind(dmachine, action_binding->realm, action_binding->input, 0, digit_action_callback, action_binding); + switch_ivr_dmachine_bind(dmachine, action_binding->realm, action_binding->input, 0, 0, digit_action_callback, action_binding); bind = bind->next; } @@ -1067,7 +1067,7 @@ static switch_status_t parse_record(const char *tag_name, client_t *client, swit action_binding->error_file = (char *) error_file; action_binding->parent = top_action_binding; - switch_ivr_dmachine_bind(dmachine, action_binding->realm, action_binding->input, 0, digit_action_callback, action_binding); + switch_ivr_dmachine_bind(dmachine, action_binding->realm, action_binding->input, 0, 0, digit_action_callback, action_binding); bind = bind->next; } diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index 8df35b5a0b..6b8e4d933d 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -44,6 +44,7 @@ struct switch_ivr_dmachine_binding { uint8_t rmatch; switch_ivr_dmachine_callback_t callback; switch_byte_t is_regex; + switch_byte_t is_priority; void *user_data; struct switch_ivr_dmachine_binding *next; }; @@ -247,7 +248,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_clear_realm(switch_ivr_dmach SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_bind(switch_ivr_dmachine_t *dmachine, const char *realm, - const char *digits, + const char *digits, + switch_byte_t is_priority, int32_t key, switch_ivr_dmachine_callback_t callback, void *user_data) @@ -291,6 +293,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_bind(switch_ivr_dmachine_t * binding->key = key; binding->digits = switch_core_strdup(dmachine->pool, digits); + binding->is_priority = is_priority; binding->callback = callback; binding->user_data = user_data; @@ -348,11 +351,7 @@ static dm_match_t switch_ivr_dmachine_check_match(switch_ivr_dmachine_t *dmachin if (bp->is_regex) { switch_status_t r_status = switch_regex_match(dmachine->digits, bp->digits); - if (r_status == SWITCH_STATUS_SUCCESS) { - bp->rmatch++; - } else { - bp->rmatch = 0; - } + bp->rmatch = r_status == SWITCH_STATUS_SUCCESS; rmatches++; pmatches++; @@ -360,7 +359,9 @@ static dm_match_t switch_ivr_dmachine_check_match(switch_ivr_dmachine_t *dmachin } else { if (!strncmp(dmachine->digits, bp->digits, strlen(dmachine->digits))) { pmatches++; - ematches = 1; + if (dmachine->cur_digit_len == strlen(bp->digits)) { + ematches++; + } } } } @@ -382,7 +383,7 @@ static dm_match_t switch_ivr_dmachine_check_match(switch_ivr_dmachine_t *dmachin for(bp = dmachine->realm->binding_list; bp; bp = bp->next) { if (bp->is_regex) { if (bp->rmatch) { - if (is_timeout || (bp == dmachine->realm->binding_list && !bp->next)) { + if ((bp->is_priority && ! ematches) || is_timeout || (bp == dmachine->realm->binding_list && !bp->next)) { best = DM_MATCH_EXACT; exact_bp = bp; break; @@ -392,10 +393,10 @@ static dm_match_t switch_ivr_dmachine_check_match(switch_ivr_dmachine_t *dmachin } else { int pmatch = !strncmp(dmachine->digits, bp->digits, strlen(dmachine->digits)); - if (!exact_bp && pmatch && (((pmatches == 1 || ematches == 1) && !rmatches) || is_timeout) && !strcmp(bp->digits, dmachine->digits)) { + if (!exact_bp && pmatch && (!rmatches || bp->is_priority || is_timeout) && !strcmp(bp->digits, dmachine->digits)) { best = DM_MATCH_EXACT; exact_bp = bp; - if (dmachine->cur_digit_len == dmachine->max_digit_len) break; + if (bp->is_priority || dmachine->cur_digit_len == dmachine->max_digit_len) break; } if (!(both_bp && partial_bp) && strlen(bp->digits) != strlen(dmachine->digits) && pmatch) {