]> git.ipfire.org Git - thirdparty/freeswitch.git/blob - src/mod/event_handlers/mod_kazoo/kazoo_ei_config.c
3c626c15da0a22f200307ebb2ad1a66a7f45041d
[thirdparty/freeswitch.git] / src / mod / event_handlers / mod_kazoo / kazoo_ei_config.c
1 /*
2 * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
3 * Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
4 *
5 * Version: MPL 1.1
6 *
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
11 *
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
15 * License.
16 *
17 * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
18 *
19 * The Initial Developer of the Original Code is
20 * Anthony Minessale II <anthm@freeswitch.org>
21 * Portions created by the Initial Developer are Copyright (C)
22 * the Initial Developer. All Rights Reserved.
23 *
24 * Based on mod_skel by
25 * Anthony Minessale II <anthm@freeswitch.org>
26 *
27 * Contributor(s):
28 *
29 * Daniel Bryars <danb@aeriandi.com>
30 * Tim Brown <tim.brown@aeriandi.com>
31 * Anthony Minessale II <anthm@freeswitch.org>
32 * William King <william.king@quentustech.com>
33 * Mike Jerris <mike@jerris.com>
34 *
35 * kazoo.c -- Sends FreeSWITCH events to an AMQP broker
36 *
37 */
38
39 #include "mod_kazoo.h"
40
41 #define KZ_DEFAULT_STREAM_PRE_ALLOCATE 8192
42
43 #define KAZOO_DECLARE_GLOBAL_STRING_FUNC(fname, vname) static void __attribute__((__unused__)) fname(const char *string) { if (!string) return;\
44 if (vname) {free(vname); vname = NULL;}vname = strdup(string);} static void fname(const char *string)
45
46 KAZOO_DECLARE_GLOBAL_STRING_FUNC(set_pref_ip, kazoo_globals.ip);
47 KAZOO_DECLARE_GLOBAL_STRING_FUNC(set_pref_ei_cookie, kazoo_globals.ei_cookie);
48 KAZOO_DECLARE_GLOBAL_STRING_FUNC(set_pref_ei_nodename, kazoo_globals.ei_nodename);
49 //KAZOO_DECLARE_GLOBAL_STRING_FUNC(set_pref_kazoo_var_prefix, kazoo_globals.kazoo_var_prefix);
50
51 static int read_cookie_from_file(char *filename) {
52 int fd;
53 char cookie[MAXATOMLEN + 1];
54 char *end;
55 struct stat buf;
56
57 if (!stat(filename, &buf)) {
58 if ((buf.st_mode & S_IRWXG) || (buf.st_mode & S_IRWXO)) {
59 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s must only be accessible by owner only.\n", filename);
60 return 2;
61 }
62 if (buf.st_size > MAXATOMLEN) {
63 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s contains a cookie larger than the maximum atom size of %d.\n", filename, MAXATOMLEN);
64 return 2;
65 }
66 fd = open(filename, O_RDONLY);
67 if (fd < 1) {
68 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to open cookie file %s : %d.\n", filename, errno);
69 return 2;
70 }
71
72 if (read(fd, cookie, MAXATOMLEN) < 1) {
73 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to read cookie file %s : %d.\n", filename, errno);
74 }
75
76 cookie[MAXATOMLEN] = '\0';
77
78 /* replace any end of line characters with a null */
79 if ((end = strchr(cookie, '\n'))) {
80 *end = '\0';
81 }
82
83 if ((end = strchr(cookie, '\r'))) {
84 *end = '\0';
85 }
86
87 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set cookie from file %s: %s\n", filename, cookie);
88
89 set_pref_ei_cookie(cookie);
90 return 0;
91 } else {
92 /* don't error here, because we might be blindly trying to read $HOME/.erlang.cookie, and that can fail silently */
93 return 1;
94 }
95 }
96
97 void kz_set_hostname()
98 {
99 if (kazoo_globals.hostname == NULL) {
100 char hostname[NODENAME_MAX];
101 memcpy(hostname, switch_core_get_hostname(), NODENAME_MAX);
102 kazoo_globals.hostname_ent = gethostbyname(hostname);
103 if(kazoo_globals.hostname_ent != NULL) {
104 kazoo_globals.hostname = switch_core_strdup(kazoo_globals.pool, kazoo_globals.hostname_ent->h_name);
105 } else {
106 kazoo_globals.hostname = switch_core_strdup(kazoo_globals.pool, hostname);
107 }
108 }
109 }
110
111 switch_status_t kazoo_ei_config(switch_xml_t cfg) {
112 switch_xml_t child, param;
113 char* kazoo_var_prefix = NULL;
114 char* profile_vars_prefix = NULL;
115 char* sep_array[KZ_MAX_SEPARATE_STRINGS];
116 int array_len, i;
117 kazoo_globals.send_all_headers = 0;
118 kazoo_globals.send_all_private_headers = 1;
119 kazoo_globals.connection_timeout = 500;
120 kazoo_globals.ei_receive_timeout = 200;
121 kazoo_globals.receive_msg_preallocate = 2000;
122 kazoo_globals.event_stream_preallocate = KZ_DEFAULT_STREAM_PRE_ALLOCATE;
123 kazoo_globals.send_msg_batch = 10;
124 kazoo_globals.event_stream_framing = 2;
125 kazoo_globals.event_stream_keepalive = 1;
126 kazoo_globals.event_stream_queue_timeout = 200000;
127 kazoo_globals.node_receiver_queue_timeout = 100000;
128 kazoo_globals.node_sender_queue_timeout = 0;
129 kazoo_globals.port = 0;
130 kazoo_globals.io_fault_tolerance = 3;
131 kazoo_globals.io_fault_tolerance_sleep = 100000; // 100 ms
132 kazoo_globals.json_encoding = ERLANG_TUPLE;
133 kazoo_globals.delay_before_initial_fetch = 10000000;
134
135 kazoo_globals.legacy_events = SWITCH_FALSE;
136 kazoo_globals.expand_headers_on_fetch = SWITCH_TRUE;
137
138 kz_set_tweak(KZ_TWEAK_INTERACTION_ID);
139 kz_set_tweak(KZ_TWEAK_EXPORT_VARS);
140 kz_set_tweak(KZ_TWEAK_SWITCH_URI);
141 kz_set_tweak(KZ_TWEAK_REPLACES_CALL_ID);
142 kz_set_tweak(KZ_TWEAK_LOOPBACK_VARS);
143 kz_set_tweak(KZ_TWEAK_CALLER_ID);
144 kz_set_tweak(KZ_TWEAK_TRANSFERS);
145 kz_set_tweak(KZ_TWEAK_BRIDGE);
146 kz_set_tweak(KZ_TWEAK_BRIDGE_REPLACES_ALEG);
147 kz_set_tweak(KZ_TWEAK_BRIDGE_REPLACES_CALL_ID);
148 kz_set_tweak(KZ_TWEAK_BRIDGE_VARIABLES);
149 kz_set_tweak(KZ_TWEAK_RESTORE_CALLER_ID_ON_BLIND_XFER);
150
151
152
153 if ((child = switch_xml_child(cfg, "settings"))) {
154 for (param = switch_xml_child(child, "param"); param; param = param->next) {
155 char *var = (char *) switch_xml_attr_soft(param, "name");
156 char *val = (char *) switch_xml_attr_soft(param, "value");
157
158 if (!strcmp(var, "listen-ip")) {
159 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set bind ip address: %s\n", val);
160 set_pref_ip(val);
161 } else if (!strcmp(var, "listen-port")) {
162 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set bind port: %s\n", val);
163 kazoo_globals.port = atoi(val);
164 } else if (!strcmp(var, "cookie")) {
165 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set cookie: %s\n", val);
166 set_pref_ei_cookie(val);
167 } else if (!strcmp(var, "cookie-file")) {
168 if (read_cookie_from_file(val) == 1) {
169 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to read cookie from %s\n", val);
170 }
171 } else if (!strcmp(var, "nodename")) {
172 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set node name: %s\n", val);
173 set_pref_ei_nodename(val);
174 } else if (!strcmp(var, "shortname")) {
175 kazoo_globals.ei_shortname = switch_true(val);
176 } else if (!strcmp(var, "kazoo-var-prefix")) {
177 kazoo_var_prefix = switch_core_strdup(kazoo_globals.pool, val);
178 } else if (!strcmp(var, "set-profile-vars-prefix")) {
179 profile_vars_prefix = switch_core_strdup(kazoo_globals.pool, val);
180 } else if (!strcmp(var, "compat-rel")) {
181 if (atoi(val) >= 7)
182 kazoo_globals.ei_compat_rel = atoi(val);
183 else
184 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid compatibility release '%s' specified\n", val);
185 } else if (!strcmp(var, "nat-map")) {
186 kazoo_globals.nat_map = switch_true(val);
187 } else if (!strcmp(var, "send-all-headers")) {
188 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set send-all-headers: %s\n", val);
189 kazoo_globals.send_all_headers = switch_true(val);
190 } else if (!strcmp(var, "send-all-private-headers")) {
191 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set send-all-private-headers: %s\n", val);
192 kazoo_globals.send_all_private_headers = switch_true(val);
193 } else if (!strcmp(var, "connection-timeout")) {
194 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set connection-timeout: %s\n", val);
195 kazoo_globals.connection_timeout = atoi(val);
196 } else if (!strcmp(var, "receive-timeout")) {
197 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set receive-timeout: %s\n", val);
198 kazoo_globals.ei_receive_timeout = atoi(val);
199 } else if (!strcmp(var, "receive-msg-preallocate")) {
200 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set receive-msg-preallocate: %s\n", val);
201 kazoo_globals.receive_msg_preallocate = atoi(val);
202 } else if (!strcmp(var, "event-stream-preallocate")) {
203 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set event-stream-preallocate: %s\n", val);
204 kazoo_globals.event_stream_preallocate = atoi(val);
205 } else if (!strcmp(var, "send-msg-batch-size")) {
206 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set send-msg-batch-size: %s\n", val);
207 kazoo_globals.send_msg_batch = atoi(val);
208 } else if (!strcmp(var, "event-stream-framing")) {
209 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set event-stream-framing: %s\n", val);
210 kazoo_globals.event_stream_framing = atoi(val);
211
212 } else if (!strcmp(var, "event-stream-keep-alive")) {
213 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set event-stream-keep-alive: %s\n", val);
214 kazoo_globals.event_stream_keepalive = switch_true(val);
215
216 } else if (!strcmp(var, "io-fault-tolerance")) {
217 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set io-fault-tolerance: %s\n", val);
218 kazoo_globals.io_fault_tolerance = atoi(val);
219 } else if (!strcmp(var, "io-fault-tolerance-sleep-micro")) {
220 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set %s : %s\n", var, val);
221 kazoo_globals.io_fault_tolerance_sleep = atoi(val);
222 } else if (!strcmp(var, "io-fault-tolerance-sleep-ms")) {
223 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set %s : %s\n", var, val);
224 kazoo_globals.io_fault_tolerance_sleep = atoi(val) * 1000;
225 } else if (!strcmp(var, "io-fault-tolerance-sleep-sec")) {
226 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set %s : %s\n", var, val);
227 kazoo_globals.io_fault_tolerance_sleep = atoi(val) * 1000000;
228
229
230 } else if (!strcmp(var, "node-worker-threads")) {
231 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set node-worker-threads: %s\n", val);
232 kazoo_globals.node_worker_threads = atoi(val);
233 } else if (!strcmp(var, "json-term-encoding")) {
234 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set json-term-encoding: %s\n", val);
235 if(!strcmp(val, "map")) {
236 kazoo_globals.json_encoding = ERLANG_MAP;
237 }
238 } else if (!strcmp(var, "legacy-events")) {
239 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set legacy-events: %s\n", val);
240 kazoo_globals.legacy_events = switch_true(val);
241 } else if (!strcmp(var, "expand-headers-on-fetch")) {
242 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set expand-headers-on-fetch: %s\n", val);
243 kazoo_globals.expand_headers_on_fetch = switch_true(val);
244 } else if (!strcmp(var, "node-receiver-queue-timeout")) {
245 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set %s : %s\n", var, val);
246 kazoo_globals.node_receiver_queue_timeout = atoi(val);
247 } else if (!strcmp(var, "node-sender-queue-timeout")) {
248 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set %s : %s\n", var, val);
249 kazoo_globals.node_sender_queue_timeout = atoi(val);
250 } else if (!strcmp(var, "event-stream-queue-timeout")) {
251 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set %s : %s\n", var, val);
252 kazoo_globals.event_stream_queue_timeout = atoi(val);
253 } else if (!strcmp(var, "delay-before-initial-fetch-micro")) {
254 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set %s : %s\n", var, val);
255 kazoo_globals.delay_before_initial_fetch = atoi(val);
256 } else if (!strcmp(var, "delay-before-initial-fetch-ms")) {
257 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set %s : %s\n", var, val);
258 kazoo_globals.delay_before_initial_fetch = atoi(val) * 1000;
259 } else if (!strcmp(var, "delay-before-initial-fetch-sec")) {
260 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set %s : %s\n", var, val);
261 kazoo_globals.delay_before_initial_fetch = atoi(val) * 1000000;
262 } else {
263 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "unknown config option %s : %s\n", var, val);
264 }
265 }
266 }
267
268 if ((child = switch_xml_child(cfg, "tweaks"))) {
269 char *default_tweaks = (char *) switch_xml_attr_soft(child, "default");
270 if (default_tweaks && !zstr(default_tweaks)) {
271 int i, v = switch_true(default_tweaks) ? 1 : 0;
272 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set tweak default : %s\n", default_tweaks);
273 for (i = 0; i < KZ_TWEAK_MAX; i++) kazoo_globals.tweaks[i] = v;
274 }
275 for (param = switch_xml_child(child, "tweak"); param; param = param->next) {
276 kz_tweak_t tweak = KZ_TWEAK_MAX;
277 char *var = (char *) switch_xml_attr_soft(param, "name");
278 char *val = (char *) switch_xml_attr_soft(param, "value");
279 if(var && val && kz_name_tweak(var, &tweak) == SWITCH_STATUS_SUCCESS) {
280 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set tweak %s : %s\n", var, val);
281 if(switch_true(val)) {
282 kz_set_tweak(tweak);
283 } else {
284 kz_clear_tweak(tweak);
285 }
286 }
287 }
288 }
289
290 if ((child = switch_xml_child(cfg, "variables"))) {
291 for (param = switch_xml_child(child, "variable"); param; param = param->next) {
292 char *var = (char *) switch_xml_attr_soft(param, "name");
293 char *val = (char *) switch_xml_attr_soft(param, "value");
294 if(var && val) {
295 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set core variable %s : %s\n", var, val);
296 switch_core_set_variable(var, val);
297 }
298 }
299 }
300
301 if ((child = switch_xml_child(cfg, "event-filter"))) {
302 switch_hash_t *filter;
303
304 switch_core_hash_init(&filter);
305 for (param = switch_xml_child(child, "header"); param; param = param->next) {
306 char *var = (char *) switch_xml_attr_soft(param, "name");
307 switch_core_hash_insert(filter, var, "1");
308 }
309 kazoo_globals.event_filter = filter;
310 }
311
312 if (kazoo_globals.receive_msg_preallocate < 0) {
313 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid receive message preallocate value, disabled\n");
314 kazoo_globals.receive_msg_preallocate = 0;
315 }
316
317 if (kazoo_globals.event_stream_preallocate < 0) {
318 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid event stream preallocate value, disabled\n");
319 kazoo_globals.event_stream_preallocate = 0;
320 }
321
322 if (kazoo_globals.send_msg_batch < 1) {
323 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid send message batch size, reverting to default\n");
324 kazoo_globals.send_msg_batch = 10;
325 }
326
327 if (kazoo_globals.io_fault_tolerance < 1) {
328 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid I/O fault tolerance, reverting to default\n");
329 kazoo_globals.io_fault_tolerance = 10;
330 }
331
332 if (!kazoo_globals.event_filter) {
333 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Event filter not found in configuration, using default\n");
334 kazoo_globals.event_filter = create_default_filter();
335 }
336
337 if (kazoo_globals.event_stream_framing < 1 || kazoo_globals.event_stream_framing > 4) {
338 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid event stream framing value, using default\n");
339 kazoo_globals.event_stream_framing = 2;
340 }
341
342 if (zstr(kazoo_var_prefix)) {
343 kazoo_var_prefix = switch_core_strdup(kazoo_globals.pool, "ecallmgr_;cav_");
344 }
345
346 if (zstr(profile_vars_prefix)) {
347 profile_vars_prefix = switch_core_strdup(kazoo_globals.pool, "effective_;origination_");
348 }
349
350 kazoo_globals.kazoo_var_prefixes = switch_core_alloc(kazoo_globals.pool, sizeof(char*) * KZ_MAX_SEPARATE_STRINGS);
351 array_len = switch_separate_string(kazoo_var_prefix, ';', sep_array, KZ_MAX_SEPARATE_STRINGS - 1);
352 for(i=0; i < array_len; i++) {
353 char var[100];
354 sprintf(var, "variable_%s", sep_array[i]);
355 kazoo_globals.kazoo_var_prefixes[i] = switch_core_strdup(kazoo_globals.pool, var);
356 }
357
358 kazoo_globals.profile_vars_prefixes = switch_core_alloc(kazoo_globals.pool, sizeof(char*) * KZ_MAX_SEPARATE_STRINGS);
359 array_len = switch_separate_string(profile_vars_prefix, ';', sep_array, KZ_MAX_SEPARATE_STRINGS - 1);
360 for(i=0; i < array_len; i++) {
361 kazoo_globals.profile_vars_prefixes[i] = switch_core_strdup(kazoo_globals.pool, sep_array[i]);
362 }
363
364 if (!kazoo_globals.node_worker_threads) {
365 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Number of node worker threads not found in configuration, using default\n");
366 kazoo_globals.node_worker_threads = 10;
367 }
368
369 if (zstr(kazoo_globals.ip)) {
370 set_pref_ip("0.0.0.0");
371 }
372
373 if (zstr(kazoo_globals.ei_cookie)) {
374 int res;
375 char *home_dir = getenv("HOME");
376 char path_buf[1024];
377
378 if (!zstr(home_dir)) {
379 /* $HOME/.erlang.cookie */
380 switch_snprintf(path_buf, sizeof (path_buf), "%s%s%s", home_dir, SWITCH_PATH_SEPARATOR, ".erlang.cookie");
381 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Checking for cookie at path: %s\n", path_buf);
382
383 res = read_cookie_from_file(path_buf);
384 if (res) {
385 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "No cookie or valid cookie file specified, using default cookie\n");
386 set_pref_ei_cookie("ClueCon");
387 }
388 }
389 }
390
391 if (!kazoo_globals.ei_nodename) {
392 set_pref_ei_nodename("freeswitch");
393 }
394
395 if (!kazoo_globals.nat_map) {
396 kazoo_globals.nat_map = 0;
397 }
398
399 return SWITCH_STATUS_SUCCESS;
400 }
401
402 switch_status_t kazoo_config_handlers(switch_xml_t cfg)
403 {
404 switch_xml_t def = NULL;
405 switch_xml_t child, param;
406 char* xml = NULL;
407 kazoo_config_ptr definitions = NULL, fetch_handlers = NULL, event_handlers = NULL;
408 kazoo_event_profile_ptr events = NULL;
409
410 xml = strndup(kz_default_config, kz_default_config_size);
411 def = switch_xml_parse_str_dup(xml);
412
413 kz_xml_process(def);
414 kz_xml_process(cfg);
415
416 if ((child = switch_xml_child(cfg, "variables"))) {
417 for (param = switch_xml_child(child, "variable"); param; param = param->next) {
418 char *var = (char *) switch_xml_attr_soft(param, "name");
419 char *val = (char *) switch_xml_attr_soft(param, "value");
420 if(var && val) {
421 switch_core_set_variable(var, val);
422 }
423 }
424 } else if ((child = switch_xml_child(def, "variables"))) {
425 for (param = switch_xml_child(child, "variable"); param; param = param->next) {
426 char *var = (char *) switch_xml_attr_soft(param, "name");
427 char *val = (char *) switch_xml_attr_soft(param, "value");
428 if(var && val) {
429 switch_core_set_variable(var, val);
430 }
431 }
432 }
433
434 definitions = kazoo_config_definitions(cfg);
435 if(definitions == NULL) {
436 if(kazoo_globals.definitions == NULL) {
437 definitions = kazoo_config_definitions(def);
438 } else {
439 definitions = kazoo_globals.definitions;
440 }
441 }
442
443 fetch_handlers = kazoo_config_fetch_handlers(definitions, cfg);
444 if(fetch_handlers == NULL) {
445 if(kazoo_globals.fetch_handlers == NULL) {
446 fetch_handlers = kazoo_config_fetch_handlers(definitions, def);
447 } else {
448 fetch_handlers = kazoo_globals.fetch_handlers;
449 }
450 }
451
452 event_handlers = kazoo_config_event_handlers(definitions, cfg);
453 if(event_handlers == NULL) {
454 if(kazoo_globals.event_handlers == NULL) {
455 event_handlers = kazoo_config_event_handlers(definitions, def);
456 } else {
457 event_handlers = kazoo_globals.event_handlers;
458 }
459 }
460
461 if(event_handlers != NULL) {
462 events = (kazoo_event_profile_ptr) switch_core_hash_find(event_handlers->hash, "default");
463 }
464
465 if(events == NULL) {
466 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to get default handler for events\n");
467 destroy_config(&event_handlers);
468 event_handlers = kazoo_config_event_handlers(definitions, def);
469 events = (kazoo_event_profile_ptr) switch_core_hash_find(event_handlers->hash, "default");
470 }
471
472 if(kazoo_globals.events != events) {
473 bind_event_profiles(events->events);
474 kazoo_globals.events = events;
475 }
476
477 if(kazoo_globals.event_handlers != event_handlers) {
478 kazoo_config_ptr tmp = kazoo_globals.event_handlers;
479 kazoo_globals.event_handlers = event_handlers;
480 destroy_config(&tmp);
481 }
482
483 if(kazoo_globals.fetch_handlers != fetch_handlers) {
484 kazoo_config_ptr tmp = kazoo_globals.fetch_handlers;
485 kazoo_globals.fetch_handlers = fetch_handlers;
486 rebind_fetch_profiles(fetch_handlers);
487 destroy_config(&tmp);
488 }
489
490 if(kazoo_globals.definitions != definitions) {
491 kazoo_config_ptr tmp = kazoo_globals.definitions;
492 kazoo_globals.definitions = definitions;
493 destroy_config(&tmp);
494 }
495
496
497 switch_xml_free(def);
498 switch_safe_free(xml);
499
500 return SWITCH_STATUS_SUCCESS;
501 }
502
503 switch_status_t kazoo_load_config()
504 {
505 char *cf = "kazoo.conf";
506 switch_xml_t cfg, xml;
507 if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
508 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open configuration file %s\n", cf);
509 return SWITCH_STATUS_FALSE;
510 } else {
511 kazoo_ei_config(cfg);
512 kazoo_config_handlers(cfg);
513 switch_xml_free(xml);
514 }
515
516 return SWITCH_STATUS_SUCCESS;
517 }
518
519 void kazoo_destroy_config()
520 {
521 destroy_config(&kazoo_globals.event_handlers);
522 destroy_config(&kazoo_globals.fetch_handlers);
523 destroy_config(&kazoo_globals.definitions);
524 }
525
526 switch_status_t kazoo_config_events(kazoo_config_ptr definitions, switch_memory_pool_t *pool, switch_xml_t cfg, kazoo_event_profile_ptr profile)
527 {
528 switch_xml_t events, event;
529 kazoo_event_ptr prv = NULL, cur = NULL;
530
531
532 if ((events = switch_xml_child(cfg, "events")) != NULL) {
533 for (event = switch_xml_child(events, "event"); event; event = event->next) {
534 const char *var = switch_xml_attr(event, "name");
535 cur = (kazoo_event_ptr) switch_core_alloc(pool, sizeof(kazoo_event_t));
536 memset(cur, 0, sizeof(kazoo_event_t));
537 if(prv == NULL) {
538 profile->events = prv = cur;
539 } else {
540 prv->next = cur;
541 prv = cur;
542 }
543 cur->profile = profile;
544 cur->name = switch_core_strdup(pool, var);
545 kazoo_config_filters(pool, event, &cur->filter);
546 kazoo_config_fields(definitions, pool, event, &cur->fields);
547 if (switch_xml_child(event, "logging") != NULL) {
548 kazoo_config_loglevels(pool, event, &cur->logging);
549 }
550 }
551 }
552
553 return SWITCH_STATUS_SUCCESS;
554
555 }
556
557
558 switch_status_t kazoo_config_fetch_handler(kazoo_config_ptr definitions, kazoo_config_ptr root, switch_xml_t cfg, kazoo_fetch_profile_ptr *ptr)
559 {
560 kazoo_fetch_profile_ptr profile = NULL;
561 switch_xml_t params, param;
562 switch_xml_section_t fetch_section;
563 int fetch_timeout = 2000000;
564 switch_memory_pool_t *pool = NULL;
565
566 char *name = (char *) switch_xml_attr_soft(cfg, "name");
567
568 if (zstr(name)) {
569 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "missing name in profile\n");
570
571 return SWITCH_STATUS_GENERR;
572 }
573
574 if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
575 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error allocation pool for new profile : %s\n", name);
576
577 return SWITCH_STATUS_GENERR;
578 }
579
580 profile = switch_core_alloc(pool, sizeof(kazoo_fetch_profile_t));
581 profile->pool = pool;
582 profile->root = root;
583 profile->name = switch_core_strdup(profile->pool, name);
584
585 fetch_section = switch_xml_parse_section_string(name);
586
587 if ((params = switch_xml_child(cfg, "params")) != NULL) {
588
589 for (param = switch_xml_child(params, "param"); param; param = param->next) {
590 char *var = (char *) switch_xml_attr_soft(param, "name");
591 char *val = (char *) switch_xml_attr_soft(param, "value");
592
593 if (!var) {
594 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Profile[%s] param missing 'name' attribute\n", name);
595 continue;
596 }
597
598 if (!val) {
599 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Profile[%s] param[%s] missing 'value' attribute\n", name, var);
600 continue;
601 }
602
603 if (!strncmp(var, "fetch-timeout", 13)) {
604 fetch_timeout = atoi(val);
605 } else if (!strncmp(var, "fetch-section", 13)) {
606 fetch_section = switch_xml_parse_section_string(val);
607 }
608 }
609 }
610
611 if (fetch_section == SWITCH_XML_SECTION_RESULT) {
612 char *tmp = switch_xml_toxml(cfg, SWITCH_FALSE);
613 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Fetch Profile[%s] invalid fetch-section: %s\n", name, tmp);
614 free(tmp);
615 goto err;
616 }
617
618
619 profile->fetch_timeout = fetch_timeout;
620 profile->section = fetch_section;
621 kazoo_config_fields(definitions, pool, cfg, &profile->fields);
622 kazoo_config_loglevels(pool, cfg, &profile->logging);
623
624 if(root) {
625 if ( switch_core_hash_insert(root->hash, name, (void *) profile) != SWITCH_STATUS_SUCCESS) {
626 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to insert new fetch profile [%s] into kazoo profile hash\n", name);
627 goto err;
628 }
629 }
630
631 if (ptr) {
632 *ptr = profile;
633 }
634
635 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "fetch handler profile %s successfully configured\n", name);
636
637 return SWITCH_STATUS_SUCCESS;
638
639 err:
640 /* Cleanup */
641 if(pool) {
642 switch_core_destroy_memory_pool(&pool);
643 }
644
645 return SWITCH_STATUS_GENERR;
646
647 }
648
649 switch_status_t kazoo_config_event_handler(kazoo_config_ptr definitions, kazoo_config_ptr root, switch_xml_t cfg, kazoo_event_profile_ptr *ptr)
650 {
651 kazoo_event_profile_ptr profile = NULL;
652 switch_memory_pool_t *pool = NULL;
653
654 char *name = (char *) switch_xml_attr_soft(cfg, "name");
655 if (zstr(name)) {
656 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "missing name in profile\n");
657 return SWITCH_STATUS_GENERR;
658 }
659
660 if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
661 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error allocation pool for new profile : %s\n", name);
662 return SWITCH_STATUS_GENERR;
663 }
664
665 profile = switch_core_alloc(pool, sizeof(kazoo_event_profile_t));
666 profile->pool = pool;
667 profile->root = root;
668 profile->name = switch_core_strdup(profile->pool, name);
669
670 kazoo_config_filters(pool, cfg, &profile->filter);
671 kazoo_config_fields(definitions, pool, cfg, &profile->fields);
672 kazoo_config_events(definitions, pool, cfg, profile);
673 kazoo_config_loglevels(pool, cfg, &profile->logging);
674
675 if(root) {
676 if ( switch_core_hash_insert(root->hash, name, (void *) profile) != SWITCH_STATUS_SUCCESS) {
677 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to insert new profile [%s] into kazoo profile hash\n", name);
678 goto err;
679 }
680 }
681
682 if(ptr)
683 *ptr = profile;
684
685 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "event handler profile %s successfully configured\n", name);
686 return SWITCH_STATUS_SUCCESS;
687
688 err:
689 /* Cleanup */
690 if(pool) {
691 switch_core_destroy_memory_pool(&pool);
692 }
693 return SWITCH_STATUS_GENERR;
694
695 }
696
697
698
699 /* For Emacs:
700 * Local Variables:
701 * mode:c
702 * indent-tabs-mode:t
703 * tab-width:4
704 * c-basic-offset:4
705 * End:
706 * For VIM:
707 * vim:set softtabstop=4 shiftwidth=4 tabstop=4
708 */