freeswitch/src/mod/event_handlers/mod_kazoo/kazoo_ei_config.c

660 lines
23 KiB
C

/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* 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 <anthm@freeswitch.org>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Based on mod_skel by
* Anthony Minessale II <anthm@freeswitch.org>
*
* Contributor(s):
*
* Daniel Bryars <danb@aeriandi.com>
* Tim Brown <tim.brown@aeriandi.com>
* Anthony Minessale II <anthm@freeswitch.org>
* William King <william.king@quentustech.com>
* Mike Jerris <mike@jerris.com>
*
* kazoo.c -- Sends FreeSWITCH events to an AMQP broker
*
*/
#include "mod_kazoo.h"
#define KZ_DEFAULT_STREAM_PRE_ALLOCATE 8192
#define KAZOO_DECLARE_GLOBAL_STRING_FUNC(fname, vname) static void __attribute__((__unused__)) fname(const char *string) { if (!string) return;\
if (vname) {free(vname); vname = NULL;}vname = strdup(string);} static void fname(const char *string)
KAZOO_DECLARE_GLOBAL_STRING_FUNC(set_pref_ip, kazoo_globals.ip);
KAZOO_DECLARE_GLOBAL_STRING_FUNC(set_pref_ei_cookie, kazoo_globals.ei_cookie);
KAZOO_DECLARE_GLOBAL_STRING_FUNC(set_pref_ei_nodename, kazoo_globals.ei_nodename);
//KAZOO_DECLARE_GLOBAL_STRING_FUNC(set_pref_kazoo_var_prefix, kazoo_globals.kazoo_var_prefix);
static int read_cookie_from_file(char *filename) {
int fd;
char cookie[MAXATOMLEN + 1];
char *end;
struct stat buf;
ssize_t res;
if (!stat(filename, &buf)) {
if ((buf.st_mode & S_IRWXG) || (buf.st_mode & S_IRWXO)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s must only be accessible by owner only.\n", filename);
return 2;
}
if (buf.st_size > MAXATOMLEN) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s contains a cookie larger than the maximum atom size of %d.\n", filename, MAXATOMLEN);
return 2;
}
fd = open(filename, O_RDONLY);
if (fd < 1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to open cookie file %s : %d.\n", filename, errno);
return 2;
}
if ((res = read(fd, cookie, MAXATOMLEN)) < 1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to read cookie file %s : %d.\n", filename, errno);
}
cookie[MAXATOMLEN] = '\0';
/* replace any end of line characters with a null */
if ((end = strchr(cookie, '\n'))) {
*end = '\0';
}
if ((end = strchr(cookie, '\r'))) {
*end = '\0';
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set cookie from file %s: %s\n", filename, cookie);
set_pref_ei_cookie(cookie);
return 0;
} else {
/* don't error here, because we might be blindly trying to read $HOME/.erlang.cookie, and that can fail silently */
return 1;
}
}
void kz_set_hostname()
{
if (kazoo_globals.hostname == NULL) {
char hostname[NODENAME_MAX];
memcpy(hostname, switch_core_get_hostname(), NODENAME_MAX);
kazoo_globals.hostname_ent = gethostbyname(hostname);
if(kazoo_globals.hostname_ent != NULL) {
kazoo_globals.hostname = switch_core_strdup(kazoo_globals.pool, kazoo_globals.hostname_ent->h_name);
} else {
kazoo_globals.hostname = switch_core_strdup(kazoo_globals.pool, hostname);
}
}
}
switch_status_t kazoo_ei_config(switch_xml_t cfg) {
switch_xml_t child, param;
char* kazoo_var_prefix = NULL;
char* profile_vars_prefix = NULL;
char* sep_array[KZ_MAX_SEPARATE_STRINGS];
int array_len, i;
kazoo_globals.send_all_headers = 0;
kazoo_globals.send_all_private_headers = 1;
kazoo_globals.connection_timeout = 500;
kazoo_globals.receive_timeout = 200;
kazoo_globals.receive_msg_preallocate = 2000;
kazoo_globals.event_stream_preallocate = KZ_DEFAULT_STREAM_PRE_ALLOCATE;
kazoo_globals.send_msg_batch = 10;
kazoo_globals.event_stream_framing = 2;
kazoo_globals.port = 0;
kazoo_globals.io_fault_tolerance = 10;
kazoo_globals.json_encoding = ERLANG_TUPLE;
kazoo_globals.legacy_events = SWITCH_FALSE;
kz_set_tweak(KZ_TWEAK_INTERACTION_ID);
kz_set_tweak(KZ_TWEAK_EXPORT_VARS);
kz_set_tweak(KZ_TWEAK_SWITCH_URI);
kz_set_tweak(KZ_TWEAK_REPLACES_CALL_ID);
kz_set_tweak(KZ_TWEAK_LOOPBACK_VARS);
kz_set_tweak(KZ_TWEAK_CALLER_ID);
kz_set_tweak(KZ_TWEAK_TRANSFERS);
kz_set_tweak(KZ_TWEAK_BRIDGE);
kz_set_tweak(KZ_TWEAK_BRIDGE_REPLACES_ALEG);
kz_set_tweak(KZ_TWEAK_BRIDGE_REPLACES_CALL_ID);
kz_set_tweak(KZ_TWEAK_BRIDGE_VARIABLES);
kz_set_tweak(KZ_TWEAK_RESTORE_CALLER_ID_ON_BLIND_XFER);
if ((child = switch_xml_child(cfg, "settings"))) {
for (param = switch_xml_child(child, "param"); param; param = param->next) {
char *var = (char *) switch_xml_attr_soft(param, "name");
char *val = (char *) switch_xml_attr_soft(param, "value");
if (!strcmp(var, "listen-ip")) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set bind ip address: %s\n", val);
set_pref_ip(val);
} else if (!strcmp(var, "listen-port")) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set bind port: %s\n", val);
kazoo_globals.port = atoi(val);
} else if (!strcmp(var, "cookie")) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set cookie: %s\n", val);
set_pref_ei_cookie(val);
} else if (!strcmp(var, "cookie-file")) {
if (read_cookie_from_file(val) == 1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to read cookie from %s\n", val);
}
} else if (!strcmp(var, "nodename")) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set node name: %s\n", val);
set_pref_ei_nodename(val);
} else if (!strcmp(var, "shortname")) {
kazoo_globals.ei_shortname = switch_true(val);
} else if (!strcmp(var, "kazoo-var-prefix")) {
kazoo_var_prefix = switch_core_strdup(kazoo_globals.pool, val);
} else if (!strcmp(var, "set-profile-vars-prefix")) {
profile_vars_prefix = switch_core_strdup(kazoo_globals.pool, val);
} else if (!strcmp(var, "compat-rel")) {
if (atoi(val) >= 7)
kazoo_globals.ei_compat_rel = atoi(val);
else
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid compatibility release '%s' specified\n", val);
} else if (!strcmp(var, "nat-map")) {
kazoo_globals.nat_map = switch_true(val);
} else if (!strcmp(var, "send-all-headers")) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set send-all-headers: %s\n", val);
kazoo_globals.send_all_headers = switch_true(val);
} else if (!strcmp(var, "send-all-private-headers")) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set send-all-private-headers: %s\n", val);
kazoo_globals.send_all_private_headers = switch_true(val);
} else if (!strcmp(var, "connection-timeout")) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set connection-timeout: %s\n", val);
kazoo_globals.connection_timeout = atoi(val);
} else if (!strcmp(var, "receive-timeout")) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set receive-timeout: %s\n", val);
kazoo_globals.receive_timeout = atoi(val);
} else if (!strcmp(var, "receive-msg-preallocate")) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set receive-msg-preallocate: %s\n", val);
kazoo_globals.receive_msg_preallocate = atoi(val);
} else if (!strcmp(var, "event-stream-preallocate")) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set event-stream-preallocate: %s\n", val);
kazoo_globals.event_stream_preallocate = atoi(val);
} else if (!strcmp(var, "send-msg-batch-size")) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set send-msg-batch-size: %s\n", val);
kazoo_globals.send_msg_batch = atoi(val);
} else if (!strcmp(var, "event-stream-framing")) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set event-stream-framing: %s\n", val);
kazoo_globals.event_stream_framing = atoi(val);
} else if (!strcmp(var, "io-fault-tolerance")) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set io-fault-tolerance: %s\n", val);
kazoo_globals.io_fault_tolerance = atoi(val);
} else if (!strcmp(var, "num-worker-threads")) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set num-worker-threads: %s\n", val);
kazoo_globals.num_worker_threads = atoi(val);
} else if (!strcmp(var, "json-term-encoding")) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set json-term-encoding: %s\n", val);
if(!strcmp(val, "map")) {
kazoo_globals.json_encoding = ERLANG_MAP;
}
} else if (!strcmp(var, "legacy-events")) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set legacy-events: %s\n", val);
kazoo_globals.legacy_events = switch_true(val);
} else if (!strcmp(var, "expand-headers-on-fetch")) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set expand-headers-on-fetch: %s\n", val);
kazoo_globals.expand_headers_on_fetch = switch_true(val);
}
}
}
if ((child = switch_xml_child(cfg, "tweaks"))) {
char *default_tweaks = (char *) switch_xml_attr_soft(param, "default");
if (default_tweaks) {
int i, v = switch_true(default_tweaks) ? 1 : 0;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set tweak default : %s\n", default_tweaks);
for (i = 0; i < KZ_TWEAK_MAX; i++) kazoo_globals.tweaks[i] = v;
}
for (param = switch_xml_child(child, "tweak"); param; param = param->next) {
kz_tweak_t tweak = KZ_TWEAK_MAX;
char *var = (char *) switch_xml_attr_soft(param, "name");
char *val = (char *) switch_xml_attr_soft(param, "value");
if(var && val && kz_name_tweak(var, &tweak) == SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set tweak %s : %s\n", var, val);
if(switch_true(val)) {
kz_set_tweak(tweak);
} else {
kz_clear_tweak(tweak);
}
}
}
}
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_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set core variable %s : %s\n", var, val);
switch_core_set_variable(var, val);
}
}
}
if ((child = switch_xml_child(cfg, "event-filter"))) {
switch_hash_t *filter;
switch_core_hash_init(&filter);
for (param = switch_xml_child(child, "header"); param; param = param->next) {
char *var = (char *) switch_xml_attr_soft(param, "name");
switch_core_hash_insert(filter, var, "1");
}
kazoo_globals.event_filter = filter;
}
if (kazoo_globals.receive_msg_preallocate < 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid receive message preallocate value, disabled\n");
kazoo_globals.receive_msg_preallocate = 0;
}
if (kazoo_globals.event_stream_preallocate < 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid event stream preallocate value, disabled\n");
kazoo_globals.event_stream_preallocate = 0;
}
if (kazoo_globals.send_msg_batch < 1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid send message batch size, reverting to default\n");
kazoo_globals.send_msg_batch = 10;
}
if (kazoo_globals.io_fault_tolerance < 1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid I/O fault tolerance, reverting to default\n");
kazoo_globals.io_fault_tolerance = 10;
}
if (!kazoo_globals.event_filter) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Event filter not found in configuration, using default\n");
kazoo_globals.event_filter = create_default_filter();
}
if (kazoo_globals.event_stream_framing < 1 || kazoo_globals.event_stream_framing > 4) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid event stream framing value, using default\n");
kazoo_globals.event_stream_framing = 2;
}
if (zstr(kazoo_var_prefix)) {
kazoo_var_prefix = switch_core_strdup(kazoo_globals.pool, "ecallmgr_;cav_");
}
if (zstr(profile_vars_prefix)) {
profile_vars_prefix = switch_core_strdup(kazoo_globals.pool, "effective_;origination_");
}
kazoo_globals.kazoo_var_prefixes = switch_core_alloc(kazoo_globals.pool, sizeof(char*) * KZ_MAX_SEPARATE_STRINGS);
array_len = switch_separate_string(kazoo_var_prefix, ';', sep_array, KZ_MAX_SEPARATE_STRINGS - 1);
for(i=0; i < array_len; i++) {
char var[100];
sprintf(var, "variable_%s", sep_array[i]);
kazoo_globals.kazoo_var_prefixes[i] = switch_core_strdup(kazoo_globals.pool, var);
}
kazoo_globals.profile_vars_prefixes = switch_core_alloc(kazoo_globals.pool, sizeof(char*) * KZ_MAX_SEPARATE_STRINGS);
array_len = switch_separate_string(profile_vars_prefix, ';', sep_array, KZ_MAX_SEPARATE_STRINGS - 1);
for(i=0; i < array_len; i++) {
kazoo_globals.profile_vars_prefixes[i] = switch_core_strdup(kazoo_globals.pool, sep_array[i]);
}
if (!kazoo_globals.num_worker_threads) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Number of worker threads not found in configuration, using default\n");
kazoo_globals.num_worker_threads = 10;
}
if (zstr(kazoo_globals.ip)) {
set_pref_ip("0.0.0.0");
}
if (zstr(kazoo_globals.ei_cookie)) {
int res;
char *home_dir = getenv("HOME");
char path_buf[1024];
if (!zstr(home_dir)) {
/* $HOME/.erlang.cookie */
switch_snprintf(path_buf, sizeof (path_buf), "%s%s%s", home_dir, SWITCH_PATH_SEPARATOR, ".erlang.cookie");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Checking for cookie at path: %s\n", path_buf);
res = read_cookie_from_file(path_buf);
if (res) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "No cookie or valid cookie file specified, using default cookie\n");
set_pref_ei_cookie("ClueCon");
}
}
}
if (!kazoo_globals.ei_nodename) {
set_pref_ei_nodename("freeswitch");
}
if (!kazoo_globals.nat_map) {
kazoo_globals.nat_map = 0;
}
return SWITCH_STATUS_SUCCESS;
}
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;
xml = strndup(kz_default_config, kz_default_config_size);
def = switch_xml_parse_str_dup(xml);
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) {
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) {
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) {
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) {
events = (kazoo_event_profile_ptr) switch_core_hash_find(event_handlers->hash, "default");
}
if(events == NULL) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to get default handler for events\n");
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;
}
if(kazoo_globals.events != events) {
bind_event_profiles(events->events);
kazoo_globals.events = events;
}
if(kazoo_globals.event_handlers != event_handlers) {
kazoo_config_ptr tmp = kazoo_globals.event_handlers;
kazoo_globals.event_handlers = event_handlers;
destroy_config(&tmp);
}
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);
}
if(kazoo_globals.definitions != definitions) {
kazoo_config_ptr tmp = kazoo_globals.definitions;
kazoo_globals.definitions = definitions;
destroy_config(&tmp);
}
switch_xml_free(def);
switch_safe_free(xml);
return SWITCH_STATUS_SUCCESS;
}
switch_status_t kazoo_load_config()
{
char *cf = "kazoo.conf";
switch_xml_t cfg, xml;
if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open configuration file %s\n", cf);
return SWITCH_STATUS_FALSE;
} else {
kazoo_ei_config(cfg);
kazoo_config_handlers(cfg);
switch_xml_free(xml);
}
return SWITCH_STATUS_SUCCESS;
}
void kazoo_destroy_config()
{
destroy_config(&kazoo_globals.event_handlers);
destroy_config(&kazoo_globals.fetch_handlers);
destroy_config(&kazoo_globals.definitions);
}
switch_status_t kazoo_config_events(kazoo_config_ptr definitions, switch_memory_pool_t *pool, switch_xml_t cfg, kazoo_event_profile_ptr profile)
{
switch_xml_t events, event;
kazoo_event_ptr prv = NULL, cur = NULL;
if ((events = switch_xml_child(cfg, "events")) != NULL) {
for (event = switch_xml_child(events, "event"); event; event = event->next) {
const char *var = switch_xml_attr(event, "name");
cur = (kazoo_event_ptr) switch_core_alloc(pool, sizeof(kazoo_event_t));
memset(cur, 0, sizeof(kazoo_event_t));
if(prv == NULL) {
profile->events = prv = cur;
} else {
prv->next = cur;
prv = cur;
}
cur->profile = profile;
cur->name = switch_core_strdup(pool, var);
kazoo_config_filters(pool, event, &cur->filter);
kazoo_config_fields(definitions, pool, event, &cur->fields);
}
}
return SWITCH_STATUS_SUCCESS;
}
switch_status_t kazoo_config_fetch_handler(kazoo_config_ptr definitions, kazoo_config_ptr root, switch_xml_t cfg, kazoo_fetch_profile_ptr *ptr)
{
kazoo_fetch_profile_ptr profile = NULL;
switch_xml_t params, param;
switch_xml_section_t fetch_section;
int fetch_timeout = 2000000;
switch_memory_pool_t *pool = NULL;
char *name = (char *) switch_xml_attr_soft(cfg, "name");
if (zstr(name)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "missing name in profile\n");
return SWITCH_STATUS_GENERR;
}
if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error allocation pool for new profile : %s\n", name);
return SWITCH_STATUS_GENERR;
}
profile = switch_core_alloc(pool, sizeof(kazoo_fetch_profile_t));
profile->pool = pool;
profile->root = root;
profile->name = switch_core_strdup(profile->pool, name);
fetch_section = switch_xml_parse_section_string(name);
if ((params = switch_xml_child(cfg, "params")) != NULL) {
for (param = switch_xml_child(params, "param"); param; param = param->next) {
char *var = (char *) switch_xml_attr_soft(param, "name");
char *val = (char *) switch_xml_attr_soft(param, "value");
if (!var) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Profile[%s] param missing 'name' attribute\n", name);
continue;
}
if (!val) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Profile[%s] param[%s] missing 'value' attribute\n", name, var);
continue;
}
if (!strncmp(var, "fetch-timeout", 13)) {
fetch_timeout = atoi(val);
} else if (!strncmp(var, "fetch-section", 13)) {
fetch_section = switch_xml_parse_section_string(val);
}
}
}
if (fetch_section == SWITCH_XML_SECTION_RESULT) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Fetch Profile[%s] invalid fetch-section: %s\n", name, switch_xml_toxml(cfg, SWITCH_FALSE));
goto err;
}
profile->fetch_timeout = fetch_timeout;
profile->section = fetch_section;
kazoo_config_fields(definitions, pool, cfg, &profile->fields);
kazoo_config_loglevels(pool, cfg, &profile->logging);
if(root) {
if ( switch_core_hash_insert(root->hash, name, (void *) profile) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to insert new fetch profile [%s] into kazoo profile hash\n", name);
goto err;
}
}
if(ptr)
*ptr = profile;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "fetch handler profile %s successfully configured\n", name);
return SWITCH_STATUS_SUCCESS;
err:
/* Cleanup */
if(pool) {
switch_core_destroy_memory_pool(&pool);
}
return SWITCH_STATUS_GENERR;
}
switch_status_t kazoo_config_event_handler(kazoo_config_ptr definitions, kazoo_config_ptr root, switch_xml_t cfg, kazoo_event_profile_ptr *ptr)
{
kazoo_event_profile_ptr profile = NULL;
switch_memory_pool_t *pool = NULL;
char *name = (char *) switch_xml_attr_soft(cfg, "name");
if (zstr(name)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "missing name in profile\n");
return SWITCH_STATUS_GENERR;
}
if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error allocation pool for new profile : %s\n", name);
return SWITCH_STATUS_GENERR;
}
profile = switch_core_alloc(pool, sizeof(kazoo_event_profile_t));
profile->pool = pool;
profile->root = root;
profile->name = switch_core_strdup(profile->pool, name);
kazoo_config_filters(pool, cfg, &profile->filter);
kazoo_config_fields(definitions, pool, cfg, &profile->fields);
kazoo_config_events(definitions, pool, cfg, profile);
kazoo_config_loglevels(pool, cfg, &profile->logging);
if(root) {
if ( switch_core_hash_insert(root->hash, name, (void *) profile) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to insert new profile [%s] into kazoo profile hash\n", name);
goto err;
}
}
if(ptr)
*ptr = profile;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "event handler profile %s successfully configured\n", name);
return SWITCH_STATUS_SUCCESS;
err:
/* Cleanup */
if(pool) {
switch_core_destroy_memory_pool(&pool);
}
return SWITCH_STATUS_GENERR;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4
*/