From 9eba3a9b9926a71ea88a54c66722d34be1fd972e Mon Sep 17 00:00:00 2001 From: lazedo Date: Sun, 31 Mar 2019 22:14:23 +0100 Subject: [PATCH 1/2] FS-11741 [mod_kazoo] add kz_node api --- src/mod/event_handlers/mod_kazoo/Makefile.am | 1 + .../event_handlers/mod_kazoo/kazoo_utils.c | 31 ++++++- src/mod/event_handlers/mod_kazoo/kz_node.c | 89 +++++++++++++++++++ src/mod/event_handlers/mod_kazoo/mod_kazoo.c | 3 + src/mod/event_handlers/mod_kazoo/mod_kazoo.h | 7 +- 5 files changed, 126 insertions(+), 5 deletions(-) create mode 100644 src/mod/event_handlers/mod_kazoo/kz_node.c 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_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); From ece804c9b83ced8bdd3a3f0cc5836326b38257f5 Mon Sep 17 00:00:00 2001 From: lazedo Date: Sun, 31 Mar 2019 22:17:42 +0100 Subject: [PATCH 2/2] FS-11741 [mod_kazoo] add compare to field option & json_history --- .../event_handlers/mod_kazoo/kazoo.conf.xml | 48 +++++---- .../event_handlers/mod_kazoo/kazoo_commands.c | 98 +++++++++++++++++++ .../event_handlers/mod_kazoo/kazoo_config.c | 18 ++-- src/mod/event_handlers/mod_kazoo/kazoo_ei.h | 4 - .../mod_kazoo/kazoo_ei_config.c | 74 +++++++++++--- .../event_handlers/mod_kazoo/kazoo_fields.h | 6 +- .../event_handlers/mod_kazoo/kazoo_message.c | 27 ++++- src/mod/event_handlers/mod_kazoo/kazoo_node.c | 4 +- .../event_handlers/mod_kazoo/kazoo_tweaks.c | 97 ++++++++++++------ 9 files changed, 291 insertions(+), 85 deletions(-) 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(); }