FS-10820 [mod_kazoo] add more kazoo interactions

* initialize ei
* defaults for definitions
* add kz endpoint
* add kz_bridge
* add setters with encoding
* add tweaks after merged core PRs
This commit is contained in:
lazedo 2019-03-27 06:13:32 +00:00
parent 1dea2b2f7f
commit efafdefe07
10 changed files with 559 additions and 64 deletions

View File

@ -11,6 +11,7 @@ mod_kazoo_la_SOURCES += kazoo_api.c kazoo_commands.c kazoo_config.c
mod_kazoo_la_SOURCES += kazoo_message.c
mod_kazoo_la_SOURCES += kazoo_ei_config.c kazoo_ei_utils.c kazoo_event_stream.c
mod_kazoo_la_SOURCES += kazoo_fetch_agent.c kazoo_node.c
mod_kazoo_la_SOURCES += kazoo_endpoints.c
mod_kazoo_la_CFLAGS = $(AM_CFLAGS) @ERLANG_CFLAGS@ -D_REENTRANT
mod_kazoo_la_LIBADD = $(KAZOO_DEFS) $(switch_builddir)/libfreeswitch.la

View File

@ -66,34 +66,31 @@
<field name="Metaflow-Control" type="reference" />
</definition>
<definition name="Privacy">
<field name="Caller-Privacy-Hide-Number" as="Hide-Number" serialize-as="boolean" />
<field name="Caller-Privacy-Hide-Name" as="Hide-Name" serialize-as="boolean" />
<field name="Caller-Screen-Bit" as="Screen-Bit" serialize-as="boolean" />
</definition>
<definition name="Custom-Channel-Vars">
<field name="Custom-Channel-Vars" type="static" serialize-as="object">
<fields verbose="false">
<field name="X-ecallmgr_" type="prefix"
exclude-prefix="true" />
<field name="variable_sip_h_X-ecallmgr_" type="prefix"
exclude-prefix="true" />
<field name="variable_ecallmgr_" type="prefix"
exclude-prefix="true" />
<!-- special case for booleans -->
<field name="variable_ecallmgr_Caller-Privacy-Hide-Number"
as="Caller-Privacy-Hide-Number" serialize-as="boolean" />
<field name="variable_ecallmgr_Caller-Privacy-Hide-Name" as="Caller-Privacy-Hide-Name"
serialize-as="boolean" />
<field name="variable_ecallmgr_Caller-Screen-Bit" as="Caller-Screen-Bit"
serialize-as="boolean" />
<field name="Caller-Privacy-Hide-Number" serialize-as="boolean" />
<field name="Caller-Privacy-Hide-Name" serialize-as="boolean" />
<field name="Caller-Screen-Bit" serialize-as="boolean" />
<field name="Fetch-UUID" as="Fetch-ID" />
<field name="Referred-To" type="expand"
value="${regex(${url_decode(${variable_sip_refer_to})}|&lt;sips?:(.*)&gt;|%1)}">
value="sip:${regex(${url_decode(${variable_sip_refer_to})}|&lt;sips?:(.*)&gt;|%1)}">
<filters>
<filter name="variable_sip_refer_to" type="include" compare="exists" />
</filters>
</field>
<field name="Referred-By" type="expand" value="${regex(${variable_sip_h_Referred-By}|&lt;sips?:(.*)&gt;|%1)}">
<field name="Referred-By" type="expand" value="sip:${regex(${variable_sip_h_Referred-By}|&lt;sips?:(.*)&gt;|%1)}">
<filters>
<filter name="variable_sip_h_Referred-By" type="include" compare="exists" />
</filters>
@ -119,7 +116,7 @@
<filter name="variable_sip_redirected_by" type="include" compare="exists" />
</filters>
<fields verbose="false">
<field name="Redirected-By" type="expand" value="${regex(${variable_sip_redirected_by}|&lt;sips?:(.*)&gt;|%1)}"/>
<field name="Redirected-By" type="expand" value="sip:${regex(${variable_sip_redirected_by}|&lt;sips?:(.*)&gt;|%1)}"/>
<field name="Redirected-Reason" type="expand" value="${regex(${variable_sip_redirected_by}|reason=(.*)|%1)}"/>
</fields>
</field>
@ -258,10 +255,18 @@
<field name="Hunt-Context" />
<field name="Hunt-Dialplan" />
<field name="Hunt-Destination-Number" />
<!--
<field name="Request" type="expand"
value="${Hunt-Destination-Number}@${first-of(variable_sip_invite_domain|variable_sip_to_host|variable_sip_req_host)}" />
value="${first-of(variable_sip_to_uri|variable_sip_req_uri|#${Hunt-Destination-Number}@${first-of(variable_sip_invite_domain|variable_sip_to_host|variable_sip_req_host|variable_ecallmgr_Realm)})}" />
<field name="To" type="expand"
value="${first-of(variable_sip_to_uri|variable_sip_req_uri|#${Hunt-Destination-Number}@${first-of(variable_sip_invite_domain|variable_sip_to_host|variable_sip_req_host)})}" />
value="${first-of(variable_sip_to_uri|variable_sip_req_uri|#${Hunt-Destination-Number}@${first-of(variable_sip_invite_domain|variable_sip_to_host|variable_sip_req_host|variable_ecallmgr_Realm)})}" />
-->
<field name="Request" type="expand"
value="${Hunt-Destination-Number}@${first-of(variable_sip_invite_domain|variable_sip_to_host|variable_sip_req_host|variable_ecallmgr_Realm)}" />
<field name="To" type="expand"
value="${Hunt-Destination-Number}@${first-of(variable_sip_invite_domain|variable_sip_to_host|variable_sip_req_host|variable_ecallmgr_Realm)}" />
<field name="From" type="expand"
value="${first-of(Hunt-Caller-ID-Number|origination_callee_id_number|variable_sip_from_user)}@${first-of(variable_sip_invite_domain|variable_sip_from_host|variable_sip_req_host|variable_ecallmgr_Realm)}" />
</definition>
<definition name="sip-tags">
@ -322,7 +327,7 @@
<field name="user-agent" type="reference" />
<field name="Custom-Channel-Vars" type="reference" />
<field name="Custom-Application-Vars" type="reference" />
<field name="Control" type="reference" />
<field name="Control" type="reference" />
</definition>
<definition name="fetch-info">
@ -344,6 +349,8 @@
<field name="Custom-Application-Vars" type="reference" />
<field name="freeswitch-url" type="reference" />
<field name="Control" type="reference" />
<field name="Privacy" type="reference" />
</definition>
<definition name="destination-number">
@ -353,7 +360,7 @@
<definition name="from-to">
<field name="Request" type="first-of"
value="variable_sip_req_uri|variable_sip_loopback_req_uri" />
value="variable_sip_req_uri|variable_sip_loopback_req_uri|variable_sip_to_uri" />
<field name="To" type="first-of"
value="variable_sip_to_uri|variable_sip_req_uri|variable_sip_loopback_req_uri" />
<field name="variable_sip_to_uri" as="To-URI" />
@ -448,6 +455,7 @@
serialize-as="object">
<fields verbose="false">
<field name="Conference-" type="prefix" exclude-prefix="true" />
<field name="Account-ID" type="first-of" value="Account-ID|Conference-Account-ID|variable_ecallmgr_Account-ID" />
</fields>
</field>
</definition>
@ -529,14 +537,15 @@
<field name="Application-Name" type="static" value="record" />
<field name="Application-Response" type="first-of"
value="Record-File-Path|kazoo_application_response" />
<field name="recording_vars" type="reference" />
<field name="recording_vars" type="reference" />
</definition>
<definition name="fax_data">
<field name="variable_fax_success" as="Fax-Success" serialize-as="boolean" />
<field name="variable_has_t38" as="Fax-T38-Used" serialize-as="boolean" />
<field name="variable_fax_ecm_used" as="Fax-ECM-Used" serialize-as="boolean" />
<field name="variable_fax_t38_status" as="Fax-T38-Status" />
<field name="variable_fax_ecm_used" as="Fax-ECM-Used" serialize-as="boolean" />
<field name="variable_fax_ecm_requested" as="Fax-ECM-Requested" serialize-as="boolean" />
<field name="variable_fax_document_transferred_pages" as="Fax-Transferred-Pages" serialize-as="number" />
<field name="variable_fax_document_total_pages" as="Fax-Total-Pages" serialize-as="number" />
<field name="variable_fax_bad_rows" as="Fax-Bad-Rows" serialize-as="number" />
@ -575,7 +584,6 @@
<field name="Custom-Application-Vars" type="reference" />
</definition>
<definition name="voice_dialplan">
<field name="fetch-info" type="reference" />
<field name="Timestamp" type="expand"
@ -589,6 +597,7 @@
<field name="user-agent" type="reference" />
<field name="from-to" type="reference" />
<field name="to-did" type="reference" />
<field name="loopback" type="reference" />
<field name="sip-tags" type="reference" />
<field name="freeswitch-url" type="reference" />
<field name="destination-number" type="reference" />
@ -601,7 +610,6 @@
<field name="Event-Name" type="static" value="route_req" />
<field name="Hunt-Context" as="Fetch-Key-Value" />
</definition>
<definition name="metaflow_dialplan">
<field name="metaflow" type="group">
<filters>
@ -621,7 +629,7 @@
serialize-as="object">
<fields verbose="false">
<field name="Metaflow-Request-Type" type="static" value="in-call" />
<field name="Other-Leg-Call-ID" type="first-of" value="variable_Application-Other-Leg-UUID|Other-Leg-Unique-ID" />
<field name="Other-Leg-Unique-ID" as="Other-Leg-Call-ID" />
<field name="Hunt-Destination-Number" as="Metaflow-Request" />
</fields>
</field>
@ -630,9 +638,9 @@
</field>
</definition>
</definitions>
<event-handlers>
<profile name="default">
<events>

