]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add scoped channel variables (%[var=val,var2=val2] blocks valid in any app data field...
authorAnthony Minessale <anthm@freeswitch.org>
Wed, 15 Jun 2011 18:03:39 +0000 (13:03 -0500)
committerAnthony Minessale <anthm@freeswitch.org>
Wed, 15 Jun 2011 18:03:45 +0000 (13:03 -0500)
src/include/switch_channel.h
src/switch_channel.c
src/switch_core_session.c

index 40d4ee6b13d1e6ff1fc13d15d5f5ddfaae81a85e..11ce877b8e3e46fd04748abf526f8853ca4cfff2 100644 (file)
@@ -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
index ec01c22a52a4eba3119ec986d0787cd52c78ca43..67046aec7073d5fc1c1f11fd778b5ecfb2f2f939 100644 (file)
@@ -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];
index ea07a7805e1df950821b183e56802e2f537d407d..89a78f51e3d3859505d06aad7d263e5f5194ad37 100644 (file)
@@ -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;
 }