[mod_kazoo] some fixes & enhancements

* [mod_kazoo] address scan-build warnings

* [mod_kazoo] don't use switch_core_session_force_locate

* [mod_kazoo] add loglevel support per event

* [mod_kazoo] add option to serialize as array

* [mod_kazoo] handle verbose fields

* [mod_kazoo] handle _body header field

* [mod_kazoo] ensure raw json is valid

* [mod_kazoo] encode json number

encodes double as unsigned long long if possible

note: file was formatted

* [mod_kazoo] fix tweaks configuration

* [mod_kazoo] move headers to proper place

* to use Target-Node in filtering
  we need to add and then remove it
  since the next node uses the same event
  to build the message

* [mod_kazoo] handle cleanup in new_event_stream

* [mod_kazoo] do not decode _json_ headers

* [mod_kazoo] add kz_cdr event

* fires the event in report state
* adds json serialized parts
  that can be included
  in event message
* moves history funcs from
  kazoo_commands to kazoo_cdr

* [mod_kazoo] format default configuration

* [mod_kazoo] validate bracket creation

* [mod_kazoo] use single fd for kz_http_put

* [mod_kazoo] add uuid to kz_expand
This commit is contained in:
Andrey Volk 2020-03-05 20:48:40 +04:00 committed by GitHub
parent 6190fa6242
commit 59551f0fd0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 1961 additions and 1254 deletions

View File

@ -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_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_fetch_agent.c kazoo_node.c
mod_kazoo_la_SOURCES += kazoo_endpoints.c mod_kazoo_la_SOURCES += kazoo_endpoints.c
mod_kazoo_la_SOURCES += kazoo_cdr.c
mod_kazoo_la_SOURCES += kz_node.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_CFLAGS = $(AM_CFLAGS) @ERLANG_CFLAGS@ -D_REENTRANT -DERLANG_VERSION=@ERLANG_VERSION@ -DERLANG_MAJOR=@ERLANG_MAJOR@ -DERLANG_MINOR=@ERLANG_MINOR@

File diff suppressed because it is too large Load Diff

View File

