diff --git a/src/include/switch_ivr.h b/src/include/switch_ivr.h index 3c93487ce6..3283833e6b 100644 --- a/src/include/switch_ivr.h +++ b/src/include/switch_ivr.h @@ -298,7 +298,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_stop_tone_detect_session(switch_core_ */ SWITCH_DECLARE(switch_status_t) switch_ivr_tone_detect_session(switch_core_session_t *session, const char *key, const char *tone_spec, - const char *flags, time_t timeout, int hits, const char *app, const char *data); + const char *flags, time_t timeout, int hits, + const char *app, const char *data, switch_tone_detect_callback_t callback); diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 533927bdd4..6ab295a556 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -1343,6 +1343,7 @@ typedef struct switch_management_interface switch_management_interface_t; typedef struct switch_core_port_allocator switch_core_port_allocator_t; typedef struct switch_media_bug switch_media_bug_t; typedef switch_bool_t (*switch_media_bug_callback_t) (switch_media_bug_t *, void *, switch_abc_type_t); +typedef switch_bool_t (*switch_tone_detect_callback_t) (switch_core_session_t *, const char *, const char *); typedef struct switch_xml_binding switch_xml_binding_t; typedef switch_status_t (*switch_core_codec_encode_func_t) (switch_codec_t *codec, diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index bc77405d4d..044e5843c3 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -1405,7 +1405,7 @@ SWITCH_STANDARD_API(tone_detect_session_function) } } - switch_ivr_tone_detect_session(rsession, argv[1], argv[2], argv[3], to, hits, argv[5], argv[6]); + switch_ivr_tone_detect_session(rsession, argv[1], argv[2], argv[3], to, hits, argv[5], argv[6], NULL); stream->write_function(stream, "+OK Enabling tone detection '%s' '%s' '%s'\n", argv[1], argv[2], argv[3]); done: diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index d541bd9138..a195b72792 100644 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -1178,7 +1178,7 @@ SWITCH_STANDARD_APP(stop_dtmf_session_generate_function) SWITCH_STANDARD_APP(fax_detect_session_function) { - switch_ivr_tone_detect_session(session, "fax", "1100.0", "r", 0, 1, NULL, NULL); + switch_ivr_tone_detect_session(session, "fax", "1100.0", "r", 0, 1, NULL, NULL, NULL); } SWITCH_STANDARD_APP(system_session_function) @@ -1234,7 +1234,7 @@ SWITCH_STANDARD_APP(tone_detect_session_function) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Enabling tone detection '%s' '%s'\n", argv[0], argv[1]); - switch_ivr_tone_detect_session(session, argv[0], argv[1], argv[2], to, hits, argv[4], argv[5]); + switch_ivr_tone_detect_session(session, argv[0], argv[1], argv[2], to, hits, argv[4], argv[5], NULL); } SWITCH_STANDARD_APP(stop_fax_detect_session_function) diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index f3b0aeac72..3b8554e30f 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -1197,6 +1197,8 @@ typedef struct { int hits; int sleep; int expires; + int once; + switch_tone_detect_callback_t callback; } switch_tone_detect_t; typedef struct { @@ -1211,6 +1213,7 @@ static switch_bool_t tone_detect_callback(switch_media_bug_t *bug, void *user_da switch_tone_container_t *cont = (switch_tone_container_t *) user_data; switch_frame_t *frame = NULL; int i = 0; + switch_bool_t rval = SWITCH_TRUE; switch (type) { case SWITCH_ABC_TYPE_INIT: @@ -1264,8 +1267,13 @@ static switch_bool_t tone_detect_callback(switch_media_bug_t *bug, void *user_da if (cont->list[i].hits >= cont->list[i].total_hits) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "TONE %s DETECTED\n", cont->list[i].key); cont->list[i].up = 0; - - if (cont->list[i].app) { + if (cont->list[i].once) { + rval = SWITCH_FALSE; + } + + if (cont->list[i].callback) { + rval = cont->list[i].callback(cont->session, cont->list[i].app, cont->list[i].data); + } else if (cont->list[i].app) { if (switch_event_create(&event, SWITCH_EVENT_COMMAND) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-command", "execute"); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "execute-app-name", cont->list[i].app); @@ -1278,7 +1286,7 @@ static switch_bool_t tone_detect_callback(switch_media_bug_t *bug, void *user_da if (switch_event_create(&event, SWITCH_EVENT_DETECTED_TONE) == SWITCH_STATUS_SUCCESS) { switch_event_t *dup; switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Detected-Tone", cont->list[i].key); - + if (switch_event_dup(&dup, event) == SWITCH_STATUS_SUCCESS) { switch_event_fire(&dup); } @@ -1298,7 +1306,7 @@ static switch_bool_t tone_detect_callback(switch_media_bug_t *bug, void *user_da default: break; } - return SWITCH_TRUE; + return rval; } SWITCH_DECLARE(switch_status_t) switch_ivr_stop_tone_detect_session(switch_core_session_t *session) @@ -1316,7 +1324,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_stop_tone_detect_session(switch_core_ SWITCH_DECLARE(switch_status_t) switch_ivr_tone_detect_session(switch_core_session_t *session, const char *key, const char *tone_spec, - const char *flags, time_t timeout, int hits, const char *app, const char *data) + const char *flags, time_t timeout, + int hits, const char *app, const char *data, + switch_tone_detect_callback_t callback) { switch_channel_t *channel = switch_core_session_get_channel(session); switch_codec_t *read_codec = switch_core_session_get_read_codec(session); @@ -1395,6 +1405,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_tone_detect_session(switch_core_sessi cont->list[cont->index].data = switch_core_session_strdup(session, data); } + cont->list[cont->index].callback = callback; + if (!hits) hits = 1; cont->list[cont->index].hits = 0; @@ -1410,6 +1422,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_tone_detect_session(switch_core_sessi if (switch_strlen_zero(flags)) { bflags = SMBF_READ_REPLACE; } else { + if (strchr(flags, 'o')) { + cont->list[cont->index].once = 1; + } + if (strchr(flags, 'r')) { bflags |= SMBF_READ_REPLACE; } else if (strchr(flags, 'w')) {