From fdd2acfbfef83ab5311a5b95a5a7676b62b40297 Mon Sep 17 00:00:00 2001 From: lazedo Date: Thu, 18 Apr 2019 04:05:31 +0100 Subject: [PATCH] FS-11791 [mod_kazoo] fixes & improvements * tweak configuration * customized att_xfer * json_api with uuid support --- .../event_handlers/mod_kazoo/kazoo.conf.xml | 18 +- .../event_handlers/mod_kazoo/kazoo_dptools.c | 317 ++++++++++++++++++ src/mod/event_handlers/mod_kazoo/kazoo_ei.h | 32 +- .../mod_kazoo/kazoo_ei_config.c | 42 ++- .../mod_kazoo/kazoo_event_stream.c | 2 + src/mod/event_handlers/mod_kazoo/kazoo_node.c | 77 ++++- .../event_handlers/mod_kazoo/kazoo_tweaks.c | 285 +++++++++------- src/mod/event_handlers/mod_kazoo/mod_kazoo.h | 2 + 8 files changed, 636 insertions(+), 139 deletions(-) diff --git a/src/mod/event_handlers/mod_kazoo/kazoo.conf.xml b/src/mod/event_handlers/mod_kazoo/kazoo.conf.xml index 1ca1b60e6a..5464407c7a 100644 --- a/src/mod/event_handlers/mod_kazoo/kazoo.conf.xml +++ b/src/mod/event_handlers/mod_kazoo/kazoo.conf.xml @@ -112,11 +112,13 @@ - + + @@ -882,6 +884,7 @@ name="variable_Call-Control-Queue" /> + @@ -903,7 +906,7 @@ value="Application-Response|variable_originate_disposition|variable_endpoint_disposition|#NONE" /> - + @@ -1033,6 +1036,8 @@ + + @@ -1071,6 +1076,15 @@ + + + + + + + + + diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_dptools.c b/src/mod/event_handlers/mod_kazoo/kazoo_dptools.c index 4905f09b33..72e2afa18f 100644 --- a/src/mod/event_handlers/mod_kazoo/kazoo_dptools.c +++ b/src/mod/event_handlers/mod_kazoo/kazoo_dptools.c @@ -576,6 +576,321 @@ SWITCH_STANDARD_APP(kz_audio_bridge_function) } } +SWITCH_STANDARD_APP(kz_audio_bridge_uuid_function) +{ + switch_core_session_t *peer_session = NULL; + const char * peer_uuid = NULL; + + if (zstr(data)) { + return; + } + + peer_uuid = switch_core_session_strdup(session, data); + if (peer_uuid && (peer_session = switch_core_session_locate(peer_uuid))) { + switch_ivr_multi_threaded_bridge(session, peer_session, NULL, NULL, NULL); + } + + if (peer_session) { + switch_core_session_rwunlock(peer_session); + } +} + + +struct kz_att_keys { + const char *attxfer_cancel_key; + const char *attxfer_hangup_key; + const char *attxfer_conf_key; +}; + +static switch_status_t kz_att_xfer_on_dtmf(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen) +{ + switch_core_session_t *peer_session = (switch_core_session_t *) buf; + if (!buf || !peer_session) { + return SWITCH_STATUS_SUCCESS; + } + + switch (itype) { + case SWITCH_INPUT_TYPE_DTMF: + { + switch_dtmf_t *dtmf = (switch_dtmf_t *) input; + switch_channel_t *channel = switch_core_session_get_channel(session); + switch_channel_t *peer_channel = switch_core_session_get_channel(peer_session); + struct kz_att_keys *keys = switch_channel_get_private(channel, "__kz_keys"); + + if (dtmf->digit == *keys->attxfer_hangup_key) { + switch_channel_hangup(channel, SWITCH_CAUSE_ATTENDED_TRANSFER); + return SWITCH_STATUS_FALSE; + } + + if (dtmf->digit == *keys->attxfer_cancel_key) { + switch_channel_hangup(peer_channel, SWITCH_CAUSE_NORMAL_CLEARING); + return SWITCH_STATUS_FALSE; + } + + if (dtmf->digit == *keys->attxfer_conf_key) { + switch_caller_extension_t *extension = NULL; + const char *app = "three_way"; + const char *app_arg = switch_core_session_get_uuid(session); + const char *holding = switch_channel_get_variable(channel, SWITCH_SOFT_HOLDING_UUID_VARIABLE); + switch_core_session_t *b_session; + + if (holding && (b_session = switch_core_session_locate(holding))) { + switch_channel_t *b_channel = switch_core_session_get_channel(b_session); + if (!switch_channel_ready(b_channel)) { + app = "intercept"; + } + switch_core_session_rwunlock(b_session); + } + + if ((extension = switch_caller_extension_new(peer_session, app, app_arg)) == 0) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Memory Error!\n"); + abort(); + } + + switch_caller_extension_add_application(peer_session, extension, app, app_arg); + switch_channel_set_caller_extension(peer_channel, extension); + switch_channel_set_state(peer_channel, CS_RESET); + switch_channel_wait_for_state(peer_channel, channel, CS_RESET); + switch_channel_set_state(peer_channel, CS_EXECUTE); + switch_channel_set_variable(channel, SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE, NULL); + return SWITCH_STATUS_FALSE; + } + + } + break; + default: + break; + } + + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t kz_att_xfer_tmp_hanguphook(switch_core_session_t *session) +{ + switch_channel_t *channel = switch_core_session_get_channel(session); + switch_channel_state_t state = switch_channel_get_state(channel); + + if (state == CS_HANGUP || state == CS_ROUTING) { + const char *bond = switch_channel_get_variable(channel, SWITCH_SOFT_HOLDING_UUID_VARIABLE); + + if (!zstr(bond)) { + switch_core_session_t *b_session; + + if ((b_session = switch_core_session_locate(bond))) { + switch_channel_t *b_channel = switch_core_session_get_channel(b_session); + if (switch_channel_up(b_channel)) { + switch_channel_set_flag(b_channel, CF_REDIRECT); + } + switch_core_session_rwunlock(b_session); + } + } + + switch_core_event_hook_remove_state_change(session, kz_att_xfer_tmp_hanguphook); + } + + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t kz_att_xfer_hanguphook(switch_core_session_t *session) +{ + switch_channel_t *channel = switch_core_session_get_channel(session); + switch_channel_state_t state = switch_channel_get_state(channel); + const char *id = NULL; + + if (state == CS_HANGUP || state == CS_ROUTING) { + if ((id = switch_channel_get_variable(channel, "xfer_uuids"))) { + switch_stream_handle_t stream = { 0 }; + SWITCH_STANDARD_STREAM(stream); + switch_api_execute("uuid_bridge", id, NULL, &stream); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "\nHangup Command uuid_bridge(%s):\n%s\n", id, + switch_str_nil((char *) stream.data)); + switch_safe_free(stream.data); + } + + switch_core_event_hook_remove_state_change(session, kz_att_xfer_hanguphook); + } + return SWITCH_STATUS_SUCCESS; +} + + +static void kz_att_xfer_set_result(switch_channel_t *channel, switch_status_t status) +{ + switch_channel_set_variable(channel, SWITCH_ATT_XFER_RESULT_VARIABLE, status == SWITCH_STATUS_SUCCESS ? "success" : "failure"); +} + +struct kz_att_obj { + switch_core_session_t *session; + const char *data; + int running; +}; + +void *SWITCH_THREAD_FUNC kz_att_thread_run(switch_thread_t *thread, void *obj) +{ + struct kz_att_obj *att = (struct kz_att_obj *) obj; + struct kz_att_keys *keys = NULL; + switch_core_session_t *session = att->session; + switch_core_session_t *peer_session = NULL; + const char *data = att->data; + switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING; + switch_channel_t *channel = switch_core_session_get_channel(session), *peer_channel = NULL; + const char *bond = NULL; + switch_core_session_t *b_session = NULL; + switch_bool_t follow_recording = switch_true(switch_channel_get_variable(channel, "recording_follow_attxfer")); + const char *attxfer_cancel_key = NULL, *attxfer_hangup_key = NULL, *attxfer_conf_key = NULL; + + att->running = 1; + + if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) { + return NULL; + } + + bond = switch_channel_get_partner_uuid(channel); + if ((b_session = switch_core_session_locate(bond)) == NULL) { + switch_core_session_rwunlock(peer_session); + return NULL; + } + + switch_channel_set_variable(channel, SWITCH_SOFT_HOLDING_UUID_VARIABLE, bond); + switch_core_event_hook_add_state_change(session, kz_att_xfer_tmp_hanguphook); + + if (follow_recording && (b_session = switch_core_session_locate(bond))) { + switch_ivr_transfer_recordings(b_session, session); + switch_core_session_rwunlock(b_session); + } + + if (switch_ivr_originate(session, &peer_session, &cause, data, 0, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL) + != SWITCH_STATUS_SUCCESS || !peer_session) { + switch_channel_set_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE, bond); + goto end; + } + + peer_channel = switch_core_session_get_channel(peer_session); + switch_channel_set_flag(peer_channel, CF_INNER_BRIDGE); + switch_channel_set_flag(channel, CF_INNER_BRIDGE); + + if (!(attxfer_cancel_key = switch_channel_get_variable(channel, "attxfer_cancel_key"))) { + if (!(attxfer_cancel_key = switch_channel_get_variable(peer_channel, "attxfer_cancel_key"))) { + attxfer_cancel_key = "#"; + } + } + + if (!(attxfer_hangup_key = switch_channel_get_variable(channel, "attxfer_hangup_key"))) { + if (!(attxfer_hangup_key = switch_channel_get_variable(peer_channel, "attxfer_hangup_key"))) { + attxfer_hangup_key = "*"; + } + } + + if (!(attxfer_conf_key = switch_channel_get_variable(channel, "attxfer_conf_key"))) { + if (!(attxfer_conf_key = switch_channel_get_variable(peer_channel, "attxfer_conf_key"))) { + attxfer_conf_key = "0"; + } + } + + keys = switch_core_session_alloc(session, sizeof(*keys)); + keys->attxfer_cancel_key = switch_core_session_strdup(session, attxfer_cancel_key); + keys->attxfer_hangup_key = switch_core_session_strdup(session, attxfer_hangup_key); + keys->attxfer_conf_key = switch_core_session_strdup(session, attxfer_conf_key); + switch_channel_set_private(channel, "__kz_keys", keys); + + switch_channel_set_variable(channel, "att_xfer_peer_uuid", switch_core_session_get_uuid(peer_session)); + + switch_ivr_multi_threaded_bridge(session, peer_session, kz_att_xfer_on_dtmf, peer_session, NULL); + + switch_channel_clear_flag(peer_channel, CF_INNER_BRIDGE); + switch_channel_clear_flag(channel, CF_INNER_BRIDGE); + + if (zstr(bond) && switch_channel_down(peer_channel)) { + switch_core_session_rwunlock(peer_session); + switch_channel_set_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE, bond); + goto end; + } + + if (bond) { + int br = 0; + + switch_channel_set_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE, bond); + + if (!switch_channel_down(peer_channel)) { + /* + * we're emiting the transferee event so that callctl can update + */ + switch_event_t *event = NULL; + switch_channel_t *b_channel = switch_core_session_get_channel(b_session); + if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, "sofia::transferee") == SWITCH_STATUS_SUCCESS) { + switch_channel_event_set_data(b_channel, event); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_replaced_call_id", switch_core_session_get_uuid(peer_session)); + switch_event_fire(&event); + } + if (!switch_channel_ready(channel)) { + switch_status_t status; + + if (follow_recording) { + switch_ivr_transfer_recordings(session, peer_session); + } + status = switch_ivr_uuid_bridge(switch_core_session_get_uuid(peer_session), bond); + kz_att_xfer_set_result(peer_channel, status); + br++; + } else { + switch_channel_set_variable_printf(b_channel, "xfer_uuids", "%s %s", switch_core_session_get_uuid(peer_session), switch_core_session_get_uuid(session)); + switch_channel_set_variable_printf(channel, "xfer_uuids", "%s %s", switch_core_session_get_uuid(peer_session), bond); + + switch_core_event_hook_add_state_change(session, kz_att_xfer_hanguphook); + switch_core_event_hook_add_state_change(b_session, kz_att_xfer_hanguphook); + } + } + +/* + * this was commented so that the existing bridge + * doesn't end + * + if (!br) { + switch_status_t status = switch_ivr_uuid_bridge(switch_core_session_get_uuid(session), bond); + att_xfer_set_result(channel, status); + } +*/ + + } + + switch_core_session_rwunlock(peer_session); + + end: + + switch_core_event_hook_remove_state_change(session, kz_att_xfer_tmp_hanguphook); + + switch_channel_set_variable(channel, SWITCH_SOFT_HOLDING_UUID_VARIABLE, NULL); + switch_channel_clear_flag(channel, CF_XFER_ZOMBIE); + + switch_core_session_rwunlock(b_session); + switch_core_session_rwunlock(session); + att->running = 0; + + return NULL; +} + +SWITCH_STANDARD_APP(kz_att_xfer_function) +{ + switch_thread_t *thread; + switch_threadattr_t *thd_attr = NULL; + switch_memory_pool_t *pool = switch_core_session_get_pool(session); + struct kz_att_obj *att; + switch_channel_t *channel = switch_core_session_get_channel(session); + + switch_threadattr_create(&thd_attr, pool); + switch_threadattr_detach_set(thd_attr, 1); + switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); + switch_threadattr_detach_set(thd_attr, 1); + + att = switch_core_session_alloc(session, sizeof(*att)); + att->running = -1; + att->session = session; + att->data = switch_core_session_strdup(session, data); + switch_thread_create(&thread, thd_attr, kz_att_thread_run, att, pool); + + while(att->running && switch_channel_up(channel)) { + switch_yield(100000); + } +} + 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); @@ -592,4 +907,6 @@ void add_kz_dptools(switch_loadable_module_interface_t **module_interface, switc 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, "", SAF_SUPPORT_NOMEDIA|SAF_SUPPORT_TEXT_ONLY); + SWITCH_ADD_APP(app_interface, "kz_bridge_uuid", "Bridge Audio", "Bridge the audio between two sessions", kz_audio_bridge_uuid_function, "", SAF_SUPPORT_NOMEDIA|SAF_SUPPORT_TEXT_ONLY); + SWITCH_ADD_APP(app_interface, "kz_att_xfer", "Attended Transfer", "Attended Transfer", kz_att_xfer_function, "", SAF_NONE); } diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_ei.h b/src/mod/event_handlers/mod_kazoo/kazoo_ei.h index e394742008..3d844655b7 100644 --- a/src/mod/event_handlers/mod_kazoo/kazoo_ei.h +++ b/src/mod/event_handlers/mod_kazoo/kazoo_ei.h @@ -139,6 +139,24 @@ struct ei_xml_agent_s { }; +typedef enum { + KZ_TWEAK_INTERACTION_ID, + KZ_TWEAK_EXPORT_VARS, + KZ_TWEAK_SWITCH_URI, + KZ_TWEAK_REPLACES_CALL_ID, + KZ_TWEAK_LOOPBACK_VARS, + KZ_TWEAK_CALLER_ID, + KZ_TWEAK_TRANSFERS, + KZ_TWEAK_BRIDGE, + KZ_TWEAK_BRIDGE_REPLACES_ALEG, + KZ_TWEAK_BRIDGE_REPLACES_CALL_ID, + KZ_TWEAK_BRIDGE_VARIABLES, + KZ_TWEAK_RESTORE_CALLER_ID_ON_BLIND_XFER, + + /* No new flags below this line */ + KZ_TWEAK_MAX +} kz_tweak_t; + struct globals_s { switch_memory_pool_t *pool; switch_atomic_t threads; @@ -164,8 +182,6 @@ struct globals_s { char *hostname; char *ei_cookie; char *ei_nodename; -// char *kazoo_var_prefix; -// int var_prefix_length; uint32_t flags; int send_all_headers; int send_all_private_headers; @@ -184,11 +200,13 @@ struct globals_s { kazoo_config_ptr fetch_handlers; kazoo_json_term json_encoding; - int enable_legacy; char **profile_vars_prefixes; char **kazoo_var_prefixes; - int tweaks_restore_caller_id; + int legacy_events; + uint8_t tweaks[KZ_TWEAK_MAX]; + + }; typedef struct globals_s globals_t; extern globals_t kazoo_globals; @@ -254,6 +272,12 @@ switch_status_t kazoo_config_handlers(switch_xml_t cfg); /* runtime */ SWITCH_MODULE_RUNTIME_FUNCTION(mod_kazoo_runtime); + + +#define kz_test_tweak(flag) (kazoo_globals.tweaks[flag] ? 1 : 0) +#define kz_set_tweak(flag) kazoo_globals.tweaks[flag] = 1 +#define kz_clear_tweak(flag) kazoo_globals.tweaks[flag] = 0 + #endif /* KAZOO_EI_H */ /* For Emacs: diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_ei_config.c b/src/mod/event_handlers/mod_kazoo/kazoo_ei_config.c index 3f396103f8..9357211afb 100644 --- a/src/mod/event_handlers/mod_kazoo/kazoo_ei_config.c +++ b/src/mod/event_handlers/mod_kazoo/kazoo_ei_config.c @@ -113,8 +113,22 @@ switch_status_t kazoo_ei_config(switch_xml_t cfg) { kazoo_globals.port = 0; kazoo_globals.io_fault_tolerance = 10; kazoo_globals.json_encoding = ERLANG_TUPLE; - kazoo_globals.enable_legacy = SWITCH_FALSE; - kazoo_globals.tweaks_restore_caller_id = SWITCH_TRUE; + + kazoo_globals.legacy_events = SWITCH_FALSE; + + kz_set_tweak(KZ_TWEAK_INTERACTION_ID); + kz_set_tweak(KZ_TWEAK_EXPORT_VARS); + kz_set_tweak(KZ_TWEAK_SWITCH_URI); + kz_set_tweak(KZ_TWEAK_REPLACES_CALL_ID); + kz_set_tweak(KZ_TWEAK_LOOPBACK_VARS); + kz_set_tweak(KZ_TWEAK_CALLER_ID); + kz_set_tweak(KZ_TWEAK_TRANSFERS); + kz_set_tweak(KZ_TWEAK_BRIDGE); + kz_set_tweak(KZ_TWEAK_BRIDGE_REPLACES_ALEG); + kz_set_tweak(KZ_TWEAK_BRIDGE_REPLACES_CALL_ID); + kz_set_tweak(KZ_TWEAK_BRIDGE_VARIABLES); + kz_set_tweak(KZ_TWEAK_RESTORE_CALLER_ID_ON_BLIND_XFER); + if ((child = switch_xml_child(cfg, "settings"))) { @@ -186,12 +200,24 @@ switch_status_t kazoo_ei_config(switch_xml_t cfg) { if(!strcmp(val, "map")) { kazoo_globals.json_encoding = ERLANG_MAP; } - } else if (!strcmp(var, "enable-legacy")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set enable-legacy: %s\n", val); - kazoo_globals.enable_legacy = switch_true(val); - } else if (!strcmp(var, "tweaks-restore-caller-id")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set tweaks-restore-caller-id: %s\n", val); - kazoo_globals.tweaks_restore_caller_id = switch_true(val); + } else if (!strcmp(var, "legacy-events")) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set legacy-events: %s\n", val); + kazoo_globals.legacy_events = switch_true(val); + } + } + } + + if ((child = switch_xml_child(cfg, "tweaks"))) { + for (param = switch_xml_child(child, "tweak"); param; param = param->next) { + kz_tweak_t tweak = KZ_TWEAK_MAX; + char *var = (char *) switch_xml_attr_soft(param, "name"); + char *val = (char *) switch_xml_attr_soft(param, "value"); + if(var && val && kz_name_tweak(var, &tweak) == SWITCH_STATUS_SUCCESS) { + if(switch_true(val)) { + kz_set_tweak(tweak); + } else { + kz_clear_tweak(tweak); + } } } } diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_event_stream.c b/src/mod/event_handlers/mod_kazoo/kazoo_event_stream.c index 094b910751..8d416a8317 100644 --- a/src/mod/event_handlers/mod_kazoo/kazoo_event_stream.c +++ b/src/mod/event_handlers/mod_kazoo/kazoo_event_stream.c @@ -201,6 +201,8 @@ static void event_handler(switch_event_t *event) { ei_x_encode_version(ebuf); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Target-Node", event_binding->stream->node->peer_nodename); + 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); diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_node.c b/src/mod/event_handlers/mod_kazoo/kazoo_node.c index 9b1f06afd4..a92fe49aa2 100644 --- a/src/mod/event_handlers/mod_kazoo/kazoo_node.c +++ b/src/mod/event_handlers/mod_kazoo/kazoo_node.c @@ -64,7 +64,8 @@ static char *REQUEST_ATOMS[] = { "fetch_reply", "config", "bgapi4", - "api4" + "api4", + "json_api" }; typedef enum { @@ -86,6 +87,7 @@ typedef enum { REQUEST_CONFIG, REQUEST_BGAPI4, REQUEST_API4, + REQUEST_JSON_API, REQUEST_MAX } request_atoms_t; @@ -925,10 +927,10 @@ static switch_status_t handle_request_api4(ei_node_t *ei_node, erlang_pid *pid, status = api_exec_stream(cmd, arg, &stream, &reply); if (status == SWITCH_STATUS_SUCCESS) { - ei_x_encode_tuple_header(buf, 2); + ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "ok"); } else { - ei_x_encode_tuple_header(buf, (stream.param_event ? 3 : 2)); + ei_x_encode_tuple_header(rbuf, (stream.param_event ? 3 : 2)); ei_x_encode_atom(rbuf, "error"); } @@ -951,6 +953,61 @@ static switch_status_t handle_request_api4(ei_node_t *ei_node, erlang_pid *pid, return SWITCH_STATUS_SUCCESS; } +static switch_status_t handle_request_json_api(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) +{ + char *arg; + cJSON *jcmd = NULL; + switch_core_session_t *session = NULL; + const char *uuid = NULL; + char *response = NULL; + const char *parse_end = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (ei_decode_string_or_binary(buf->buff, &buf->index, &arg)) { + return erlang_response_badarg(rbuf); + } + + jcmd = cJSON_ParseWithOpts(arg, &parse_end, 0); + + if (!jcmd) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "json api error: %s\n", parse_end); + ei_x_encode_tuple_header(rbuf, 2); + ei_x_encode_atom(rbuf, "error"); + ei_x_encode_tuple_header(rbuf, 2); + ei_x_encode_atom(rbuf, "parse_error"); + _ei_x_encode_string(rbuf, parse_end); + return status; + } + + if ((uuid = cJSON_GetObjectCstr(jcmd, "uuid"))) { + if (!(session = switch_core_session_locate(uuid))) { + return erlang_response_baduuid(rbuf); + } + } + + status = switch_json_api_execute(jcmd, session, NULL); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "json api (%i): %s\n", status , arg); + + response = cJSON_PrintUnformatted(jcmd); + ei_x_encode_tuple_header(rbuf, 2); + if (status == SWITCH_STATUS_SUCCESS) { + ei_x_encode_atom(rbuf, "ok"); + } else { + ei_x_encode_atom(rbuf, "error"); + } + _ei_x_encode_string(rbuf, response); + switch_safe_free(response); + + cJSON_Delete(jcmd); + switch_safe_free(arg); + + if (session) { + switch_core_session_rwunlock(session); + } + + return SWITCH_STATUS_SUCCESS; +} + static switch_status_t handle_request_api(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { char cmd[MAXATOMLEN + 1]; char *arg; @@ -963,7 +1020,7 @@ static switch_status_t handle_request_api(ei_node_t *ei_node, erlang_pid *pid, e return erlang_response_badarg(rbuf); } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "exec: %s(%s)\n", cmd, arg); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "exec: %s(%s)\n", cmd, arg); if (rbuf) { char *reply; @@ -1100,12 +1157,12 @@ static switch_status_t handle_kazoo_request(ei_node_t *ei_node, erlang_pid *pid, } if (ei_decode_atom_safe(buf->buff, &buf->index, atom)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Recieved mod_kazoo message that did not contain a command (ensure you are using Kazoo v2.14+).\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received mod_kazoo message that did not contain a command (ensure you are using Kazoo v2.14+).\n"); return erlang_response_badarg(rbuf); } if (find_request(atom, &request) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Recieved mod_kazoo message for unimplemented feature (ensure you are using Kazoo v2.14+): %s\n", atom); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received mod_kazoo message for unimplemented feature (ensure you are using Kazoo v2.14+): %s\n", atom); return erlang_response_badarg(rbuf); } @@ -1146,6 +1203,8 @@ static switch_status_t handle_kazoo_request(ei_node_t *ei_node, erlang_pid *pid, return handle_request_bgapi4(ei_node, pid, buf, rbuf); case REQUEST_API4: return handle_request_api4(ei_node, pid, buf, rbuf); + case REQUEST_JSON_API: + return handle_request_json_api(ei_node, pid, buf, rbuf); default: return erlang_response_notimplemented(rbuf); } @@ -1168,7 +1227,7 @@ static switch_status_t handle_mod_kazoo_request(ei_node_t *ei_node, erlang_msg * ei_decode_tuple_header(buf->buff, &buf->index, &arity); if (ei_decode_atom_safe(buf->buff, &buf->index, atom)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Recieved erlang message tuple that did not start with an atom (ensure you are using Kazoo v2.14+).\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received erlang message tuple that did not start with an atom (ensure you are using Kazoo v2.14+).\n"); return SWITCH_STATUS_GENERR; } @@ -1224,7 +1283,7 @@ static switch_status_t handle_mod_kazoo_request(ei_node_t *ei_node, erlang_msg * return status; } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Recieved inappropriate erlang message (ensure you are using Kazoo v2.14+)\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received inappropriate erlang message (ensure you are using Kazoo v2.14+)\n"); return SWITCH_STATUS_GENERR; } } @@ -1547,7 +1606,7 @@ switch_status_t new_kazoo_node(int nodefd, ErlConnect *conn) { ei_node->nodefd = nodefd; ei_node->peer_nodename = switch_core_strdup(ei_node->pool, conn->nodename); ei_node->created_time = switch_micro_time_now(); - ei_node->legacy = kazoo_globals.enable_legacy; + ei_node->legacy = kazoo_globals.legacy_events; ei_node->event_stream_framing = kazoo_globals.event_stream_framing; /* store the IP and node name we are talking with */ diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_tweaks.c b/src/mod/event_handlers/mod_kazoo/kazoo_tweaks.c index a1bd6a0876..19aa19980d 100644 --- a/src/mod/event_handlers/mod_kazoo/kazoo_tweaks.c +++ b/src/mod/event_handlers/mod_kazoo/kazoo_tweaks.c @@ -32,6 +32,21 @@ #define INTERACTION_VARIABLE "Call-Interaction-ID" +static char *TWEAK_NAMES[] = { + "interaction-id", + "export-vars", + "switch-uri", + "replaces-call-id", + "loopback-vars", + "caller-id", + "transfers", + "bridge", + "bridge-replaces-aleg", + "bridge-replaces-call-id", + "bridge-variables", + "restore-caller-id-on-blind-xfer" +}; + static const char *bridge_variables[] = { "Call-Control-Queue", "Call-Control-PID", @@ -83,7 +98,7 @@ static void kz_tweaks_handle_bridge_variables(switch_event_t *event) const char *b_leg = switch_event_get_header(event, "Bridge-B-Unique-ID"); int i; - if (kazoo_globals.enable_legacy) return; + if (!kz_test_tweak(KZ_TWEAK_BRIDGE_VARIABLES)) return; if (a_leg && (a_session = switch_core_session_force_locate(a_leg)) != NULL) { switch_channel_t *a_channel = switch_core_session_get_channel(a_session); @@ -115,7 +130,7 @@ static void kz_tweaks_handle_bridge_variables(switch_event_t *event) } -static void kz_tweaks_handle_bridge_replaces(switch_event_t *event) +static void kz_tweaks_handle_bridge_replaces_aleg(switch_event_t *event) { switch_event_t *my_event; @@ -124,7 +139,7 @@ static void kz_tweaks_handle_bridge_replaces(switch_event_t *event) const char *peer_uuid = switch_event_get_header(event, "Unique-ID"); int processed = 0; - if (kazoo_globals.enable_legacy) return; + if (!kz_test_tweak(KZ_TWEAK_BRIDGE_REPLACES_ALEG)) return; if(a_leg_call_id && replaced_call_id) { @@ -171,7 +186,7 @@ static void kz_tweaks_handle_bridge_replaces_call_id(switch_event_t *event) const char *a_leg_call_id = switch_event_get_header(event, "variable_sip_replaces_a-leg"); const char *peer_uuid = switch_event_get_header(event, "Unique-ID"); - if (kazoo_globals.enable_legacy) return; + if (!kz_test_tweak(KZ_TWEAK_BRIDGE_REPLACES_CALL_ID)) return; if(a_leg_call_id && replaced_call_id) { switch_core_session_t *call_session = NULL; @@ -196,10 +211,10 @@ static void kz_tweaks_handle_bridge_replaces_call_id(switch_event_t *event) static void kz_tweaks_channel_bridge_event_handler(switch_event_t *event) { - if (kazoo_globals.enable_legacy) return; + if (!kz_test_tweak(KZ_TWEAK_BRIDGE)) return; kz_tweaks_handle_bridge_replaces_call_id(event); - kz_tweaks_handle_bridge_replaces(event); + kz_tweaks_handle_bridge_replaces_aleg(event); kz_tweaks_handle_bridge_variables(event); } @@ -209,7 +224,8 @@ static void kz_tweaks_channel_replaced_event_handler(switch_event_t *event) { const char *uuid = switch_event_get_header(event, "Unique-ID"); const char *replaced_by = switch_event_get_header(event, "att_xfer_replaced_by"); - if (kazoo_globals.enable_legacy) return; + + if (!kz_test_tweak(KZ_TWEAK_TRANSFERS)) return; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "REPLACED : %s , %s\n", uuid, replaced_by); } @@ -219,7 +235,7 @@ static void kz_tweaks_channel_intercepted_event_handler(switch_event_t *event) const char *uuid = switch_event_get_header(event, "Unique-ID"); const char *peer_uuid = switch_event_get_header(event, "intercepted_by"); - if (kazoo_globals.enable_legacy) return; + if (!kz_test_tweak(KZ_TWEAK_TRANSFERS)) return; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "INTERCEPTED : %s => %s\n", uuid, peer_uuid); } @@ -238,7 +254,7 @@ static void kz_tweaks_channel_transferor_event_handler(switch_event_t *event) const char *func = switch_event_get_header(event, "Event-Calling-Function"); const char *line = switch_event_get_header(event, "Event-Calling-Line-Number"); - if (kazoo_globals.enable_legacy) return; + 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); if ((uuid_session = switch_core_session_force_locate(uuid)) != NULL) { @@ -304,7 +320,7 @@ static void kz_tweaks_channel_transferee_event_handler(switch_event_t *event) const char *uuid = switch_event_get_header(event, "Unique-ID"); const char *replaced_by_uuid = switch_event_get_header(event, "att_xfer_replaced_call_id"); - if (kazoo_globals.enable_legacy) return; + if (!kz_test_tweak(KZ_TWEAK_TRANSFERS)) return; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "TRANSFEREE : %s replaced by %s\n", uuid, replaced_by_uuid); } @@ -326,6 +342,10 @@ static switch_status_t kz_tweaks_handle_loopback(switch_core_session_t *session) switch_caller_profile_t *caller; int n = 0; + if (!kz_test_tweak(KZ_TWEAK_LOOPBACK_VARS)) { + return SWITCH_STATUS_SUCCESS; + } + caller = switch_channel_get_caller_profile(channel); if(strncmp(caller->source, "mod_loopback", 12)) return SWITCH_STATUS_SUCCESS; @@ -380,12 +400,14 @@ static switch_status_t kz_tweaks_handle_loopback(switch_core_session_t *session) * set Interaction-ID * if we're not crossing account boundaries */ - if (a_channel) { - const char *interaction_id = switch_channel_get_variable_dup(a_channel, INTERACTION_VARIABLE, SWITCH_FALSE, -1); - const char *a_account_id = switch_channel_get_variable_dup(a_channel, "ecallmgr_Account-ID", SWITCH_FALSE, -1); - const char *b_account_id = switch_channel_get_variable_dup(channel, "ecallmgr_Account-ID", SWITCH_FALSE, -1); - if ((!a_account_id) || (!b_account_id) || (!strcmp(a_account_id, b_account_id))) { - switch_channel_set_variable(channel, INTERACTION_VARIABLE, interaction_id); + if (kz_test_tweak(KZ_TWEAK_INTERACTION_ID)) { + if (a_channel) { + const char *interaction_id = switch_channel_get_variable_dup(a_channel, INTERACTION_VARIABLE, SWITCH_FALSE, -1); + const char *a_account_id = switch_channel_get_variable_dup(a_channel, "ecallmgr_Account-ID", SWITCH_FALSE, -1); + const char *b_account_id = switch_channel_get_variable_dup(channel, "ecallmgr_Account-ID", SWITCH_FALSE, -1); + if ((!a_account_id) || (!b_account_id) || (!strcmp(a_account_id, b_account_id))) { + switch_channel_set_variable(channel, INTERACTION_VARIABLE, interaction_id); + } } } @@ -402,18 +424,20 @@ 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); - 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 (caller && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) { - const char* val = NULL; - if((val=switch_caller_get_field_by_name(caller, "Endpoint-Caller-ID-Name"))) { - caller->caller_id_name = val; - 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; + if (kz_test_tweak(KZ_TWEAK_CALLER_ID)) { + switch_channel_t *channel = switch_core_session_get_channel(session); + 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 (caller && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) { + const char* val = NULL; + if((val=switch_caller_get_field_by_name(caller, "Endpoint-Caller-ID-Name"))) { + caller->caller_id_name = val; + 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; + } } } } @@ -442,26 +466,28 @@ static switch_status_t kz_tweaks_handle_auth_token(switch_core_session_t *sessio } */ -static switch_status_t kz_tweaks_handle_nightmare_xfer(switch_core_session_t *session) +static switch_status_t kz_tweaks_handle_nightmare_xfer_interaction_id(switch_core_session_t *session) { - switch_core_session_t *replace_session = NULL; - switch_channel_t *channel = switch_core_session_get_channel(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"); - const char *partner_uuid = switch_channel_get_variable(channel, "sip_h_X-FS-Refer-Partner-UUID"); - const char *interaction_id = switch_channel_get_variable(channel, "sip_h_X-FS-Call-Interaction-ID"); - if(core_uuid && partner_uuid && replaced_call_id && interaction_id) { - switch_channel_set_variable(channel, INTERACTION_VARIABLE, interaction_id); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "checking nightmare xfer tweak for %s\n", switch_channel_get_uuid(channel)); - if ((replace_session = switch_core_session_locate(replaced_call_id))) { - switch_channel_t *replaced_call_channel = switch_core_session_get_channel(replace_session); - switch_channel_set_variable(replaced_call_channel, INTERACTION_VARIABLE, interaction_id); - switch_core_session_rwunlock(replace_session); - } - if ((replace_session = switch_core_session_locate(partner_uuid))) { - switch_channel_t *replaced_call_channel = switch_core_session_get_channel(replace_session); - switch_channel_set_variable(replaced_call_channel, INTERACTION_VARIABLE, interaction_id); - switch_core_session_rwunlock(replace_session); + if (kz_test_tweak(KZ_TWEAK_INTERACTION_ID)) { + switch_core_session_t *replace_session = NULL; + switch_channel_t *channel = switch_core_session_get_channel(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"); + const char *partner_uuid = switch_channel_get_variable(channel, "sip_h_X-FS-Refer-Partner-UUID"); + const char *interaction_id = switch_channel_get_variable(channel, "sip_h_X-FS-Call-Interaction-ID"); + if(core_uuid && partner_uuid && replaced_call_id && interaction_id) { + switch_channel_set_variable(channel, INTERACTION_VARIABLE, interaction_id); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "checking nightmare xfer tweak for %s\n", switch_channel_get_uuid(channel)); + if ((replace_session = switch_core_session_locate(replaced_call_id))) { + switch_channel_t *replaced_call_channel = switch_core_session_get_channel(replace_session); + switch_channel_set_variable(replaced_call_channel, INTERACTION_VARIABLE, interaction_id); + switch_core_session_rwunlock(replace_session); + } + if ((replace_session = switch_core_session_locate(partner_uuid))) { + switch_channel_t *replaced_call_channel = switch_core_session_get_channel(replace_session); + switch_channel_set_variable(replaced_call_channel, INTERACTION_VARIABLE, interaction_id); + switch_core_session_rwunlock(replace_session); + } } } @@ -469,29 +495,31 @@ static switch_status_t kz_tweaks_handle_nightmare_xfer(switch_core_session_t *se } -static switch_status_t kz_tweaks_handle_replaces_id(switch_core_session_t *session) +static switch_status_t kz_tweaks_handle_replaces_call_id(switch_core_session_t *session) { - switch_core_session_t *replace_call_session = NULL; - switch_event_t *event; - switch_channel_t *channel = switch_core_session_get_channel(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))) { - switch_channel_t *replaced_call_channel = switch_core_session_get_channel(replace_call_session); - int i; - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "setting bridge variables from %s to %s\n", replaced_call_id, switch_channel_get_uuid(channel)); - for(i = 0; bridge_variables[i] != NULL; i++) { - const char *val = switch_channel_get_variable_dup(replaced_call_channel, bridge_variables[i], SWITCH_TRUE, -1); - switch_channel_set_variable(channel, bridge_variables[i], val); - switch_safe_strdup(val); + if (kz_test_tweak(KZ_TWEAK_REPLACES_CALL_ID)) { + switch_core_session_t *replace_call_session = NULL; + switch_event_t *event; + switch_channel_t *channel = switch_core_session_get_channel(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))) { + switch_channel_t *replaced_call_channel = switch_core_session_get_channel(replace_call_session); + int i; + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "setting bridge variables from %s to %s\n", replaced_call_id, switch_channel_get_uuid(channel)); + for(i = 0; bridge_variables[i] != NULL; i++) { + const char *val = switch_channel_get_variable_dup(replaced_call_channel, bridge_variables[i], SWITCH_TRUE, -1); + switch_channel_set_variable(channel, bridge_variables[i], val); + switch_safe_strdup(val); + } + if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) { + switch_channel_event_set_data(channel, event); + switch_event_fire(&event); + } + switch_core_session_rwunlock(replace_call_session); } - if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) { - switch_channel_event_set_data(channel, event); - switch_event_fire(&event); - } - switch_core_session_rwunlock(replace_call_session); } } @@ -503,11 +531,13 @@ static switch_status_t kz_tweaks_handle_replaces_id(switch_core_session_t *sessi static switch_status_t kz_tweaks_handle_switch_uri(switch_core_session_t *session) { switch_channel_t *channel = switch_core_session_get_channel(session); - const char *profile_url = switch_channel_get_variable(channel, "sofia_profile_url"); - if(profile_url) { - int n = strcspn(profile_url, "@"); - switch_channel_set_variable(channel, "Switch-URL", profile_url); - switch_channel_set_variable_printf(channel, "Switch-URI", "sip:%s", n > 0 ? profile_url + n + 1 : profile_url); + if (kz_test_tweak(KZ_TWEAK_SWITCH_URI)) { + const char *profile_url = switch_channel_get_variable(channel, "sofia_profile_url"); + if(profile_url) { + int n = strcspn(profile_url, "@"); + switch_channel_set_variable(channel, "Switch-URL", profile_url); + switch_channel_set_variable_printf(channel, "Switch-URI", "sip:%s", n > 0 ? profile_url + n + 1 : profile_url); + } } return SWITCH_STATUS_SUCCESS; @@ -518,49 +548,54 @@ static void kz_tweaks_handle_interaction_id(switch_core_session_t *session) { const char *expr = "${expr(ceil((${Event-Date-Timestamp} / 1000000) + $${UNIX_EPOCH_IN_GREGORIAN}))}-${regex(${create_uuid()}|^([^-]*)|%1)}"; switch_channel_t *channel = switch_core_session_get_channel(session); - char * val = kz_expand(expr); + char * val = NULL; switch_core_session_t *peer_session = NULL; const char* peer_interaction_id = NULL; - if (val) { - switch_channel_set_variable(channel, "Original-"INTERACTION_VARIABLE, val); - if(switch_core_session_get_partner(session, &peer_session) == SWITCH_STATUS_SUCCESS) { - switch_channel_t *peer_channel = switch_core_session_get_channel(peer_session); - peer_interaction_id = switch_channel_get_variable_dup(peer_channel, INTERACTION_VARIABLE, SWITCH_FALSE, -1); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "PEER_SESSION => %s\n", peer_interaction_id); - if(peer_interaction_id) { - switch_channel_set_variable(channel, INTERACTION_VARIABLE, peer_interaction_id); + if (kz_test_tweak(KZ_TWEAK_INTERACTION_ID)) { + val = kz_expand(expr); + if (val) { + switch_channel_set_variable(channel, "Original-"INTERACTION_VARIABLE, val); + if(switch_core_session_get_partner(session, &peer_session) == SWITCH_STATUS_SUCCESS) { + switch_channel_t *peer_channel = switch_core_session_get_channel(peer_session); + peer_interaction_id = switch_channel_get_variable_dup(peer_channel, INTERACTION_VARIABLE, SWITCH_FALSE, -1); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "PEER_SESSION => %s\n", peer_interaction_id); + if(peer_interaction_id) { + switch_channel_set_variable(channel, INTERACTION_VARIABLE, peer_interaction_id); + } + switch_core_session_rwunlock(peer_session); + } else if (!switch_channel_get_variable_dup(channel, INTERACTION_VARIABLE, SWITCH_FALSE, -1)) { + switch_channel_set_variable(channel, INTERACTION_VARIABLE, val); } - switch_core_session_rwunlock(peer_session); - } else if (!switch_channel_get_variable_dup(channel, INTERACTION_VARIABLE, SWITCH_FALSE, -1)) { - switch_channel_set_variable(channel, INTERACTION_VARIABLE, val); } - } - switch_safe_free(val); + switch_safe_free(val); + } } static switch_status_t kz_outgoing_channel(switch_core_session_t * session, switch_event_t * event, switch_caller_profile_t * cp, switch_core_session_t * peer_session, switch_originate_flag_t flag) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "GOT OUTGOING\n"); - if (peer_session) { - switch_channel_t *channel = switch_core_session_get_channel(session); - const char* interaction_id = switch_channel_get_variable_dup(channel, INTERACTION_VARIABLE, SWITCH_FALSE, -1); - switch_channel_t *peer_channel = switch_core_session_get_channel(peer_session); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "SESSION && PEER_SESSION => %s\n", interaction_id ); - if (interaction_id) { - switch_channel_set_variable(peer_channel, INTERACTION_VARIABLE, interaction_id); + if (kz_test_tweak(KZ_TWEAK_INTERACTION_ID)) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "GOT OUTGOING\n"); + if (peer_session) { + switch_channel_t *channel = switch_core_session_get_channel(session); + const char* interaction_id = switch_channel_get_variable_dup(channel, INTERACTION_VARIABLE, SWITCH_FALSE, -1); + switch_channel_t *peer_channel = switch_core_session_get_channel(peer_session); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "SESSION && PEER_SESSION => %s\n", interaction_id ); + if (interaction_id) { + switch_channel_set_variable(peer_channel, INTERACTION_VARIABLE, interaction_id); + } + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "NO SESSION && PEER_SESSION\n"); } - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "NO SESSION && PEER_SESSION\n"); } return SWITCH_STATUS_SUCCESS; } -static switch_status_t kz_tweaks_register_handle_xfer(switch_core_session_t *session) +static switch_status_t kz_tweaks_register_handle_blind_xfer(switch_core_session_t *session) { - if (kazoo_globals.tweaks_restore_caller_id) { + if (kz_test_tweak(KZ_TWEAK_RESTORE_CALLER_ID_ON_BLIND_XFER)) { switch_channel_t *channel = switch_core_session_get_channel(session); switch_channel_set_variable(channel, "execute_on_blind_transfer", "kz_restore_caller_id"); } @@ -570,24 +605,25 @@ static switch_status_t kz_tweaks_register_handle_xfer(switch_core_session_t *ses 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 (kz_test_tweak(KZ_TWEAK_EXPORT_VARS)) { + 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; + 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); } - switch_channel_set_variable(channel, SWITCH_EXPORT_VARS_VARIABLE, new_exports); - - switch_safe_free(new_exports_d); - return SWITCH_STATUS_SUCCESS; } @@ -595,18 +631,17 @@ static switch_status_t kz_tweaks_set_export_vars(switch_core_session_t *session) static switch_status_t kz_tweaks_on_init(switch_core_session_t *session) { switch_channel_t *channel = switch_core_session_get_channel(session); - if (kazoo_globals.enable_legacy) return SWITCH_STATUS_SUCCESS; - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "checking tweaks for %s\n", switch_channel_get_uuid(channel)); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "checking tweaks for %s\n", switch_channel_get_uuid(channel)); switch_channel_set_flag(channel, CF_VERBOSE_EVENTS); switch_core_event_hook_add_outgoing_channel(session, kz_outgoing_channel); kz_tweaks_handle_interaction_id(session); kz_tweaks_handle_switch_uri(session); kz_tweaks_handle_caller_id(session); // kz_tweaks_handle_auth_token(session); - kz_tweaks_handle_nightmare_xfer(session); - kz_tweaks_handle_replaces_id(session); + kz_tweaks_handle_nightmare_xfer_interaction_id(session); + kz_tweaks_handle_replaces_call_id(session); kz_tweaks_handle_loopback(session); - kz_tweaks_register_handle_xfer(session); + kz_tweaks_register_handle_blind_xfer(session); kz_tweaks_set_export_vars(session); return SWITCH_STATUS_SUCCESS; @@ -693,6 +728,24 @@ void kz_tweaks_stop() kz_tweaks_unregister_state_handlers(); } +SWITCH_DECLARE(const char *) kz_tweak_name(kz_tweak_t tweak) +{ + return TWEAK_NAMES[tweak]; +} + +SWITCH_DECLARE(switch_status_t) kz_name_tweak(const char *name, kz_tweak_t *type) +{ + kz_tweak_t x; + for (x = 0; x < KZ_TWEAK_MAX; x++) { + if (!strcasecmp(name, TWEAK_NAMES[x])) { + *type = x; + return SWITCH_STATUS_SUCCESS; + } + } + + return SWITCH_STATUS_FALSE; +} + /* For Emacs: * Local Variables: * mode:c diff --git a/src/mod/event_handlers/mod_kazoo/mod_kazoo.h b/src/mod/event_handlers/mod_kazoo/mod_kazoo.h index bbf511a280..1fc12ba2aa 100644 --- a/src/mod/event_handlers/mod_kazoo/mod_kazoo.h +++ b/src/mod/event_handlers/mod_kazoo/mod_kazoo.h @@ -57,6 +57,8 @@ void add_kz_endpoints(switch_loadable_module_interface_t **module_interface); /* kazoo_tweaks.c */ void kz_tweaks_start(); void kz_tweaks_stop(); +SWITCH_DECLARE(const char *) kz_tweak_name(kz_tweak_t tweak); +SWITCH_DECLARE(switch_status_t) kz_name_tweak(const char *name, kz_tweak_t *type); /* kazoo_node.c */ void add_kz_node(switch_loadable_module_interface_t **module_interface);