@ -175,7 +175,6 @@ static switch_status_t api_erlang_event_filter(switch_stream_handle_t *stream) {
if (++column > 2) { if (++column > 2) {
stream->write_function(stream, "\n"); stream->write_function(stream, "\n");
column = 0;
} }
while(kazoo_globals.kazoo_var_prefixes[idx] != NULL) { while(kazoo_globals.kazoo_var_prefixes[idx] != NULL) {

View File

@ -0,0 +1,630 @@
/*
* 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.
*
* Contributor(s):
*
* Luis Azedo <luis@2600hz.com>
*
* mod_hacks.c -- hacks with state handlers
*
*/
#include "mod_kazoo.h"
#define MY_EVENT_JSON_CDR "KZ_CDR"
#define maybe_add_json_string(_json, _name, _string) \
if (!zstr(_string)) cJSON_AddItemToObject(_json, _name, cJSON_CreateString((char *)_string))
static void kz_switch_ivr_set_json_profile_data(cJSON *json, switch_caller_profile_t *caller_profile)
{
cJSON *soft = NULL;
profile_node_t *pn = NULL;
maybe_add_json_string(json, "Username", caller_profile->username);
maybe_add_json_string(json, "Dialplan", caller_profile->dialplan);
maybe_add_json_string(json, "ANI", caller_profile->ani);
maybe_add_json_string(json, "ANIII", caller_profile->aniii);
maybe_add_json_string(json, "Caller-ID-Name", caller_profile->caller_id_name);
maybe_add_json_string(json, "Caller-ID-Number", caller_profile->caller_id_number);
maybe_add_json_string(json, "Caller-ID-Original-Name", caller_profile->orig_caller_id_name);
maybe_add_json_string(json, "Caller-ID-Original-Number", caller_profile->orig_caller_id_number);
maybe_add_json_string(json, "Network-Address", caller_profile->network_addr);
maybe_add_json_string(json, "RDNIS", caller_profile->rdnis);
maybe_add_json_string(json, "Destination-Number", caller_profile->destination_number);
maybe_add_json_string(json, "Callee-ID-Name", caller_profile->callee_id_name);
maybe_add_json_string(json, "Callee-ID-Number", caller_profile->callee_id_number);
maybe_add_json_string(json, "UUID", caller_profile->uuid);
maybe_add_json_string(json, "Source", caller_profile->source);
maybe_add_json_string(json, "Context", caller_profile->context);
maybe_add_json_string(json, "Channel-Name", caller_profile->chan_name);
maybe_add_json_string(json, "Profile-UUID", caller_profile->uuid_str);
maybe_add_json_string(json, "Profile-Clone-Of", caller_profile->clone_of);
maybe_add_json_string(json, "Transfer-Source", caller_profile->transfer_source);
cJSON_AddItemToObject(json, "Direction", cJSON_CreateString(caller_profile->direction == SWITCH_CALL_DIRECTION_OUTBOUND ? "outbound" : "inbound"));
cJSON_AddItemToObject(json, "Logical-Direction", cJSON_CreateString(caller_profile->logical_direction == SWITCH_CALL_DIRECTION_OUTBOUND ? "outbound" : "inbound"));
soft = cJSON_CreateObject();
for (pn = caller_profile->soft; pn; pn = pn->next) {
maybe_add_json_string(soft, pn->var, pn->val);
}
cJSON_AddItemToObject(json, "Directory", soft);
}
SWITCH_DECLARE(void) kz_switch_ivr_set_json_call_flaws(cJSON *json, switch_core_session_t *session, switch_media_type_t type)
{
const char *name = (type == SWITCH_MEDIA_TYPE_VIDEO) ? "Video" : "Audio";
cJSON *j_stat;
switch_rtp_stats_t *stats = switch_core_media_get_stats(session, type, NULL);
if (!stats) return;
if (!stats->inbound.error_log && !stats->outbound.error_log) return;
j_stat = cJSON_CreateObject();
cJSON_AddItemToObject(json, name, j_stat);
if (stats->inbound.error_log) {
cJSON *j_err_log, *j_err, *j_in;
switch_error_period_t *ep;
j_in = cJSON_CreateObject();
cJSON_AddItemToObject(j_stat, "Inbound", j_in);
j_err_log = cJSON_CreateArray();
cJSON_AddItemToObject(j_in, "Error-Log", j_err_log);
for(ep = stats->inbound.error_log; ep; ep = ep->next) {
if (!(ep->start && ep->stop)) continue;
j_err = cJSON_CreateObject();
cJSON_AddItemToObject(j_err, "Start", cJSON_CreateNumber(ep->start));
cJSON_AddItemToObject(j_err, "Stop", cJSON_CreateNumber(ep->stop));
cJSON_AddItemToObject(j_err, "Flaws", cJSON_CreateNumber(ep->flaws));
cJSON_AddItemToObject(j_err, "Consecutive-Flaws", cJSON_CreateNumber(ep->consecutive_flaws));
cJSON_AddItemToObject(j_err, "Duration-MS", cJSON_CreateNumber((ep->stop - ep->start) / 1000));
cJSON_AddItemToArray(j_err_log, j_err);
}
}
if (stats->outbound.error_log) {
cJSON *j_err_log, *j_err, *j_out;
switch_error_period_t *ep;
j_out = cJSON_CreateObject();
cJSON_AddItemToObject(j_stat, "Outbound", j_out);
j_err_log = cJSON_CreateArray();
cJSON_AddItemToObject(j_out, "Error-Log", j_err_log);
for(ep = stats->outbound.error_log; ep; ep = ep->next) {
if (!(ep->start && ep->stop)) continue;
j_err = cJSON_CreateObject();
cJSON_AddItemToObject(j_err, "Start", cJSON_CreateNumber(ep->start));
cJSON_AddItemToObject(j_err, "Stop", cJSON_CreateNumber(ep->stop));
cJSON_AddItemToObject(j_err, "Flaws", cJSON_CreateNumber(ep->flaws));
cJSON_AddItemToObject(j_err, "Consecutive-Flaws", cJSON_CreateNumber(ep->consecutive_flaws));
cJSON_AddItemToObject(j_err, "Duration-MS", cJSON_CreateNumber((ep->stop - ep->start) / 1000));
cJSON_AddItemToArray(j_err_log, j_err);
}
}
}
#define add_jstat(_j, _i, _s) \
switch_snprintf(var_val, sizeof(var_val), "%" SWITCH_SIZE_T_FMT, _i); \
cJSON_AddItemToObject(_j, _s, cJSON_CreateNumber(_i))
SWITCH_DECLARE(void) kz_switch_ivr_set_json_call_stats(cJSON *json, switch_core_session_t *session, switch_media_type_t type)
{
const char *name = (type == SWITCH_MEDIA_TYPE_VIDEO) ? "Video" : "Audio";
cJSON *j_stat, *j_in, *j_out;
switch_rtp_stats_t *stats = switch_core_media_get_stats(session, type, NULL);
char var_val[35] = "";
if (!stats) return;
j_stat = cJSON_CreateObject();
j_in = cJSON_CreateObject();
j_out = cJSON_CreateObject();
cJSON_AddItemToObject(json, name, j_stat);
cJSON_AddItemToObject(j_stat, "Inbound", j_in);
cJSON_AddItemToObject(j_stat, "Outbound", j_out);
stats->inbound.std_deviation = sqrt(stats->inbound.variance);
add_jstat(j_in, stats->inbound.raw_bytes, "Raw-Bytes");
add_jstat(j_in, stats->inbound.media_bytes, "Media-Bytes");
add_jstat(j_in, stats->inbound.packet_count, "Packet-Count");
add_jstat(j_in, stats->inbound.media_packet_count, "Media-Packet-Count");
add_jstat(j_in, stats->inbound.skip_packet_count, "Skip-Packet-Count");
add_jstat(j_in, stats->inbound.jb_packet_count, "Jitter-Packet-Count");
add_jstat(j_in, stats->inbound.dtmf_packet_count, "DTMF-Packet-Count");
add_jstat(j_in, stats->inbound.cng_packet_count, "CNG-Packet-Count");
add_jstat(j_in, stats->inbound.flush_packet_count, "Flush-Packet-Count");
add_jstat(j_in, stats->inbound.largest_jb_size, "Largest-JB-Size");
add_jstat(j_in, stats->inbound.min_variance, "Jitter-Min-Variance");
add_jstat(j_in, stats->inbound.max_variance, "Jitter-Max-Variance");
add_jstat(j_in, stats->inbound.lossrate, "Jitter-Loss-Rate");
add_jstat(j_in, stats->inbound.burstrate, "Jitter-Burst-Rate");
add_jstat(j_in, stats->inbound.mean_interval, "Mean-Interval");
add_jstat(j_in, stats->inbound.flaws, "Flaw-Total");
add_jstat(j_in, stats->inbound.R, "Quality-Percentage");
add_jstat(j_in, stats->inbound.mos, "MOS");
add_jstat(j_out, stats->outbound.raw_bytes, "Raw-Bytes");
add_jstat(j_out, stats->outbound.media_bytes, "Media-Bytes");
add_jstat(j_out, stats->outbound.packet_count, "Packet-Count");
add_jstat(j_out, stats->outbound.media_packet_count, "Media-Packet-Count");
add_jstat(j_out, stats->outbound.skip_packet_count, "Skip-Packet-Count");
add_jstat(j_out, stats->outbound.dtmf_packet_count, "DTMF-Packet-Count");
add_jstat(j_out, stats->outbound.cng_packet_count, "CNG-Packet-Count");
add_jstat(j_out, stats->rtcp.packet_count, "RTCP-Packet-Count");
add_jstat(j_out, stats->rtcp.octet_count, "RTCP-Octet-Count");
}
static switch_status_t kz_report_channel_flaws(switch_core_session_t *session, switch_event_t *cdr_event)
{
cJSON *callStats = cJSON_CreateObject();
kz_switch_ivr_set_json_call_flaws(callStats, session, SWITCH_MEDIA_TYPE_AUDIO);
kz_switch_ivr_set_json_call_flaws(callStats, session, SWITCH_MEDIA_TYPE_VIDEO);
switch_event_add_header_string(cdr_event, SWITCH_STACK_BOTTOM | SWITCH_STACK_NODUP, "_json_channel_media_errors", cJSON_PrintUnformatted(callStats));
cJSON_Delete(callStats);
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t kz_report_channel_stats(switch_core_session_t *session, switch_event_t *cdr_event)
{
cJSON *callStats = cJSON_CreateObject();
kz_switch_ivr_set_json_call_stats(callStats, session, SWITCH_MEDIA_TYPE_AUDIO);
kz_switch_ivr_set_json_call_stats(callStats, session, SWITCH_MEDIA_TYPE_VIDEO);
switch_event_add_header_string(cdr_event, SWITCH_STACK_BOTTOM | SWITCH_STACK_NODUP, "_json_channel_stats", cJSON_PrintUnformatted(callStats));
cJSON_Delete(callStats);
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t kz_report_app_log(switch_core_session_t *session, switch_event_t *cdr_event)
{
switch_app_log_t *ap, *app_log = switch_core_session_get_app_log(session);
cJSON *j_apps = NULL;
if (!app_log) {
return SWITCH_STATUS_FALSE;
}
j_apps = cJSON_CreateArray();
for (ap = app_log; ap; ap = ap->next) {
cJSON *j_application = cJSON_CreateObject();
cJSON_AddItemToObject(j_application, "app_name", cJSON_CreateString(ap->app));
cJSON_AddItemToObject(j_application, "app_data", cJSON_CreateString(ap->arg));
cJSON_AddItemToObject(j_application, "app_stamp", cJSON_CreateNumber(ap->stamp));
cJSON_AddItemToArray(j_apps, j_application);
}
switch_event_add_header_string(cdr_event, SWITCH_STACK_BOTTOM | SWITCH_STACK_NODUP, "_json_application_log", cJSON_PrintUnformatted(j_apps));
cJSON_Delete(j_apps);
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t kz_report_callflow_extension(switch_caller_profile_t *caller_profile, cJSON *j_profile)
{
cJSON *j_caller_extension, *j_caller_extension_apps, *j_application, *j_inner_extension;
if (caller_profile->caller_extension) {
switch_caller_application_t *ap;
j_caller_extension = cJSON_CreateObject();
j_caller_extension_apps = cJSON_CreateArray();
cJSON_AddItemToObject(j_profile, "extension", j_caller_extension);
cJSON_AddItemToObject(j_caller_extension, "name", cJSON_CreateString(caller_profile->caller_extension->extension_name));
cJSON_AddItemToObject(j_caller_extension, "number", cJSON_CreateString(caller_profile->caller_extension->extension_number));
cJSON_AddItemToObject(j_caller_extension, "applications", j_caller_extension_apps);
if (caller_profile->caller_extension->current_application) {
cJSON_AddItemToObject(j_caller_extension, "current_app", cJSON_CreateString(caller_profile->caller_extension->current_application->application_name));
}
for (ap = caller_profile->caller_extension->applications; ap; ap = ap->next) {
j_application = cJSON_CreateObject();
cJSON_AddItemToArray(j_caller_extension_apps, j_application);
if (ap == caller_profile->caller_extension->current_application) {
cJSON_AddItemToObject(j_application, "last_executed", cJSON_CreateString("true"));
}
cJSON_AddItemToObject(j_application, "app_name", cJSON_CreateString(ap->application_name));
cJSON_AddItemToObject(j_application, "app_data", cJSON_CreateString(switch_str_nil(ap->application_data)));
}
if (caller_profile->caller_extension->children) {
switch_caller_profile_t *cp = NULL;
j_inner_extension = cJSON_CreateArray();
cJSON_AddItemToObject(j_caller_extension, "sub_extensions", j_inner_extension);
for (cp = caller_profile->caller_extension->children; cp; cp = cp->next) {
if (!cp->caller_extension) {
continue;
}
j_caller_extension = cJSON_CreateObject();
cJSON_AddItemToArray(j_inner_extension, j_caller_extension);
cJSON_AddItemToObject(j_caller_extension, "name", cJSON_CreateString(cp->caller_extension->extension_name));
cJSON_AddItemToObject(j_caller_extension, "number", cJSON_CreateString(cp->caller_extension->extension_number));
cJSON_AddItemToObject(j_caller_extension, "dialplan", cJSON_CreateString((char *)cp->dialplan));
if (cp->caller_extension->current_application) {
cJSON_AddItemToObject(j_caller_extension, "current_app", cJSON_CreateString(cp->caller_extension->current_application->application_name));
}
j_caller_extension_apps = cJSON_CreateArray();
cJSON_AddItemToObject(j_caller_extension, "applications", j_caller_extension_apps);
for (ap = cp->caller_extension->applications; ap; ap = ap->next) {
j_application = cJSON_CreateObject();
cJSON_AddItemToArray(j_caller_extension_apps, j_application);
if (ap == cp->caller_extension->current_application) {
cJSON_AddItemToObject(j_application, "last_executed", cJSON_CreateString("true"));
}
cJSON_AddItemToObject(j_application, "app_name", cJSON_CreateString(ap->application_name));
cJSON_AddItemToObject(j_application, "app_data", cJSON_CreateString(switch_str_nil(ap->application_data)));
}
}
}
}
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t kz_report_callflow(switch_core_session_t *session, switch_event_t *cdr_event)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_caller_profile_t *caller_profile;
cJSON *j_main_cp, *j_times, *j_callflow, *j_profile, *j_o;
caller_profile = switch_channel_get_caller_profile(channel);
j_callflow = cJSON_CreateArray();
while (caller_profile) {
j_profile = cJSON_CreateObject();
if (!zstr(caller_profile->dialplan)) {
cJSON_AddItemToObject(j_profile, "dialplan", cJSON_CreateString((char *)caller_profile->dialplan));
}
if (!zstr(caller_profile->profile_index)) {
cJSON_AddItemToObject(j_profile, "profile_index", cJSON_CreateString((char *)caller_profile->profile_index));
}
kz_report_callflow_extension(caller_profile, j_profile);
j_main_cp = cJSON_CreateObject();
cJSON_AddItemToObject(j_profile, "Caller-Profile", j_main_cp);
kz_switch_ivr_set_json_profile_data(j_main_cp, caller_profile);
if (caller_profile->originator_caller_profile) {
j_o = cJSON_CreateObject();
cJSON_AddItemToObject(j_main_cp, "originator", j_o);
kz_switch_ivr_set_json_profile_data(j_o, caller_profile->originator_caller_profile);
kz_report_callflow_extension(caller_profile->originator_caller_profile, j_o);
}
if (caller_profile->originatee_caller_profile) {
j_o = cJSON_CreateObject();
cJSON_AddItemToObject(j_main_cp, "originatee", j_o);
kz_switch_ivr_set_json_profile_data(j_o, caller_profile->originatee_caller_profile);
kz_report_callflow_extension(caller_profile->originatee_caller_profile, j_o);
}
if (caller_profile->times) {
j_times = cJSON_CreateObject();
cJSON_AddItemToObject(j_profile, "Time", j_times);
cJSON_AddItemToObject(j_times, "Created", cJSON_CreateNumber(caller_profile->times->created));
cJSON_AddItemToObject(j_times, "Profile-Created", cJSON_CreateNumber(caller_profile->times->profile_created));
cJSON_AddItemToObject(j_times, "Progress", cJSON_CreateNumber(caller_profile->times->progress));
cJSON_AddItemToObject(j_times, "Progress-Media", cJSON_CreateNumber(caller_profile->times->progress_media));
cJSON_AddItemToObject(j_times, "Answered", cJSON_CreateNumber(caller_profile->times->answered));
cJSON_AddItemToObject(j_times, "Bridged", cJSON_CreateNumber(caller_profile->times->bridged));
cJSON_AddItemToObject(j_times, "Last-Hold", cJSON_CreateNumber(caller_profile->times->last_hold));
cJSON_AddItemToObject(j_times, "Hold-Accumulated", cJSON_CreateNumber(caller_profile->times->hold_accum));
cJSON_AddItemToObject(j_times, "Hangup", cJSON_CreateNumber(caller_profile->times->hungup));
cJSON_AddItemToObject(j_times, "Resurrect", cJSON_CreateNumber(caller_profile->times->resurrected));
cJSON_AddItemToObject(j_times, "Transfer", cJSON_CreateNumber(caller_profile->times->transferred));
}
cJSON_AddItemToArray(j_callflow, j_profile);
caller_profile = caller_profile->next;
}
switch_event_add_header_string(cdr_event, SWITCH_STACK_BOTTOM | SWITCH_STACK_NODUP, "_json_callflow", cJSON_PrintUnformatted(j_callflow));
cJSON_Delete(j_callflow);
return SWITCH_STATUS_SUCCESS;
}
#define ORIGINATED_LEGS_VARIABLE "originated_legs"
#define ORIGINATED_LEGS_ITEM_DELIM ';'
#define ORIGINATE_CAUSES_VARIABLE "originate_causes"
#define ORIGINATE_CAUSES_ITEM_DELIM ';'
static switch_status_t kz_report_originated_legs(switch_core_session_t *session, switch_event_t *cdr_event)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
cJSON *j_originated = cJSON_CreateArray();
const char *originated_legs_var = NULL, *originate_causes_var = NULL;
int idx = 0;
while(1) {
char *argv_leg[10] = { 0 }, *argv_cause[10] = { 0 };
char *originated_legs, *originate_causes;
cJSON *j_originated_leg;
originated_legs_var = switch_channel_get_variable_dup(channel, ORIGINATED_LEGS_VARIABLE, SWITCH_FALSE, idx);
originate_causes_var = switch_channel_get_variable_dup(channel, ORIGINATE_CAUSES_VARIABLE, SWITCH_FALSE, idx);
if (zstr(originated_legs_var) || zstr(originate_causes_var)) {
break;
}
originated_legs = strdup(originated_legs_var);
originate_causes = strdup(originate_causes_var);
switch_separate_string(originated_legs, ORIGINATED_LEGS_ITEM_DELIM, argv_leg, (sizeof(argv_leg) / sizeof(argv_leg[0])));
switch_separate_string(originate_causes, ORIGINATE_CAUSES_ITEM_DELIM, argv_cause, (sizeof(argv_cause) / sizeof(argv_cause[0])));
j_originated_leg = cJSON_CreateObject();
cJSON_AddItemToObject(j_originated_leg, "Call-ID", cJSON_CreateString(argv_leg[0]));
cJSON_AddItemToObject(j_originated_leg, "Caller-ID-Name", cJSON_CreateString(argv_leg[1]));
cJSON_AddItemToObject(j_originated_leg, "Caller-ID-Number", cJSON_CreateString(argv_leg[2]));
cJSON_AddItemToObject(j_originated_leg, "Result", cJSON_CreateString(argv_cause[1]));
cJSON_AddItemToArray(j_originated, j_originated_leg);
switch_safe_free(originated_legs);
switch_safe_free(originate_causes);
idx++;
}
switch_event_add_header_string(cdr_event, SWITCH_STACK_BOTTOM | SWITCH_STACK_NODUP, "_json_originated_legs", cJSON_PrintUnformatted(j_originated));
cJSON_Delete(j_originated);
return SWITCH_STATUS_SUCCESS;
}
#define MAX_HISTORY 50
#define HST_ARRAY_DELIM "|:"
#define HST_ITEM_DELIM ':'
static void kz_report_transfer_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, "Caller-Profile-ID", cJSON_CreateString(callid));
cJSON_AddItemToObject(jitem, "Type", cJSON_CreateString("blind"));
cJSON_AddItemToObject(jitem, "Extension", cJSON_CreateString(argv[3]));
cJSON_AddItemToObject(jitem, "Timestamp", cJSON_CreateNumber(strtod(epoch, NULL)));
} else if(!strncmp(type, "att_xfer", 8)) {
char *split = strchr(argv[3], '/');
if(split) {
*(split++) = '\0';
cJSON_AddItemToObject(jitem, "Caller-Profile-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));
cJSON_AddItemToObject(jitem, "Timestamp", cJSON_CreateNumber(strtod(epoch, NULL)));
} 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, "Caller-Profile-ID", cJSON_CreateString(callid));
cJSON_AddItemToObject(jitem, "Type", cJSON_CreateString("bridge"));
cJSON_AddItemToObject(jitem, "Other-Leg", cJSON_CreateString(argv[3]));
cJSON_AddItemToObject(jitem, "Timestamp", cJSON_CreateNumber(strtod(epoch, NULL)));
} 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_AddItemToArray(json, jitem);
} else {
cJSON_Delete(jitem);
}
switch_safe_free(item);
}
static switch_status_t kz_report_transfer_history(switch_core_session_t *session, switch_event_t *cdr_event, const char* var_name)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
cJSON *j_transfer = NULL;
char *tmp_history = NULL, *history = NULL, *argv[MAX_HISTORY] = { 0 };
char event_header[50];
int n, argc = 0;
const char *transfer_var = switch_channel_get_variable_dup(channel, var_name, SWITCH_FALSE, -1);
if (zstr(transfer_var)) {
return SWITCH_STATUS_SUCCESS;
}
if (!(tmp_history = strdup(transfer_var))) {
return SWITCH_STATUS_SUCCESS;
}
sprintf(event_header, "_json_%s", var_name);
history = tmp_history;
j_transfer = cJSON_CreateArray();
if (!strncmp(history, "ARRAY::", 7)) {
history += 7;
argc = switch_separate_string_string(history, HST_ARRAY_DELIM, argv, (sizeof(argv) / sizeof(argv[0])));
for(n=0; n < argc; n++) {
kz_report_transfer_history_item(argv[n], j_transfer);
}
switch_event_add_header_string(cdr_event, SWITCH_STACK_BOTTOM | SWITCH_STACK_NODUP, event_header, cJSON_PrintUnformatted(j_transfer));
} else if (strchr(history, HST_ITEM_DELIM)) {
kz_report_transfer_history_item(history, j_transfer);
switch_event_add_header_string(cdr_event, SWITCH_STACK_BOTTOM | SWITCH_STACK_NODUP, event_header, cJSON_PrintUnformatted(j_transfer));
}
cJSON_Delete(j_transfer);
switch_safe_free(tmp_history);
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t kz_report(switch_core_session_t *session, switch_event_t *cdr_event)
{
kz_report_app_log(session, cdr_event);
kz_report_callflow(session, cdr_event);
kz_report_channel_stats(session, cdr_event);
kz_report_channel_flaws(session, cdr_event);
kz_report_originated_legs(session, cdr_event);
kz_report_transfer_history(session, cdr_event, SWITCH_TRANSFER_HISTORY_VARIABLE);
kz_report_transfer_history(session, cdr_event, SWITCH_TRANSFER_SOURCE_VARIABLE);
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t kz_cdr_on_reporting(switch_core_session_t *session)
{
switch_event_t *cdr_event = NULL;
switch_channel_t *channel = switch_core_session_get_channel(session);
if (switch_event_create_subclass(&cdr_event, SWITCH_EVENT_CUSTOM, MY_EVENT_JSON_CDR) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "error creating event for report data!\n");
return SWITCH_STATUS_FALSE;
}
kz_report(session, cdr_event);
switch_channel_event_set_data(channel, cdr_event);
switch_event_fire(&cdr_event);
return SWITCH_STATUS_SUCCESS;
}
static switch_state_handler_table_t kz_cdr_state_handlers = {
/*.on_init */ NULL,
/*.on_routing */ NULL,
/*.on_execute */ NULL,
/*.on_hangup */ NULL,
/*.on_exchange_media */ NULL,
/*.on_soft_execute */ NULL,
/*.on_consume_media */ NULL,
/*.on_hibernate */ NULL,
/*.on_reset */ NULL,
/*.on_park */ NULL,
/*.on_reporting */ kz_cdr_on_reporting
};
static void kz_cdr_register_state_handlers()
{
switch_core_add_state_handler(&kz_cdr_state_handlers);
}
static void kz_cdr_unregister_state_handlers()
{
switch_core_remove_state_handler(&kz_cdr_state_handlers);
}
static void kz_cdr_register_events()
{
if (switch_event_reserve_subclass(MY_EVENT_JSON_CDR) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_JSON_CDR);
}
}
static void kz_cdr_unregister_events()
{
switch_event_free_subclass(MY_EVENT_JSON_CDR);
}
void kz_cdr_start()
{
kz_cdr_register_events();
kz_cdr_register_state_handlers();
}
void kz_cdr_stop()
{
kz_cdr_unregister_state_handlers();
kz_cdr_unregister_events();
}
/* 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:
*/