View File

@ -350,7 +350,7 @@ SWITCH_STANDARD_API(kz_http_put)
switch_curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1);
switch_curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 10);
switch_curl_easy_setopt(curl_handle, CURLOPT_FAILONERROR, 1);
switch_curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-http-cache/1.0");
switch_curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-kazoo/1.0");
switch_curl_easy_setopt(curl_handle, CURLOPT_HEADERDATA, stream->param_event);
switch_curl_easy_setopt(curl_handle, CURLOPT_HEADERFUNCTION, header_callback);
switch_curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, body_callback);

View File

@ -98,7 +98,7 @@ static void base_set (switch_core_session_t *session, const char *data, int urld
expanded = switch_channel_expand_variables(channel, val);
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s SET [%s]=[%s]\n", switch_channel_get_name(channel), var,
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s SET [%s]=[%s] => [%s]\n", switch_channel_get_name(channel), var, val,
expanded ? expanded : "UNDEF");
switch_channel_add_variable_var_check(channel, var, expanded, SWITCH_FALSE, stack);
kz_check_set_profile_var(channel, var, expanded);
@ -458,6 +458,124 @@ SWITCH_STANDARD_APP(noop_function)
switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, response);
}
SWITCH_STANDARD_APP(kz_restore_caller_id_function)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_caller_profile_t *cp = switch_channel_get_caller_profile(channel);
cp->caller_id_name = cp->orig_caller_id_name;
cp->caller_id_number = cp->orig_caller_id_number;
}
SWITCH_STANDARD_APP(kz_audio_bridge_function)
{
switch_channel_t *caller_channel = switch_core_session_get_channel(session);
switch_core_session_t *peer_session = NULL;
switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING;
switch_status_t status = SWITCH_STATUS_FALSE;
if (zstr(data)) {
return;
}
status = switch_ivr_originate(session, &peer_session, &cause, data, 0, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
if (status != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Originate Failed. Cause: %s\n", switch_channel_cause2str(cause));
switch_channel_set_variable(caller_channel, "originate_failed_cause", switch_channel_cause2str(cause));
switch_channel_set_variable(caller_channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, switch_channel_cause2str(cause));
switch_channel_handle_cause(caller_channel, cause);
return;
} else {
const char* uuid = switch_core_session_get_uuid(session);
const char* peer_uuid = switch_core_session_get_uuid(peer_session);
switch_channel_t *peer_channel = switch_core_session_get_channel(peer_session);
if (switch_true(switch_channel_get_variable(caller_channel, SWITCH_BYPASS_MEDIA_AFTER_BRIDGE_VARIABLE)) ||
switch_true(switch_channel_get_variable(peer_channel, SWITCH_BYPASS_MEDIA_AFTER_BRIDGE_VARIABLE))) {
switch_channel_set_flag(caller_channel, CF_BYPASS_MEDIA_AFTER_BRIDGE);
}
while(1) {
const char *xfer_uuid;
switch_channel_state_t a_state , a_running_state;
switch_channel_state_t b_state , b_running_state;
status = switch_ivr_multi_threaded_bridge(session, peer_session, NULL, NULL, NULL);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "BRIDGE RESULT %i\n", status);
if(status != 0) {
break;
}
a_state = switch_channel_get_state(caller_channel);
a_running_state = switch_channel_get_running_state(caller_channel);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "A STATE %s %s => %s , %s\n", switch_channel_state_name(a_running_state), switch_channel_state_name(a_state), uuid, peer_uuid);
if(a_state >= CS_HANGUP) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "A HANGUP = %s , %s\n", uuid, peer_uuid);
break;
}
b_state = switch_channel_get_state(peer_channel);
b_running_state = switch_channel_get_running_state(peer_channel);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "B STATE %s %s => %s , %s\n", switch_channel_state_name(b_running_state), switch_channel_state_name(b_state), uuid, peer_uuid);
if(b_state >= CS_HANGUP) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "B HANGUP = %s , %s\n", uuid, peer_uuid);
switch_channel_set_variable(caller_channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, switch_channel_cause2str(switch_channel_get_cause(peer_channel)));
break;
}
if(!(xfer_uuid=switch_channel_get_variable(caller_channel, "att_xfer_peer_uuid"))) {
if(!(xfer_uuid=switch_channel_get_variable(peer_channel, "att_xfer_peer_uuid"))) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "XFER UUID NULL\n");
break;
}
}
switch_channel_set_variable(caller_channel, "att_xfer_peer_uuid", NULL);
switch_channel_set_variable(peer_channel, "att_xfer_peer_uuid", NULL);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "WAIT 1\n");
switch_channel_clear_flag(peer_channel, CF_UUID_BRIDGE_ORIGINATOR);
switch_channel_set_state(peer_channel, CS_RESET);
switch_channel_wait_for_state(peer_channel, NULL, CS_RESET);
switch_channel_clear_state_handler(peer_channel, NULL);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "WAIT 3\n");
switch_channel_set_flag(caller_channel, CF_UUID_BRIDGE_ORIGINATOR);
switch_channel_clear_flag(caller_channel, CF_TRANSFER);
switch_channel_clear_flag(caller_channel, CF_REDIRECT);
switch_channel_set_flag(peer_channel, CF_UUID_BRIDGE_ORIGINATOR);
switch_channel_clear_flag(peer_channel, CF_TRANSFER);
switch_channel_clear_flag(peer_channel, CF_REDIRECT);
if(!switch_channel_media_up(caller_channel)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "A MEDIA DOWN HANGUP = %s, %s , %s\n", xfer_uuid, uuid, peer_uuid);
}
if(!switch_channel_media_up(peer_channel)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "B MEDIA DOWN HANGUP = %s, %s , %s\n", xfer_uuid, uuid, peer_uuid);
}
switch_channel_set_state(caller_channel, CS_EXECUTE);
switch_channel_set_state(peer_channel, CS_EXECUTE);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "XFER LOOP %s %s , %s\n", xfer_uuid, uuid, peer_uuid);
}
if (peer_session) {
switch_core_session_rwunlock(peer_session);
}
}
}
void add_kz_dptools(switch_loadable_module_interface_t **module_interface, switch_application_interface_t *app_interface) {
SWITCH_ADD_APP(app_interface, "kz_set", SET_SHORT_DESC, SET_LONG_DESC, set_function, SET_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC);
SWITCH_ADD_APP(app_interface, "kz_set_encoded", SET_SHORT_DESC, SET_LONG_DESC, set_encoded_function, SET_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC);
@ -471,5 +589,7 @@ void add_kz_dptools(switch_loadable_module_interface_t **module_interface, switc
SWITCH_ADD_APP(app_interface, "kz_uuid_multiset", UUID_MULTISET_SHORT_DESC, UUID_MULTISET_LONG_DESC, uuid_multiset_function, UUID_MULTISET_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC);
SWITCH_ADD_APP(app_interface, "kz_uuid_multiset_encoded", UUID_MULTISET_SHORT_DESC, UUID_MULTISET_LONG_DESC, uuid_multiset_encoded_function, UUID_MULTISET_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC);
SWITCH_ADD_APP(app_interface, "kz_endless_playback", KZ_ENDLESS_PLAYBACK_SHORT_DESC, KZ_ENDLESS_PLAYBACK_LONG_DESC, kz_endless_playback_function, KZ_ENDLESS_PLAYBACK_SYNTAX, SAF_NONE);
SWITCH_ADD_APP(app_interface, "kz_restore_caller_id", NOOP_SHORT_DESC, NOOP_LONG_DESC, kz_restore_caller_id_function, NOOP_SYNTAX, SAF_NONE);
SWITCH_ADD_APP(app_interface, "noop", NOOP_SHORT_DESC, NOOP_LONG_DESC, noop_function, NOOP_SYNTAX, SAF_NONE);
SWITCH_ADD_APP(app_interface, "kz_bridge", "Bridge Audio", "Bridge the audio between two sessions", kz_audio_bridge_function, "<channel_url>", SAF_SUPPORT_NOMEDIA|SAF_SUPPORT_TEXT_ONLY);
}

View File

@ -519,6 +519,8 @@ switch_status_t create_acceptor() {
char ipbuf[48];
const char *ip_addr;
ei_init();
/* if the config has specified an erlang release compatibility then pass that along to the erlang interface */
if (kazoo_globals.ei_compat_rel) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Compatability with OTP R%d requested\n", kazoo_globals.ei_compat_rel);

View File

@ -0,0 +1,284 @@
/*
* 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):
*
* Karl Anderson <karl@2600hz.com>
* Darren Schreiber <darren@2600hz.com>
*
*
* kazoo_dptools.c -- clones of mod_dptools commands slightly modified for kazoo
*
*/
#include "mod_kazoo.h"
/* kazoo endpoint */
switch_endpoint_interface_t *kz_endpoint_interface;
static switch_call_cause_t kz_endpoint_outgoing_channel(switch_core_session_t *session,
switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause);
switch_io_routines_t kz_endpoint_io_routines = {
/*.outgoing_channel */ kz_endpoint_outgoing_channel
};
static switch_call_cause_t kz_endpoint_outgoing_channel(switch_core_session_t *session,
switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause)
{
switch_xml_t x_user = NULL, x_param, x_params;
char *user = NULL, *domain = NULL, *dup_domain = NULL, *dialed_user = NULL;
const char *dest = NULL;
switch_call_cause_t cause = SWITCH_CAUSE_NONE;
unsigned int timelimit = SWITCH_DEFAULT_TIMEOUT;
switch_channel_t *new_channel = NULL;
switch_event_t *params = NULL, *var_event_orig = var_event;
char stupid[128] = "";
const char *skip = NULL, *var = NULL;
if (zstr(outbound_profile->destination_number)) {
goto done;
}
user = strdup(outbound_profile->destination_number);
if (!user)
goto done;
if ((domain = strchr(user, '@'))) {
*domain++ = '\0';
} else {
domain = switch_core_get_domain(SWITCH_TRUE);
dup_domain = domain;
}
if (!domain) {
goto done;
}
switch_event_create(&params, SWITCH_EVENT_REQUEST_PARAMS);
switch_assert(params);
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "as_channel", "true");
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "action", "user_call");
if (var_event) {
switch_event_merge(params, var_event);
}
if (var_event && (skip = switch_event_get_header(var_event, "user_recurse_variables")) && switch_false(skip)) {
if ((var = switch_event_get_header(var_event, SWITCH_CALL_TIMEOUT_VARIABLE)) || (var = switch_event_get_header(var_event, "leg_timeout"))) {
timelimit = atoi(var);
}
var_event = NULL;
}
if (switch_xml_locate_user_merged("id", user, domain, NULL, &x_user, params) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Can't find user [%s@%s]\n", user, domain);
cause = SWITCH_CAUSE_SUBSCRIBER_ABSENT;
goto done;
}
if ((x_params = switch_xml_child(x_user, "params"))) {
for (x_param = switch_xml_child(x_params, "param"); x_param; x_param = x_param->next) {
const char *pvar = switch_xml_attr_soft(x_param, "name");
const char *val = switch_xml_attr(x_param, "value");
if (!strcasecmp(pvar, "dial-string")) {
dest = val;
} else if (!strncasecmp(pvar, "dial-var-", 9)) {
if (!var_event) {
switch_event_create(&var_event, SWITCH_EVENT_GENERAL);
} else {
switch_event_del_header(var_event, pvar + 9);
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "adding variable to var_event => %s = %s\n", pvar + 9, val);
switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, pvar + 9, val);
}
}
}
dialed_user = (char *)switch_xml_attr(x_user, "id");
if (var_event) {
switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "dialed_user", dialed_user);
switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "dialed_domain", domain);
if (!zstr(dest) && !strstr(dest, "presence_id=")) {
switch_event_add_header(var_event, SWITCH_STACK_BOTTOM, "presence_id", "%s@%s", dialed_user, domain);
}
}
if (!dest) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No dial-string available, please check your user directory.\n");
cause = SWITCH_CAUSE_MANDATORY_IE_MISSING;
} else {
const char *varval;
char *d_dest = NULL;
switch_channel_t *channel;
switch_originate_flag_t myflags = SOF_NONE;
char *cid_name_override = NULL;
char *cid_num_override = NULL;
if (var_event) {
cid_name_override = switch_event_get_header(var_event, "origination_caller_id_name");
cid_num_override = switch_event_get_header(var_event, "origination_caller_id_number");
}
if (session) {
switch_event_t *event = NULL;
switch_event_create(&event, SWITCH_EVENT_GENERAL);
channel = switch_core_session_get_channel(session);
if ((varval = switch_channel_get_variable(channel, SWITCH_CALL_TIMEOUT_VARIABLE))
|| (var_event && (varval = switch_event_get_header(var_event, "leg_timeout")))) {
timelimit = atoi(varval);
}
switch_channel_event_set_data(channel, event);
if(var_event) {
switch_event_merge(event, var_event);
}
switch_channel_set_variable(channel, "dialed_user", dialed_user);
switch_channel_set_variable(channel, "dialed_domain", domain);
d_dest = switch_event_expand_headers(event, dest);
switch_event_destroy(&event);
} else {
switch_event_t *event = NULL;
if (var_event) {
switch_event_dup(&event, var_event);
switch_event_del_header(event, "dialed_user");
switch_event_del_header(event, "dialed_domain");
if ((varval = switch_event_get_header(var_event, SWITCH_CALL_TIMEOUT_VARIABLE)) ||
(varval = switch_event_get_header(var_event, "leg_timeout"))) {
timelimit = atoi(varval);
}
} else {
switch_event_create(&event, SWITCH_EVENT_REQUEST_PARAMS);
switch_assert(event);
}
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "dialed_user", dialed_user);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "dialed_domain", domain);
d_dest = switch_event_expand_headers(event, dest);
switch_event_destroy(&event);
}
if ((flags & SOF_NO_LIMITS)) {
myflags |= SOF_NO_LIMITS;
}
if ((flags & SOF_FORKED_DIAL)) {
myflags |= SOF_NOBLOCK;
}
switch_snprintf(stupid, sizeof(stupid), "kz/%s", dialed_user);
if (switch_stristr(stupid, d_dest)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Waddya Daft? You almost called '%s' in an infinate loop!\n",
stupid);
cause = SWITCH_CAUSE_INVALID_IE_CONTENTS;
} else if (switch_ivr_originate(session, new_session, &cause, d_dest, timelimit, NULL,
cid_name_override, cid_num_override, outbound_profile, var_event, myflags,
cancel_cause, NULL) == SWITCH_STATUS_SUCCESS) {
const char *context;
switch_caller_profile_t *cp;
if (var_event) {
switch_event_del_header(var_event, "origination_uuid");
}
new_channel = switch_core_session_get_channel(*new_session);
if ((context = switch_channel_get_variable(new_channel, "user_context"))) {
if ((cp = switch_channel_get_caller_profile(new_channel))) {
cp->context = switch_core_strdup(cp->pool, context);
}
}
if ((x_params = switch_xml_child(x_user, "variables"))) {
for (x_param = switch_xml_child(x_params, "variable"); x_param; x_param = x_param->next) {
const char *pvar = switch_xml_attr(x_param, "name");
const char *val = switch_xml_attr(x_param, "value");
switch_channel_set_variable(new_channel, pvar, val);
}
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_DEBUG1, "CHECKING CALLER-ID\n");
if ((x_params = switch_xml_child(x_user, "profile-variables"))) {
switch_caller_profile_t *cp = NULL;
const char* val = NULL;
for (x_param = switch_xml_child(x_params, "variable"); x_param; x_param = x_param->next) {
const char *pvar = switch_xml_attr(x_param, "name");
const char *val = switch_xml_attr(x_param, "value");
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_DEBUG1, "setting profile var %s = %s\n", pvar, val);
switch_channel_set_profile_var(new_channel, pvar, val);
}
cp = switch_channel_get_caller_profile(new_channel);
if((val=switch_caller_get_field_by_name(cp, "Endpoint-Caller-ID-Name"))) {
cp->callee_id_name = val;
cp->orig_caller_id_name = val;
}
if((val=switch_caller_get_field_by_name(cp, "Endpoint-Caller-ID-Number"))) {
cp->callee_id_number = val;
cp->orig_caller_id_number = val;
}
}
switch_core_session_rwunlock(*new_session);
}
if (d_dest != dest) {
switch_safe_free(d_dest);
}
}
done:
if (x_user) {
switch_xml_free(x_user);
}
if (params) {
switch_event_destroy(&params);
}
if (var_event && var_event_orig != var_event) {
switch_event_destroy(&var_event);
}
switch_safe_free(user);
switch_safe_free(dup_domain);
return cause;
}
void add_kz_endpoints(switch_loadable_module_interface_t **module_interface) {
kz_endpoint_interface = (switch_endpoint_interface_t *) switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE);
kz_endpoint_interface->interface_name = "kz";
kz_endpoint_interface->io_routines = &kz_endpoint_io_routines;
}

