Make channel variables inheritable by _ (bug #928)
authorMark Spencer <markster@digium.com>
Mon, 1 Nov 2004 02:23:28 +0000 (02:23 +0000)
committerMark Spencer <markster@digium.com>
Mon, 1 Nov 2004 02:23:28 +0000 (02:23 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@4141 65c4cc65-6c06-0410-ace0-fbb531ad65f3

apps/app_dial.c
chanvars.c
include/asterisk/chanvars.h
pbx.c

index 04ea18b..bc1cfcb 100755 (executable)
@@ -48,7 +48,7 @@ static char *descrip =
 "Requests one or more channels and places specified outgoing calls on them.\n"
 "As soon as a channel answers, the Dial app will answer the originating\n"
 "channel (if it needs to be answered) and will bridge a call with the channel\n"
-"which first answered. All other calls placed by the Dial app will be hung up\n"
+"which first answered. All other calls placed by the Dial app will be hung up.\n"
 "If a timeout is not specified, the Dial application will wait indefinitely\n"
 "until either one of the called channels answers, the user hangs up, or all\n"
 "channels return busy or error. In general, the dialer will return 0 if it\n"
@@ -482,6 +482,9 @@ static int dial_exec(struct ast_channel *chan, void *data)
        char toast[80];
        int play_to_caller=0,play_to_callee=0;
        int playargs=0, sentringing=0, moh=0;
+       char *varname;
+       int vartype;
+
        int digit = 0;
        time_t start_time, answer_time, end_time;
 
@@ -512,9 +515,12 @@ static int dial_exec(struct ast_channel *chan, void *data)
                                if (url) {
                                        *url = '\0';
                                        url++;
-                                       ast_log(LOG_DEBUG, "DIAL WITH URL=%s_\n", url);
+                                       if (option_debug)
+                                               ast_log(LOG_DEBUG, "DIAL WITH URL=%s_\n", url);
                                } else 
-                                       ast_log(LOG_DEBUG, "SIMPLE DIAL (NO URL)\n");
+                                       if (option_debug) {
+                                               ast_log(LOG_DEBUG, "SIMPLE DIAL (NO URL)\n");
+                                       }
                                /* /JDG */
                        }
                }
@@ -792,27 +798,42 @@ static int dial_exec(struct ast_channel *chan, void *data)
                                continue;
                        }
                }
-               /* If creating a SIP channel, look for a variable called */
-               /* VXML_URL in the calling channel and copy it to the    */
-               /* new channel.                                          */
 
