From 58f281a67059c4348ac84544210f03a7527883d6 Mon Sep 17 00:00:00 2001 From: Mark Michelson Date: Tue, 31 Jul 2012 21:21:57 +0000 Subject: [PATCH] Add "setvar" option to manager.conf. With this option set, channel variables can be set on every manager originate. The Variable header can still be used to set additional channel variables for individual calls if desired. This work was completed by Olle Johansson on review board. I have applied the review feedback and am committing it in order to get this into trunk before Asterisk 11 is branched. Review: https://reviewboard.asterisk.org/r/1412 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@370681 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- CHANGES | 3 ++- configs/manager.conf.sample | 6 +++++ main/manager.c | 46 ++++++++++++++++++++++++++++++++++++- 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 7d5e7fbc71..3baf959fa3 100644 --- a/CHANGES +++ b/CHANGES @@ -7,7 +7,6 @@ === and the other UPGRADE files for older releases. === ============================================================================== - ------------------------------------------------------------------------------ --- Functionality changes from Asterisk 10 to Asterisk 11 -------------------- ------------------------------------------------------------------------------ @@ -420,6 +419,8 @@ AGI AMI (Asterisk Manager Interface) ------------------ + * Added setvar= option to manager accounts (much like sip.conf) + * Originate now generates an error response if the extension given is not found in the dialplan diff --git a/configs/manager.conf.sample b/configs/manager.conf.sample index 31c1820079..54f6928c86 100644 --- a/configs/manager.conf.sample +++ b/configs/manager.conf.sample @@ -87,6 +87,12 @@ bindaddr = 0.0.0.0 ;permit=209.16.236.73/255.255.255.0 ;acl=named_acl_example ; use a named ACL from acl.conf ; +; +;setvar=PBXACCOUNT=edvina +; The setvar option defines channel variables that will be set when this account +; originates a call. You can define multiple setvar= commands for one manager +; user. +; ;eventfilter=Event: Newchannel ;eventfilter=!Channel: DAHDI* ; The eventfilter option is used to whitelist or blacklist events per user to be diff --git a/main/manager.c b/main/manager.c index 84eb33d163..f7fa7b53db 100644 --- a/main/manager.c +++ b/main/manager.c @@ -1082,6 +1082,7 @@ struct mansession_session { int inlen; /*!< number of buffered bytes */ struct ao2_container *whitefilters; /*!< Manager event filters - white list */ struct ao2_container *blackfilters; /*!< Manager event filters - black list */ + struct ast_variable *chanvars; /*!< Channel variables to set for originate */ int send_events; /*!< XXX what ? */ struct eventqent *last_ev; /*!< last event processed. */ int writetimeout; /*!< Timeout for ast_carefulwrite() */ @@ -1137,6 +1138,7 @@ struct ast_manager_user { struct ao2_container *blackfilters; /*!< Manager event filters - black list */ struct ast_acl_list *acl; /*!< ACL setting */ char *a1_hash; /*!< precalculated A1 for Digest auth */ + struct ast_variable *chanvars; /*!< Channel variables to set for originate */ AST_RWLIST_ENTRY(ast_manager_user) list; }; @@ -1430,6 +1432,9 @@ static void session_destructor(void *obj) if (eqe) { ast_atomic_fetchadd_int(&eqe->usecount, -1); } + if (session->chanvars) { + ast_variables_destroy(session->chanvars); + } if (session->whitefilters) { ao2_t_callback(session->whitefilters, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL, "unlink all white filters"); @@ -1643,6 +1648,7 @@ static char *handle_showmanager(struct ast_cli_entry *e, int cmd, struct ast_cli char *ret = NULL; struct ast_str *rauthority = ast_str_alloca(128); struct ast_str *wauthority = ast_str_alloca(128); + struct ast_variable *v; switch (cmd) { case CLI_INIT: @@ -1694,6 +1700,10 @@ static char *handle_showmanager(struct ast_cli_entry *e, int cmd, struct ast_cli authority_to_str(user->readperm, &rauthority), authority_to_str(user->writeperm, &wauthority), (user->displayconnects ? "yes" : "no")); + ast_cli(a->fd, " Variables: \n"); + for (v = user->chanvars ; v ; v = v->next) { + ast_cli(a->fd, " %s = %s\n", v->name, v->value); + } AST_RWLIST_UNLOCK(&users); @@ -2546,6 +2556,7 @@ static int authenticate(struct mansession *s, const struct message *m) s->session->readperm = user->readperm; s->session->writeperm = user->writeperm; s->session->writetimeout = user->writetimeout; + s->session->chanvars = ast_variables_dup(user->chanvars); filter_iter = ao2_iterator_init(user->whitefilters, 0); while ((regex_filter = ao2_iterator_next(&filter_iter))) { @@ -4210,7 +4221,7 @@ static int action_originate(struct mansession *s, const struct message *m) const char *async = astman_get_header(m, "Async"); const char *id = astman_get_header(m, "ActionID"); const char *codecs = astman_get_header(m, "Codecs"); - struct ast_variable *vars; + struct ast_variable *vars = NULL; char *tech, *data; char *l = NULL, *n = NULL; int pi = 0; @@ -4308,6 +4319,21 @@ static int action_originate(struct mansession *s, const struct message *m) /* Allocate requested channel variables */ vars = astman_get_variables(m); + if (s->session->chanvars) { + struct ast_variable *v, *old; + old = vars; + vars = NULL; + + /* The variables in the AMI originate action are appended at the end of the list, to override any user variables that apply*/ + + vars = ast_variables_dup(s->session->chanvars); + if (old) { + for (v = vars; v->next; v = v->next ); + if (v->next) { + v->next = old; /* Append originate variables at end of list */ + } + } + } if (ast_true(async)) { struct fast_originate_helper *fast; @@ -7425,6 +7451,7 @@ static int __init_manager(int reload, int by_external_config) user->keep = 1; oldacl = user->acl; user->acl = NULL; + ast_variables_destroy(user->chanvars); var = ast_variable_browse(cfg, cat); for (; var; var = var->next) { @@ -7450,6 +7477,22 @@ static int __init_manager(int reload, int by_external_config) } else { user->writetimeout = value; } + } else if (!strcasecmp(var->name, "setvar")) { + struct ast_variable *tmpvar; + char varbuf[256]; + char *varval; + char *varname; + + ast_copy_string(varbuf, var->value, sizeof(varbuf)); + varname = varbuf; + + if ((varval = strchr(varname,'='))) { + *varval++ = '\0'; + if ((tmpvar = ast_variable_new(varname, varval, ""))) { + tmpvar->next = user->chanvars; + user->chanvars = tmpvar; + } + } } else if (!strcasecmp(var->name, "eventfilter")) { const char *value = var->value; manager_add_filter(value, user->whitefilters, user->blackfilters); @@ -7496,6 +7539,7 @@ static int __init_manager(int reload, int by_external_config) ao2_t_ref(user->whitefilters, -1, "decrement ref for white container, should be last one"); ao2_t_ref(user->blackfilters, -1, "decrement ref for black container, should be last one"); user->acl = ast_free_acl_list(user->acl); + ast_variables_destroy(user->chanvars); ast_free(user); } AST_RWLIST_TRAVERSE_SAFE_END;