View File

@ -36,6 +36,9 @@ static const char *bridge_variables[] = {
"Call-Control-Node",
"ecallmgr_Call-Interaction-ID",
"ecallmgr_Ecallmgr-Node",
"sip_h_k-cid",
"Switch-URI",
"Switch-URL",
NULL
};
@ -146,10 +149,12 @@ static void kz_tweaks_handle_bridge_replaces(switch_event_t *event)
}
}
}
}
}
static void kz_tweaks_handle_bridge_replaces_caller_id(switch_event_t *event)
static void kz_tweaks_handle_bridge_replaces_call_id(switch_event_t *event)
{
switch_event_t *my_event;
@ -178,12 +183,11 @@ static void kz_tweaks_handle_bridge_replaces_caller_id(switch_event_t *event)
}
static void kz_tweaks_channel_bridge_event_handler(switch_event_t *event)
{
kz_tweaks_handle_bridge_variables(event);
kz_tweaks_handle_bridge_replaces_caller_id(event);
kz_tweaks_handle_bridge_replaces_call_id(event);
kz_tweaks_handle_bridge_replaces(event);
kz_tweaks_handle_bridge_variables(event);
}
// TRANSFERS
@ -300,11 +304,11 @@ static switch_status_t kz_tweaks_handle_loopback(switch_core_session_t *session)
for(header = event->headers; header; header = header->next) {
if(!strncmp(header->name, "Export-Loopback-", 16)) {
switch_event_add_variable_name_printf(to_add, SWITCH_STACK_BOTTOM, header->value, "%s", header->name+16);
kz_switch_event_add_variable_name_printf(to_add, SWITCH_STACK_BOTTOM, header->value, "%s", header->name+16);
switch_channel_set_variable(channel, header->name, NULL);
n++;
} else if(!strncmp(header->name, "sip_loopback_", 13)) {
switch_event_add_variable_name_printf(to_add, SWITCH_STACK_BOTTOM, header->value, "sip_%s", header->name+13);
kz_switch_event_add_variable_name_printf(to_add, SWITCH_STACK_BOTTOM, header->value, "sip_%s", header->name+13);
} else if(!strncmp(header->name, "ecallmgr_", 9)) {
switch_event_add_header_string(to_remove, SWITCH_STACK_BOTTOM, header->name, header->value);
}
@ -347,9 +351,19 @@ static switch_status_t kz_tweaks_handle_loopback(switch_core_session_t *session)
static void kz_tweaks_handle_caller_id(switch_core_session_t *session)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
const char *acl_token = switch_channel_get_variable(channel, "acl_token");
if(acl_token) {
switch_ivr_set_user(session, acl_token);
const char *token = switch_channel_get_variable(channel, "acl_token");
switch_caller_profile_t* caller = switch_channel_get_caller_profile(channel);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "CHECKING CALLER-ID\n");
if (token) {
const char* val = NULL;
if((val=switch_caller_get_field_by_name(caller, "Endpoint-Caller-ID-Name"))) {
caller->caller_id_name = val;
caller->orig_caller_id_name = val;
}
if((val=switch_caller_get_field_by_name(caller, "Endpoint-Caller-ID-Number"))) {
caller->caller_id_number = val;
caller->orig_caller_id_number = val;
}
}
}
@ -420,14 +434,11 @@ static switch_status_t kz_tweaks_handle_replaces_id(switch_core_session_t *sessi
switch_core_session_t *replace_call_session = NULL;
switch_event_t *event;
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_memory_pool_t *pool = switch_core_session_get_pool(session);
const char *replaced_call_id = switch_channel_get_variable(channel, "sip_replaces_call_id");
const char *core_uuid = switch_channel_get_variable(channel, "sip_h_X-FS-From-Core-UUID");
if((!core_uuid) && replaced_call_id) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "checking replaces header tweak for %s\n", replaced_call_id);
if ((replace_call_session = switch_core_session_locate(replaced_call_id))) {
const char* tmp_caller = NULL;
switch_caller_profile_t * cp = switch_channel_get_caller_profile(channel);
switch_channel_t *replaced_call_channel = switch_core_session_get_channel(replace_call_session);
int i;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "setting bridge variables from %s to %s\n", replaced_call_id, switch_channel_get_uuid(channel));
@ -440,12 +451,6 @@ static switch_status_t kz_tweaks_handle_replaces_id(switch_core_session_t *sessi
switch_channel_event_set_data(channel, event);
switch_event_fire(&event);
}
if((tmp_caller = switch_channel_get_variable(channel, "Internal-Caller-ID-Number")) != NULL) {
profile_dup_clean(tmp_caller, cp->caller_id_number, pool);
}
if((tmp_caller = switch_channel_get_variable(channel, "Internal-Caller-ID-Name")) != NULL) {
profile_dup_clean(tmp_caller, cp->caller_id_name, pool);
}
switch_core_session_rwunlock(replace_call_session);
}
}
@ -469,11 +474,42 @@ static switch_status_t kz_tweaks_handle_switch_uri(switch_core_session_t *sessio
}
static switch_status_t kz_tweaks_register_handle_xfer(switch_core_session_t *session)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_channel_set_variable(channel, "execute_on_blind_transfer", "kz_restore_caller_id");
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t kz_tweaks_set_export_vars(switch_core_session_t *session)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
const char *exports;
char *var, *new_exports, *new_exports_d = NULL;
exports = switch_channel_get_variable(channel, SWITCH_EXPORT_VARS_VARIABLE);
var = switch_core_session_strdup(session, "Switch-URI,Switch-URL");
if (exports) {
new_exports_d = switch_mprintf("%s,%s", exports, var);
new_exports = new_exports_d;
} else {
new_exports = var;
}
switch_channel_set_variable(channel, SWITCH_EXPORT_VARS_VARIABLE, new_exports);
switch_safe_free(new_exports_d);
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t kz_tweaks_on_init(switch_core_session_t *session)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "checking tweaks for %s\n", switch_channel_get_uuid(channel));
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "checking tweaks for %s\n", switch_channel_get_uuid(channel));
switch_channel_set_flag(channel, CF_VERBOSE_EVENTS);
kz_tweaks_handle_switch_uri(session);
kz_tweaks_handle_caller_id(session);
@ -481,6 +517,8 @@ static switch_status_t kz_tweaks_on_init(switch_core_session_t *session)
kz_tweaks_handle_nightmare_xfer(session);
kz_tweaks_handle_replaces_id(session);
kz_tweaks_handle_loopback(session);
kz_tweaks_register_handle_xfer(session);
kz_tweaks_set_export_vars(session);
return SWITCH_STATUS_SUCCESS;
}

