diff --git a/src/include/switch_channel.h b/src/include/switch_channel.h index 3f92534e3e..a1f13edd85 100644 --- a/src/include/switch_channel.h +++ b/src/include/switch_channel.h @@ -261,10 +261,17 @@ SWITCH_DECLARE(const char *) switch_channel_get_variable_partner(switch_channel_ #define switch_channel_set_variable_partner(_channel, _var, _val) switch_channel_set_variable_partner_var_check(_channel, _var, _val, SWITCH_TRUE) -SWITCH_DECLARE(switch_status_t) switch_channel_export_variable_var_check(switch_channel_t *channel, const char *varname, const char *value, switch_bool_t var_check); +SWITCH_DECLARE(switch_status_t) switch_channel_export_variable_var_check(switch_channel_t *channel, + const char *varname, const char *val, + const char *export_varname, + switch_bool_t var_check); -#define switch_channel_export_variable(_channel, _varname, _value) switch_channel_export_variable_var_check(_channel, _varname, _value, SWITCH_TRUE) -SWITCH_DECLARE(switch_status_t) switch_channel_export_variable_printf(switch_channel_t *channel, const char *varname, const char *fmt, ...); +SWITCH_DECLARE(void) switch_channel_process_export(switch_channel_t *channel, switch_channel_t *peer_channel, + switch_event_t *var_event, const char *export_varname); + +#define switch_channel_export_variable(_channel, _varname, _value, _ev) switch_channel_export_variable_var_check(_channel, _varname, _value, _ev, SWITCH_TRUE) +SWITCH_DECLARE(switch_status_t) switch_channel_export_variable_printf(switch_channel_t *channel, const char *varname, + const char *export_varname, const char *fmt, ...); /*! diff --git a/src/include/switch_types.h b/src/include/switch_types.h index c7d7b0a7ec..668fdc81c4 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -156,6 +156,7 @@ SWITCH_BEGIN_EXTERN_C #define SWITCH_ENDPOINT_DISPOSITION_VARIABLE "endpoint_disposition" #define SWITCH_HOLD_MUSIC_VARIABLE "hold_music" #define SWITCH_EXPORT_VARS_VARIABLE "export_vars" +#define SWITCH_BRIDGE_EXPORT_VARS_VARIABLE "bridge_export_vars" #define SWITCH_R_SDP_VARIABLE "switch_r_sdp" #define SWITCH_L_SDP_VARIABLE "switch_l_sdp" #define SWITCH_B_SDP_VARIABLE "switch_m_sdp" diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index dd63f8aae9..9fb6b1b454 100755 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -909,48 +909,42 @@ SWITCH_STANDARD_APP(set_profile_var_function) SWITCH_STANDARD_APP(export_function) { switch_channel_t *channel = switch_core_session_get_channel(session); - const char *exports; - char *new_exports = NULL, *new_exports_d = NULL, *var, *val = NULL, *var_name = NULL; - int local = 1; + char *var, *val = NULL; if (zstr(data)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No variable name specified.\n"); } else { - exports = switch_channel_get_variable(channel, SWITCH_EXPORT_VARS_VARIABLE); var = switch_core_session_strdup(session, data); - if (var) { - val = strchr(var, '='); - if (!strncasecmp(var, "nolocal:", 8)) { - var_name = var + 8; - local = 0; - } else { - var_name = var; - } - } - if (val) { + if ((val = strchr(var, '='))) { *val++ = '\0'; if (zstr(val)) { val = NULL; } } - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "EXPORT %s[%s]=[%s]\n", local ? "" : "(REMOTE ONLY) ", - var_name ? var_name : "", val ? val : "UNDEF"); - switch_channel_set_variable(channel, var, val); + switch_channel_export_variable(channel, var, val, SWITCH_EXPORT_VARS_VARIABLE); + } +} - if (var && val) { - if (exports) { - new_exports_d = switch_mprintf("%s,%s", exports, var); - new_exports = new_exports_d; - } else { - new_exports = var; +SWITCH_STANDARD_APP(bridge_export_function) +{ + switch_channel_t *channel = switch_core_session_get_channel(session); + char *var, *val = NULL; + + if (zstr(data)) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No variable name specified.\n"); + } else { + var = switch_core_session_strdup(session, data); + + if ((val = strchr(var, '='))) { + *val++ = '\0'; + if (zstr(val)) { + val = NULL; } - - switch_channel_set_variable(channel, SWITCH_EXPORT_VARS_VARIABLE, new_exports); - - switch_safe_free(new_exports_d); } + + switch_channel_export_variable(channel, var, val, SWITCH_BRIDGE_EXPORT_VARS_VARIABLE); } } @@ -3317,6 +3311,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load) SWITCH_ADD_APP(app_interface, "sound_test", "Analyze Audio", "Analyze Audio", sound_test_function, "", SAF_NONE); SWITCH_ADD_APP(app_interface, "export", "Export a channel variable across a bridge", EXPORT_LONG_DESC, export_function, "=", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC); + SWITCH_ADD_APP(app_interface, "bridge_export", "Export a channel variable across a bridge", EXPORT_LONG_DESC, bridge_export_function, "=", + SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC); SWITCH_ADD_APP(app_interface, "set", "Set a channel variable", SET_LONG_DESC, set_function, "=", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC); SWITCH_ADD_APP(app_interface, "set_global", "Set a global variable", SET_GLOBAL_LONG_DESC, set_global_function, "=", diff --git a/src/switch_channel.c b/src/switch_channel.c index ece3fa27bb..81baa2f40d 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -847,29 +847,109 @@ SWITCH_DECLARE(switch_status_t) switch_channel_set_profile_var(switch_channel_t return status; } -SWITCH_DECLARE(switch_status_t) switch_channel_export_variable_var_check(switch_channel_t *channel, const char *varname, const char *value, switch_bool_t var_check) -{ - const char *exports; - switch_status_t status = SWITCH_STATUS_FALSE; - exports = switch_channel_get_variable(channel, SWITCH_EXPORT_VARS_VARIABLE); - - if ((status = switch_channel_set_variable_var_check(channel, varname, value, var_check)) != SWITCH_STATUS_SUCCESS) { - return status; +SWITCH_DECLARE(void) switch_channel_process_export(switch_channel_t *channel, switch_channel_t *peer_channel, + switch_event_t *var_event, const char *export_varname) +{ + + const char *export_vars = switch_channel_get_variable(channel, export_varname); + char *cptmp = switch_core_session_strdup(channel->session, export_vars); + int argc; + char *argv[256]; + + if (zstr(export_vars)) return; + + + if (var_event) { + switch_event_del_header(var_event, export_varname); + switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, export_varname, export_vars); + } + + if (peer_channel) { + switch_channel_set_variable(peer_channel, export_varname, export_vars); } - if (varname && value) { - if (exports) { - switch_channel_set_variable_printf(channel, SWITCH_EXPORT_VARS_VARIABLE, "%s,%s", exports, varname); - } else { - switch_channel_set_variable(channel, SWITCH_EXPORT_VARS_VARIABLE, varname); + if ((argc = switch_separate_string(cptmp, ',', argv, (sizeof(argv) / sizeof(argv[0]))))) { + int x; + + for (x = 0; x < argc; x++) { + const char *vval; + if ((vval = switch_channel_get_variable(channel, argv[x]))) { + char *vvar = argv[x]; + if (!strncasecmp(vvar, "nolocal:", 8)) { + vvar += 8; + } + if (var_event) { + switch_event_del_header(var_event, vvar); + switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, vvar, vval); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(channel->session), SWITCH_LOG_DEBUG, + "%s EXPORTING[%s] [%s]=[%s] to event\n", + switch_channel_get_name(channel), + export_varname, + vvar, vval); + } + if (peer_channel) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(channel->session), SWITCH_LOG_DEBUG, + "%s EXPORTING[%s] [%s]=[%s] to %s\n", + switch_channel_get_name(channel), + export_varname, + vvar, vval, switch_channel_get_name(peer_channel)); + switch_channel_set_variable(peer_channel, vvar, vval); + } + } } } - return status; + } -SWITCH_DECLARE(switch_status_t) switch_channel_export_variable_printf(switch_channel_t *channel, const char *varname, const char *fmt, ...) +SWITCH_DECLARE(switch_status_t) switch_channel_export_variable_var_check(switch_channel_t *channel, + const char *varname, const char *val, + const char *export_varname, switch_bool_t var_check) +{ + char *var_name = NULL; + const char *exports; + char *var, *new_exports, *new_exports_d = NULL; + int local = 1; + + exports = switch_channel_get_variable(channel, export_varname); + + var = switch_core_session_strdup(channel->session, varname); + + if (var) { + if (!strncasecmp(var, "nolocal:", 8)) { + var_name = var + 8; + local = 0; + } else { + var_name = var; + } + } + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(channel->session), SWITCH_LOG_DEBUG, "EXPORT (%s) %s[%s]=[%s]\n", + export_varname, local ? "" : "(REMOTE ONLY) ", + var_name ? var_name : "", val ? val : "UNDEF"); + + + switch_channel_set_variable_var_check(channel, var, val, var_check); + + if (var && val) { + 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, export_varname, new_exports); + + switch_safe_free(new_exports_d); + } + + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_DECLARE(switch_status_t) switch_channel_export_variable_printf(switch_channel_t *channel, const char *varname, + const char *export_varname, const char *fmt, ...) { switch_status_t status = SWITCH_STATUS_FALSE; char *data = NULL; @@ -886,7 +966,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_export_variable_printf(switch_cha return SWITCH_STATUS_FALSE; } - status = switch_channel_export_variable(channel, varname, data); + status = switch_channel_export_variable(channel, varname, export_varname, data); free(data); @@ -902,6 +982,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_set_variable_var_check(switch_cha switch_mutex_lock(channel->profile_mutex); if (channel->variables && !zstr(varname)) { + switch_event_del_header(channel->variables, varname); if (!zstr(value)) { int ok = 1; @@ -3016,7 +3097,7 @@ SWITCH_DECLARE(char *) switch_channel_build_param_string(switch_channel_t *chann new_len = (strlen(prof[x]) * 3) + 1; if (encode_len < new_len) { char *tmp; - + encode_len = new_len; if (!(tmp = realloc(encode_buf, encode_len))) { diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index b317cef628..f92e254008 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -963,6 +963,12 @@ static const switch_state_handler_table_t signal_bridge_state_handlers = { /*.on_hibernate */ signal_bridge_on_hibernate }; +static void check_bridge_export(switch_channel_t *channel, switch_channel_t *peer_channel) +{ + switch_channel_process_export(peer_channel, channel, NULL, SWITCH_BRIDGE_EXPORT_VARS_VARIABLE); + switch_channel_process_export(channel, peer_channel, NULL, SWITCH_BRIDGE_EXPORT_VARS_VARIABLE); +} + SWITCH_DECLARE(switch_status_t) switch_ivr_signal_bridge(switch_core_session_t *session, switch_core_session_t *peer_session) { switch_channel_t *caller_channel = switch_core_session_get_channel(session); @@ -979,6 +985,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_signal_bridge(switch_core_session_t * return SWITCH_STATUS_FALSE; } + check_bridge_export(caller_channel, peer_channel); + switch_channel_set_flag_recursive(caller_channel, CF_SIGNAL_BRIDGE_TTL); switch_channel_set_flag_recursive(peer_channel, CF_SIGNAL_BRIDGE_TTL); @@ -1054,7 +1062,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses return switch_ivr_signal_bridge(session, peer_session); } - + check_bridge_export(caller_channel, peer_channel); + switch_channel_set_flag_recursive(caller_channel, CF_MEDIA_BRIDGE_TTL); switch_channel_set_flag_recursive(peer_channel, CF_MEDIA_BRIDGE_TTL); diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index 1cbd2b9d39..0b5ab77ffd 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -1328,7 +1328,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_enterprise_originate(switch_core_sess int var_block_count = 0; char *e = NULL; switch_event_t *var_event = NULL; - const char *export_vars = NULL; switch_core_new_memory_pool(&pool); @@ -1395,33 +1394,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_enterprise_originate(switch_core_sess } switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "ent_originate_aleg_uuid", switch_core_session_get_uuid(session)); - - /* A comma (,) separated list of variable names that should ne propagated from originator to originatee */ - if (channel && (export_vars = switch_channel_get_variable(channel, SWITCH_EXPORT_VARS_VARIABLE))) { - char *cptmp = switch_core_session_strdup(session, export_vars); - int argc; - char *argv[256]; - switch_event_del_header(var_event, SWITCH_EXPORT_VARS_VARIABLE); - switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, SWITCH_EXPORT_VARS_VARIABLE, export_vars); - - if ((argc = switch_separate_string(cptmp, ',', argv, (sizeof(argv) / sizeof(argv[0]))))) { - int x; - - for (x = 0; x < argc; x++) { - const char *vval; - if ((vval = switch_channel_get_variable(channel, argv[x]))) { - char *vvar = argv[x]; - if (!strncasecmp(vvar, "nolocal:", 8)) { - vvar += 8; - } - switch_event_del_header(var_event, vvar); - switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, vvar, vval); - } - } - } + if (channel) { + switch_channel_process_export(channel, NULL, var_event, SWITCH_EXPORT_VARS_VARIABLE); } - + if (vars) { /* Parse parameters specified from the dialstring */ char *var_array[1024] = { 0 }; int var_count = 0; @@ -1756,7 +1733,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess const char *cancel_key = NULL; const char *holding = NULL; const char *soft_holding = NULL; - const char *export_vars = NULL; early_state_t early_state = { 0 }; int read_packet = 0; @@ -1945,27 +1921,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess } } - /* A comma (,) separated list of variable names that should ne propagated from originator to originatee */ - if (caller_channel && (export_vars = switch_channel_get_variable(caller_channel, SWITCH_EXPORT_VARS_VARIABLE))) { - char *cptmp = switch_core_session_strdup(session, export_vars); - int argc; - char *argv[256]; - - if ((argc = switch_separate_string(cptmp, ',', argv, (sizeof(argv) / sizeof(argv[0]))))) { - int x; - - for (x = 0; x < argc; x++) { - const char *vval; - if ((vval = switch_channel_get_variable(caller_channel, argv[x]))) { - char *vvar = argv[x]; - if (!strncasecmp(vvar, "nolocal:", 8)) { - vvar += 8; - } - switch_event_del_header(var_event, vvar); - switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, vvar, vval); - } - } - } + if (caller_channel) { + switch_channel_process_export(caller_channel, NULL, var_event, SWITCH_EXPORT_VARS_VARIABLE); } if (vars) { /* Parse parameters specified from the dialstring */