diff --git a/src/mod/event_handlers/mod_kazoo/Makefile.am b/src/mod/event_handlers/mod_kazoo/Makefile.am
index 516c192c93..668d9ffed2 100644
--- a/src/mod/event_handlers/mod_kazoo/Makefile.am
+++ b/src/mod/event_handlers/mod_kazoo/Makefile.am
@@ -12,6 +12,7 @@ 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_SOURCES += kz_node.c
mod_kazoo_la_CFLAGS = $(AM_CFLAGS) @ERLANG_CFLAGS@ -D_REENTRANT -DERLANG_VERSION=@ERLANG_VERSION@ -DERLANG_MAJOR=@ERLANG_MAJOR@ -DERLANG_MINOR=@ERLANG_MINOR@
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 155bb5f328..71a05e18e7 100644
--- a/src/mod/event_handlers/mod_kazoo/kazoo.conf.xml
+++ b/src/mod/event_handlers/mod_kazoo/kazoo.conf.xml
@@ -21,8 +21,6 @@
-
-
@@ -30,13 +28,37 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -96,18 +118,9 @@
-
-
-
-
-
-
-
-
+
+
+
@@ -671,6 +684,7 @@
+
@@ -1078,8 +1092,6 @@
-
-
@@ -1157,8 +1169,6 @@
-
-
diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_commands.c b/src/mod/event_handlers/mod_kazoo/kazoo_commands.c
index 6bae6c822e..d61a1054ac 100644
--- a/src/mod/event_handlers/mod_kazoo/kazoo_commands.c
+++ b/src/mod/event_handlers/mod_kazoo/kazoo_commands.c
@@ -48,6 +48,103 @@
#define MAX_FIRST_OF 25
+#define MAX_HISTORY 50
+#define HST_ARRAY_DELIM "|:"
+#define HST_ITEM_DELIM ':'
+
+static void process_history_item(char* value, cJSON *json)
+{
+ char *argv[4] = { 0 };
+ char *item = strdup(value);
+ int argc = switch_separate_string(item, HST_ITEM_DELIM, argv, (sizeof(argv) / sizeof(argv[0])));
+ cJSON *jitem = cJSON_CreateObject();
+ char *epoch = NULL, *callid = NULL, *type = NULL;
+ int add = 0;
+ if(argc == 4) {
+ add = 1;
+ epoch = argv[0];
+ callid = argv[1];
+ type = argv[2];
+
+ if(!strncmp(type, "bl_xfer", 7)) {
+ char *split = strchr(argv[3], '/');
+ if(split) *(split++) = '\0';
+ cJSON_AddItemToObject(jitem, "Call-ID", cJSON_CreateString(callid));
+ cJSON_AddItemToObject(jitem, "Type", cJSON_CreateString("blind"));
+ cJSON_AddItemToObject(jitem, "Extension", cJSON_CreateString(argv[3]));
+ } else if(!strncmp(type, "att_xfer", 8)) {
+ char *split = strchr(argv[3], '/');
+ if(split) {
+ *(split++) = '\0';
+ cJSON_AddItemToObject(jitem, "Call-ID", cJSON_CreateString(callid));
+ cJSON_AddItemToObject(jitem, "Type", cJSON_CreateString("attended"));
+ cJSON_AddItemToObject(jitem, "Transferee", cJSON_CreateString(argv[3]));
+ cJSON_AddItemToObject(jitem, "Transferer", cJSON_CreateString(split));
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "TRANSFER TYPE '%s' NOT HANDLED => %s\n", type, item);
+ add = 0;
+ }
+ } else if(!strncmp(type, "uuid_br", 7)) {
+ cJSON_AddItemToObject(jitem, "Call-ID", cJSON_CreateString(callid));
+ cJSON_AddItemToObject(jitem, "Type", cJSON_CreateString("bridge"));
+ cJSON_AddItemToObject(jitem, "Other-Leg", cJSON_CreateString(argv[3]));
+
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "TRANSFER TYPE '%s' NOT HANDLED => %s\n", type, item);
+ add = 0;
+ }
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "TRANSFER TYPE SPLIT ERROR %i => %s\n", argc, item);
+ }
+ if(add) {
+ cJSON_AddItemToObject(json, epoch, jitem);
+ } else {
+ cJSON_Delete(jitem);
+ }
+ switch_safe_free(item);
+}
+
+SWITCH_STANDARD_API(kz_json_history) {
+ char *mycmd = NULL, *argv[MAX_HISTORY] = { 0 };
+ int n, argc = 0;
+ cJSON *json = cJSON_CreateObject();
+ char* output = NULL;
+ switch_event_header_t *header = NULL;
+ if (!zstr(cmd) && (mycmd = strdup(cmd))) {
+ if (!strncmp(mycmd, "ARRAY::", 7)) {
+ mycmd += 7;
+ argc = switch_separate_string_string(mycmd, HST_ARRAY_DELIM, argv, (sizeof(argv) / sizeof(argv[0])));
+ for(n=0; n < argc; n++) {
+ process_history_item(argv[n], json);
+ }
+ } else if (strchr(mycmd, HST_ITEM_DELIM)) {
+ process_history_item(mycmd, json);
+ } else if (stream->param_event) {
+ header = switch_event_get_header_ptr(stream->param_event, mycmd);
+ if (header != NULL) {
+ if(header->idx) {
+ for(n = 0; n < header->idx; n++) {
+ process_history_item(header->array[n], json);
+ }
+ } else {
+ process_history_item(header->value, json);
+ }
+
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "TRANSFER HISTORY HEADER NOT FOUND => %s\n", mycmd);
+ }
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "TRANSFER HISTORY NOT PARSED => %s\n", mycmd);
+ }
+ }
+ output = cJSON_PrintUnformatted(json);
+ stream->write_function(stream, "%s", output);
+ switch_safe_free(output);
+ cJSON_Delete(json);
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
SWITCH_STANDARD_API(kz_first_of) {
char delim = '|';
char *mycmd = NULL, *argv[MAX_FIRST_OF] = { 0 };
@@ -413,5 +510,6 @@ void add_kz_commands(switch_loadable_module_interface_t **module_interface, swit
switch_console_set_complete("add kz_uuid_setvar_encoded ::console::list_uuid");
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_json_history", KZ_FIRST_OF_DESC, kz_json_history, KZ_FIRST_OF_SYNTAX);
}
diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_config.c b/src/mod/event_handlers/mod_kazoo/kazoo_config.c
index 5608b10211..fcda9012ff 100644
--- a/src/mod/event_handlers/mod_kazoo/kazoo_config.c
+++ b/src/mod/event_handlers/mod_kazoo/kazoo_config.c
@@ -217,6 +217,8 @@ switch_status_t kazoo_config_filters(switch_memory_pool_t *pool, switch_xml_t cf
cur->compare = FILTER_COMPARE_EXISTS;
} else if (!strncmp(compare, "regex", 5)) {
cur->compare = FILTER_COMPARE_REGEX;
+ } else if (!strncmp(compare, "field", 5)) {
+ cur->compare = FILTER_COMPARE_FIELD;
}
}
@@ -400,11 +402,11 @@ kazoo_config_ptr kazoo_config_event_handlers(kazoo_config_ptr definitions, switc
kazoo_config_event_handler(definitions, profiles, xml_profile, NULL);
}
} else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Unable to locate a event-handler profile for kazoo\n" );
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "unable to locate a event-handler profile for kazoo\n" );
}
} else {
destroy_config(&profiles);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unable to locate event-handlers section for kazoo\n" );
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "unable to locate event-handlers section for kazoo, using default\n" );
}
return profiles;
@@ -437,11 +439,11 @@ kazoo_config_ptr kazoo_config_fetch_handlers(kazoo_config_ptr definitions, switc
kazoo_config_fetch_handler(definitions, profiles, xml_profile, NULL);
}
} else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Unable to locate a fetch-handler profile for kazoo\n" );
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "unable to locate a fetch-handler profile for kazoo\n" );
}
} else {
destroy_config(&profiles);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unable to locate fetch-handlers section for kazoo\n" );
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "unable to locate fetch-handlers section for kazoo, using default\n" );
}
return profiles;
@@ -455,7 +457,7 @@ switch_status_t kazoo_config_definition(kazoo_config_ptr root, switch_xml_t cfg)
char *name = (char *) switch_xml_attr_soft(cfg, "name");
if (zstr(name)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to load kazoo profile. Check definition missing name attr\n");
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to load kazoo profile, check definition missing name attr\n");
return SWITCH_STATUS_GENERR;
}
@@ -466,11 +468,11 @@ switch_status_t kazoo_config_definition(kazoo_config_ptr root, switch_xml_t cfg)
kazoo_config_fields_loop(root, root->pool, cfg, &definition->head);
if ( switch_core_hash_insert(root->hash, name, (void *) definition) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to insert new definition [%s] into kazoo definitions hash\n", name);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to insert new definition [%s] into kazoo definitions hash\n", name);
return SWITCH_STATUS_GENERR;
}
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Definition[%s] Successfully configured\n", definition->name);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "definition[%s] successfully configured\n", definition->name);
return SWITCH_STATUS_SUCCESS;
}
@@ -499,7 +501,7 @@ kazoo_config_ptr kazoo_config_definitions(switch_xml_t cfg)
}
} else {
destroy_config(&definitions);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "no definitions section for kazoo\n" );
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "unable to locate definitions section for kazoo, using default\n" );
}
return definitions;
diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_ei.h b/src/mod/event_handlers/mod_kazoo/kazoo_ei.h
index fd03239751..7939145947 100644
--- a/src/mod/event_handlers/mod_kazoo/kazoo_ei.h
+++ b/src/mod/event_handlers/mod_kazoo/kazoo_ei.h
@@ -185,10 +185,6 @@ struct globals_s {
kazoo_json_term json_encoding;
int enable_legacy;
-// char *profile_vars_prefixes[KZ_MAX_SEPARATE_STRINGS];
-// char *kazoo_var_prefixes[KZ_MAX_SEPARATE_STRINGS];
-// char *profile_vars_prefixes;
-// char *kazoo_var_prefixes;
char **profile_vars_prefixes;
char **kazoo_var_prefixes;
diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_ei_config.c b/src/mod/event_handlers/mod_kazoo/kazoo_ei_config.c
index 67c8d5d9df..a9f50df988 100644
--- a/src/mod/event_handlers/mod_kazoo/kazoo_ei_config.c
+++ b/src/mod/event_handlers/mod_kazoo/kazoo_ei_config.c
@@ -113,7 +113,7 @@ switch_status_t kazoo_ei_config(switch_xml_t cfg) {
kazoo_globals.port = 0;
kazoo_globals.io_fault_tolerance = 10;
kazoo_globals.json_encoding = ERLANG_TUPLE;
- kazoo_globals.enable_legacy = SWITCH_TRUE;
+ kazoo_globals.enable_legacy = SWITCH_FALSE;
if ((child = switch_xml_child(cfg, "settings"))) {
@@ -306,6 +306,7 @@ switch_status_t kazoo_ei_config(switch_xml_t cfg) {
switch_status_t kazoo_config_handlers(switch_xml_t cfg)
{
switch_xml_t def = NULL;
+ switch_xml_t child, param;
char* xml = NULL;
kazoo_config_ptr definitions = NULL, fetch_handlers = NULL, event_handlers = NULL;
kazoo_event_profile_ptr events = NULL;
@@ -316,19 +317,49 @@ switch_status_t kazoo_config_handlers(switch_xml_t cfg)
kz_xml_process(def);
kz_xml_process(cfg);
+ if ((child = switch_xml_child(cfg, "variables"))) {
+ for (param = switch_xml_child(child, "variable"); param; param = param->next) {
+ char *var = (char *) switch_xml_attr_soft(param, "name");
+ char *val = (char *) switch_xml_attr_soft(param, "value");
+ if(var && val) {
+ switch_core_set_variable(var, val);
+ }
+ }
+ } else if ((child = switch_xml_child(def, "variables"))) {
+ for (param = switch_xml_child(child, "variable"); param; param = param->next) {
+ char *var = (char *) switch_xml_attr_soft(param, "name");
+ char *val = (char *) switch_xml_attr_soft(param, "value");
+ if(var && val) {
+ switch_core_set_variable(var, val);
+ }
+ }
+ }
+
definitions = kazoo_config_definitions(cfg);
if(definitions == NULL) {
- definitions = kazoo_config_definitions(def);
+ if(kazoo_globals.definitions == NULL) {
+ definitions = kazoo_config_definitions(def);
+ } else {
+ definitions = kazoo_globals.definitions;
+ }
}
fetch_handlers = kazoo_config_fetch_handlers(definitions, cfg);
if(fetch_handlers == NULL) {
- fetch_handlers = kazoo_config_fetch_handlers(definitions, def);
+ if(kazoo_globals.fetch_handlers == NULL) {
+ fetch_handlers = kazoo_config_fetch_handlers(definitions, def);
+ } else {
+ fetch_handlers = kazoo_globals.fetch_handlers;
+ }
}
event_handlers = kazoo_config_event_handlers(definitions, cfg);
if(event_handlers == NULL) {
- event_handlers = kazoo_config_event_handlers(definitions, def);
+ if(kazoo_globals.event_handlers == NULL) {
+ event_handlers = kazoo_config_event_handlers(definitions, def);
+ } else {
+ event_handlers = kazoo_globals.event_handlers;
+ }
}
if(event_handlers != NULL) {
@@ -337,26 +368,37 @@ switch_status_t kazoo_config_handlers(switch_xml_t cfg)
if(events == NULL) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to get default handler for events\n");
- destroy_config(&event_handlers);
- destroy_config(&fetch_handlers);
- destroy_config(&definitions);
+ if(kazoo_globals.event_handlers != event_handlers) destroy_config(&event_handlers);
+ if(kazoo_globals.fetch_handlers != fetch_handlers) destroy_config(&fetch_handlers);
+ if(kazoo_globals.definitions != definitions) destroy_config(&definitions);
switch_xml_free(def);
switch_safe_free(xml);
return SWITCH_STATUS_GENERR;
}
- bind_event_profiles(events->events);
- kazoo_globals.events = events;
+ if(kazoo_globals.events != events) {
+ bind_event_profiles(events->events);
+ kazoo_globals.events = events;
+ }
- destroy_config(&kazoo_globals.event_handlers);
- kazoo_globals.event_handlers = event_handlers;
+ if(kazoo_globals.event_handlers != event_handlers) {
+ kazoo_config_ptr tmp = kazoo_globals.event_handlers;
+ kazoo_globals.event_handlers = event_handlers;
+ destroy_config(&tmp);
+ }
- rebind_fetch_profiles(fetch_handlers);
- destroy_config(&kazoo_globals.fetch_handlers);
- kazoo_globals.fetch_handlers = fetch_handlers;
+ if(kazoo_globals.fetch_handlers != fetch_handlers) {
+ kazoo_config_ptr tmp = kazoo_globals.fetch_handlers;
+ kazoo_globals.fetch_handlers = fetch_handlers;
+ rebind_fetch_profiles(fetch_handlers);
+ destroy_config(&tmp);
+ }
- destroy_config(&kazoo_globals.definitions);
- kazoo_globals.definitions = definitions;
+ if(kazoo_globals.definitions != definitions) {
+ kazoo_config_ptr tmp = kazoo_globals.definitions;
+ kazoo_globals.definitions = definitions;
+ destroy_config(&tmp);
+ }
switch_xml_free(def);
diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_fields.h b/src/mod/event_handlers/mod_kazoo/kazoo_fields.h
index 95aab4e917..6c8111bfe4 100644
--- a/src/mod/event_handlers/mod_kazoo/kazoo_fields.h
+++ b/src/mod/event_handlers/mod_kazoo/kazoo_fields.h
@@ -78,7 +78,9 @@ typedef enum {
FILTER_COMPARE_LIST,
FILTER_COMPARE_VALUE,
FILTER_COMPARE_PREFIX,
- FILTER_COMPARE_EXISTS
+ FILTER_COMPARE_EXISTS,
+ FILTER_COMPARE_FIELD
+
} kazoo_filter_compare_type;
typedef enum {
@@ -115,7 +117,7 @@ typedef enum {
FIELD_PREFIX,
FIELD_OBJECT,
FIELD_GROUP,
- FIELD_REFERENCE,
+ FIELD_REFERENCE
} kazoo_field_type;
diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_message.c b/src/mod/event_handlers/mod_kazoo/kazoo_message.c
index 2c4d81d7ae..74ddff6647 100644
--- a/src/mod/event_handlers/mod_kazoo/kazoo_message.c
+++ b/src/mod/event_handlers/mod_kazoo/kazoo_message.c
@@ -49,7 +49,7 @@ static int inline filter_compare(switch_event_t* evt, kazoo_filter_ptr filter)
{
switch_event_header_t *header;
int hasValue = 0, n;
- char *value;
+ char *value = NULL, *expr = NULL;
switch(filter->compare) {
@@ -58,8 +58,21 @@ static int inline filter_compare(switch_event_t* evt, kazoo_filter_ptr filter)
break;
case FILTER_COMPARE_VALUE:
- value = switch_event_get_header_nil(evt, filter->name);
- hasValue = !strcmp(value, filter->value);
+ if (*filter->name == '$') {
+ value = expr = kz_event_expand_headers(evt, filter->name);
+ } else {
+ value = switch_event_get_header(evt, filter->name);
+ }
+ hasValue = value ? !strcmp(value, filter->value) : 0;
+ break;
+
+ case FILTER_COMPARE_FIELD:
+ if (*filter->name == '$') {
+ value = expr = kz_event_expand_headers(evt, filter->name);
+ } else {
+ value = switch_event_get_header(evt, filter->name);
+ }
+ hasValue = value ? !strcmp(value, switch_event_get_header_nil(evt, filter->value)) : 0;
break;
case FILTER_COMPARE_PREFIX:
@@ -72,7 +85,11 @@ static int inline filter_compare(switch_event_t* evt, kazoo_filter_ptr filter)
break;
case FILTER_COMPARE_LIST:
- value = switch_event_get_header(evt, filter->name);
+ if (*filter->name == '$') {
+ value = expr = kz_event_expand_headers(evt, filter->name);
+ } else {
+ value = switch_event_get_header(evt, filter->name);
+ }
if(value) {
for(n = 0; n < filter->list.size; n++) {
if(!strncmp(value, filter->list.value[n], strlen(filter->list.value[n]))) {
@@ -90,6 +107,8 @@ static int inline filter_compare(switch_event_t* evt, kazoo_filter_ptr filter)
break;
}
+ switch_safe_free(expr);
+
return hasValue;
}
diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_node.c b/src/mod/event_handlers/mod_kazoo/kazoo_node.c
index 32129150a0..9b1f06afd4 100644
--- a/src/mod/event_handlers/mod_kazoo/kazoo_node.c
+++ b/src/mod/event_handlers/mod_kazoo/kazoo_node.c
@@ -799,8 +799,10 @@ static switch_status_t handle_request_bind(ei_node_t *ei_node, erlang_pid *pid,
switch(section) {
case SWITCH_XML_SECTION_CONFIG:
add_fetch_handler(ei_node, pid, kazoo_globals.config_fetch_binding);
- if(!kazoo_globals.config_fetched)
+ if(!kazoo_globals.config_fetched) {
+ kazoo_globals.config_fetched = 1;
fetch_config();
+ }
break;
case SWITCH_XML_SECTION_DIRECTORY:
add_fetch_handler(ei_node, pid, kazoo_globals.directory_fetch_binding);
diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_tweaks.c b/src/mod/event_handlers/mod_kazoo/kazoo_tweaks.c
index d7fa0293c6..c391617d5c 100644
--- a/src/mod/event_handlers/mod_kazoo/kazoo_tweaks.c
+++ b/src/mod/event_handlers/mod_kazoo/kazoo_tweaks.c
@@ -30,11 +30,13 @@
*/
#include "mod_kazoo.h"
+#define INTERACTION_VARIABLE "Call-Interaction-ID"
+
static const char *bridge_variables[] = {
"Call-Control-Queue",
"Call-Control-PID",
"Call-Control-Node",
- "ecallmgr_Call-Interaction-ID",
+ INTERACTION_VARIABLE,
"ecallmgr_Ecallmgr-Node",
"sip_h_k-cid",
"Switch-URI",
@@ -67,7 +69,11 @@ static const switch_state_handler_table_t kz_tweaks_signal_bridge_state_handlers
/*.on_exchange_media */ NULL,
/*.on_soft_execute */ NULL,
/*.on_consume_media */ NULL,
- /*.on_hibernate */ NULL
+ /*.on_hibernate */ NULL,
+ /*.on_reset */ NULL,
+ /*.on_park */ NULL,
+ /*.on_reporting */ NULL,
+ /*.on_destroy */ NULL
};
static void kz_tweaks_handle_bridge_variables(switch_event_t *event)
@@ -77,15 +83,16 @@ static void kz_tweaks_handle_bridge_variables(switch_event_t *event)
const char *b_leg = switch_event_get_header(event, "Bridge-B-Unique-ID");
int i;
+ if (kazoo_globals.enable_legacy) return;
+
if (a_leg && (a_session = switch_core_session_force_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_force_locate(b_leg)) != NULL) {
switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
for(i = 0; bridge_variables[i] != NULL; i++) {
- const char *val = switch_channel_get_variable_dup(b_channel, bridge_variables[i], SWITCH_TRUE, -1);
+ 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_safe_strdup(val);
}
switch_core_session_rwunlock(b_session);
}
@@ -94,9 +101,8 @@ static void kz_tweaks_handle_bridge_variables(switch_event_t *event)
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(b_channel, bridge_variables[i], SWITCH_TRUE, -1);
+ 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_safe_strdup(val);
}
}
switch_core_session_rwunlock(b_session);
@@ -118,6 +124,9 @@ static void kz_tweaks_handle_bridge_replaces(switch_event_t *event)
const char *peer_uuid = switch_event_get_header(event, "Unique-ID");
int processed = 0;
+ if (kazoo_globals.enable_legacy) 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;
@@ -162,6 +171,8 @@ static void kz_tweaks_handle_bridge_replaces_call_id(switch_event_t *event)
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");
+ if (kazoo_globals.enable_legacy) return;
+
if(a_leg_call_id && replaced_call_id) {
switch_core_session_t *call_session = NULL;
const char *call_id = switch_event_get_header(event, "Bridge-B-Unique-ID");
@@ -185,6 +196,8 @@ static void kz_tweaks_handle_bridge_replaces_call_id(switch_event_t *event)
static void kz_tweaks_channel_bridge_event_handler(switch_event_t *event)
{
+ if (kazoo_globals.enable_legacy) return;
+
kz_tweaks_handle_bridge_replaces_call_id(event);
kz_tweaks_handle_bridge_replaces(event);
kz_tweaks_handle_bridge_variables(event);
@@ -196,6 +209,8 @@ static void kz_tweaks_channel_replaced_event_handler(switch_event_t *event)
{
const char *uuid = switch_event_get_header(event, "Unique-ID");
const char *replaced_by = switch_event_get_header(event, "att_xfer_replaced_by");
+ if (kazoo_globals.enable_legacy) return;
+
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "REPLACED : %s , %s\n", uuid, replaced_by);
}
@@ -203,6 +218,9 @@ static void kz_tweaks_channel_intercepted_event_handler(switch_event_t *event)
{
const char *uuid = switch_event_get_header(event, "Unique-ID");
const char *peer_uuid = switch_event_get_header(event, "intercepted_by");
+
+ if (kazoo_globals.enable_legacy) return;
+
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "INTERCEPTED : %s => %s\n", uuid, peer_uuid);
}
@@ -220,19 +238,20 @@ static void kz_tweaks_channel_transferor_event_handler(switch_event_t *event)
const char *func = switch_event_get_header(event, "Event-Calling-Function");
const char *line = switch_event_get_header(event, "Event-Calling-Line-Number");
+ if (kazoo_globals.enable_legacy) return;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "TRANSFEROR : %s , %s , %s, %s, %s , %s , %s \n", uuid, orig_call_id, dest_peer_uuid, dest_call_id, file, func, line);
if ((uuid_session = switch_core_session_force_locate(uuid)) != NULL) {
switch_channel_t *uuid_channel = switch_core_session_get_channel(uuid_session);
- const char* interaction_id = switch_channel_get_variable_dup(uuid_channel, "ecallmgr_Call-Interaction-ID", SWITCH_TRUE, -1);
+ const char* interaction_id = switch_channel_get_variable_dup(uuid_channel, INTERACTION_VARIABLE, SWITCH_TRUE, -1);
// set to uuid & peer_uuid
if(interaction_id != NULL) {
switch_core_session_t *session = NULL;
if(dest_call_id && (session = switch_core_session_force_locate(dest_call_id)) != NULL) {
switch_channel_t *channel = switch_core_session_get_channel(session);
- const char* prv_interaction_id = switch_channel_get_variable_dup(channel, "ecallmgr_Call-Interaction-ID", SWITCH_TRUE, -1);
+ const char* prv_interaction_id = switch_channel_get_variable_dup(channel, INTERACTION_VARIABLE, SWITCH_TRUE, -1);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "LOCATING UUID PRV : %s : %s\n", prv_interaction_id, interaction_id);
- switch_channel_set_variable(channel, "ecallmgr_Call-Interaction-ID", interaction_id);
+ switch_channel_set_variable(channel, INTERACTION_VARIABLE, interaction_id);
if (switch_event_create(&evt, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_set_data(channel, evt);
switch_event_fire(&evt);
@@ -244,9 +263,9 @@ static void kz_tweaks_channel_transferor_event_handler(switch_event_t *event)
}
if(dest_peer_uuid && (session = switch_core_session_force_locate(dest_peer_uuid)) != NULL) {
switch_channel_t *channel = switch_core_session_get_channel(session);
- const char* prv_interaction_id = switch_channel_get_variable_dup(channel, "ecallmgr_Call-Interaction-ID", SWITCH_TRUE, -1);
+ const char* prv_interaction_id = switch_channel_get_variable_dup(channel, INTERACTION_VARIABLE, SWITCH_TRUE, -1);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "LOCATING PEER UUID PRV : %s : %s\n", prv_interaction_id, interaction_id);
- switch_channel_set_variable(channel, "ecallmgr_Call-Interaction-ID", interaction_id);
+ switch_channel_set_variable(channel, INTERACTION_VARIABLE, interaction_id);
if (switch_event_create(&evt, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_set_data(channel, evt);
switch_event_fire(&evt);
@@ -270,6 +289,9 @@ static void kz_tweaks_channel_transferee_event_handler(switch_event_t *event)
{
const char *uuid = switch_event_get_header(event, "Unique-ID");
const char *replaced_by_uuid = switch_event_get_header(event, "att_xfer_replaced_call_id");
+
+ if (kazoo_globals.enable_legacy) return;
+
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "TRANSFEREE : %s replaced by %s\n", uuid, replaced_by_uuid);
}
@@ -351,10 +373,9 @@ 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 *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) {
+ if (caller && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
const char* val = NULL;
if((val=switch_caller_get_field_by_name(caller, "Endpoint-Caller-ID-Name"))) {
caller->caller_id_name = val;
@@ -367,6 +388,7 @@ static void kz_tweaks_handle_caller_id(switch_core_session_t *session)
}
}
+/*
static switch_status_t kz_tweaks_handle_auth_token(switch_core_session_t *session)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
@@ -388,39 +410,27 @@ static switch_status_t kz_tweaks_handle_auth_token(switch_core_session_t *sessio
return SWITCH_STATUS_SUCCESS;
}
+*/
static switch_status_t kz_tweaks_handle_nightmare_xfer(switch_core_session_t *session)
{
switch_core_session_t *replace_session = NULL;
switch_channel_t *channel = switch_core_session_get_channel(session);
- switch_event_t *event;
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");
const char *partner_uuid = switch_channel_get_variable(channel, "sip_h_X-FS-Refer-Partner-UUID");
const char *interaction_id = switch_channel_get_variable(channel, "sip_h_X-FS-Call-Interaction-ID");
if(core_uuid && partner_uuid && replaced_call_id && interaction_id) {
- switch_channel_set_variable(channel, "ecallmgr_Call-Interaction-ID", interaction_id);
- if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) {
- switch_channel_event_set_data(channel, event);
- switch_event_fire(&event);
- }
+ switch_channel_set_variable(channel, INTERACTION_VARIABLE, interaction_id);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "checking nightmare xfer tweak for %s\n", switch_channel_get_uuid(channel));
if ((replace_session = switch_core_session_locate(replaced_call_id))) {
switch_channel_t *replaced_call_channel = switch_core_session_get_channel(replace_session);
- switch_channel_set_variable(replaced_call_channel, "ecallmgr_Call-Interaction-ID", interaction_id);
- if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) {
- switch_channel_event_set_data(replaced_call_channel, event);
- switch_event_fire(&event);
- }
+ switch_channel_set_variable(replaced_call_channel, INTERACTION_VARIABLE, interaction_id);
switch_core_session_rwunlock(replace_session);
}
if ((replace_session = switch_core_session_locate(partner_uuid))) {
switch_channel_t *replaced_call_channel = switch_core_session_get_channel(replace_session);
- switch_channel_set_variable(replaced_call_channel, "ecallmgr_Call-Interaction-ID", interaction_id);
- if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) {
- switch_channel_event_set_data(replaced_call_channel, event);
- switch_event_fire(&event);
- }
+ switch_channel_set_variable(replaced_call_channel, INTERACTION_VARIABLE, interaction_id);
switch_core_session_rwunlock(replace_session);
}
}
@@ -474,6 +484,21 @@ static switch_status_t kz_tweaks_handle_switch_uri(switch_core_session_t *sessio
}
+static void kz_tweaks_handle_interaction_id(switch_core_session_t *session)
+{
+ const char *expr = "${expr(ceil((${Event-Date-Timestamp} / 1000000) + $${UNIX_EPOCH_IN_GREGORIAN}))}-${regex(${create_uuid()}|^([^-]*)|%1)}";
+ switch_channel_t *channel = switch_core_session_get_channel(session);
+ char * val = kz_expand(expr);
+
+ if (val) {
+ switch_channel_set_variable(channel, "Original-"INTERACTION_VARIABLE, val);
+ switch_channel_set_variable(channel, INTERACTION_VARIABLE, val);
+ }
+
+ switch_safe_free(val);
+
+}
+
static switch_status_t kz_tweaks_register_handle_xfer(switch_core_session_t *session)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
@@ -509,11 +534,13 @@ static switch_status_t kz_tweaks_set_export_vars(switch_core_session_t *session)
static switch_status_t kz_tweaks_on_init(switch_core_session_t *session)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
+ if (kazoo_globals.enable_legacy) return SWITCH_STATUS_SUCCESS;
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_interaction_id(session);
kz_tweaks_handle_switch_uri(session);
kz_tweaks_handle_caller_id(session);
- kz_tweaks_handle_auth_token(session);
+// kz_tweaks_handle_auth_token(session);
kz_tweaks_handle_nightmare_xfer(session);
kz_tweaks_handle_replaces_id(session);
kz_tweaks_handle_loopback(session);
@@ -534,12 +561,14 @@ static switch_state_handler_table_t kz_tweaks_state_handlers = {
/*.on_hibernate */ NULL,
/*.on_reset */ NULL,
/*.on_park */ NULL,
- /*.on_reporting */ NULL
+ /*.on_reporting */ NULL,
+ /*.on_destroy */ NULL
};
static void kz_tweaks_register_state_handlers()
{
+ kz_tweaks_state_handlers.flags = SSH_FLAG_PRE_EXEC;
switch_core_add_state_handler(&kz_tweaks_state_handlers);
}
@@ -576,8 +605,14 @@ static void kz_tweaks_unbind_events()
switch_event_unbind_callback(kz_tweaks_channel_transferee_event_handler);
}
+void kz_tweaks_add_core_variables()
+{
+ switch_core_set_variable("UNIX_EPOCH_IN_GREGORIAN", "62167219200");
+}
+
void kz_tweaks_start()
{
+ kz_tweaks_add_core_variables();
kz_tweaks_register_state_handlers();
kz_tweaks_bind_events();
}
diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_utils.c b/src/mod/event_handlers/mod_kazoo/kazoo_utils.c
index deb33e1a03..f4050bb34a 100644
--- a/src/mod/event_handlers/mod_kazoo/kazoo_utils.c
+++ b/src/mod/event_handlers/mod_kazoo/kazoo_utils.c
@@ -445,16 +445,28 @@ SWITCH_DECLARE(char *) kz_event_expand(const char *in)
return ret;
}
-char *kazoo_expand_header(switch_memory_pool_t *pool, switch_event_t *event, char *val)
+SWITCH_DECLARE(char *) kz_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;
+}
+
+SWITCH_DECLARE(char *) kz_expand_pool(switch_memory_pool_t *pool, const char *in)
{
char *expanded;
char *dup = NULL;
- expanded = kz_event_expand_headers(event, val);
+ if(!(expanded = kz_expand(in))) {
+ return NULL;
+ }
dup = switch_core_strdup(pool, expanded);
- if (expanded != val) {
- free(expanded);
+ if (expanded != in) {
+ switch_safe_free(expanded);
}
return dup;
@@ -609,6 +621,17 @@ char * kz_expand_vars_pool(char *xml_str, switch_memory_pool_t *pool) {
}
+switch_status_t kz_json_api(const char * command, cJSON *args, cJSON **res)
+{
+ switch_status_t status = SWITCH_STATUS_SUCCESS;
+ cJSON *req = cJSON_CreateObject();
+ cJSON_AddItemToObject(req, "command", cJSON_CreateString(command));
+ cJSON_AddItemToObject(req, "data", args ? args : cJSON_CreateObject());
+ status = switch_json_api_execute(req, NULL, res);
+ cJSON_Delete(req);
+ return status;
+}
+
/* For Emacs:
* Local Variables:
* mode:c
diff --git a/src/mod/event_handlers/mod_kazoo/kz_node.c b/src/mod/event_handlers/mod_kazoo/kz_node.c
new file mode 100644
index 0000000000..2da5c4a658
--- /dev/null
+++ b/src/mod/event_handlers/mod_kazoo/kz_node.c
@@ -0,0 +1,89 @@
+#include "mod_kazoo.h"
+
+static int kz_nodes_module_names_array_callback(void *pArg, const char *module_name)
+{
+ cJSON *json = (cJSON *) pArg;
+ if(!strstr(module_name, "CORE")) {
+ cJSON_AddItemToArray(json, cJSON_CreateString(module_name));
+ }
+ return 0;
+}
+
+void kz_nodes_collect_media_role(cJSON *container)
+{
+ cJSON *retval = NULL;
+ if(kz_json_api("sofia.status.info", NULL, &retval) == SWITCH_STATUS_SUCCESS) {
+ if(retval != NULL && (!(retval->type & cJSON_NULL))) {
+ cJSON_AddItemToObject(container, "Media", cJSON_Duplicate(retval, 1));
+ }
+ }
+ if(retval) {
+ cJSON_Delete(retval);
+ }
+}
+
+void kz_nodes_collect_modules(cJSON *container)
+{
+ cJSON *modules = cJSON_CreateObject();
+ cJSON *loaded = cJSON_CreateArray();
+ cJSON *available = cJSON_CreateArray();
+ switch_loadable_module_enumerate_available(SWITCH_GLOBAL_dirs.mod_dir, kz_nodes_module_names_array_callback, available);
+ switch_loadable_module_enumerate_loaded(kz_nodes_module_names_array_callback, loaded);
+ cJSON_AddItemToObject(modules, "available", available);
+ cJSON_AddItemToObject(modules, "loaded", loaded);
+ cJSON_AddItemToObject(container, "Modules", modules);
+}
+
+void kz_nodes_collect_runtime(cJSON *container)
+{
+ cJSON *retval = NULL;
+ if(kz_json_api("status", NULL, &retval) == SWITCH_STATUS_SUCCESS) {
+ if(retval != NULL && (!(retval->type & cJSON_NULL))) {
+ cJSON_AddItemToObject(container, "Runtime-Info", cJSON_Duplicate(retval, 1));
+ }
+ }
+ if(retval) {
+ cJSON_Delete(retval);
+ }
+}
+
+void kz_nodes_collect_apps(cJSON *container)
+{
+ cJSON *apps = cJSON_CreateObject();
+ cJSON *app = cJSON_CreateObject();
+ cJSON_AddItemToObject(app, "Uptime", cJSON_CreateNumber(switch_core_uptime()));
+ cJSON_AddItemToObject(apps, "freeswitch", app);
+ cJSON_AddItemToObject(container, "WhApps", apps);
+}
+
+void kz_nodes_collect_roles(cJSON *container)
+{
+ cJSON *roles = cJSON_CreateObject();
+ cJSON_AddItemToObject(container, "Roles", roles);
+ kz_nodes_collect_media_role(roles);
+}
+
+cJSON * kz_node_create()
+{
+ cJSON *node = cJSON_CreateObject();
+
+ kz_nodes_collect_apps(node);
+ kz_nodes_collect_runtime(node);
+ kz_nodes_collect_modules(node);
+ kz_nodes_collect_roles(node);
+
+ return node;
+}
+
+SWITCH_STANDARD_JSON_API(kz_node_info_json_function)
+{
+ cJSON * ret = kz_node_create();
+ *json_reply = ret;
+ return SWITCH_STATUS_SUCCESS;
+}
+
+void add_kz_node(switch_loadable_module_interface_t **module_interface)
+{
+ switch_json_api_interface_t *json_api_interface = NULL;
+ SWITCH_ADD_JSON_API(json_api_interface, "node.info", "JSON node API", kz_node_info_json_function, "");
+}
diff --git a/src/mod/event_handlers/mod_kazoo/mod_kazoo.c b/src/mod/event_handlers/mod_kazoo/mod_kazoo.c
index 13ab8de247..ca0538039b 100644
--- a/src/mod/event_handlers/mod_kazoo/mod_kazoo.c
+++ b/src/mod/event_handlers/mod_kazoo/mod_kazoo.c
@@ -77,6 +77,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_kazoo_load) {
/* add our endpoints */
add_kz_endpoints(module_interface);
+ /* add our kz_node api */
+ add_kz_node(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 2b02ee973a..bbf511a280 100644
--- a/src/mod/event_handlers/mod_kazoo/mod_kazoo.h
+++ b/src/mod/event_handlers/mod_kazoo/mod_kazoo.h
@@ -39,7 +39,6 @@ void remove_cli_api();
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* 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);
@@ -47,6 +46,9 @@ 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);
+SWITCH_DECLARE(char *) kz_expand(const char *in);
+SWITCH_DECLARE(char *) kz_expand_pool(switch_memory_pool_t *pool, const char *in);
+switch_status_t kz_json_api(const char * command, cJSON *args, cJSON **res);
/* kazoo_endpoints.c */
void add_kz_endpoints(switch_loadable_module_interface_t **module_interface);
@@ -56,6 +58,9 @@ void add_kz_endpoints(switch_loadable_module_interface_t **module_interface);
void kz_tweaks_start();
void kz_tweaks_stop();
+/* kazoo_node.c */
+void add_kz_node(switch_loadable_module_interface_t **module_interface);
+
SWITCH_MODULE_LOAD_FUNCTION(mod_kazoo_load);
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_kazoo_shutdown);