diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_commands.c b/src/mod/event_handlers/mod_kazoo/kazoo_commands.c index bf191127c2..c1ac69f620 100644 --- a/src/mod/event_handlers/mod_kazoo/kazoo_commands.c +++ b/src/mod/event_handlers/mod_kazoo/kazoo_commands.c @@ -54,12 +54,18 @@ SWITCH_STANDARD_API(kz_first_of) char *mycmd = NULL, *mycmd_dup = NULL, *argv[MAX_FIRST_OF] = { 0 }; int n, argc = 0; switch_event_header_t *header = NULL; + switch_channel_t *channel = NULL; if (zstr(cmd)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "invalid arg\n"); return SWITCH_STATUS_GENERR; } + if ( session ) { + channel = switch_core_session_get_channel(session); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "GOT CHANNEL\n"); + } + mycmd_dup = mycmd = strdup(cmd); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "FIRST-OF %s\n", mycmd); if (!zstr(mycmd) && *mycmd == '^' && *(mycmd+1) == '^') { @@ -77,6 +83,24 @@ SWITCH_STANDARD_API(kz_first_of) } } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "CHECKING %s\n", item); + if (channel) { + const char *var = switch_channel_get_variable_dup(channel, item, SWITCH_FALSE, -1); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "CHECKING CHANNEL %s\n", item); + if (var) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "GOT FROM CHANNEL %s => %s\n", item, var); + stream->write_function(stream, var); + break; + } + if (!strncmp(item, "variable_", 9)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "CHECKING CHANNEL %s\n", item+9); + var = switch_channel_get_variable_dup(channel, item+9, SWITCH_FALSE, -1); + if (var) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "GOT FROM CHANNEL %s => %s\n", item+9, var); + stream->write_function(stream, var); + break; + } + } + } header = switch_event_get_header_ptr(stream->param_event, item); if(header) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "RETURNING %s : %s\n", item, header->value); @@ -440,6 +464,61 @@ SWITCH_STANDARD_API(kz_expand_api) return SWITCH_STATUS_SUCCESS; } +SWITCH_STANDARD_API(kz_eval_api) +{ + char *p = NULL, *input = NULL; + char *uuid = NULL, *mycmd; + switch_core_session_t *nsession = NULL; + switch_channel_t *channel = NULL; + + + if (zstr(cmd)) { + stream->write_function(stream, "-ERR invalid input"); + return SWITCH_STATUS_GENERR; + } + + if (!(mycmd = strdup(cmd))) { + stream->write_function(stream, "-ERR no memory"); + return SWITCH_STATUS_GENERR; + } + + if (!strncasecmp(mycmd, "uuid:", 5)) { + uuid = mycmd + 5; + if ((input = strchr(uuid, ' ')) != NULL) { + *input++ = '\0'; + if ((nsession = switch_core_session_locate(uuid)) != NULL) { + channel = switch_core_session_get_channel(nsession); + } else { + stream->write_function(stream, "-ERR invalid session"); + switch_safe_free(mycmd); + return SWITCH_STATUS_GENERR; + } + } else { + stream->write_function(stream, "-ERR invalid argument"); + switch_safe_free(mycmd); + return SWITCH_STATUS_GENERR; + } + } else if (session == NULL) { + stream->write_function(stream, "-ERR invalid argument"); + switch_safe_free(mycmd); + return SWITCH_STATUS_GENERR; + } else { + channel = switch_core_session_get_channel(session); + input = mycmd; + } + + p = switch_channel_expand_variables_check(channel, input, NULL, NULL, 0); + stream->write_function(stream, "+OK %s", p); + if (p != input) { + switch_safe_free(p); + } + switch_safe_free(mycmd); + if (nsession) { + switch_core_session_rwunlock(nsession); + } + return SWITCH_STATUS_SUCCESS; +} + void add_kz_commands(switch_loadable_module_interface_t **module_interface) { switch_api_interface_t *api_interface = NULL; SWITCH_ADD_API(api_interface, "kz_uuid_setvar_multi", UUID_SET_DESC, uuid_setvar_multi_function, UUID_MULTISET_SYNTAX); @@ -453,5 +532,6 @@ void add_kz_commands(switch_loadable_module_interface_t **module_interface) { SWITCH_ADD_API(api_interface, "kz_http_put", KZ_HTTP_PUT_DESC, kz_http_put, KZ_HTTP_PUT_SYNTAX); SWITCH_ADD_API(api_interface, "first-of", KZ_FIRST_OF_DESC, kz_first_of, KZ_FIRST_OF_SYNTAX); SWITCH_ADD_API(api_interface, "kz_expand", KZ_FIRST_OF_DESC, kz_expand_api, KZ_FIRST_OF_SYNTAX); + SWITCH_ADD_API(api_interface, "kz_eval", KZ_FIRST_OF_DESC, kz_eval_api, KZ_FIRST_OF_SYNTAX); } diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_dptools.c b/src/mod/event_handlers/mod_kazoo/kazoo_dptools.c index d5bd64fa9a..073986e1ee 100644 --- a/src/mod/event_handlers/mod_kazoo/kazoo_dptools.c +++ b/src/mod/event_handlers/mod_kazoo/kazoo_dptools.c @@ -443,6 +443,60 @@ SWITCH_STANDARD_APP(kz_endless_playback_function) } +SWITCH_STANDARD_APP(kz_moh_function) +{ + switch_channel_t *channel = switch_core_session_get_channel(session); + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_file_handle_t fh = { 0 }; + const char *var_samples = switch_channel_get_variable_dup(channel, "moh_playback_samples", SWITCH_FALSE, -1); + unsigned int samples = 0; + + if (var_samples) { + fh.samples = samples = atoi(var_samples); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "SETTING SAMPLES %d\n", samples); + } + + switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, ""); + + status = switch_ivr_play_file(session, &fh, data, NULL); + switch_assert(!(fh.flags & SWITCH_FILE_OPEN)); + + switch (status) { + case SWITCH_STATUS_SUCCESS: + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "MOH PLAYED SUCCESS\n"); + switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, "MOH FILE PLAYED"); + switch_channel_set_variable(channel, "moh_playback_samples", "0"); + break; + case SWITCH_STATUS_BREAK: + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "MOH PLAYED BREAK\n"); + switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, "MOH FILE PLAYED"); + if ((var_samples = switch_channel_get_variable_dup(channel, "playback_samples", SWITCH_FALSE, -1)) != NULL) { + samples += atoi(var_samples); + if (samples >= fh.samples) { + samples = 0; + } + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "SETTING MOH SAMPLES %d\n", samples); + switch_channel_set_variable_printf(channel, "moh_playback_samples", "%d", samples); + } + break; + case SWITCH_STATUS_NOTFOUND: + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "MOH PLAYED NOT FOUND\n"); + switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, "MOH FILE NOT FOUND"); + break; + default: + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "MOH PLAYED DEFAULT\n"); + switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, "MOH PLAYBACK ERROR"); + break; + } + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "MOH duration %ld\n", fh.duration); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "MOH offset_pos %d\n", fh.offset_pos); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "MOH pos %ld\n", fh.pos); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "MOH sample_count %ld\n", fh.sample_count); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "MOH samples %d\n", fh.samples); + +} + SWITCH_STANDARD_APP(noop_function) { switch_channel_t *channel = switch_core_session_get_channel(session); @@ -907,4 +961,5 @@ void add_kz_dptools(switch_loadable_module_interface_t **module_interface) { SWITCH_ADD_APP(app_interface, "kz_bridge", "Bridge Audio", "Bridge the audio between two sessions", kz_audio_bridge_function, "", SAF_SUPPORT_NOMEDIA|SAF_SUPPORT_TEXT_ONLY); SWITCH_ADD_APP(app_interface, "kz_bridge_uuid", "Bridge Audio", "Bridge the audio between two sessions", kz_audio_bridge_uuid_function, "", SAF_SUPPORT_NOMEDIA|SAF_SUPPORT_TEXT_ONLY); SWITCH_ADD_APP(app_interface, "kz_att_xfer", "Attended Transfer", "Attended Transfer", kz_att_xfer_function, "", SAF_NONE); + SWITCH_ADD_APP(app_interface, "kz_moh", "Kazoo MOH Playback", "Kazoo MOH Playback", kz_moh_function, "", SAF_NONE); } diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_ei_utils.c b/src/mod/event_handlers/mod_kazoo/kazoo_ei_utils.c index 416098b972..a5e59b9978 100644 --- a/src/mod/event_handlers/mod_kazoo/kazoo_ei_utils.c +++ b/src/mod/event_handlers/mod_kazoo/kazoo_ei_utils.c @@ -922,6 +922,10 @@ static void fetch_config_handlers(switch_memory_pool_t *pool) static void *SWITCH_THREAD_FUNC fetch_config_exec(switch_thread_t *thread, void *obj) { switch_memory_pool_t *pool = (switch_memory_pool_t *) obj; + + // give some time for node initialization + switch_sleep(10000); + fetch_config_filters(pool); fetch_config_handlers(pool); diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_tweaks.c b/src/mod/event_handlers/mod_kazoo/kazoo_tweaks.c index 8b1d19d89c..bb7c792b88 100644 --- a/src/mod/event_handlers/mod_kazoo/kazoo_tweaks.c +++ b/src/mod/event_handlers/mod_kazoo/kazoo_tweaks.c @@ -64,7 +64,7 @@ static switch_status_t kz_tweaks_signal_bridge_on_hangup(switch_core_session_t * const char *peer_uuid = switch_channel_get_variable(channel, "Bridge-B-Unique-ID"); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "tweak signal bridge on hangup: %s , %s\n", switch_core_session_get_uuid(session), peer_uuid); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "tweak signal bridge on hangup: %s , %s\n", switch_core_session_get_uuid(session), peer_uuid); if (switch_event_create(&my_event, SWITCH_EVENT_CHANNEL_UNBRIDGE) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(my_event, SWITCH_STACK_BOTTOM, "Bridge-A-Unique-ID", switch_core_session_get_uuid(session)); @@ -96,88 +96,38 @@ static void kz_tweaks_handle_bridge_variables(switch_event_t *event) switch_core_session_t *a_session = NULL, *b_session = NULL; const char *a_leg = switch_event_get_header(event, "Bridge-A-Unique-ID"); const char *b_leg = switch_event_get_header(event, "Bridge-B-Unique-ID"); + const char *reentry = switch_event_get_header(event, "Bridge-Event-Processed"); int i; if (!kz_test_tweak(KZ_TWEAK_BRIDGE_VARIABLES)) return; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "tweak bridge event handler: variables : %s , %s\n", a_leg, b_leg); + if(reentry) return; + + switch_log_printf(SWITCH_CHANNEL_UUID_LOG(a_leg), SWITCH_LOG_DEBUG, "tweak bridge event handler: variables : %s , %s\n", a_leg, b_leg); if (a_leg && (a_session = switch_core_session_locate(a_leg)) != NULL) { switch_channel_t *a_channel = switch_core_session_get_channel(a_session); - if(switch_channel_get_variable_dup(a_channel, bridge_variables[0], SWITCH_FALSE, -1) == NULL) { - if(b_leg && (b_session = switch_core_session_locate(b_leg)) != NULL) { - switch_channel_t *b_channel = switch_core_session_get_channel(b_session); + switch_channel_timetable_t *a_times = switch_channel_get_timetable(a_channel); + if(b_leg && (b_session = switch_core_session_locate(b_leg)) != NULL) { + switch_channel_t *b_channel = switch_core_session_get_channel(b_session); + switch_channel_timetable_t *b_times = switch_channel_get_timetable(b_channel); + if (a_times->created <= b_times->created) { + for(i = 0; bridge_variables[i] != NULL; i++) { + const char *val = switch_channel_get_variable_dup(a_channel, bridge_variables[i], SWITCH_FALSE, -1); + switch_channel_set_variable(b_channel, bridge_variables[i], val); + } + } else { for(i = 0; bridge_variables[i] != NULL; i++) { const char *val = switch_channel_get_variable_dup(b_channel, bridge_variables[i], SWITCH_FALSE, -1); switch_channel_set_variable(a_channel, bridge_variables[i], val); } - switch_core_session_rwunlock(b_session); - } - } else { - if(b_leg && (b_session = switch_core_session_locate(b_leg)) != NULL) { - switch_channel_t *b_channel = switch_core_session_get_channel(b_session); - if(switch_channel_get_variable_dup(b_channel, bridge_variables[0], SWITCH_FALSE, -1) == NULL) { - for(i = 0; bridge_variables[i] != NULL; i++) { - const char *val = switch_channel_get_variable_dup(a_channel, bridge_variables[i], SWITCH_FALSE, -1); - switch_channel_set_variable(b_channel, bridge_variables[i], val); - } - } - switch_core_session_rwunlock(b_session); } + switch_core_session_rwunlock(b_session); } switch_core_session_rwunlock(a_session); } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "NOT FOUND : %s\n", a_leg); + switch_log_printf(SWITCH_CHANNEL_UUID_LOG(a_leg), SWITCH_LOG_DEBUG1, "NOT FOUND : %s\n", a_leg); } - -} - -static void kz_tweaks_handle_bridge_replaces_aleg(switch_event_t *event) -{ - switch_event_t *my_event; - - const char *replaced_call_id = switch_event_get_header(event, "variable_sip_replaces_call_id"); - const char *a_leg_call_id = switch_event_get_header(event, "variable_sip_replaces_a-leg"); - const char *peer_uuid = switch_event_get_header(event, "Unique-ID"); - int processed = 0; - - if (!kz_test_tweak(KZ_TWEAK_BRIDGE_REPLACES_ALEG)) return; - - - if(a_leg_call_id && replaced_call_id) { - const char *call_id = switch_event_get_header(event, "Bridge-B-Unique-ID"); - switch_core_session_t *session = NULL; - if ((session = switch_core_session_locate(peer_uuid)) != NULL) { - switch_channel_t *channel = switch_core_session_get_channel(session); - processed = switch_true(switch_channel_get_variable_dup(channel, "Bridge-Event-Processed", SWITCH_FALSE, -1)); - switch_channel_set_variable(channel, "Bridge-Event-Processed", "true"); - switch_core_session_rwunlock(session); - } - - if(processed) { - if(call_id) { - if((session = switch_core_session_locate(call_id)) != NULL) { - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_channel_set_variable(channel, "Bridge-Event-Processed", "true"); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "creating channel_bridge event A - %s , B - %s\n", switch_core_session_get_uuid(session), peer_uuid); - if (switch_event_create(&my_event, SWITCH_EVENT_CHANNEL_BRIDGE) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header_string(my_event, SWITCH_STACK_BOTTOM, "Bridge-A-Unique-ID", switch_core_session_get_uuid(session)); - switch_event_add_header_string(my_event, SWITCH_STACK_BOTTOM, "Bridge-B-Unique-ID", peer_uuid); - switch_channel_event_set_data(channel, my_event); - switch_event_fire(&my_event); - } - switch_channel_set_variable(channel, "Bridge-B-Unique-ID", peer_uuid); - switch_channel_add_state_handler(channel, &kz_tweaks_signal_bridge_state_handlers); - switch_core_session_rwunlock(session); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "invalid session : %s\n", call_id); - DUMP_EVENT(event); - } - } - } - - } - } static void kz_tweaks_handle_bridge_replaces_call_id(switch_event_t *event) @@ -185,12 +135,14 @@ static void kz_tweaks_handle_bridge_replaces_call_id(switch_event_t *event) switch_event_t *my_event; const char *replaced_call_id = switch_event_get_header(event, "variable_sip_replaces_call_id"); - const char *a_leg_call_id = switch_event_get_header(event, "variable_sip_replaces_a-leg"); const char *peer_uuid = switch_event_get_header(event, "Unique-ID"); + const char *reentry = switch_event_get_header(event, "Bridge-Event-Processed"); if (!kz_test_tweak(KZ_TWEAK_BRIDGE_REPLACES_CALL_ID)) return; - if(a_leg_call_id && replaced_call_id) { + if(reentry) return; + + if(replaced_call_id) { switch_core_session_t *call_session = NULL; const char *call_id = switch_event_get_header(event, "Bridge-B-Unique-ID"); if (call_id && (call_session = switch_core_session_locate(call_id)) != NULL) { @@ -198,6 +150,7 @@ static void kz_tweaks_handle_bridge_replaces_call_id(switch_event_t *event) if (switch_event_create(&my_event, SWITCH_EVENT_CHANNEL_BRIDGE) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(my_event, SWITCH_STACK_BOTTOM, "Bridge-A-Unique-ID", switch_core_session_get_uuid(call_session)); switch_event_add_header_string(my_event, SWITCH_STACK_BOTTOM, "Bridge-B-Unique-ID", peer_uuid); + switch_event_add_header_string(my_event, SWITCH_STACK_BOTTOM, "Bridge-Event-Processed", "true"); switch_channel_event_set_data(call_channel, my_event); switch_event_fire(&my_event); } @@ -208,7 +161,6 @@ static void kz_tweaks_handle_bridge_replaces_call_id(switch_event_t *event) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "NOT FOUND : %s\n", call_id); } } - } static void kz_tweaks_channel_bridge_event_handler(switch_event_t *event) @@ -216,7 +168,6 @@ static void kz_tweaks_channel_bridge_event_handler(switch_event_t *event) if (!kz_test_tweak(KZ_TWEAK_BRIDGE)) return; kz_tweaks_handle_bridge_replaces_call_id(event); - kz_tweaks_handle_bridge_replaces_aleg(event); kz_tweaks_handle_bridge_variables(event); } @@ -482,7 +433,7 @@ static switch_status_t kz_tweaks_handle_replaces_call_id(switch_core_session_t * const char *replaced_call_id = switch_channel_get_variable(channel, "sip_replaces_call_id"); const char *core_uuid = switch_channel_get_variable(channel, "sip_h_X-FS-From-Core-UUID"); if((!core_uuid) && replaced_call_id) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "checking replaces header tweak for %s\n", replaced_call_id); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "checking replaces header tweak for %s\n", replaced_call_id); if ((replace_call_session = switch_core_session_locate(replaced_call_id))) { switch_channel_t *replaced_call_channel = switch_core_session_get_channel(replace_call_session); int i;