View File

@ -34,6 +34,17 @@
*/
#include "mod_kazoo.h"
#define kz_resize(l) {\
char *dp;\
olen += (len + l + block);\
cpos = c - data;\
if ((dp = realloc(data, olen))) {\
data = dp;\
c = data + cpos;\
memset(c, 0, olen - cpos);\
}} \
void kz_check_set_profile_var(switch_channel_t *channel, char* var, char *val)
{
int idx = 0;
@ -47,6 +58,27 @@ void kz_check_set_profile_var(switch_channel_t *channel, char* var, char *val)
}
}
SWITCH_DECLARE(switch_status_t) kz_switch_core_merge_variables(switch_event_t *event)
{
switch_event_t *global_vars;
switch_status_t status = switch_core_get_variables(&global_vars);
if(status == SWITCH_STATUS_SUCCESS) {
switch_event_merge(event, global_vars);
switch_event_destroy(&global_vars);
}
return status;
}
SWITCH_DECLARE(switch_status_t) kz_switch_core_base_headers_for_expand(switch_event_t **event)
{
switch_status_t status = SWITCH_STATUS_GENERR;
*event = NULL;
if(switch_event_create(event, SWITCH_EVENT_GENERAL) == SWITCH_STATUS_SUCCESS) {
status = kz_switch_core_merge_variables(*event);
}
return status;
}
SWITCH_DECLARE(switch_status_t) kz_expand_api_execute(const char *cmd, const char *arg, switch_core_session_t *session, switch_stream_handle_t *stream)
{
switch_api_interface_t *api;
@ -87,15 +119,6 @@ SWITCH_DECLARE(switch_status_t) kz_expand_api_execute(const char *cmd, const cha
return status;
}
#define resize(l) {\
char *dp;\
olen += (len + l + block);\
cpos = c - data;\
if ((dp = realloc(data, olen))) {\
data = dp;\
c = data + cpos;\
memset(c, 0, olen - cpos);\
}} \
SWITCH_DECLARE(char *) kz_event_expand_headers_check(switch_event_t *event, const char *in, switch_event_t *var_list, switch_event_t *api_list, uint32_t recur)
{
@ -146,7 +169,7 @@ SWITCH_DECLARE(char *) kz_event_expand_headers_check(switch_event_t *event, cons
continue;
} else if (*(p + 1) == '\\') {
if (len + 1 >= olen) {
resize(1);
kz_resize(1);
}
*c++ = *p++;
@ -174,7 +197,7 @@ SWITCH_DECLARE(char *) kz_event_expand_headers_check(switch_event_t *event, cons
if (nv) {
if (len + 1 >= olen) {
resize(1);
kz_resize(1);
}
*c++ = *p;
@ -362,7 +385,7 @@ SWITCH_DECLARE(char *) kz_event_expand_headers_check(switch_event_t *event, cons
}
if ((nlen = sub_val ? strlen(sub_val) : 0)) {
if (len + nlen >= olen) {
resize(nlen);
kz_resize(nlen);
}
len += nlen;
@ -381,7 +404,7 @@ SWITCH_DECLARE(char *) kz_event_expand_headers_check(switch_event_t *event, cons
if (sp) {
if (len + 1 >= olen) {
resize(1);
kz_resize(1);
}
*c++ = ' ';
@ -393,7 +416,7 @@ SWITCH_DECLARE(char *) kz_event_expand_headers_check(switch_event_t *event, cons
p--;
} else {
if (len + 1 >= olen) {
resize(1);
kz_resize(1);
}
*c++ = *p;
@ -412,6 +435,16 @@ SWITCH_DECLARE(char *) kz_event_expand_headers(switch_event_t *event, const char
return kz_event_expand_headers_check(event, in, NULL, NULL, 0);
}
SWITCH_DECLARE(char *) kz_event_expand(const char *in)
{
switch_event_t *event = NULL;
char *ret = NULL;
kz_switch_core_base_headers_for_expand(&event);
ret = kz_event_expand_headers_check(event, in, NULL, NULL, 0);
switch_event_destroy(&event);
return ret;
}
char *kazoo_expand_header(switch_memory_pool_t *pool, switch_event_t *event, char *val)
{
char *expanded;
@ -427,7 +460,7 @@ char *kazoo_expand_header(switch_memory_pool_t *pool, switch_event_t *event, cha
return dup;
}
char* switch_event_get_first_of(switch_event_t *event, const char *list[])
char* kz_switch_event_get_first_of(switch_event_t *event, const char *list[])
{
switch_event_header_t *header = NULL;
int i = 0;
@ -443,7 +476,7 @@ char* switch_event_get_first_of(switch_event_t *event, const char *list[])
}
}
SWITCH_DECLARE(switch_status_t) switch_event_add_variable_name_printf(switch_event_t *event, switch_stack_t stack, const char *val, const char *fmt, ...)
SWITCH_DECLARE(switch_status_t) kz_switch_event_add_variable_name_printf(switch_event_t *event, switch_stack_t stack, const char *val, const char *fmt, ...)
{
int ret = 0;
char *varname;

View File

@ -74,6 +74,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_kazoo_load) {
/* add our modified dptools */
add_kz_dptools(module_interface, app_interface);
/* add our endpoints */
add_kz_endpoints(module_interface);
/* add tweaks */
kz_tweaks_start();

View File

@ -36,16 +36,22 @@ void add_cli_api(switch_loadable_module_interface_t **module_interface, switch_a
void remove_cli_api();
/* kazoo_utils.c */
SWITCH_DECLARE(switch_status_t) kz_switch_core_merge_variables(switch_event_t *event);
SWITCH_DECLARE(switch_status_t) kz_switch_core_base_headers_for_expand(switch_event_t **event);
void kz_check_set_profile_var(switch_channel_t *channel, char* var, char *val);
char *kazoo_expand_header(switch_memory_pool_t *pool, switch_event_t *event, char *val);
char* switch_event_get_first_of(switch_event_t *event, const char *list[]);
SWITCH_DECLARE(switch_status_t) switch_event_add_variable_name_printf(switch_event_t *event, switch_stack_t stack, const char *val, const char *fmt, ...);
char* kz_switch_event_get_first_of(switch_event_t *event, const char *list[]);
SWITCH_DECLARE(switch_status_t) kz_switch_event_add_variable_name_printf(switch_event_t *event, switch_stack_t stack, const char *val, const char *fmt, ...);
void kz_xml_process(switch_xml_t cfg);
void kz_event_decode(switch_event_t *event);
char * kz_expand_vars(char *xml_str);
char * kz_expand_vars_pool(char *xml_str, switch_memory_pool_t *pool);
SWITCH_DECLARE(char *) kz_event_expand_headers(switch_event_t *event, const char *in);
/* kazoo_endpoints.c */
void add_kz_endpoints(switch_loadable_module_interface_t **module_interface);
/* kazoo_tweaks.c */
void kz_tweaks_start();
void kz_tweaks_stop();