Make channel variables inheritable by _ (bug #928)

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@4141 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Mark Spencer
2004-11-01 02:23:28 +00:00
parent a872c59003
commit 668001f9c8
4 changed files with 99 additions and 54 deletions

View File

@@ -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,24 +798,39 @@ 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));
}
}

View File

@@ -69,6 +69,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);
}

View File

@@ -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

52
pbx.c
View File

@@ -56,6 +56,10 @@
#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",
@@ -4974,15 +4978,16 @@ 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;
else
headp=&globals;
AST_LIST_TRAVERSE (headp,newvariable,entries) {
if (strcasecmp(ast_var_name(newvariable),name)==0) {
if (chan)
headp = &chan->varshead;
else
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;
}
@@ -4990,9 +4995,9 @@ void pbx_builtin_setvar_helper(struct ast_channel *chan, char *name, char *value
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);
}
}
@@ -5007,36 +5012,35 @@ int pbx_builtin_setvar(struct ast_channel *chan, void *data)
return 0;
}
stringp=data;
name=strsep(&stringp,"=");
value=strsep(&stringp,"\0");
stringp = data;
name = strsep(&stringp,"=");
value = strsep(&stringp,"\0");
pbx_builtin_setvar_helper(chan,name,value);
pbx_builtin_setvar_helper(chan, name, value);
return(0);
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");
stringp = data;
name = strsep(&stringp, "=");
value = strsep(&stringp, "\0");
pbx_builtin_setvar_helper(NULL,name,value);
pbx_builtin_setvar_helper(NULL, name, value);
return(0);
return(0);
}
static int pbx_builtin_noop(struct ast_channel *chan, void *data)
{
return 0;