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();