View File

@ -48,138 +48,45 @@
#define MAX_FIRST_OF 25 #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) SWITCH_STANDARD_API(kz_first_of)
{ {
char delim = '|'; char delim = '|';
char *mycmd = NULL, *argv[MAX_FIRST_OF] = { 0 }; char *mycmd = NULL, *mycmd_dup = NULL, *argv[MAX_FIRST_OF] = { 0 };
int n, argc = 0; int n, argc = 0;
switch_event_header_t *header = NULL; switch_event_header_t *header = NULL;
if (!zstr(cmd) && (mycmd = strdup(cmd))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "FIRST-OF %s\n", mycmd); if (zstr(cmd)) {
if (!zstr(mycmd) && *mycmd == '^' && *(mycmd+1) == '^') { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "invalid arg\n");
mycmd += 2; return SWITCH_STATUS_GENERR;
delim = *mycmd++; }
}
argc = switch_separate_string(mycmd, delim, argv, (sizeof(argv) / sizeof(argv[0]))); mycmd_dup = mycmd = strdup(cmd);
for(n=0; n < argc; n++) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "FIRST-OF %s\n", mycmd);
char* item = argv[n]; if (!zstr(mycmd) && *mycmd == '^' && *(mycmd+1) == '^') {
if(*item == '#') { mycmd += 2;
if(*(++item) != '\0') { delim = *mycmd++;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "RETURNING default %s\n", item); }
stream->write_function(stream, item); argc = switch_separate_string(mycmd, delim, argv, (sizeof(argv) / sizeof(argv[0])));
break; for(n=0; n < argc; n++) {
} char* item = argv[n];
} else { if(*item == '#' || *item == '!' || *item == '?') {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "CHECKING %s\n", item); if(*(++item) != '\0') {
header = switch_event_get_header_ptr(stream->param_event, item); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "RETURNING default %s\n", item);
if(header) { stream->write_function(stream, item);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "RETURNING %s : %s\n", item, header->value); break;
stream->write_function(stream, header->value); }
break; } else {
} switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "CHECKING %s\n", item);
header = switch_event_get_header_ptr(stream->param_event, item);
if(header) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "RETURNING %s : %s\n", item, header->value);
stream->write_function(stream, header->value);
break;
} }
} }
} }
switch_safe_free(mycmd); switch_safe_free(mycmd_dup);
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
@ -364,7 +271,6 @@ SWITCH_STANDARD_API(kz_http_put)
long httpRes = 0; long httpRes = 0;
struct stat file_info = {0}; struct stat file_info = {0};
FILE *file_to_put = NULL; FILE *file_to_put = NULL;
int fd;
if (session) { if (session) {
pool = switch_core_session_get_pool(session); pool = switch_core_session_get_pool(session);
@ -390,7 +296,11 @@ SWITCH_STANDARD_API(kz_http_put)
/* parse params and get profile */ /* parse params and get profile */
url = switch_core_strdup(pool, argv[0]); url = switch_core_strdup(pool, argv[0]);
if (*url == '{') { if (*url == '{') {
switch_event_create_brackets(url, '{', '}', ',', &params, &url, SWITCH_FALSE); if (switch_event_create_brackets(url, '{', '}', ',', &params, &url, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS) {
status = SWITCH_STATUS_FALSE;
stream->write_function(stream, "-ERR error parsing parameters\n");
goto done;
}
} }
filename = switch_core_strdup(pool, argv[1]); filename = switch_core_strdup(pool, argv[1]);
@ -404,34 +314,26 @@ SWITCH_STANDARD_API(kz_http_put)
} }
buf = switch_mprintf("Content-Type: %s", mime_type); buf = switch_mprintf("Content-Type: %s", mime_type);
headers = switch_curl_slist_append(headers, buf); headers = switch_curl_slist_append(headers, buf);
/* open file and get the file size */ /* open file and get the file size */
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "opening %s for upload to %s\n", filename, url); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "opening %s for upload to %s\n", filename, url);
fd = open(filename, O_RDONLY);
if (fd == -1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open() error: %s\n", strerror(errno));
status = SWITCH_STATUS_FALSE;
stream->write_function(stream, "-ERR error opening file\n");
goto done;
}
if (fstat(fd, &file_info) == -1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "fstat() error: %s\n", strerror(errno));
stream->write_function(stream, "-ERR fstat error\n");
close(fd);
goto done;
}
close(fd);
/* libcurl requires FILE* */ /* libcurl requires FILE* */
file_to_put = fopen(filename, "rb"); file_to_put = fopen(filename, "rb");
if (!file_to_put) { if (!file_to_put) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "fopen() error: %s\n", strerror(errno)); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "fopen() error: %s\n", strerror(errno));
stream->write_function(stream, "-ERR error opening file\n");
status = SWITCH_STATUS_FALSE; status = SWITCH_STATUS_FALSE;
goto done; goto done;
} }
if (fstat(fileno(file_to_put), &file_info) == -1) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "fstat() error: %s\n", strerror(errno));
stream->write_function(stream, "-ERR fstat error\n");
goto done;
}
curl_handle = switch_curl_easy_init(); curl_handle = switch_curl_easy_init();
if (!curl_handle) { if (!curl_handle) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "switch_curl_easy_init() failure\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "switch_curl_easy_init() failure\n");
@ -503,13 +405,36 @@ done:
SWITCH_STANDARD_API(kz_expand_api) SWITCH_STANDARD_API(kz_expand_api)
{ {
if (!zstr(cmd)) { char *p = NULL, *input = NULL;
char * val = kz_expand(cmd); char *uuid = NULL, *mycmd;
stream->write_function(stream, "+OK %s", val);
switch_safe_free(val); if (zstr(cmd)) {
} else { stream->write_function(stream, "-ERR invalid input");
stream->write_function(stream, "ERR invalid input"); return SWITCH_STATUS_GENERR;
} }
if (!(mycmd = strdup(cmd))) {
stream->write_function(stream, "-ERR no memory");
return SWITCH_STATUS_GENERR;
}
if (!strncasecmp(mycmd, "uuid:", 5)) {
uuid = mycmd + 5;
if ((input = strchr(uuid, ' ')) != NULL) {
*input++ = '\0';
} else {
stream->write_function(stream, "-ERR invalid argument");
switch_safe_free(mycmd);
return SWITCH_STATUS_GENERR;
}
}
p = kz_expand(input, uuid);
stream->write_function(stream, "+OK %s", p);
if (p != input) {
switch_safe_free(p);
}
switch_safe_free(mycmd);
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
@ -525,7 +450,6 @@ void add_kz_commands(switch_loadable_module_interface_t **module_interface) {
switch_console_set_complete("add kz_uuid_setvar_encoded ::console::list_uuid"); 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, "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, "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);
SWITCH_ADD_API(api_interface, "kz_expand", KZ_FIRST_OF_DESC, kz_expand_api, KZ_FIRST_OF_SYNTAX); SWITCH_ADD_API(api_interface, "kz_expand", KZ_FIRST_OF_DESC, kz_expand_api, KZ_FIRST_OF_SYNTAX);
} }

View File

@ -129,6 +129,10 @@ switch_status_t kazoo_config_loglevels(switch_memory_pool_t *pool, switch_xml_t
loglevels->warn_log_level = SWITCH_LOG_WARNING; loglevels->warn_log_level = SWITCH_LOG_WARNING;
loglevels->success_log_level = SWITCH_LOG_DEBUG; loglevels->success_log_level = SWITCH_LOG_DEBUG;
loglevels->time_log_level = SWITCH_LOG_DEBUG1; loglevels->time_log_level = SWITCH_LOG_DEBUG1;
loglevels->trace_log_level = SWITCH_LOG_DEBUG1;
loglevels->debug_log_level = SWITCH_LOG_DEBUG;
loglevels->error_log_level = SWITCH_LOG_ERROR;
loglevels->hashing_log_level = SWITCH_LOG_DEBUG1;
if ((xml_logging = switch_xml_child(cfg, "logging")) != NULL) { if ((xml_logging = switch_xml_child(cfg, "logging")) != NULL) {
for (xml_level = switch_xml_child(xml_logging, "log"); xml_level; xml_level = xml_level->next) { for (xml_level = switch_xml_child(xml_logging, "log"); xml_level; xml_level = xml_level->next) {
@ -159,6 +163,14 @@ switch_status_t kazoo_config_loglevels(switch_memory_pool_t *pool, switch_xml_t
loglevels->filtered_event_log_level = log_str2level(val); loglevels->filtered_event_log_level = log_str2level(val);
} else if (!strncmp(var, "filtered-field", 14)) { } else if (!strncmp(var, "filtered-field", 14)) {
loglevels->filtered_field_log_level = log_str2level(val); loglevels->filtered_field_log_level = log_str2level(val);
} else if (!strncmp(var, "trace", 5)) {
loglevels->trace_log_level = log_str2level(val);
} else if (!strncmp(var, "debug", 5)) {
loglevels->debug_log_level = log_str2level(val);
} else if (!strncmp(var, "error", 5)) {
loglevels->error_log_level = log_str2level(val);
} else if (!strncmp(var, "hashing", 7)) {
loglevels->hashing_log_level = log_str2level(val);
} }
} /* xml_level for loop */ } /* xml_level for loop */
} }
@ -247,6 +259,7 @@ switch_status_t kazoo_config_field(kazoo_config_ptr definitions, switch_memory_p
const char *type = switch_xml_attr(cfg, "type"); const char *type = switch_xml_attr(cfg, "type");
const char *exclude_prefix = switch_xml_attr(cfg, "exclude-prefix"); const char *exclude_prefix = switch_xml_attr(cfg, "exclude-prefix");
const char *serialize_as = switch_xml_attr(cfg, "serialize-as"); const char *serialize_as = switch_xml_attr(cfg, "serialize-as");
const char *as_array = switch_xml_attr(cfg, "as-array");
kazoo_field_ptr cur = (kazoo_field_ptr) switch_core_alloc(pool, sizeof(kazoo_field)); kazoo_field_ptr cur = (kazoo_field_ptr) switch_core_alloc(pool, sizeof(kazoo_field));
cur->in_type = FIELD_NONE; cur->in_type = FIELD_NONE;
cur->out_type = JSON_NONE; cur->out_type = JSON_NONE;
@ -292,6 +305,10 @@ switch_status_t kazoo_config_field(kazoo_config_ptr definitions, switch_memory_p
} }
} }
if(as_array) {
cur->out_type_as_array = switch_true(as_array);
}
if(exclude_prefix) if(exclude_prefix)
cur->exclude_prefix = switch_true(exclude_prefix); cur->exclude_prefix = switch_true(exclude_prefix);

View File

