From b2c3199f653ab6f9d3fd8d218c24a4962feda2ca Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 15 Jun 2011 13:03:39 -0500 Subject: [PATCH] add scoped channel variables (%[var=val,var2=val2] blocks valid in any app data field and will only last for that one app execution) --- src/include/switch_channel.h | 2 ++ src/switch_channel.c | 52 +++++++++++++++++++++++++++++++++++- src/switch_core_session.c | 29 +++++++++++++++++++- 3 files changed, 81 insertions(+), 2 deletions(-) diff --git a/src/include/switch_channel.h b/src/include/switch_channel.h index 40d4ee6b13..11ce877b8e 100644 --- a/src/include/switch_channel.h +++ b/src/include/switch_channel.h @@ -279,6 +279,8 @@ SWITCH_DECLARE(void) switch_channel_process_export(switch_channel_t *channel, sw 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_DECLARE(void) switch_channel_set_scope_variables(switch_channel_t *channel, switch_event_t **event); +SWITCH_DECLARE(switch_status_t) switch_channel_get_scope_variables(switch_channel_t *channel, switch_event_t **event); /*! \brief Retrieve a variable from a given channel diff --git a/src/switch_channel.c b/src/switch_channel.c index ec01c22a52..67046aec70 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -131,6 +131,7 @@ struct switch_channel { const switch_state_handler_table_t *state_handlers[SWITCH_MAX_STATE_HANDLERS]; int state_handler_index; switch_event_t *variables; + switch_event_t *scope_variables; switch_hash_t *private_hash; switch_hash_t *app_flag_hash; switch_call_cause_t hangup_cause; @@ -692,13 +693,47 @@ SWITCH_DECLARE(const char *) switch_channel_get_hold_music_partner(switch_channe return r; } +SWITCH_DECLARE(void) switch_channel_set_scope_variables(switch_channel_t *channel, switch_event_t **event) +{ + switch_mutex_lock(channel->profile_mutex); + if (channel->scope_variables) { + switch_event_destroy(&channel->scope_variables); + } + if (event) { + channel->scope_variables = *event; + *event = NULL; + } else { + channel->scope_variables = NULL; + } + switch_mutex_unlock(channel->profile_mutex); + +} + +SWITCH_DECLARE(switch_status_t) switch_channel_get_scope_variables(switch_channel_t *channel, switch_event_t **event) +{ + switch_status_t status = SWITCH_STATUS_FALSE; + + switch_mutex_lock(channel->profile_mutex); + if (channel->scope_variables) { + status = switch_event_dup(event, channel->scope_variables); + } + switch_mutex_unlock(channel->profile_mutex); + + return status; +} + SWITCH_DECLARE(const char *) switch_channel_get_variable_dup(switch_channel_t *channel, const char *varname, switch_bool_t dup, int idx) { const char *v = NULL, *r = NULL, *vdup = NULL; switch_assert(channel != NULL); switch_mutex_lock(channel->profile_mutex); - if (!channel->variables || !(v = switch_event_get_header_idx(channel->variables, varname, idx))) { + + if (channel->scope_variables) { + v = switch_event_get_header_idx(channel->scope_variables, varname, idx); + } + + if (!v && (!channel->variables || !(v = switch_event_get_header_idx(channel->variables, varname, idx)))) { switch_caller_profile_t *cp = channel->caller_profile; if (cp) { @@ -2129,6 +2164,21 @@ SWITCH_DECLARE(void) switch_channel_event_set_extended_data(switch_channel_t *ch event->event_id == SWITCH_EVENT_CUSTOM) { /* Index Variables */ + + if (channel->scope_variables) { + for (hi = channel->scope_variables->headers; hi; hi = hi->next) { + char buf[1024]; + char *vvar = NULL, *vval = NULL; + + vvar = (char *) hi->name; + vval = (char *) hi->value; + + switch_assert(vvar && vval); + switch_snprintf(buf, sizeof(buf), "scope_variable_%s", vvar); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, buf, vval); + } + } + if (channel->variables) { for (hi = channel->variables->headers; hi; hi = hi->next) { char buf[1024]; diff --git a/src/switch_core_session.c b/src/switch_core_session.c index ea07a7805e..89a78f51e3 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -1979,7 +1979,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_exec(switch_core_session_t * char *expanded = NULL; const char *app; switch_core_session_message_t msg = { 0 }; - + char delim = ','; + switch_assert(application_interface); app = application_interface->interface_name; @@ -1988,6 +1989,30 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_exec(switch_core_session_t * expanded = switch_channel_expand_variables(session->channel, arg); } + if (expanded && *expanded == '%' && (*(expanded+1) == '[' || *(expanded+2) == '[')) { + char *p, *dup; + switch_event_t *ovars = NULL; + + p = expanded + 1; + + if (*p != '[') { + delim = *p; + p++; + } + + dup = strdup(p); + + if (expanded != arg) { + switch_safe_free(expanded); + } + + switch_event_create_brackets(dup, '[', ']', delim, &ovars, &expanded, SWITCH_TRUE); + free(dup); + + switch_channel_set_scope_variables(session->channel, &ovars); + } + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG, "EXECUTE %s %s(%s)\n", switch_channel_get_name(session->channel), app, switch_str_nil(expanded)); @@ -2066,6 +2091,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_exec(switch_core_session_t * switch_safe_free(expanded); } + switch_channel_set_scope_variables(session->channel, NULL); + return SWITCH_STATUS_SUCCESS; }