From efafdefe07c470545fe5c2043d0380a0949b37c4 Mon Sep 17 00:00:00 2001 From: lazedo Date: Wed, 27 Mar 2019 06:13:32 +0000 Subject: [PATCH] FS-10820 [mod_kazoo] add more kazoo interactions * initialize ei * defaults for definitions * add kz endpoint * add kz_bridge * add setters with encoding * add tweaks after merged core PRs --- src/mod/event_handlers/mod_kazoo/Makefile.am | 1 + .../event_handlers/mod_kazoo/kazoo.conf.xml | 58 ++-- .../event_handlers/mod_kazoo/kazoo_commands.c | 2 +- .../event_handlers/mod_kazoo/kazoo_dptools.c | 122 +++++++- .../event_handlers/mod_kazoo/kazoo_ei_utils.c | 2 + .../mod_kazoo/kazoo_endpoints.c | 284 ++++++++++++++++++ .../event_handlers/mod_kazoo/kazoo_tweaks.c | 76 +++-- .../event_handlers/mod_kazoo/kazoo_utils.c | 65 +++- src/mod/event_handlers/mod_kazoo/mod_kazoo.c | 3 + src/mod/event_handlers/mod_kazoo/mod_kazoo.h | 10 +- 10 files changed, 559 insertions(+), 64 deletions(-) create mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_endpoints.c diff --git a/src/mod/event_handlers/mod_kazoo/Makefile.am b/src/mod/event_handlers/mod_kazoo/Makefile.am index 96b5c6cc30..0d7af80177 100644 --- a/src/mod/event_handlers/mod_kazoo/Makefile.am +++ b/src/mod/event_handlers/mod_kazoo/Makefile.am @@ -11,6 +11,7 @@ mod_kazoo_la_SOURCES += kazoo_api.c kazoo_commands.c kazoo_config.c mod_kazoo_la_SOURCES += kazoo_message.c mod_kazoo_la_SOURCES += kazoo_ei_config.c kazoo_ei_utils.c kazoo_event_stream.c mod_kazoo_la_SOURCES += kazoo_fetch_agent.c kazoo_node.c +mod_kazoo_la_SOURCES += kazoo_endpoints.c mod_kazoo_la_CFLAGS = $(AM_CFLAGS) @ERLANG_CFLAGS@ -D_REENTRANT mod_kazoo_la_LIBADD = $(KAZOO_DEFS) $(switch_builddir)/libfreeswitch.la diff --git a/src/mod/event_handlers/mod_kazoo/kazoo.conf.xml b/src/mod/event_handlers/mod_kazoo/kazoo.conf.xml index b1a6756a6f..155bb5f328 100644 --- a/src/mod/event_handlers/mod_kazoo/kazoo.conf.xml +++ b/src/mod/event_handlers/mod_kazoo/kazoo.conf.xml @@ -66,34 +66,31 @@ + + + + + + + - - - - - - - - - + + value="sip:${regex(${url_decode(${variable_sip_refer_to})}|<sips?:(.*)>|%1)}"> - + @@ -119,7 +116,7 @@ - + @@ -258,10 +255,18 @@ + + + + @@ -322,7 +327,7 @@ - + @@ -344,6 +349,8 @@ + + @@ -353,7 +360,7 @@ + value="variable_sip_req_uri|variable_sip_loopback_req_uri|variable_sip_to_uri" /> @@ -448,6 +455,7 @@ serialize-as="object"> + @@ -529,14 +537,15 @@ - + - + + @@ -575,7 +584,6 @@ - + @@ -601,7 +610,6 @@ - @@ -621,7 +629,7 @@ serialize-as="object"> - + @@ -630,9 +638,9 @@ - + diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_commands.c b/src/mod/event_handlers/mod_kazoo/kazoo_commands.c index 017c99959a..6bae6c822e 100644 --- a/src/mod/event_handlers/mod_kazoo/kazoo_commands.c +++ b/src/mod/event_handlers/mod_kazoo/kazoo_commands.c @@ -350,7 +350,7 @@ SWITCH_STANDARD_API(kz_http_put) switch_curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1); switch_curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 10); switch_curl_easy_setopt(curl_handle, CURLOPT_FAILONERROR, 1); - switch_curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-http-cache/1.0"); + switch_curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-kazoo/1.0"); switch_curl_easy_setopt(curl_handle, CURLOPT_HEADERDATA, stream->param_event); switch_curl_easy_setopt(curl_handle, CURLOPT_HEADERFUNCTION, header_callback); switch_curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, body_callback); diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_dptools.c b/src/mod/event_handlers/mod_kazoo/kazoo_dptools.c index fe555f95bb..4905f09b33 100644 --- a/src/mod/event_handlers/mod_kazoo/kazoo_dptools.c +++ b/src/mod/event_handlers/mod_kazoo/kazoo_dptools.c @@ -98,7 +98,7 @@ static void base_set (switch_core_session_t *session, const char *data, int urld expanded = switch_channel_expand_variables(channel, val); } - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s SET [%s]=[%s]\n", switch_channel_get_name(channel), var, + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s SET [%s]=[%s] => [%s]\n", switch_channel_get_name(channel), var, val, expanded ? expanded : "UNDEF"); switch_channel_add_variable_var_check(channel, var, expanded, SWITCH_FALSE, stack); kz_check_set_profile_var(channel, var, expanded); @@ -458,6 +458,124 @@ SWITCH_STANDARD_APP(noop_function) switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, response); } +SWITCH_STANDARD_APP(kz_restore_caller_id_function) +{ + switch_channel_t *channel = switch_core_session_get_channel(session); + switch_caller_profile_t *cp = switch_channel_get_caller_profile(channel); + cp->caller_id_name = cp->orig_caller_id_name; + cp->caller_id_number = cp->orig_caller_id_number; +} + +SWITCH_STANDARD_APP(kz_audio_bridge_function) +{ + switch_channel_t *caller_channel = switch_core_session_get_channel(session); + switch_core_session_t *peer_session = NULL; + switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING; + switch_status_t status = SWITCH_STATUS_FALSE; + + if (zstr(data)) { + return; + } + + status = switch_ivr_originate(session, &peer_session, &cause, data, 0, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL); + + if (status != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Originate Failed. Cause: %s\n", switch_channel_cause2str(cause)); + + switch_channel_set_variable(caller_channel, "originate_failed_cause", switch_channel_cause2str(cause)); + switch_channel_set_variable(caller_channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, switch_channel_cause2str(cause)); + switch_channel_handle_cause(caller_channel, cause); + + return; + } else { + const char* uuid = switch_core_session_get_uuid(session); + const char* peer_uuid = switch_core_session_get_uuid(peer_session); + + + switch_channel_t *peer_channel = switch_core_session_get_channel(peer_session); + if (switch_true(switch_channel_get_variable(caller_channel, SWITCH_BYPASS_MEDIA_AFTER_BRIDGE_VARIABLE)) || + switch_true(switch_channel_get_variable(peer_channel, SWITCH_BYPASS_MEDIA_AFTER_BRIDGE_VARIABLE))) { + switch_channel_set_flag(caller_channel, CF_BYPASS_MEDIA_AFTER_BRIDGE); + } + + while(1) { + const char *xfer_uuid; + switch_channel_state_t a_state , a_running_state; + switch_channel_state_t b_state , b_running_state; + status = switch_ivr_multi_threaded_bridge(session, peer_session, NULL, NULL, NULL); + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "BRIDGE RESULT %i\n", status); + if(status != 0) { + break; + } + + a_state = switch_channel_get_state(caller_channel); + a_running_state = switch_channel_get_running_state(caller_channel); + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "A STATE %s %s => %s , %s\n", switch_channel_state_name(a_running_state), switch_channel_state_name(a_state), uuid, peer_uuid); + + if(a_state >= CS_HANGUP) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "A HANGUP = %s , %s\n", uuid, peer_uuid); + break; + } + + b_state = switch_channel_get_state(peer_channel); + b_running_state = switch_channel_get_running_state(peer_channel); + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "B STATE %s %s => %s , %s\n", switch_channel_state_name(b_running_state), switch_channel_state_name(b_state), uuid, peer_uuid); + + if(b_state >= CS_HANGUP) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "B HANGUP = %s , %s\n", uuid, peer_uuid); + switch_channel_set_variable(caller_channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, switch_channel_cause2str(switch_channel_get_cause(peer_channel))); + break; + } + + if(!(xfer_uuid=switch_channel_get_variable(caller_channel, "att_xfer_peer_uuid"))) { + if(!(xfer_uuid=switch_channel_get_variable(peer_channel, "att_xfer_peer_uuid"))) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "XFER UUID NULL\n"); + break; + } + } + + switch_channel_set_variable(caller_channel, "att_xfer_peer_uuid", NULL); + switch_channel_set_variable(peer_channel, "att_xfer_peer_uuid", NULL); + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "WAIT 1\n"); + + switch_channel_clear_flag(peer_channel, CF_UUID_BRIDGE_ORIGINATOR); + switch_channel_set_state(peer_channel, CS_RESET); + switch_channel_wait_for_state(peer_channel, NULL, CS_RESET); + switch_channel_clear_state_handler(peer_channel, NULL); + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "WAIT 3\n"); + + switch_channel_set_flag(caller_channel, CF_UUID_BRIDGE_ORIGINATOR); + switch_channel_clear_flag(caller_channel, CF_TRANSFER); + switch_channel_clear_flag(caller_channel, CF_REDIRECT); + switch_channel_set_flag(peer_channel, CF_UUID_BRIDGE_ORIGINATOR); + switch_channel_clear_flag(peer_channel, CF_TRANSFER); + switch_channel_clear_flag(peer_channel, CF_REDIRECT); + + if(!switch_channel_media_up(caller_channel)) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "A MEDIA DOWN HANGUP = %s, %s , %s\n", xfer_uuid, uuid, peer_uuid); + } + if(!switch_channel_media_up(peer_channel)) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "B MEDIA DOWN HANGUP = %s, %s , %s\n", xfer_uuid, uuid, peer_uuid); + } + switch_channel_set_state(caller_channel, CS_EXECUTE); + switch_channel_set_state(peer_channel, CS_EXECUTE); + + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "XFER LOOP %s %s , %s\n", xfer_uuid, uuid, peer_uuid); + + } + + if (peer_session) { + switch_core_session_rwunlock(peer_session); + } + } +} + void add_kz_dptools(switch_loadable_module_interface_t **module_interface, switch_application_interface_t *app_interface) { SWITCH_ADD_APP(app_interface, "kz_set", SET_SHORT_DESC, SET_LONG_DESC, set_function, SET_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC); SWITCH_ADD_APP(app_interface, "kz_set_encoded", SET_SHORT_DESC, SET_LONG_DESC, set_encoded_function, SET_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC); @@ -471,5 +589,7 @@ void add_kz_dptools(switch_loadable_module_interface_t **module_interface, switc SWITCH_ADD_APP(app_interface, "kz_uuid_multiset", UUID_MULTISET_SHORT_DESC, UUID_MULTISET_LONG_DESC, uuid_multiset_function, UUID_MULTISET_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC); SWITCH_ADD_APP(app_interface, "kz_uuid_multiset_encoded", UUID_MULTISET_SHORT_DESC, UUID_MULTISET_LONG_DESC, uuid_multiset_encoded_function, UUID_MULTISET_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC); SWITCH_ADD_APP(app_interface, "kz_endless_playback", KZ_ENDLESS_PLAYBACK_SHORT_DESC, KZ_ENDLESS_PLAYBACK_LONG_DESC, kz_endless_playback_function, KZ_ENDLESS_PLAYBACK_SYNTAX, SAF_NONE); + SWITCH_ADD_APP(app_interface, "kz_restore_caller_id", NOOP_SHORT_DESC, NOOP_LONG_DESC, kz_restore_caller_id_function, NOOP_SYNTAX, SAF_NONE); SWITCH_ADD_APP(app_interface, "noop", NOOP_SHORT_DESC, NOOP_LONG_DESC, noop_function, NOOP_SYNTAX, SAF_NONE); + 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); } 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 d1e925a66a..1dcbfa4733 100644 --- a/src/mod/event_handlers/mod_kazoo/kazoo_ei_utils.c +++ b/src/mod/event_handlers/mod_kazoo/kazoo_ei_utils.c @@ -519,6 +519,8 @@ switch_status_t create_acceptor() { char ipbuf[48]; const char *ip_addr; + ei_init(); + /* if the config has specified an erlang release compatibility then pass that along to the erlang interface */ if (kazoo_globals.ei_compat_rel) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Compatability with OTP R%d requested\n", kazoo_globals.ei_compat_rel); diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_endpoints.c b/src/mod/event_handlers/mod_kazoo/kazoo_endpoints.c new file mode 100644 index 0000000000..fba1adddb1 --- /dev/null +++ b/src/mod/event_handlers/mod_kazoo/kazoo_endpoints.c @@ -0,0 +1,284 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005-2012, Anthony Minessale II + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is + * Anthony Minessale II + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Karl Anderson + * Darren Schreiber + * + * + * kazoo_dptools.c -- clones of mod_dptools commands slightly modified for kazoo + * + */ +#include "mod_kazoo.h" + +/* kazoo endpoint */ +switch_endpoint_interface_t *kz_endpoint_interface; +static switch_call_cause_t kz_endpoint_outgoing_channel(switch_core_session_t *session, + switch_event_t *var_event, + switch_caller_profile_t *outbound_profile, + switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, + switch_call_cause_t *cancel_cause); +switch_io_routines_t kz_endpoint_io_routines = { + /*.outgoing_channel */ kz_endpoint_outgoing_channel +}; + +static switch_call_cause_t kz_endpoint_outgoing_channel(switch_core_session_t *session, + switch_event_t *var_event, + switch_caller_profile_t *outbound_profile, + switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, + switch_call_cause_t *cancel_cause) +{ + switch_xml_t x_user = NULL, x_param, x_params; + char *user = NULL, *domain = NULL, *dup_domain = NULL, *dialed_user = NULL; + const char *dest = NULL; + switch_call_cause_t cause = SWITCH_CAUSE_NONE; + unsigned int timelimit = SWITCH_DEFAULT_TIMEOUT; + switch_channel_t *new_channel = NULL; + switch_event_t *params = NULL, *var_event_orig = var_event; + char stupid[128] = ""; + const char *skip = NULL, *var = NULL; + + if (zstr(outbound_profile->destination_number)) { + goto done; + } + + user = strdup(outbound_profile->destination_number); + + if (!user) + goto done; + + if ((domain = strchr(user, '@'))) { + *domain++ = '\0'; + } else { + domain = switch_core_get_domain(SWITCH_TRUE); + dup_domain = domain; + } + + if (!domain) { + goto done; + } + + + switch_event_create(¶ms, SWITCH_EVENT_REQUEST_PARAMS); + switch_assert(params); + switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "as_channel", "true"); + switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "action", "user_call"); + + if (var_event) { + switch_event_merge(params, var_event); + } + + if (var_event && (skip = switch_event_get_header(var_event, "user_recurse_variables")) && switch_false(skip)) { + if ((var = switch_event_get_header(var_event, SWITCH_CALL_TIMEOUT_VARIABLE)) || (var = switch_event_get_header(var_event, "leg_timeout"))) { + timelimit = atoi(var); + } + var_event = NULL; + } + + if (switch_xml_locate_user_merged("id", user, domain, NULL, &x_user, params) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Can't find user [%s@%s]\n", user, domain); + cause = SWITCH_CAUSE_SUBSCRIBER_ABSENT; + goto done; + } + + if ((x_params = switch_xml_child(x_user, "params"))) { + for (x_param = switch_xml_child(x_params, "param"); x_param; x_param = x_param->next) { + const char *pvar = switch_xml_attr_soft(x_param, "name"); + const char *val = switch_xml_attr(x_param, "value"); + + if (!strcasecmp(pvar, "dial-string")) { + dest = val; + } else if (!strncasecmp(pvar, "dial-var-", 9)) { + if (!var_event) { + switch_event_create(&var_event, SWITCH_EVENT_GENERAL); + } else { + switch_event_del_header(var_event, pvar + 9); + } + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "adding variable to var_event => %s = %s\n", pvar + 9, val); + switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, pvar + 9, val); + } + } + } + + dialed_user = (char *)switch_xml_attr(x_user, "id"); + + if (var_event) { + switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "dialed_user", dialed_user); + switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "dialed_domain", domain); + if (!zstr(dest) && !strstr(dest, "presence_id=")) { + switch_event_add_header(var_event, SWITCH_STACK_BOTTOM, "presence_id", "%s@%s", dialed_user, domain); + } + } + + if (!dest) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No dial-string available, please check your user directory.\n"); + cause = SWITCH_CAUSE_MANDATORY_IE_MISSING; + } else { + const char *varval; + char *d_dest = NULL; + switch_channel_t *channel; + switch_originate_flag_t myflags = SOF_NONE; + char *cid_name_override = NULL; + char *cid_num_override = NULL; + + if (var_event) { + cid_name_override = switch_event_get_header(var_event, "origination_caller_id_name"); + cid_num_override = switch_event_get_header(var_event, "origination_caller_id_number"); + } + + if (session) { + switch_event_t *event = NULL; + switch_event_create(&event, SWITCH_EVENT_GENERAL); + channel = switch_core_session_get_channel(session); + if ((varval = switch_channel_get_variable(channel, SWITCH_CALL_TIMEOUT_VARIABLE)) + || (var_event && (varval = switch_event_get_header(var_event, "leg_timeout")))) { + timelimit = atoi(varval); + } + switch_channel_event_set_data(channel, event); + if(var_event) { + switch_event_merge(event, var_event); + } + + switch_channel_set_variable(channel, "dialed_user", dialed_user); + switch_channel_set_variable(channel, "dialed_domain", domain); + + d_dest = switch_event_expand_headers(event, dest); + + switch_event_destroy(&event); + + } else { + switch_event_t *event = NULL; + + if (var_event) { + switch_event_dup(&event, var_event); + switch_event_del_header(event, "dialed_user"); + switch_event_del_header(event, "dialed_domain"); + if ((varval = switch_event_get_header(var_event, SWITCH_CALL_TIMEOUT_VARIABLE)) || + (varval = switch_event_get_header(var_event, "leg_timeout"))) { + timelimit = atoi(varval); + } + } else { + switch_event_create(&event, SWITCH_EVENT_REQUEST_PARAMS); + switch_assert(event); + } + + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "dialed_user", dialed_user); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "dialed_domain", domain); + d_dest = switch_event_expand_headers(event, dest); + switch_event_destroy(&event); + } + + if ((flags & SOF_NO_LIMITS)) { + myflags |= SOF_NO_LIMITS; + } + + if ((flags & SOF_FORKED_DIAL)) { + myflags |= SOF_NOBLOCK; + } + + switch_snprintf(stupid, sizeof(stupid), "kz/%s", dialed_user); + if (switch_stristr(stupid, d_dest)) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Waddya Daft? You almost called '%s' in an infinate loop!\n", + stupid); + cause = SWITCH_CAUSE_INVALID_IE_CONTENTS; + } else if (switch_ivr_originate(session, new_session, &cause, d_dest, timelimit, NULL, + cid_name_override, cid_num_override, outbound_profile, var_event, myflags, + cancel_cause, NULL) == SWITCH_STATUS_SUCCESS) { + const char *context; + switch_caller_profile_t *cp; + + if (var_event) { + switch_event_del_header(var_event, "origination_uuid"); + } + + new_channel = switch_core_session_get_channel(*new_session); + + if ((context = switch_channel_get_variable(new_channel, "user_context"))) { + if ((cp = switch_channel_get_caller_profile(new_channel))) { + cp->context = switch_core_strdup(cp->pool, context); + } + } + + if ((x_params = switch_xml_child(x_user, "variables"))) { + for (x_param = switch_xml_child(x_params, "variable"); x_param; x_param = x_param->next) { + const char *pvar = switch_xml_attr(x_param, "name"); + const char *val = switch_xml_attr(x_param, "value"); + switch_channel_set_variable(new_channel, pvar, val); + } + } + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_DEBUG1, "CHECKING CALLER-ID\n"); + if ((x_params = switch_xml_child(x_user, "profile-variables"))) { + switch_caller_profile_t *cp = NULL; + const char* val = NULL; + for (x_param = switch_xml_child(x_params, "variable"); x_param; x_param = x_param->next) { + const char *pvar = switch_xml_attr(x_param, "name"); + const char *val = switch_xml_attr(x_param, "value"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_DEBUG1, "setting profile var %s = %s\n", pvar, val); + switch_channel_set_profile_var(new_channel, pvar, val); + } + cp = switch_channel_get_caller_profile(new_channel); + if((val=switch_caller_get_field_by_name(cp, "Endpoint-Caller-ID-Name"))) { + cp->callee_id_name = val; + cp->orig_caller_id_name = val; + } + if((val=switch_caller_get_field_by_name(cp, "Endpoint-Caller-ID-Number"))) { + cp->callee_id_number = val; + cp->orig_caller_id_number = val; + } + } + switch_core_session_rwunlock(*new_session); + } + + if (d_dest != dest) { + switch_safe_free(d_dest); + } + } + + done: + + if (x_user) { + switch_xml_free(x_user); + } + + if (params) { + switch_event_destroy(¶ms); + } + + if (var_event && var_event_orig != var_event) { + switch_event_destroy(&var_event); + } + + switch_safe_free(user); + switch_safe_free(dup_domain); + + return cause; +} + + +void add_kz_endpoints(switch_loadable_module_interface_t **module_interface) { + kz_endpoint_interface = (switch_endpoint_interface_t *) switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE); + kz_endpoint_interface->interface_name = "kz"; + kz_endpoint_interface->io_routines = &kz_endpoint_io_routines; +} diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_tweaks.c b/src/mod/event_handlers/mod_kazoo/kazoo_tweaks.c index 7b8d83fce9..d7fa0293c6 100644 --- a/src/mod/event_handlers/mod_kazoo/kazoo_tweaks.c +++ b/src/mod/event_handlers/mod_kazoo/kazoo_tweaks.c @@ -36,6 +36,9 @@ static const char *bridge_variables[] = { "Call-Control-Node", "ecallmgr_Call-Interaction-ID", "ecallmgr_Ecallmgr-Node", + "sip_h_k-cid", + "Switch-URI", + "Switch-URL", NULL }; @@ -146,10 +149,12 @@ static void kz_tweaks_handle_bridge_replaces(switch_event_t *event) } } } + } + } -static void kz_tweaks_handle_bridge_replaces_caller_id(switch_event_t *event) +static void kz_tweaks_handle_bridge_replaces_call_id(switch_event_t *event) { switch_event_t *my_event; @@ -178,12 +183,11 @@ static void kz_tweaks_handle_bridge_replaces_caller_id(switch_event_t *event) } - static void kz_tweaks_channel_bridge_event_handler(switch_event_t *event) { - kz_tweaks_handle_bridge_variables(event); - kz_tweaks_handle_bridge_replaces_caller_id(event); + kz_tweaks_handle_bridge_replaces_call_id(event); kz_tweaks_handle_bridge_replaces(event); + kz_tweaks_handle_bridge_variables(event); } // TRANSFERS @@ -300,11 +304,11 @@ static switch_status_t kz_tweaks_handle_loopback(switch_core_session_t *session) for(header = event->headers; header; header = header->next) { if(!strncmp(header->name, "Export-Loopback-", 16)) { - switch_event_add_variable_name_printf(to_add, SWITCH_STACK_BOTTOM, header->value, "%s", header->name+16); + kz_switch_event_add_variable_name_printf(to_add, SWITCH_STACK_BOTTOM, header->value, "%s", header->name+16); switch_channel_set_variable(channel, header->name, NULL); n++; } else if(!strncmp(header->name, "sip_loopback_", 13)) { - switch_event_add_variable_name_printf(to_add, SWITCH_STACK_BOTTOM, header->value, "sip_%s", header->name+13); + kz_switch_event_add_variable_name_printf(to_add, SWITCH_STACK_BOTTOM, header->value, "sip_%s", header->name+13); } else if(!strncmp(header->name, "ecallmgr_", 9)) { switch_event_add_header_string(to_remove, SWITCH_STACK_BOTTOM, header->name, header->value); } @@ -347,9 +351,19 @@ static switch_status_t kz_tweaks_handle_loopback(switch_core_session_t *session) static void kz_tweaks_handle_caller_id(switch_core_session_t *session) { switch_channel_t *channel = switch_core_session_get_channel(session); - const char *acl_token = switch_channel_get_variable(channel, "acl_token"); - if(acl_token) { - switch_ivr_set_user(session, acl_token); + const char *token = switch_channel_get_variable(channel, "acl_token"); + switch_caller_profile_t* caller = switch_channel_get_caller_profile(channel); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "CHECKING CALLER-ID\n"); + if (token) { + const char* val = NULL; + if((val=switch_caller_get_field_by_name(caller, "Endpoint-Caller-ID-Name"))) { + caller->caller_id_name = val; + caller->orig_caller_id_name = val; + } + if((val=switch_caller_get_field_by_name(caller, "Endpoint-Caller-ID-Number"))) { + caller->caller_id_number = val; + caller->orig_caller_id_number = val; + } } } @@ -420,14 +434,11 @@ static switch_status_t kz_tweaks_handle_replaces_id(switch_core_session_t *sessi switch_core_session_t *replace_call_session = NULL; switch_event_t *event; switch_channel_t *channel = switch_core_session_get_channel(session); - switch_memory_pool_t *pool = switch_core_session_get_pool(session); 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); if ((replace_call_session = switch_core_session_locate(replaced_call_id))) { - const char* tmp_caller = NULL; - switch_caller_profile_t * cp = switch_channel_get_caller_profile(channel); switch_channel_t *replaced_call_channel = switch_core_session_get_channel(replace_call_session); int i; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "setting bridge variables from %s to %s\n", replaced_call_id, switch_channel_get_uuid(channel)); @@ -440,12 +451,6 @@ static switch_status_t kz_tweaks_handle_replaces_id(switch_core_session_t *sessi switch_channel_event_set_data(channel, event); switch_event_fire(&event); } - if((tmp_caller = switch_channel_get_variable(channel, "Internal-Caller-ID-Number")) != NULL) { - profile_dup_clean(tmp_caller, cp->caller_id_number, pool); - } - if((tmp_caller = switch_channel_get_variable(channel, "Internal-Caller-ID-Name")) != NULL) { - profile_dup_clean(tmp_caller, cp->caller_id_name, pool); - } switch_core_session_rwunlock(replace_call_session); } } @@ -469,11 +474,42 @@ static switch_status_t kz_tweaks_handle_switch_uri(switch_core_session_t *sessio } +static switch_status_t kz_tweaks_register_handle_xfer(switch_core_session_t *session) +{ + switch_channel_t *channel = switch_core_session_get_channel(session); + switch_channel_set_variable(channel, "execute_on_blind_transfer", "kz_restore_caller_id"); + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t kz_tweaks_set_export_vars(switch_core_session_t *session) +{ + switch_channel_t *channel = switch_core_session_get_channel(session); + + const char *exports; + char *var, *new_exports, *new_exports_d = NULL; + + exports = switch_channel_get_variable(channel, SWITCH_EXPORT_VARS_VARIABLE); + var = switch_core_session_strdup(session, "Switch-URI,Switch-URL"); + + if (exports) { + new_exports_d = switch_mprintf("%s,%s", exports, var); + new_exports = new_exports_d; + } else { + new_exports = var; + } + + switch_channel_set_variable(channel, SWITCH_EXPORT_VARS_VARIABLE, new_exports); + + switch_safe_free(new_exports_d); + + + return SWITCH_STATUS_SUCCESS; +} static switch_status_t kz_tweaks_on_init(switch_core_session_t *session) { switch_channel_t *channel = switch_core_session_get_channel(session); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "checking tweaks for %s\n", switch_channel_get_uuid(channel)); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "checking tweaks for %s\n", switch_channel_get_uuid(channel)); switch_channel_set_flag(channel, CF_VERBOSE_EVENTS); kz_tweaks_handle_switch_uri(session); kz_tweaks_handle_caller_id(session); @@ -481,6 +517,8 @@ static switch_status_t kz_tweaks_on_init(switch_core_session_t *session) kz_tweaks_handle_nightmare_xfer(session); kz_tweaks_handle_replaces_id(session); kz_tweaks_handle_loopback(session); + kz_tweaks_register_handle_xfer(session); + kz_tweaks_set_export_vars(session); return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_utils.c b/src/mod/event_handlers/mod_kazoo/kazoo_utils.c index d97b5b5a93..deb33e1a03 100644 --- a/src/mod/event_handlers/mod_kazoo/kazoo_utils.c +++ b/src/mod/event_handlers/mod_kazoo/kazoo_utils.c @@ -34,6 +34,17 @@ */ #include "mod_kazoo.h" +#define kz_resize(l) {\ +char *dp;\ +olen += (len + l + block);\ +cpos = c - data;\ +if ((dp = realloc(data, olen))) {\ + data = dp;\ + c = data + cpos;\ + memset(c, 0, olen - cpos);\ + }} \ + + void kz_check_set_profile_var(switch_channel_t *channel, char* var, char *val) { int idx = 0; @@ -47,6 +58,27 @@ void kz_check_set_profile_var(switch_channel_t *channel, char* var, char *val) } } +SWITCH_DECLARE(switch_status_t) kz_switch_core_merge_variables(switch_event_t *event) +{ + switch_event_t *global_vars; + switch_status_t status = switch_core_get_variables(&global_vars); + if(status == SWITCH_STATUS_SUCCESS) { + switch_event_merge(event, global_vars); + switch_event_destroy(&global_vars); + } + return status; +} + +SWITCH_DECLARE(switch_status_t) kz_switch_core_base_headers_for_expand(switch_event_t **event) +{ + switch_status_t status = SWITCH_STATUS_GENERR; + *event = NULL; + if(switch_event_create(event, SWITCH_EVENT_GENERAL) == SWITCH_STATUS_SUCCESS) { + status = kz_switch_core_merge_variables(*event); + } + return status; +} + SWITCH_DECLARE(switch_status_t) kz_expand_api_execute(const char *cmd, const char *arg, switch_core_session_t *session, switch_stream_handle_t *stream) { switch_api_interface_t *api; @@ -87,15 +119,6 @@ SWITCH_DECLARE(switch_status_t) kz_expand_api_execute(const char *cmd, const cha return status; } -#define resize(l) {\ -char *dp;\ -olen += (len + l + block);\ -cpos = c - data;\ -if ((dp = realloc(data, olen))) {\ - data = dp;\ - c = data + cpos;\ - memset(c, 0, olen - cpos);\ - }} \ SWITCH_DECLARE(char *) kz_event_expand_headers_check(switch_event_t *event, const char *in, switch_event_t *var_list, switch_event_t *api_list, uint32_t recur) { @@ -146,7 +169,7 @@ SWITCH_DECLARE(char *) kz_event_expand_headers_check(switch_event_t *event, cons continue; } else if (*(p + 1) == '\\') { if (len + 1 >= olen) { - resize(1); + kz_resize(1); } *c++ = *p++; @@ -174,7 +197,7 @@ SWITCH_DECLARE(char *) kz_event_expand_headers_check(switch_event_t *event, cons if (nv) { if (len + 1 >= olen) { - resize(1); + kz_resize(1); } *c++ = *p; @@ -362,7 +385,7 @@ SWITCH_DECLARE(char *) kz_event_expand_headers_check(switch_event_t *event, cons } if ((nlen = sub_val ? strlen(sub_val) : 0)) { if (len + nlen >= olen) { - resize(nlen); + kz_resize(nlen); } len += nlen; @@ -381,7 +404,7 @@ SWITCH_DECLARE(char *) kz_event_expand_headers_check(switch_event_t *event, cons if (sp) { if (len + 1 >= olen) { - resize(1); + kz_resize(1); } *c++ = ' '; @@ -393,7 +416,7 @@ SWITCH_DECLARE(char *) kz_event_expand_headers_check(switch_event_t *event, cons p--; } else { if (len + 1 >= olen) { - resize(1); + kz_resize(1); } *c++ = *p; @@ -412,6 +435,16 @@ SWITCH_DECLARE(char *) kz_event_expand_headers(switch_event_t *event, const char return kz_event_expand_headers_check(event, in, NULL, NULL, 0); } +SWITCH_DECLARE(char *) kz_event_expand(const char *in) +{ + switch_event_t *event = NULL; + char *ret = NULL; + kz_switch_core_base_headers_for_expand(&event); + ret = kz_event_expand_headers_check(event, in, NULL, NULL, 0); + switch_event_destroy(&event); + return ret; +} + char *kazoo_expand_header(switch_memory_pool_t *pool, switch_event_t *event, char *val) { char *expanded; @@ -427,7 +460,7 @@ char *kazoo_expand_header(switch_memory_pool_t *pool, switch_event_t *event, cha return dup; } -char* switch_event_get_first_of(switch_event_t *event, const char *list[]) +char* kz_switch_event_get_first_of(switch_event_t *event, const char *list[]) { switch_event_header_t *header = NULL; int i = 0; @@ -443,7 +476,7 @@ char* switch_event_get_first_of(switch_event_t *event, const char *list[]) } } -SWITCH_DECLARE(switch_status_t) switch_event_add_variable_name_printf(switch_event_t *event, switch_stack_t stack, const char *val, const char *fmt, ...) +SWITCH_DECLARE(switch_status_t) kz_switch_event_add_variable_name_printf(switch_event_t *event, switch_stack_t stack, const char *val, const char *fmt, ...) { int ret = 0; char *varname; diff --git a/src/mod/event_handlers/mod_kazoo/mod_kazoo.c b/src/mod/event_handlers/mod_kazoo/mod_kazoo.c index 31d998b5dc..13ab8de247 100644 --- a/src/mod/event_handlers/mod_kazoo/mod_kazoo.c +++ b/src/mod/event_handlers/mod_kazoo/mod_kazoo.c @@ -74,6 +74,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_kazoo_load) { /* add our modified dptools */ add_kz_dptools(module_interface, app_interface); + /* add our endpoints */ + add_kz_endpoints(module_interface); + /* add tweaks */ kz_tweaks_start(); diff --git a/src/mod/event_handlers/mod_kazoo/mod_kazoo.h b/src/mod/event_handlers/mod_kazoo/mod_kazoo.h index 9848f2a2b8..2b02ee973a 100644 --- a/src/mod/event_handlers/mod_kazoo/mod_kazoo.h +++ b/src/mod/event_handlers/mod_kazoo/mod_kazoo.h @@ -36,16 +36,22 @@ void add_cli_api(switch_loadable_module_interface_t **module_interface, switch_a void remove_cli_api(); /* kazoo_utils.c */ +SWITCH_DECLARE(switch_status_t) kz_switch_core_merge_variables(switch_event_t *event); +SWITCH_DECLARE(switch_status_t) kz_switch_core_base_headers_for_expand(switch_event_t **event); void kz_check_set_profile_var(switch_channel_t *channel, char* var, char *val); char *kazoo_expand_header(switch_memory_pool_t *pool, switch_event_t *event, char *val); -char* switch_event_get_first_of(switch_event_t *event, const char *list[]); -SWITCH_DECLARE(switch_status_t) switch_event_add_variable_name_printf(switch_event_t *event, switch_stack_t stack, const char *val, const char *fmt, ...); +char* kz_switch_event_get_first_of(switch_event_t *event, const char *list[]); +SWITCH_DECLARE(switch_status_t) kz_switch_event_add_variable_name_printf(switch_event_t *event, switch_stack_t stack, const char *val, const char *fmt, ...); void kz_xml_process(switch_xml_t cfg); void kz_event_decode(switch_event_t *event); char * kz_expand_vars(char *xml_str); char * kz_expand_vars_pool(char *xml_str, switch_memory_pool_t *pool); SWITCH_DECLARE(char *) kz_event_expand_headers(switch_event_t *event, const char *in); +/* kazoo_endpoints.c */ +void add_kz_endpoints(switch_loadable_module_interface_t **module_interface); + + /* kazoo_tweaks.c */ void kz_tweaks_start(); void kz_tweaks_stop();