@ -267,7 +267,7 @@ void kz_uuid_multiset(switch_core_session_t *session, const char* data, int urld
if(delim != '\0') { if(delim != '\0') {
switch_core_session_t *uuid_session = NULL; switch_core_session_t *uuid_session = NULL;
if ((uuid_session = switch_core_session_force_locate(arg0)) != NULL) { if ((uuid_session = switch_core_session_locate(arg0)) != NULL) {
switch_channel_t *uuid_channel = switch_core_session_get_channel(uuid_session); switch_channel_t *uuid_channel = switch_core_session_get_channel(uuid_session);
if (arg) { if (arg) {
char *array[256] = {0}; char *array[256] = {0};

View File

@ -238,8 +238,8 @@ switch_status_t kazoo_ei_config(switch_xml_t cfg) {
} }
if ((child = switch_xml_child(cfg, "tweaks"))) { if ((child = switch_xml_child(cfg, "tweaks"))) {
char *default_tweaks = (char *) switch_xml_attr_soft(param, "default"); char *default_tweaks = (char *) switch_xml_attr_soft(child, "default");
if (default_tweaks) { if (default_tweaks && !zstr(default_tweaks)) {
int i, v = switch_true(default_tweaks) ? 1 : 0; 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); 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 (i = 0; i < KZ_TWEAK_MAX; i++) kazoo_globals.tweaks[i] = v;
@ -516,9 +516,10 @@ switch_status_t kazoo_config_events(kazoo_config_ptr definitions, switch_memory_
cur->name = switch_core_strdup(pool, var); cur->name = switch_core_strdup(pool, var);
kazoo_config_filters(pool, event, &cur->filter); kazoo_config_filters(pool, event, &cur->filter);
kazoo_config_fields(definitions, pool, event, &cur->fields); kazoo_config_fields(definitions, pool, event, &cur->fields);
if (switch_xml_child(event, "logging") != NULL) {
kazoo_config_loglevels(pool, event, &cur->logging);
}
} }
} }
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;

View File

@ -54,91 +54,87 @@
#ifdef EI_DEBUG #ifdef EI_DEBUG
static void ei_x_print_reg_msg(ei_x_buff *buf, char *dest, int send) { static void ei_x_print_reg_msg(ei_x_buff *buf, char *dest, int send) {
char *mbuf = NULL; char *mbuf = NULL;
int i = 1; int i = 1;
ei_s_print_term(&mbuf, buf->buff, &i); ei_s_print_term(&mbuf, buf->buff, &i);
if (send) { if (send) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Encoded term %s to '%s'\n", mbuf, dest); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Encoded term %s to '%s'\n", mbuf, dest);
} else { } else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Decoded term %s for '%s'\n", mbuf, dest); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Decoded term %s for '%s'\n", mbuf, dest);
} }
free(mbuf); free(mbuf);
} }
static void ei_x_print_msg(ei_x_buff *buf, erlang_pid *pid, int send) { static void ei_x_print_msg(ei_x_buff *buf, erlang_pid *pid, int send) {
char *pbuf = NULL; char *pbuf = NULL;
int i = 0; int i = 0;
ei_x_buff pidbuf; ei_x_buff pidbuf;
ei_x_new(&pidbuf); ei_x_new(&pidbuf);
ei_x_encode_pid(&pidbuf, pid); ei_x_encode_pid(&pidbuf, pid);
ei_s_print_term(&pbuf, pidbuf.buff, &i); ei_s_print_term(&pbuf, pidbuf.buff, &i);
ei_x_print_reg_msg(buf, pbuf, send); ei_x_print_reg_msg(buf, pbuf, send);
free(pbuf); free(pbuf);
} }
#endif #endif
void ei_encode_switch_event_headers(ei_x_buff *ebuf, switch_event_t *event) { void ei_encode_switch_event_headers(ei_x_buff *ebuf, switch_event_t *event)
{
ei_encode_switch_event_headers_2(ebuf, event, 1); ei_encode_switch_event_headers_2(ebuf, event, 1);
} }
void ei_encode_switch_event_headers_2(ei_x_buff *ebuf, switch_event_t *event, int encode) { void ei_encode_switch_event_headers_2(ei_x_buff *ebuf, switch_event_t *event, int encode)
switch_event_header_t *hp; {
char *uuid = switch_event_get_header(event, "unique-id"); switch_event_header_t *hp;
int i; char *uuid = switch_event_get_header(event, "unique-id");
int i;
for (i = 0, hp = event->headers; hp; hp = hp->next, i++); for (i = 0, hp = event->headers; hp; hp = hp->next, i++)
;
if (event->body) if (event->body)
i++; i++;
ei_x_encode_list_header(ebuf, i + 1); ei_x_encode_list_header(ebuf, i + 1);
if (uuid) { if (uuid) {
char *unique_id = switch_event_get_header(event, "unique-id"); char *unique_id = switch_event_get_header(event, "unique-id");
ei_x_encode_binary(ebuf, unique_id, strlen(unique_id)); ei_x_encode_binary(ebuf, unique_id, strlen(unique_id));
} else { } else {
ei_x_encode_atom(ebuf, "undefined"); ei_x_encode_atom(ebuf, "undefined");
} }
for (hp = event->headers; hp; hp = hp->next) { for (hp = event->headers; hp; hp = hp->next) {
ei_x_encode_tuple_header(ebuf, 2); ei_x_encode_tuple_header(ebuf, 2);
ei_x_encode_binary(ebuf, hp->name, strlen(hp->name)); ei_x_encode_binary(ebuf, hp->name, strlen(hp->name));
if(encode) { if (encode) {
switch_url_decode(hp->value); switch_url_decode(hp->value);
} }
ei_x_encode_binary(ebuf, hp->value, strlen(hp->value)); ei_x_encode_binary(ebuf, hp->value, strlen(hp->value));
} }
if (event->body) { if (event->body) {
ei_x_encode_tuple_header(ebuf, 2); ei_x_encode_tuple_header(ebuf, 2);
ei_x_encode_binary(ebuf, "body", strlen("body")); ei_x_encode_binary(ebuf, "body", strlen("body"));
ei_x_encode_binary(ebuf, event->body, strlen(event->body)); ei_x_encode_binary(ebuf, event->body, strlen(event->body));
} }
ei_x_encode_empty_list(ebuf); ei_x_encode_empty_list(ebuf);
} }
int ei_json_child_count(cJSON *JObj) int ei_json_child_count(cJSON *JObj)
{ {
int mask = cJSON_False int mask = cJSON_False | cJSON_True | cJSON_NULL | cJSON_Number | cJSON_String | cJSON_Array | cJSON_Object | cJSON_Raw;
| cJSON_True
| cJSON_NULL
| cJSON_Number
| cJSON_String
| cJSON_Array
| cJSON_Object
| cJSON_Raw;
cJSON *item = JObj->child; cJSON *item = JObj->child;
int i = 0; int i = 0;
while(item) { while (item) {
if(item->type & mask) if (item->type & mask)
i++; i++;
item = item->next; item = item->next;
} }
@ -146,154 +142,165 @@ int ei_json_child_count(cJSON *JObj)
} }
void ei_encode_json_array(ei_x_buff *ebuf, cJSON *JObj) { void ei_encode_json_array(ei_x_buff *ebuf, cJSON *JObj)
{
cJSON *item; cJSON *item;
int count = ei_json_child_count(JObj); int count = ei_json_child_count(JObj);
ei_x_encode_list_header(ebuf, count); ei_x_encode_list_header(ebuf, count);
if(count == 0) if (count == 0)
return; return;
item = JObj->child; item = JObj->child;
while(item) { while (item) {
switch(item->type) { switch (item->type){
case cJSON_String: case cJSON_String:
ei_x_encode_binary(ebuf, item->valuestring, strlen(item->valuestring)); ei_x_encode_binary(ebuf, item->valuestring, strlen(item->valuestring));
break; break;
case cJSON_Number: case cJSON_Number:
ei_x_encode_double(ebuf, item->valuedouble); if ((fabs(((double) item->valueint) - item->valuedouble) <= DBL_EPSILON) && (item->valuedouble <= INT_MAX) && (item->valuedouble >= INT_MIN)) {
break; ei_x_encode_longlong(ebuf, item->valueint);
} else {
if (fmod(item->valuedouble, 1) == 0) {
ei_x_encode_ulonglong(ebuf, item->valuedouble);
} else {
ei_x_encode_double(ebuf, item->valuedouble);
}
}
break;
case cJSON_True: case cJSON_True:
ei_x_encode_boolean(ebuf, 1); ei_x_encode_boolean(ebuf, 1);
break; break;
case cJSON_False: case cJSON_False:
ei_x_encode_boolean(ebuf, 0); ei_x_encode_boolean(ebuf, 0);
break; break;
case cJSON_Object: case cJSON_Object:
ei_encode_json(ebuf, item); ei_encode_json(ebuf, item);
break; break;
case cJSON_Array: case cJSON_Array:
ei_encode_json_array(ebuf, item); ei_encode_json_array(ebuf, item);
break; break;
case cJSON_Raw: case cJSON_Raw: {
{ cJSON *Decoded = cJSON_Parse(item->valuestring);
cJSON *Decoded = cJSON_Parse(item->valuestring); if (!Decoded) {
if(!Decoded) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR DECODING RAW JSON %s\n", item->valuestring);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR DECODING RAW JSON %s\n", item->valuestring); ei_x_encode_tuple_header(ebuf, 0);
ei_x_encode_tuple_header(ebuf, 0); } else {
} else { ei_encode_json(ebuf, Decoded);
ei_encode_json(ebuf, Decoded); cJSON_Delete(Decoded);
cJSON_Delete(Decoded); }
} break;
break; }
}
case cJSON_NULL: case cJSON_NULL:
ei_x_encode_atom(ebuf, "null"); ei_x_encode_atom(ebuf, "null");
break; break;
default: default:
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "NOT ENCODED %i\n", item->type); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "NOT ENCODED %i\n", item->type);
break; break;
} }
item = item->next; item = item->next;
} }
ei_x_encode_empty_list(ebuf); ei_x_encode_empty_list(ebuf);
} }
void ei_encode_json(ei_x_buff *ebuf, cJSON *JObj) { void ei_encode_json(ei_x_buff *ebuf, cJSON *JObj)
{
cJSON *item; cJSON *item;
int count = ei_json_child_count(JObj); int count = ei_json_child_count(JObj);
if(kazoo_globals.json_encoding == ERLANG_TUPLE) { if (kazoo_globals.json_encoding == ERLANG_TUPLE) {
ei_x_encode_tuple_header(ebuf, 1); ei_x_encode_tuple_header(ebuf, 1);
ei_x_encode_list_header(ebuf, count); ei_x_encode_list_header(ebuf, count);
} else { } else {
ei_x_encode_map_header(ebuf, count); ei_x_encode_map_header(ebuf, count);
} }
if(count == 0) if (count == 0)
return; return;
item = JObj->child; item = JObj->child;
while(item) { while (item) {
if(kazoo_globals.json_encoding == ERLANG_TUPLE) { if (kazoo_globals.json_encoding == ERLANG_TUPLE) {
ei_x_encode_tuple_header(ebuf, 2); ei_x_encode_tuple_header(ebuf, 2);
} }
ei_x_encode_binary(ebuf, item->string, strlen(item->string)); ei_x_encode_binary(ebuf, item->string, strlen(item->string));
switch(item->type) { switch (item->type){
case cJSON_String: case cJSON_String:
ei_x_encode_binary(ebuf, item->valuestring, strlen(item->valuestring)); ei_x_encode_binary(ebuf, item->valuestring, strlen(item->valuestring));
break; break;
case cJSON_Number: case cJSON_Number:
if ((fabs(((double)item->valueint) - item->valuedouble) <= DBL_EPSILON) if ((fabs(((double) item->valueint) - item->valuedouble) <= DBL_EPSILON) && (item->valuedouble <= INT_MAX) && (item->valuedouble >= INT_MIN)) {
&& (item->valuedouble <= INT_MAX) ei_x_encode_longlong(ebuf, item->valueint);
&& (item->valuedouble >= INT_MIN)) { } else {
ei_x_encode_longlong(ebuf, item->valueint); if (fmod(item->valuedouble, 1) == 0) {
} else { ei_x_encode_ulonglong(ebuf, item->valuedouble);
ei_x_encode_double(ebuf, item->valuedouble); } else {
} ei_x_encode_double(ebuf, item->valuedouble);
break; }
}
break;
case cJSON_True: case cJSON_True:
ei_x_encode_boolean(ebuf, 1); ei_x_encode_boolean(ebuf, 1);
break; break;
case cJSON_False: case cJSON_False:
ei_x_encode_boolean(ebuf, 0); ei_x_encode_boolean(ebuf, 0);
break; break;
case cJSON_Object: case cJSON_Object:
ei_encode_json(ebuf, item); ei_encode_json(ebuf, item);
break; break;
case cJSON_Array: case cJSON_Array:
ei_encode_json_array(ebuf, item); ei_encode_json_array(ebuf, item);
break; break;
case cJSON_Raw: case cJSON_Raw: {
{ cJSON *Decoded = cJSON_Parse(item->valuestring);
cJSON *Decoded = cJSON_Parse(item->valuestring); if (!Decoded) {
if(!Decoded) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR DECODING RAW JSON %s\n", item->valuestring);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR DECODING RAW JSON %s\n", item->valuestring); ei_x_encode_tuple_header(ebuf, 0);
ei_x_encode_tuple_header(ebuf, 0); } else {
} else { ei_encode_json(ebuf, Decoded);
ei_encode_json(ebuf, Decoded); cJSON_Delete(Decoded);
cJSON_Delete(Decoded); }
} break;
break; }
}
case cJSON_NULL: case cJSON_NULL:
ei_x_encode_atom(ebuf, "null"); ei_x_encode_atom(ebuf, "null");
break; break;
default: default:
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "NOT ENCODED %i\n", item->type); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "NOT ENCODED %i\n", item->type);
break; break;
} }
item = item->next; item = item->next;
} }
if(kazoo_globals.json_encoding == ERLANG_TUPLE) { if (kazoo_globals.json_encoding == ERLANG_TUPLE) {
ei_x_encode_empty_list(ebuf); ei_x_encode_empty_list(ebuf);
} }
} }
void close_socket(switch_socket_t ** sock) { void close_socket(switch_socket_t ** sock)
{
if (*sock) { if (*sock) {
switch_socket_shutdown(*sock, SWITCH_SHUTDOWN_READWRITE); switch_socket_shutdown(*sock, SWITCH_SHUTDOWN_READWRITE);
switch_socket_close(*sock); switch_socket_close(*sock);
@ -301,18 +308,20 @@ void close_socket(switch_socket_t ** sock) {
} }
} }
void close_socketfd(int *sockfd) { void close_socketfd(int *sockfd)
{
if (*sockfd) { if (*sockfd) {
shutdown(*sockfd, SHUT_RDWR); shutdown(*sockfd, SHUT_RDWR);
close(*sockfd); close(*sockfd);
} }
} }
switch_socket_t *create_socket_with_port(switch_memory_pool_t *pool, switch_port_t port) { switch_socket_t *create_socket_with_port(switch_memory_pool_t *pool, switch_port_t port)
{
switch_sockaddr_t *sa; switch_sockaddr_t *sa;
switch_socket_t *socket; switch_socket_t *socket;
if(switch_sockaddr_info_get(&sa, kazoo_globals.ip, SWITCH_UNSPEC, port, 0, pool)) { if (switch_sockaddr_info_get(&sa, kazoo_globals.ip, SWITCH_UNSPEC, port, 0, pool)) {
return NULL; return NULL;
} }
@ -328,7 +337,7 @@ switch_socket_t *create_socket_with_port(switch_memory_pool_t *pool, switch_port
return NULL; return NULL;
} }
if (switch_socket_listen(socket, 5)){ if (switch_socket_listen(socket, 5)) {
return NULL; return NULL;
} }
@ -339,30 +348,32 @@ switch_socket_t *create_socket_with_port(switch_memory_pool_t *pool, switch_port
return socket; return socket;
} }
switch_socket_t *create_socket(switch_memory_pool_t *pool) { switch_socket_t *create_socket(switch_memory_pool_t *pool)
{
return create_socket_with_port(pool, 0); return create_socket_with_port(pool, 0);
} }
switch_status_t create_ei_cnode(const char *ip_addr, const char *name, struct ei_cnode_s *ei_cnode) { switch_status_t create_ei_cnode(const char *ip_addr, const char *name, struct ei_cnode_s *ei_cnode)
char hostname[EI_MAXHOSTNAMELEN + 1]; {
char nodename[MAXNODELEN + 1]; char hostname[EI_MAXHOSTNAMELEN + 1];
char cnodename[EI_MAXALIVELEN + 1]; char nodename[MAXNODELEN + 1];
char *atsign; char cnodename[EI_MAXALIVELEN + 1];
char *atsign;
/* copy the erlang interface nodename into something we can modify */ /* copy the erlang interface nodename into something we can modify */
strncpy(cnodename, name, EI_MAXALIVELEN); strncpy(cnodename, name, EI_MAXALIVELEN);
if ((atsign = strchr(cnodename, '@'))) { if ((atsign = strchr(cnodename, '@'))) {
/* we got a qualified node name, don't guess the host/domain */ /* we got a qualified node name, don't guess the host/domain */
snprintf(nodename, MAXNODELEN + 1, "%s", name); snprintf(nodename, MAXNODELEN + 1, "%s", name);
/* truncate the alivename at the @ */ /* truncate the alivename at the @ */
*atsign++ = '\0'; *atsign++ = '\0';
strncpy(hostname, atsign, EI_MAXHOSTNAMELEN); strncpy(hostname, atsign, EI_MAXHOSTNAMELEN);
} else { } else {
strncpy(hostname, kazoo_globals.hostname, EI_MAXHOSTNAMELEN); strncpy(hostname, kazoo_globals.hostname, EI_MAXHOSTNAMELEN);
snprintf(nodename, MAXNODELEN + 1, "%s@%s", name, hostname); snprintf(nodename, MAXNODELEN + 1, "%s@%s", name, hostname);
} }
if (kazoo_globals.ei_shortname) { if (kazoo_globals.ei_shortname) {
char *off; char *off;
@ -373,94 +384,97 @@ switch_status_t create_ei_cnode(const char *ip_addr, const char *name, struct ei
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "creating nodename: %s\n", nodename); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "creating nodename: %s\n", nodename);
/* init the ec stuff */ /* init the ec stuff */
if (ei_connect_xinit(ei_cnode, hostname, cnodename, nodename, (Erl_IpAddr) ip_addr, kazoo_globals.ei_cookie, 0) < 0) { if (ei_connect_xinit(ei_cnode, hostname, cnodename, nodename, (Erl_IpAddr) ip_addr, kazoo_globals.ei_cookie, 0) < 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to initialize the erlang interface connection structure\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to initialize the erlang interface connection structure\n");
return SWITCH_STATUS_FALSE; return SWITCH_STATUS_FALSE;
} }
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
switch_status_t ei_compare_pids(const erlang_pid *pid1, const erlang_pid *pid2) { switch_status_t ei_compare_pids(const erlang_pid *pid1, const erlang_pid *pid2)
if ((!strcmp(pid1->node, pid2->node)) {
&& pid1->creation == pid2->creation if ((!strcmp(pid1->node, pid2->node)) && pid1->creation == pid2->creation && pid1->num == pid2->num && pid1->serial == pid2->serial) {
&& pid1->num == pid2->num return SWITCH_STATUS_SUCCESS;
&& pid1->serial == pid2->serial) { } else {
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_FALSE;
} else { }
return SWITCH_STATUS_FALSE;
}
} }
void ei_link(ei_node_t *ei_node, erlang_pid * from, erlang_pid * to) { void ei_link(ei_node_t *ei_node, erlang_pid * from, erlang_pid * to)
char msgbuf[2048]; {
char *s; char msgbuf[2048];
int index = 0; char *s;
int index = 0;
index = 5; /* max sizes: */ index = 5; /* max sizes: */
ei_encode_version(msgbuf, &index); /* 1 */ ei_encode_version(msgbuf, &index); /* 1 */
ei_encode_tuple_header(msgbuf, &index, 3); ei_encode_tuple_header(msgbuf, &index, 3);
ei_encode_long(msgbuf, &index, ERL_LINK); ei_encode_long(msgbuf, &index, ERL_LINK);
ei_encode_pid(msgbuf, &index, from); /* 268 */ ei_encode_pid(msgbuf, &index, from); /* 268 */
ei_encode_pid(msgbuf, &index, to); /* 268 */ ei_encode_pid(msgbuf, &index, to); /* 268 */
/* 5 byte header missing */ /* 5 byte header missing */
s = msgbuf; s = msgbuf;
put32be(s, index - 4); /* 4 */ put32be(s, index - 4); /* 4 */
put8(s, ERL_PASS_THROUGH); /* 1 */ put8(s, ERL_PASS_THROUGH); /* 1 */
/* sum: 542 */ /* sum: 542 */
if (write(ei_node->nodefd, msgbuf, index) == -1) { if (write(ei_node->nodefd, msgbuf, index) == -1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to link to process on %s\n", ei_node->peer_nodename); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to link to process on %s\n", ei_node->peer_nodename);
} }
} }
void ei_encode_switch_event(ei_x_buff *ebuf, switch_event_t *event) { void ei_encode_switch_event(ei_x_buff *ebuf, switch_event_t *event)
ei_x_encode_tuple_header(ebuf, 2); {
ei_x_encode_atom(ebuf, "event"); ei_x_encode_tuple_header(ebuf, 2);
ei_encode_switch_event_headers(ebuf, event); ei_x_encode_atom(ebuf, "event");
ei_encode_switch_event_headers(ebuf, event);
} }
int ei_helper_send(ei_node_t *ei_node, erlang_pid *to, ei_x_buff *buf) { int ei_helper_send(ei_node_t *ei_node, erlang_pid *to, ei_x_buff *buf)
int ret = 0; {
int ret = 0;
if (ei_node->nodefd) { if (ei_node->nodefd) {
#ifdef EI_DEBUG #ifdef EI_DEBUG
ei_x_print_msg(buf, to, 1); ei_x_print_msg(buf, to, 1);
#endif #endif
ret = ei_send(ei_node->nodefd, to, buf->buff, buf->index); ret = ei_send(ei_node->nodefd, to, buf->buff, buf->index);
} }
return ret; return ret;
} }
int ei_decode_atom_safe(char *buf, int *index, char *dst) { int ei_decode_atom_safe(char *buf, int *index, char *dst)
int type, size; {
int type, size;
ei_get_type(buf, index, &type, &size); ei_get_type(buf, index, &type, &size);
if (type != ERL_ATOM_EXT) { if (type != ERL_ATOM_EXT) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unexpected erlang term type %d (size %d), needed atom\n", type, size); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unexpected erlang term type %d (size %d), needed atom\n", type, size);
return -1; return -1;
} else if (size > MAXATOMLEN) { } else if (size > MAXATOMLEN) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Requested decoding of atom with size %d into a buffer of size %d\n", size, MAXATOMLEN); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Requested decoding of atom with size %d into a buffer of size %d\n", size, MAXATOMLEN);
return -1; return -1;
} else { } else {
return ei_decode_atom(buf, index, dst); return ei_decode_atom(buf, index, dst);
} }
} }
int ei_decode_string_or_binary(char *buf, int *index, char **dst) { int ei_decode_string_or_binary(char *buf, int *index, char **dst)
int type, size, res; {
long len; int type, size, res;
long len;
ei_get_type(buf, index, &type, &size); ei_get_type(buf, index, &type, &size);
if (type != ERL_STRING_EXT && type != ERL_BINARY_EXT && type != ERL_LIST_EXT && type != ERL_NIL_EXT) { if (type != ERL_STRING_EXT && type != ERL_BINARY_EXT && type != ERL_LIST_EXT && type != ERL_NIL_EXT) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unexpected erlang term type %d (size %d), needed binary or string\n", type, size); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unexpected erlang term type %d (size %d), needed binary or string\n", type, size);
return -1; return -1;
} }
*dst = malloc(size + 1); *dst = malloc(size + 1);
@ -468,29 +482,30 @@ int ei_decode_string_or_binary(char *buf, int *index, char **dst) {
res = 0; res = 0;
**dst = '\0'; **dst = '\0';
} else if (type == ERL_BINARY_EXT) { } else if (type == ERL_BINARY_EXT) {
res = ei_decode_binary(buf, index, *dst, &len); res = ei_decode_binary(buf, index, *dst, &len);
(*dst)[len] = '\0'; (*dst)[len] = '\0';
} else { } else {
res = ei_decode_string(buf, index, *dst); res = ei_decode_string(buf, index, *dst);
} }
return res; return res;
} }
int ei_decode_string_or_binary_limited(char *buf, int *index, int maxsize, char *dst) { int ei_decode_string_or_binary_limited(char *buf, int *index, int maxsize, char *dst)
int type, size, res; {
long len; int type, size, res;
long len;
ei_get_type(buf, index, &type, &size); ei_get_type(buf, index, &type, &size);
if (type != ERL_STRING_EXT && type != ERL_BINARY_EXT && type != ERL_LIST_EXT && type != ERL_NIL_EXT) { if (type != ERL_STRING_EXT && type != ERL_BINARY_EXT && type != ERL_LIST_EXT && type != ERL_NIL_EXT) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unexpected erlang term type %d (size %d), needed binary or string\n", type, size); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unexpected erlang term type %d (size %d), needed binary or string\n", type, size);
return -1; return -1;
} }
if (size > maxsize) { if (size > maxsize) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Requested decoding of %s with size %d into a buffer of size %d\n", switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Requested decoding of %s with size %d into a buffer of size %d\n",
type == ERL_BINARY_EXT ? "binary" : "string", size, maxsize); type == ERL_BINARY_EXT ? "binary" : "string", size, maxsize);
return -1; return -1;
} }
@ -498,21 +513,21 @@ int ei_decode_string_or_binary_limited(char *buf, int *index, int maxsize, char
res = 0; res = 0;
*dst = '\0'; *dst = '\0';
} else if (type == ERL_BINARY_EXT) { } else if (type == ERL_BINARY_EXT) {
res = ei_decode_binary(buf, index, dst, &len); res = ei_decode_binary(buf, index, dst, &len);
dst[len] = '\0'; /* binaries aren't null terminated */ dst[len] = '\0'; /* binaries aren't null terminated */
} else { } else {
res = ei_decode_string(buf, index, dst); res = ei_decode_string(buf, index, dst);
} }
return res; return res;
} }
switch_status_t create_acceptor()
switch_status_t create_acceptor() { {
switch_sockaddr_t *sa; switch_sockaddr_t *sa;
uint16_t port; uint16_t port;
char ipbuf[48]; char ipbuf[48];
const char *ip_addr; const char *ip_addr;
/* if the config has specified an erlang release compatibility then pass that along to the erlang interface */ /* if the config has specified an erlang release compatibility then pass that along to the erlang interface */
if (kazoo_globals.ei_compat_rel) { if (kazoo_globals.ei_compat_rel) {
@ -527,7 +542,7 @@ switch_status_t create_acceptor() {
switch_socket_addr_get(&sa, SWITCH_FALSE, kazoo_globals.acceptor); switch_socket_addr_get(&sa, SWITCH_FALSE, kazoo_globals.acceptor);
port = switch_sockaddr_get_port(sa); port = switch_sockaddr_get_port(sa);
ip_addr = switch_get_addr(ipbuf, sizeof (ipbuf), sa); ip_addr = switch_get_addr(ipbuf, sizeof(ipbuf), sa);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Erlang connection acceptor listening on %s:%u\n", ip_addr, port); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Erlang connection acceptor listening on %s:%u\n", ip_addr, port);
@ -541,7 +556,7 @@ switch_status_t create_acceptor() {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to publish port to epmd, trying to start epmd via system()\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to publish port to epmd, trying to start epmd via system()\n");
if (system("fs_epmd -daemon")) { if (system("fs_epmd -daemon")) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
"Failed to start epmd manually! Is epmd in $PATH? If not, start it yourself or run an erl shell with -sname or -name\n"); "Failed to start epmd manually! Is epmd in $PATH? If not, start it yourself or run an erl shell with -sname or -name\n");
return SWITCH_STATUS_SOCKERR; return SWITCH_STATUS_SOCKERR;
} }
switch_yield(100000); switch_yield(100000);
@ -551,12 +566,14 @@ switch_status_t create_acceptor() {
} }
} }
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connected to epmd and published erlang cnode name %s at port %d\n", kazoo_globals.ei_cnode.thisnodename, port); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connected to epmd and published erlang cnode name %s at port %d\n", kazoo_globals.ei_cnode.thisnodename,
port);
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
switch_hash_t *create_default_filter() { switch_hash_t *create_default_filter()
{
switch_hash_t *filter; switch_hash_t *filter;
switch_core_hash_init(&filter); switch_core_hash_init(&filter);
@ -904,7 +921,7 @@ static void fetch_config_handlers(switch_memory_pool_t *pool)
static void *SWITCH_THREAD_FUNC fetch_config_exec(switch_thread_t *thread, void *obj) static void *SWITCH_THREAD_FUNC fetch_config_exec(switch_thread_t *thread, void *obj)
{ {
switch_memory_pool_t *pool = (switch_memory_pool_t *)obj; switch_memory_pool_t *pool = (switch_memory_pool_t *) obj;
fetch_config_filters(pool); fetch_config_filters(pool);
fetch_config_handlers(pool); fetch_config_handlers(pool);
@ -913,13 +930,13 @@ static void *SWITCH_THREAD_FUNC fetch_config_exec(switch_thread_t *thread, void
return NULL; return NULL;
} }
void fetch_config() { void fetch_config()
{
switch_memory_pool_t *pool; switch_memory_pool_t *pool;
switch_thread_t *thread; switch_thread_t *thread;
switch_threadattr_t *thd_attr = NULL; switch_threadattr_t *thd_attr = NULL;
switch_uuid_t uuid; switch_uuid_t uuid;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "fetching kazoo config\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "fetching kazoo config\n");
switch_core_new_memory_pool(&pool); switch_core_new_memory_pool(&pool);
@ -935,35 +952,35 @@ void fetch_config() {
#ifdef WITH_KAZOO_ERL_SHUTDOWN #ifdef WITH_KAZOO_ERL_SHUTDOWN
#if (ERLANG_MAJOR == 10 && ERLANG_MINOR >= 3) || ERLANG_MAJOR >= 11 #if (ERLANG_MAJOR == 10 && ERLANG_MINOR >= 3) || ERLANG_MAJOR >= 11
typedef struct ei_mutex_s { typedef struct ei_mutex_s {
#ifdef __WIN32__ #ifdef __WIN32__
HANDLE lock; HANDLE lock;
#elif VXWORKS #elif VXWORKS
SEM_ID lock; SEM_ID lock;
#else /* unix */ #else /* unix */
#if defined(HAVE_MIT_PTHREAD_H) || defined(HAVE_PTHREAD_H) #if defined(HAVE_MIT_PTHREAD_H) || defined(HAVE_PTHREAD_H)
pthread_mutex_t *lock; pthread_mutex_t *lock;
#else /* ! (HAVE_MIT_PTHREAD_H || HAVE_PTHREAD_H) */ #else /* ! (HAVE_MIT_PTHREAD_H || HAVE_PTHREAD_H) */
void *dummy; /* Actually never used */ void *dummy; /* Actually never used */
#endif /* ! (HAVE_MIT_PTHREAD_H || HAVE_PTHREAD_H) */ #endif /* ! (HAVE_MIT_PTHREAD_H || HAVE_PTHREAD_H) */
#endif /* unix */ #endif /* unix */
} ei_mutex_t; }ei_mutex_t;
typedef struct ei_socket_info_s { typedef struct ei_socket_info_s {
int socket; int socket;
ei_socket_callbacks *cbs; ei_socket_callbacks *cbs;
void *ctx; void *ctx;
int dist_version; int dist_version;
ei_cnode cnode; /* A copy, not a pointer. We don't know when freed */ ei_cnode cnode; /* A copy, not a pointer. We don't know when freed */
char cookie[EI_MAX_COOKIE_SIZE+1]; char cookie[EI_MAX_COOKIE_SIZE+1];
} ei_socket_info; }ei_socket_info;
extern ei_socket_info *ei_sockets; extern ei_socket_info *ei_sockets;
extern ei_mutex_t* ei_sockets_lock; extern ei_mutex_t* ei_sockets_lock;
extern int ei_n_sockets; extern int ei_n_sockets;
extern int ei_sz_sockets; extern int ei_sz_sockets;
int ei_mutex_free(ei_mutex_t *l, int nblock); int ei_mutex_free(ei_mutex_t *l, int nblock);
#endif #endif
#endif #endif
@ -988,10 +1005,11 @@ void kz_erl_shutdown()
#endif #endif
} }
SWITCH_MODULE_RUNTIME_FUNCTION(mod_kazoo_runtime) { SWITCH_MODULE_RUNTIME_FUNCTION(mod_kazoo_runtime)
{
switch_os_socket_t os_socket; switch_os_socket_t os_socket;
if(create_acceptor() != SWITCH_STATUS_SUCCESS) { if (create_acceptor() != SWITCH_STATUS_SUCCESS) {
// TODO: what would we need to clean up here // TODO: what would we need to clean up here
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to create erlang connection acceptor!\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to create erlang connection acceptor!\n");
close_socket(&kazoo_globals.acceptor); close_socket(&kazoo_globals.acceptor);
@ -1018,7 +1036,7 @@ SWITCH_MODULE_RUNTIME_FUNCTION(mod_kazoo_runtime) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Erlang connection acceptor socket error %d %d\n", erl_errno, errno); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Erlang connection acceptor socket error %d %d\n", erl_errno, errno);
} else { } else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"Erlang node connection failed - ensure your cookie matches '%s' and you are using a good nodename\n", kazoo_globals.ei_cookie); "Erlang node connection failed - ensure your cookie matches '%s' and you are using a good nodename\n", kazoo_globals.ei_cookie);
} }
continue; continue;
} }