-               /* Check for ALERT_INFO in the SetVar list.  This is for   */
-               /* SIP distinctive ring as per the RFC.  For Cisco 7960s,  */
-               /* SetVar(ALERT_INFO=<x>) where x is an integer value 1-5. */
-               /* However, the RFC says it should be a URL.  -km-         */
-               headp=&chan->varshead;
-               AST_LIST_TRAVERSE(headp,current,entries) {
-                       if (!strcasecmp(ast_var_name(current),"VXML_URL") ||
-                           !strcasecmp(ast_var_name(current), "ALERT_INFO") ||
-                               !strcasecmp(ast_var_name(current), "OSPTOKEN") ||
-                               !strcasecmp(ast_var_name(current), "OSPHANDLE"))
-                       {
-                               newvar=ast_var_assign(ast_var_name(current),ast_var_value(current));
-                               newheadp=&tmp->chan->varshead;
-                               AST_LIST_INSERT_HEAD(newheadp,newvar,entries);
+               /* Contitionally copy channel variables to the newly created channel */
+               headp = &chan->varshead;
+               AST_LIST_TRAVERSE(headp, current, entries) {
+                       varname = ast_var_full_name(current);
+                       vartype = 0;
+                       if (varname) {
+                               if (varname[0] == '_') {
+                                       vartype = 1;
+                                       if (varname[1] == '_')
+                                               vartype = 2;
+                               }
+                       }
+                       if (vartype == 1) {
+                               newvar = ast_var_assign((char*)&(varname[1]), 
+                                                                                               ast_var_value(current));
+                               newheadp = &tmp->chan->varshead;
+                               AST_LIST_INSERT_HEAD(newheadp, newvar, entries);
+                               if (option_debug)
+                                       ast_log(LOG_DEBUG, "Copying soft-transferable variable %s.\n", 
+                                                                                               ast_var_name(newvar));
+                       } else if (vartype == 2) {
+                               newvar = ast_var_assign(ast_var_full_name(current), 
+                                                                                               ast_var_value(current));
+                               newheadp = &tmp->chan->varshead;
+                               AST_LIST_INSERT_HEAD(newheadp, newvar, entries);
+                               if (option_debug)
+                                       ast_log(LOG_DEBUG, "Copying hard-transferable variable %s.\n", 
+                                                                                               ast_var_name(newvar));
+                       } else {
+                               if (option_debug)
+                                       ast_log(LOG_DEBUG, "Not copying variable %s.\n", 
+                                                                                               ast_var_name(current));
                        }
                }
-               
+
                tmp->chan->appl = "AppDial";
                tmp->chan->data = "(Outgoing Line)";
                tmp->chan->whentohangup = 0;
index bc13b22..dabfdda 100755 (executable)
@@ -70,6 +70,25 @@ void ast_var_delete(struct ast_var_t *var)
 
 char *ast_var_name(struct ast_var_t *var)
 {
+       char *name;
+
+       if (var == NULL)
+               return NULL;
+       if (var->name == NULL)
+               return NULL;
+       /* Return the name without the initial underscores */
+       if ((strlen(var->name) > 0) && (var->name[0] == '_')) {
+               if ((strlen(var->name) > 1) && (var->name[1] == '_'))
+                       name = (char*)&(var->name[2]);
+               else
+                       name = (char*)&(var->name[1]);
+       } else
+               name = var->name;
+       return name;
+}
+
+char *ast_var_full_name(struct ast_var_t *var)
+{
        return (var != NULL ? var->name : NULL);
 }
 
index a871707..4e0ecc6 100755 (executable)
@@ -25,6 +25,7 @@ struct ast_var_t {
 struct ast_var_t *ast_var_assign(const char *name, const char *value);
 void ast_var_delete(struct ast_var_t *var);
 char *ast_var_name(struct ast_var_t *var);
+char *ast_var_full_name(struct ast_var_t *var);
 char *ast_var_value(struct ast_var_t *var);
 
 #endif
diff --git a/pbx.c b/pbx.c
index 85bd151..de29e10 100755 (executable)
--- a/pbx.c
+++ b/pbx.c
 #define EXT_DATA_SIZE 8192
 #endif
 
+#define        VAR_NORMAL              1
+#define        VAR_SOFTTRAN    2
+#define        VAR_HARDTRAN    3
+
 struct ast_context;
 
 /* ast_exten: An extension */
@@ -375,8 +379,8 @@ static struct pbx_builtin {
 
        { "SetVar", pbx_builtin_setvar,
        "Set variable to value",
-       "  Setvar(#n=value): Sets channel specific variable n to value" 
-       },
+       "  SetVar(#n=value): Sets variable n to value.  If prefixed with _, single\n"
+       "inheritance assumed.  If prefixed with __, infinite inheritance is assumed.\n" },
 
        { "StripMSD", pbx_builtin_stripmsd,
        "Strip leading digits",
@@ -4970,29 +4974,30 @@ char *pbx_builtin_getvar_helper(struct ast_channel *chan, char *name)
        return NULL;
 }
 
-void pbx_builtin_setvar_helper(struct ast_channel *chan, char *name, char *value) 
+void pbx_builtin_setvar_helper(struct ast_channel *chan, char *name, char *value)
 {
        struct ast_var_t *newvariable;
        struct varshead *headp;
+
        if (chan)
-               headp=&chan->varshead;
+               headp = &chan->varshead;
        else
-               headp=&globals;
-                
-       AST_LIST_TRAVERSE (headp,newvariable,entries) {
-               if (strcasecmp(ast_var_name(newvariable),name)==0) {
+               headp = &globals;
+
+       AST_LIST_TRAVERSE (headp, newvariable, entries) {
+               if (strcasecmp(ast_var_name(newvariable), name) == 0) {
                        /* there is already such a variable, delete it */
-                       AST_LIST_REMOVE(headp,newvariable,ast_var_t,entries);
+                       AST_LIST_REMOVE(headp, newvariable, ast_var_t, entries);
                        ast_var_delete(newvariable);
                        break;
                }
        } 
-       
+
        if (value) {
                if ((option_verbose > 1) && (headp == &globals))
-                       ast_verbose(VERBOSE_PREFIX_3 "Setting global variable '%s' to '%s'\n",name, value);
-               newvariable=ast_var_assign(name,value); 
-               AST_LIST_INSERT_HEAD(headp,newvariable,entries);
+                       ast_verbose(VERBOSE_PREFIX_3 "Setting global variable '%s' to '%s'\n", name, value);
+               newvariable = ast_var_assign(name, value);      
+               AST_LIST_INSERT_HEAD(headp, newvariable, entries);
        }
 }
 
@@ -5001,41 +5006,40 @@ int pbx_builtin_setvar(struct ast_channel *chan, void *data)
        char *name;
        char *value;
        char *stringp=NULL;
-                
+
        if (!data || ast_strlen_zero(data)) {
                ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n");
                return 0;
        }
-       
-       stringp=data;
-       name=strsep(&stringp,"=");
-       value=strsep(&stringp,"\0"); 
-       
-       pbx_builtin_setvar_helper(chan,name,value);
-                       
-        return(0);
+
+       stringp = data;
+       name = strsep(&stringp,"=");
+       value = strsep(&stringp,"\0"); 
+
+       pbx_builtin_setvar_helper(chan, name, value);
+
+       return(0);
 }
 
 static int pbx_builtin_setglobalvar(struct ast_channel *chan, void *data)
 {
        char *name;
        char *value;
-       char *stringp=NULL;
-                
+       char *stringp = NULL;
+
        if (!data || ast_strlen_zero(data)) {
                ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n");
                return 0;
        }
-       
-       stringp=data;
-       name=strsep(&stringp,"=");
-       value=strsep(&stringp,"\0"); 
-       
-       pbx_builtin_setvar_helper(NULL,name,value);
-                       
-        return(0);
-}
 
+       stringp = data;
+       name = strsep(&stringp, "=");
+       value = strsep(&stringp, "\0"); 
+
+       pbx_builtin_setvar_helper(NULL, name, value);
+
+       return(0);
+}
 
 static int pbx_builtin_noop(struct ast_channel *chan, void *data)
 {