View File

@ -271,7 +271,7 @@ static switch_call_cause_t kz_endpoint_outgoing_channel(switch_core_session_t *s
} else if(var_event) { } else if(var_event) {
const char* uuid_e_session = switch_event_get_header(var_event, "ent_originate_aleg_uuid"); const char* uuid_e_session = switch_event_get_header(var_event, "ent_originate_aleg_uuid");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CHECKING ORIGINATE-UUID : %s\n", uuid_e_session); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CHECKING ORIGINATE-UUID : %s\n", uuid_e_session);
if (uuid_e_session && (e_session = switch_core_session_force_locate(uuid_e_session)) != NULL) { if (uuid_e_session && (e_session = switch_core_session_locate(uuid_e_session)) != NULL) {
a_session = e_session; a_session = e_session;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FOUND ORIGINATE-UUID : %s\n", uuid_e_session); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FOUND ORIGINATE-UUID : %s\n", uuid_e_session);
} }

View File

@ -202,14 +202,17 @@ static void event_handler(switch_event_t *event) {
ei_x_encode_version(ebuf); ei_x_encode_version(ebuf);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Target-Node", event_binding->stream->node->peer_nodename); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Target-Node", event_binding->stream->node->peer_nodename);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Switch-Nodename", kazoo_globals.ei_cnode.thisnodename);
if(event_stream->node->legacy) { if(event_stream->node->legacy) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Switch-Nodename", kazoo_globals.ei_cnode.thisnodename);
res = encode_event_old(event, ebuf); res = encode_event_old(event, ebuf);
} else { } else {
res = encode_event_new(event, ebuf); res = encode_event_new(event, ebuf);
} }
switch_event_del_header(event, "Switch-Nodename");
switch_event_del_header(event, "Target-Node");
if(!res) { if(!res) {
ei_x_free(ebuf); ei_x_free(ebuf);
switch_safe_free(ebuf); switch_safe_free(ebuf);
@ -391,7 +394,7 @@ ei_event_stream_t *new_event_stream(ei_node_t *ei_node, const erlang_pid *from)
/* from the memory pool, allocate the event stream structure */ /* from the memory pool, allocate the event stream structure */
if (!(event_stream = switch_core_alloc(pool, sizeof (*event_stream)))) { if (!(event_stream = switch_core_alloc(pool, sizeof (*event_stream)))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Out of memory: I may have Alzheimers but at least I dont have Alzheimers.\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Out of memory: I may have Alzheimers but at least I dont have Alzheimers.\n");
return NULL; goto cleanup;
} }
/* prepare the event stream */ /* prepare the event stream */
@ -408,28 +411,24 @@ ei_event_stream_t *new_event_stream(ei_node_t *ei_node, const erlang_pid *from)
/* create a socket for accepting the event stream client */ /* create a socket for accepting the event stream client */
if (!(event_stream->acceptor = create_socket(pool))) { if (!(event_stream->acceptor = create_socket(pool))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Like car accidents, most hardware problems are due to driver error.\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Like car accidents, most hardware problems are due to driver error.\n");
/* TODO: clean up */ goto cleanup;
return NULL;
} }
if (switch_socket_opt_set(event_stream->acceptor, SWITCH_SO_NONBLOCK, TRUE)) { if (switch_socket_opt_set(event_stream->acceptor, SWITCH_SO_NONBLOCK, TRUE)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Hey, it compiles!\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Hey, it compiles!\n");
/* TODO: clean up */ goto cleanup;
return NULL;
} }
/* create a pollset so we can efficiently check for new client connections */ /* create a pollset so we can efficiently check for new client connections */
if (switch_pollset_create(&event_stream->pollset, 1000, pool, 0) != SWITCH_STATUS_SUCCESS) { if (switch_pollset_create(&event_stream->pollset, 1000, pool, 0) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "My software never has bugs. It just develops random features.\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "My software never has bugs. It just develops random features.\n");
/* TODO: clean up */ goto cleanup;
return NULL;
} }
switch_socket_create_pollfd(&event_stream->pollfd, event_stream->acceptor, SWITCH_POLLIN | SWITCH_POLLERR, NULL, pool); switch_socket_create_pollfd(&event_stream->pollfd, event_stream->acceptor, SWITCH_POLLIN | SWITCH_POLLERR, NULL, pool);
if (switch_pollset_add(event_stream->pollset, event_stream->pollfd) != SWITCH_STATUS_SUCCESS) { if (switch_pollset_add(event_stream->pollset, event_stream->pollfd) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "If you saw a heat wave, would you wave back?\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "If you saw a heat wave, would you wave back?\n");
/* TODO: clean up */ goto cleanup;
return NULL;
} }
switch_mutex_init(&event_stream->socket_mutex, SWITCH_MUTEX_DEFAULT, pool); switch_mutex_init(&event_stream->socket_mutex, SWITCH_MUTEX_DEFAULT, pool);
@ -454,6 +453,26 @@ ei_event_stream_t *new_event_stream(ei_node_t *ei_node, const erlang_pid *from)
switch_thread_create(&thread, thd_attr, event_stream_loop, event_stream, event_stream->pool); switch_thread_create(&thread, thd_attr, event_stream_loop, event_stream, event_stream->pool);
return event_stream; return event_stream;
cleanup:
if (event_stream) {
/* remove the acceptor pollset */
if (event_stream->pollset) {
switch_pollset_remove(event_stream->pollset, event_stream->pollfd);
}
/* close any open sockets */
if (event_stream->acceptor) {
close_socket(&event_stream->acceptor);
}
}
/* clean up the memory */
switch_core_destroy_memory_pool(&pool);
return NULL;
} }
unsigned long get_stream_port(const ei_event_stream_t *event_stream) { unsigned long get_stream_port(const ei_event_stream_t *event_stream) {

View File

@ -154,6 +154,8 @@ static switch_xml_t fetch_handler(const char *section, const char *tag_name, con
} }
} }
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Switch-Nodename", kazoo_globals.ei_cnode.thisnodename);
/* prepare the reply collector */ /* prepare the reply collector */
switch_uuid_get(&uuid); switch_uuid_get(&uuid);
switch_uuid_format(reply.uuid_str, &uuid); switch_uuid_format(reply.uuid_str, &uuid);
@ -165,7 +167,7 @@ static switch_xml_t fetch_handler(const char *section, const char *tag_name, con
for(i = 0; fetch_uuid_sources[i] != NULL; i++) { for(i = 0; fetch_uuid_sources[i] != NULL; i++) {
if((fetch_call_id = switch_event_get_header(event, fetch_uuid_sources[i])) != NULL) { if((fetch_call_id = switch_event_get_header(event, fetch_uuid_sources[i])) != NULL) {
switch_core_session_t *session = NULL; switch_core_session_t *session = NULL;
if((session = switch_core_session_force_locate(fetch_call_id)) != NULL) { if((session = switch_core_session_locate(fetch_call_id)) != NULL) {
switch_channel_t *channel = switch_core_session_get_channel(session); switch_channel_t *channel = switch_core_session_get_channel(session);
uint32_t verbose = switch_channel_test_flag(channel, CF_VERBOSE_EVENTS); uint32_t verbose = switch_channel_test_flag(channel, CF_VERBOSE_EVENTS);
switch_channel_set_flag(channel, CF_VERBOSE_EVENTS); switch_channel_set_flag(channel, CF_VERBOSE_EVENTS);

View File

@ -55,6 +55,10 @@ struct kazoo_log_levels
switch_log_level_t time_log_level; switch_log_level_t time_log_level;
switch_log_level_t filtered_event_log_level; switch_log_level_t filtered_event_log_level;
switch_log_level_t filtered_field_log_level; switch_log_level_t filtered_field_log_level;
switch_log_level_t trace_log_level;
switch_log_level_t debug_log_level;
switch_log_level_t error_log_level;
switch_log_level_t hashing_log_level;
}; };
@ -138,6 +142,7 @@ struct kazoo_field_t {
switch_bool_t exclude_prefix; switch_bool_t exclude_prefix;
kazoo_field_type in_type; kazoo_field_type in_type;
kazoo_json_field_type out_type; kazoo_json_field_type out_type;
int out_type_as_array;
kazoo_filter_ptr filter; kazoo_filter_ptr filter;
kazoo_definition_ptr ref; kazoo_definition_ptr ref;
@ -162,6 +167,7 @@ struct kazoo_event {
char *name; char *name;
kazoo_fields_ptr fields; kazoo_fields_ptr fields;
kazoo_filter_ptr filter; kazoo_filter_ptr filter;
kazoo_loglevels_ptr logging;
kazoo_event_t* next; kazoo_event_t* next;
}; };

View File

@ -45,7 +45,7 @@ void kazoo_cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item)
cJSON_AddItemToObject(object, string, item); cJSON_AddItemToObject(object, string, item);
} }
static int inline filter_compare(switch_event_t* evt, kazoo_filter_ptr filter) static int inline filter_compare(switch_event_t* evt, kazoo_filter_ptr filter, kazoo_logging_ptr logging)
{ {
switch_event_header_t *header; switch_event_header_t *header;
int hasValue = 0, n; int hasValue = 0, n;
@ -55,6 +55,7 @@ static int inline filter_compare(switch_event_t* evt, kazoo_filter_ptr filter)
case FILTER_COMPARE_EXISTS: case FILTER_COMPARE_EXISTS:
hasValue = switch_event_get_header(evt, filter->name) != NULL ? 1 : 0; hasValue = switch_event_get_header(evt, filter->name) != NULL ? 1 : 0;
switch_log_printf(SWITCH_CHANNEL_LOG, logging->levels->trace_log_level, "profile[%s] event %s checking if %s exists => %s\n", logging->profile_name, logging->event_name, filter->name, hasValue ? "true" : "false");
break; break;
case FILTER_COMPARE_VALUE: case FILTER_COMPARE_VALUE:
@ -64,6 +65,7 @@ static int inline filter_compare(switch_event_t* evt, kazoo_filter_ptr filter)
value = switch_event_get_header(evt, filter->name); value = switch_event_get_header(evt, filter->name);
} }
hasValue = value ? !strcmp(value, filter->value) : 0; hasValue = value ? !strcmp(value, filter->value) : 0;
switch_log_printf(SWITCH_CHANNEL_LOG, logging->levels->trace_log_level, "profile[%s] event %s compare value %s to %s => %s == %s => %s\n", logging->profile_name, logging->event_name, filter->name, filter->value, value, filter->value, hasValue ? "true" : "false");
break; break;
case FILTER_COMPARE_FIELD: case FILTER_COMPARE_FIELD:
@ -73,6 +75,7 @@ static int inline filter_compare(switch_event_t* evt, kazoo_filter_ptr filter)
value = switch_event_get_header(evt, filter->name); value = switch_event_get_header(evt, filter->name);
} }
hasValue = value ? !strcmp(value, switch_event_get_header_nil(evt, filter->value)) : 0; hasValue = value ? !strcmp(value, switch_event_get_header_nil(evt, filter->value)) : 0;
switch_log_printf(SWITCH_CHANNEL_LOG, logging->levels->trace_log_level, "profile[%s] event %s compare field %s to %s => %s == %s => %s\n", logging->profile_name, logging->event_name, filter->name, filter->value, value, switch_event_get_header_nil(evt, filter->value), hasValue ? "true" : "false");
break; break;
case FILTER_COMPARE_PREFIX: case FILTER_COMPARE_PREFIX:
@ -112,10 +115,10 @@ static int inline filter_compare(switch_event_t* evt, kazoo_filter_ptr filter)
return hasValue; return hasValue;
} }
static kazoo_filter_ptr inline filter_event(switch_event_t* evt, kazoo_filter_ptr filter) static kazoo_filter_ptr inline filter_event(switch_event_t* evt, kazoo_filter_ptr filter, kazoo_logging_ptr logging)
{ {
while(filter) { while(filter) {
int hasValue = filter_compare(evt, filter); int hasValue = filter_compare(evt, filter, logging);
if(filter->type == FILTER_EXCLUDE) { if(filter->type == FILTER_EXCLUDE) {
if(hasValue) if(hasValue)
break; break;
@ -132,31 +135,37 @@ static void kazoo_event_init_json_fields(switch_event_t *event, cJSON *json)
{ {
switch_event_header_t *hp; switch_event_header_t *hp;
for (hp = event->headers; hp; hp = hp->next) { for (hp = event->headers; hp; hp = hp->next) {
if (hp->idx) { if (strncmp(hp->name, "_json_", 6)) {
cJSON *a = cJSON_CreateArray(); if (hp->idx) {
int i; cJSON *a = cJSON_CreateArray();
int i;
for(i = 0; i < hp->idx; i++) { for(i = 0; i < hp->idx; i++) {
cJSON_AddItemToArray(a, cJSON_CreateString(hp->array[i])); cJSON_AddItemToArray(a, cJSON_CreateString(hp->array[i]));
}
cJSON_AddItemToObject(json, hp->name, a);
} else {
cJSON_AddItemToObject(json, hp->name, cJSON_CreateString(hp->value));
} }
cJSON_AddItemToObject(json, hp->name, a);
} else {
cJSON_AddItemToObject(json, hp->name, cJSON_CreateString(hp->value));
} }
} }
} }
static switch_status_t kazoo_event_init_json(kazoo_fields_ptr fields1, kazoo_fields_ptr fields2, switch_event_t* evt, cJSON** clone) static switch_status_t kazoo_event_init_json(kazoo_fields_ptr fields1, kazoo_fields_ptr fields2, switch_event_t* evt, cJSON** clone)
{ {
switch_status_t status; switch_status_t status = SWITCH_STATUS_SUCCESS;
if( (fields2 && fields2->verbose) if( (fields2 && fields2->verbose)
|| (fields1 && fields1->verbose) || (fields1 && fields1->verbose)
|| ( (!fields2) && (!fields1)) ) { || ( (!fields2) && (!fields1)) ) {
status = switch_event_serialize_json_obj(evt, clone); *clone = cJSON_CreateObject();
if((*clone) == NULL) {
status = SWITCH_STATUS_GENERR;
} else {
kazoo_event_init_json_fields(evt, *clone);
}
} else { } else {
status = SWITCH_STATUS_SUCCESS;
*clone = cJSON_CreateObject(); *clone = cJSON_CreateObject();
if((*clone) == NULL) { if((*clone) == NULL) {
status = SWITCH_STATUS_GENERR; status = SWITCH_STATUS_GENERR;
@ -185,7 +194,11 @@ static cJSON * kazoo_event_json_value(kazoo_json_field_type type, const char *va
break; break;
case JSON_RAW: case JSON_RAW:
item = cJSON_CreateRaw(value); item = cJSON_Parse(value);
if (!item) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "parse from raw error!\n");
item = cJSON_CreateRaw(value);
}
break; break;
default: default:
@ -210,18 +223,24 @@ cJSON * kazoo_event_add_field_to_json(cJSON *dst, switch_event_t *src, kazoo_fie
{ {
switch_event_header_t *header; switch_event_header_t *header;
char *expanded; char *expanded;
uint i, n; int i, n;
cJSON *item = NULL; cJSON *item = NULL;
switch(field->in_type) { switch(field->in_type) {
case FIELD_COPY: case FIELD_COPY:
if((header = switch_event_get_header_ptr(src, field->name)) != NULL) { if (!strcmp(field->name, "_body")) {
item = kazoo_event_add_json_value(dst, field, field->as ? field->as : field->name, src->body);
} else if((header = switch_event_get_header_ptr(src, field->name)) != NULL) {
if (header->idx) { if (header->idx) {
item = cJSON_CreateArray(); item = cJSON_CreateArray();
for(i = 0; i < header->idx; i++) { for(i = 0; i < header->idx; i++) {
cJSON_AddItemToArray(item, kazoo_event_json_value(field->out_type, header->array[i])); cJSON_AddItemToArray(item, kazoo_event_json_value(field->out_type, header->array[i]));
} }
kazoo_cJSON_AddItemToObject(dst, field->as ? field->as : field->name, item); kazoo_cJSON_AddItemToObject(dst, field->as ? field->as : field->name, item);
} else if (field->out_type_as_array) {
item = cJSON_CreateArray();
cJSON_AddItemToArray(item, kazoo_event_json_value(field->out_type, header->value));
kazoo_cJSON_AddItemToObject(dst, field->as ? field->as : field->name, item);
} else { } else {
item = kazoo_event_add_json_value(dst, field, field->as ? field->as : field->name, header->value); item = kazoo_event_add_json_value(dst, field, field->as ? field->as : field->name, header->value);
} }
@ -299,7 +318,7 @@ static switch_status_t kazoo_event_add_fields_to_json(kazoo_logging_ptr logging,
while(field) { while(field) {
if(field->in_type == FIELD_REFERENCE) { if(field->in_type == FIELD_REFERENCE) {
if(field->ref) { if(field->ref) {
if((filter = filter_event(src, field->ref->filter)) != NULL) { if((filter = filter_event(src, field->ref->filter, logging)) != NULL) {
switch_log_printf(SWITCH_CHANNEL_LOG, logging->levels->filtered_field_log_level, "profile[%s] event %s, referenced field %s filtered by settings %s : %s\n", logging->profile_name, logging->event_name, field->ref->name, filter->name, filter->value); switch_log_printf(SWITCH_CHANNEL_LOG, logging->levels->filtered_field_log_level, "profile[%s] event %s, referenced field %s filtered by settings %s : %s\n", logging->profile_name, logging->event_name, field->ref->name, filter->name, filter->value);
} else { } else {
kazoo_event_add_fields_to_json(logging, dst, src, field->ref->head); kazoo_event_add_fields_to_json(logging, dst, src, field->ref->head);
@ -308,7 +327,7 @@ static switch_status_t kazoo_event_add_fields_to_json(kazoo_logging_ptr logging,
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "profile[%s] event %s, referenced field %s not found\n", logging->profile_name, logging->event_name, field->name); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "profile[%s] event %s, referenced field %s not found\n", logging->profile_name, logging->event_name, field->name);
} }
} else { } else {
if((filter = filter_event(src, field->filter)) != NULL) { if((filter = filter_event(src, field->filter, logging)) != NULL) {
switch_log_printf(SWITCH_CHANNEL_LOG, logging->levels->filtered_field_log_level, "profile[%s] event %s, field %s filtered by settings %s : %s\n", logging->profile_name, logging->event_name, field->name, filter->name, filter->value); switch_log_printf(SWITCH_CHANNEL_LOG, logging->levels->filtered_field_log_level, "profile[%s] event %s, field %s filtered by settings %s : %s\n", logging->profile_name, logging->event_name, field->name, filter->name, filter->value);
} else { } else {
item = kazoo_event_add_field_to_json(dst, src, field); item = kazoo_event_add_field_to_json(dst, src, field);
@ -351,12 +370,9 @@ kazoo_message_ptr kazoo_message_create_event(switch_event_t* evt, kazoo_event_pt
kazoo_logging_t logging; kazoo_logging_t logging;
logging.levels = profile->logging; logging.levels = profile->logging;
logging.event_name = switch_event_get_header_nil(evt, "Event-Name"); logging.event_name = evt->subclass_name ? evt->subclass_name : switch_event_get_header_nil(evt, "Event-Name");
logging.profile_name = profile->name; logging.profile_name = profile->name;
switch_event_add_header_string(evt, SWITCH_STACK_BOTTOM, "Switch-Nodename", kazoo_globals.ei_cnode.thisnodename);
message = malloc(sizeof(kazoo_message_t)); message = malloc(sizeof(kazoo_message_t));
if(message == NULL) { if(message == NULL) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error allocating memory for serializing event to json\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error allocating memory for serializing event to json\n");
@ -366,15 +382,19 @@ kazoo_message_ptr kazoo_message_create_event(switch_event_t* evt, kazoo_event_pt
if(profile->filter) { if(profile->filter) {
// filtering // filtering
if((filtered = filter_event(evt, profile->filter)) != NULL) { if((filtered = filter_event(evt, profile->filter, &logging)) != NULL) {
switch_log_printf(SWITCH_CHANNEL_LOG, logging.levels->filtered_event_log_level, "profile[%s] event %s filtered by profile settings %s : %s\n", logging.profile_name, logging.event_name, filtered->name, filtered->value); switch_log_printf(SWITCH_CHANNEL_LOG, logging.levels->filtered_event_log_level, "profile[%s] event %s filtered by profile settings %s : %s\n", logging.profile_name, logging.event_name, filtered->name, filtered->value);
kazoo_message_destroy(&message); kazoo_message_destroy(&message);
return NULL; return NULL;
} }
} }
if(event && event->filter) { if (event->logging) {
if((filtered = filter_event(evt, event->filter)) != NULL) { logging.levels = event->logging;
}
if (event && event->filter) {
if((filtered = filter_event(evt, event->filter, &logging)) != NULL) {
switch_log_printf(SWITCH_CHANNEL_LOG, logging.levels->filtered_event_log_level, "profile[%s] event %s filtered by event settings %s : %s\n", logging.profile_name, logging.event_name, filtered->name, filtered->value); switch_log_printf(SWITCH_CHANNEL_LOG, logging.levels->filtered_event_log_level, "profile[%s] event %s filtered by event settings %s : %s\n", logging.profile_name, logging.event_name, filtered->name, filtered->value);
kazoo_message_destroy(&message); kazoo_message_destroy(&message);
return NULL; return NULL;
@ -409,8 +429,6 @@ kazoo_message_ptr kazoo_message_create_fetch(switch_event_t* evt, kazoo_fetch_pr
logging.event_name = switch_event_get_header_nil(evt, "Event-Name"); logging.event_name = switch_event_get_header_nil(evt, "Event-Name");
logging.profile_name = profile->name; logging.profile_name = profile->name;
switch_event_add_header_string(evt, SWITCH_STACK_BOTTOM, "Switch-Nodename", kazoo_globals.ei_cnode.thisnodename);
message = malloc(sizeof(kazoo_message_t)); message = malloc(sizeof(kazoo_message_t));
if(message == NULL) { if(message == NULL) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error allocating memory for serializing event to json\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error allocating memory for serializing event to json\n");

View File

@ -208,15 +208,13 @@ SWITCH_DECLARE(switch_status_t) kazoo_api_execute(const char *cmd, const char *a
char *arg_used; char *arg_used;
char *cmd_used; char *cmd_used;
int fire_event = 0; int fire_event = 0;
char *arg_expanded; char *arg_expanded = NULL;
switch_event_t* evt; switch_event_t* evt;
switch_assert(stream != NULL); switch_assert(stream != NULL);
switch_assert(stream->data != NULL); switch_assert(stream->data != NULL);
switch_assert(stream->write_function != NULL); switch_assert(stream->write_function != NULL);
arg_expanded = (char *) arg;
switch_event_create(&evt, SWITCH_EVENT_GENERAL); switch_event_create(&evt, SWITCH_EVENT_GENERAL);
arg_expanded = switch_event_expand_headers(evt, arg); arg_expanded = switch_event_expand_headers(evt, arg);
switch_event_destroy(&evt); switch_event_destroy(&evt);
@ -507,7 +505,7 @@ static switch_status_t build_event(switch_event_t *event, ei_x_buff * buf) {
if(!strcasecmp(key, "Call-ID")) { if(!strcasecmp(key, "Call-ID")) {
switch_core_session_t *session = NULL; switch_core_session_t *session = NULL;
if(!zstr(value)) { if(!zstr(value)) {
if ((session = switch_core_session_force_locate(value)) != NULL) { if ((session = switch_core_session_locate(value)) != NULL) {
switch_channel_t *channel = switch_core_session_get_channel(session); switch_channel_t *channel = switch_core_session_get_channel(session);
switch_channel_event_set_data(channel, event); switch_channel_event_set_data(channel, event);
switch_core_session_rwunlock(session); switch_core_session_rwunlock(session);

View File

@ -102,10 +102,10 @@ static void kz_tweaks_handle_bridge_variables(switch_event_t *event)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "tweak bridge event handler: variables : %s , %s\n", a_leg, b_leg); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "tweak bridge event handler: variables : %s , %s\n", a_leg, b_leg);
if (a_leg && (a_session = switch_core_session_force_locate(a_leg)) != NULL) { if (a_leg && (a_session = switch_core_session_locate(a_leg)) != NULL) {
switch_channel_t *a_channel = switch_core_session_get_channel(a_session); 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(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) { if(b_leg && (b_session = switch_core_session_locate(b_leg)) != NULL) {
switch_channel_t *b_channel = switch_core_session_get_channel(b_session); switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
for(i = 0; bridge_variables[i] != NULL; i++) { for(i = 0; bridge_variables[i] != NULL; i++) {
const char *val = switch_channel_get_variable_dup(b_channel, bridge_variables[i], SWITCH_FALSE, -1); const char *val = switch_channel_get_variable_dup(b_channel, bridge_variables[i], SWITCH_FALSE, -1);
@ -114,7 +114,7 @@ static void kz_tweaks_handle_bridge_variables(switch_event_t *event)
switch_core_session_rwunlock(b_session); switch_core_session_rwunlock(b_session);
} }
} else { } else {
if(b_leg && (b_session = switch_core_session_force_locate(b_leg)) != NULL) { if(b_leg && (b_session = switch_core_session_locate(b_leg)) != NULL) {
switch_channel_t *b_channel = switch_core_session_get_channel(b_session); 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) { if(switch_channel_get_variable_dup(b_channel, bridge_variables[0], SWITCH_FALSE, -1) == NULL) {
for(i = 0; bridge_variables[i] != NULL; i++) { for(i = 0; bridge_variables[i] != NULL; i++) {
@ -193,7 +193,7 @@ static void kz_tweaks_handle_bridge_replaces_call_id(switch_event_t *event)
if(a_leg_call_id && replaced_call_id) { if(a_leg_call_id && replaced_call_id) {
switch_core_session_t *call_session = NULL; switch_core_session_t *call_session = NULL;
const char *call_id = switch_event_get_header(event, "Bridge-B-Unique-ID"); const char *call_id = switch_event_get_header(event, "Bridge-B-Unique-ID");
if (call_id && (call_session = switch_core_session_force_locate(call_id)) != NULL) { if (call_id && (call_session = switch_core_session_locate(call_id)) != NULL) {
switch_channel_t *call_channel = switch_core_session_get_channel(call_session); switch_channel_t *call_channel = switch_core_session_get_channel(call_session);
if (switch_event_create(&my_event, SWITCH_EVENT_CHANNEL_BRIDGE) == SWITCH_STATUS_SUCCESS) { if (switch_event_create(&my_event, SWITCH_EVENT_CHANNEL_BRIDGE) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(my_event, SWITCH_STACK_BOTTOM, "Bridge-A-Unique-ID", switch_core_session_get_uuid(call_session)); switch_event_add_header_string(my_event, SWITCH_STACK_BOTTOM, "Bridge-A-Unique-ID", switch_core_session_get_uuid(call_session));
@ -259,13 +259,13 @@ static void kz_tweaks_channel_transferor_event_handler(switch_event_t *event)
if (!kz_test_tweak(KZ_TWEAK_TRANSFERS)) return; if (!kz_test_tweak(KZ_TWEAK_TRANSFERS)) 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); 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) { if ((uuid_session = switch_core_session_locate(uuid)) != NULL) {
switch_channel_t *uuid_channel = switch_core_session_get_channel(uuid_session); switch_channel_t *uuid_channel = switch_core_session_get_channel(uuid_session);
const char* interaction_id = switch_channel_get_variable_dup(uuid_channel, INTERACTION_VARIABLE, SWITCH_TRUE, -1); const char* interaction_id = switch_channel_get_variable_dup(uuid_channel, INTERACTION_VARIABLE, SWITCH_TRUE, -1);
// set to uuid & peer_uuid // set to uuid & peer_uuid
if(interaction_id != NULL) { if(interaction_id != NULL) {
switch_core_session_t *session = NULL; switch_core_session_t *session = NULL;
if(dest_call_id && (session = switch_core_session_force_locate(dest_call_id)) != NULL) { if(dest_call_id && (session = switch_core_session_locate(dest_call_id)) != NULL) {
switch_channel_t *channel = switch_core_session_get_channel(session); switch_channel_t *channel = switch_core_session_get_channel(session);
const char* prv_interaction_id = switch_channel_get_variable_dup(channel, INTERACTION_VARIABLE, 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_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "LOCATING UUID PRV : %s : %s\n", prv_interaction_id, interaction_id);
@ -279,7 +279,7 @@ static void kz_tweaks_channel_transferor_event_handler(switch_event_t *event)
} else { } else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "TRANSFEROR NO UUID SESSION: %s , %s , %s \n", uuid, dest_call_id, dest_peer_uuid); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "TRANSFEROR NO UUID SESSION: %s , %s , %s \n", uuid, dest_call_id, dest_peer_uuid);
} }
if(dest_peer_uuid && (session = switch_core_session_force_locate(dest_peer_uuid)) != NULL) { if(dest_peer_uuid && (session = switch_core_session_locate(dest_peer_uuid)) != NULL) {
switch_channel_t *channel = switch_core_session_get_channel(session); switch_channel_t *channel = switch_core_session_get_channel(session);
const char* prv_interaction_id = switch_channel_get_variable_dup(channel, INTERACTION_VARIABLE, 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_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "LOCATING PEER UUID PRV : %s : %s\n", prv_interaction_id, interaction_id);
@ -293,7 +293,7 @@ static void kz_tweaks_channel_transferor_event_handler(switch_event_t *event)
} else { } else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "TRANSFEROR NO PEER SESSION: %s , %s , %s \n", uuid, dest_call_id, dest_peer_uuid); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "TRANSFEROR NO PEER SESSION: %s , %s , %s \n", uuid, dest_call_id, dest_peer_uuid);
} }
if(orig_call_id && (session = switch_core_session_force_locate(orig_call_id)) != NULL) { if(orig_call_id && (session = switch_core_session_locate(orig_call_id)) != NULL) {
switch_channel_t *channel = switch_core_session_get_channel(session); switch_channel_t *channel = switch_core_session_get_channel(session);
const char* prv_interaction_id = switch_channel_get_variable_dup(channel, INTERACTION_VARIABLE, 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_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "LOCATING PEER UUID PRV : %s : %s\n", prv_interaction_id, interaction_id);

View File

@ -386,7 +386,6 @@ SWITCH_DECLARE(char *) kz_event_expand_headers_check(switch_event_t *event, cons
switch_safe_free(expanded_sub_val); switch_safe_free(expanded_sub_val);
sub_val = NULL; sub_val = NULL;
vname = NULL; vname = NULL;
vtype = 0;
br = 0; br = 0;
} }
@ -438,21 +437,18 @@ SWITCH_DECLARE(char *) kz_event_expand_headers_pool(switch_memory_pool_t *pool,
return dup; return dup;
} }
SWITCH_DECLARE(char *) kz_event_expand(const char *in) SWITCH_DECLARE(char *) kz_expand(const char *in, const char *uuid)
{
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(const char *in)
{ {
switch_event_t *event = NULL; switch_event_t *event = NULL;
char *ret = NULL; char *ret = NULL;
kz_switch_core_base_headers_for_expand(&event); kz_switch_core_base_headers_for_expand(&event);
if (uuid != NULL) {
switch_core_session_t *nsession = NULL;
if ((nsession = switch_core_session_locate(uuid))) {
switch_channel_event_set_data(switch_core_session_get_channel(nsession), event);
switch_core_session_rwunlock(nsession);
}
}
ret = kz_event_expand_headers_check(event, in, NULL, NULL, 0); ret = kz_event_expand_headers_check(event, in, NULL, NULL, 0);
switch_event_destroy(&event); switch_event_destroy(&event);
return ret; return ret;
@ -463,7 +459,7 @@ SWITCH_DECLARE(char *) kz_expand_pool(switch_memory_pool_t *pool, const char *in
char *expanded; char *expanded;
char *dup = NULL; char *dup = NULL;
if(!(expanded = kz_expand(in))) { if(!(expanded = kz_expand(in, NULL))) {
return NULL; return NULL;
} }
dup = switch_core_strdup(pool, expanded); dup = switch_core_strdup(pool, expanded);
@ -584,12 +580,14 @@ void kz_event_decode(switch_event_t *event)
switch_event_header_t *hp; switch_event_header_t *hp;
int i; int i;
for (hp = event->headers; hp; hp = hp->next) { for (hp = event->headers; hp; hp = hp->next) {
if (hp->idx) { if (strncmp(hp->name, "_json_", 6)) {
for(i = 0; i < hp->idx; i++) { if (hp->idx) {
switch_url_decode(hp->array[i]); for(i = 0; i < hp->idx; i++) {
switch_url_decode(hp->array[i]);
}
} else {
switch_url_decode(hp->value);
} }
} else {
switch_url_decode(hp->value);
} }
} }
} }

View File

@ -26,9 +26,7 @@ SWITCH_DECLARE(char *) kz_event_expand_headers(switch_event_t *event, const char
SWITCH_DECLARE(char *) kz_event_expand_headers_pool(switch_memory_pool_t *pool, switch_event_t *event, char *val); SWITCH_DECLARE(char *) kz_event_expand_headers_pool(switch_memory_pool_t *pool, switch_event_t *event, char *val);
SWITCH_DECLARE(char *) kz_event_expand(const char *in); SWITCH_DECLARE(char *) kz_expand(const char *in, const char *uuid);
SWITCH_DECLARE(char *) kz_expand(const char *in);
SWITCH_DECLARE(char *) kz_expand_pool(switch_memory_pool_t *pool, const char *in); SWITCH_DECLARE(char *) kz_expand_pool(switch_memory_pool_t *pool, const char *in);

View File

@ -79,6 +79,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_kazoo_load)
/* add tweaks */ /* add tweaks */
kz_tweaks_start(); kz_tweaks_start();
/* add our cdr */
kz_cdr_start();
/* indicate that the module should continue to be loaded */ /* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
@ -88,6 +91,8 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_kazoo_shutdown) {
remove_cli_api(); remove_cli_api();
kz_cdr_stop();
kz_tweaks_stop(); kz_tweaks_stop();
/* stop taking new requests and start shuting down the threads */ /* stop taking new requests and start shuting down the threads */

View File

@ -58,6 +58,9 @@ switch_status_t kz_json_api(const char * command, cJSON *args, cJSON **res);
/* kazoo_endpoints.c */ /* kazoo_endpoints.c */
void add_kz_endpoints(switch_loadable_module_interface_t **module_interface); void add_kz_endpoints(switch_loadable_module_interface_t **module_interface);
/* kazoo_cdr.c */
void kz_cdr_start();
void kz_cdr_stop();
/* kazoo_tweaks.c */ /* kazoo_tweaks.c */
void kz_tweaks_start(); void kz_tweaks_start();