[asterisk-commits] dlee: branch dlee/ASTERISK-21096 r383394 - in /team/dlee/ASTERISK-21096: ./ i...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Mar 19 15:48:57 CDT 2013
Author: dlee
Date: Tue Mar 19 15:48:54 2013
New Revision: 383394
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=383394
Log:
Added manager variables to channel snapshot.
This allows AMI events derived from Stasis snapshots to include channel
variables, as configured in manager.conf/channelvars. These are added
to all channel-related events, as the documentation suggests they should.
In the process, I removed the processing of channelvars as a pipe-separated
list, since that behavior has long been deprecated.
Modified:
team/dlee/ASTERISK-21096/CHANGES
team/dlee/ASTERISK-21096/include/asterisk/channel.h
team/dlee/ASTERISK-21096/main/channel.c
team/dlee/ASTERISK-21096/main/manager.c
team/dlee/ASTERISK-21096/main/manager_channels.c
Modified: team/dlee/ASTERISK-21096/CHANGES
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-21096/CHANGES?view=diff&rev=383394&r1=383393&r2=383394
==============================================================================
--- team/dlee/ASTERISK-21096/CHANGES (original)
+++ team/dlee/ASTERISK-21096/CHANGES Tue Mar 19 15:48:54 2013
@@ -49,6 +49,9 @@
* The AMI event 'UserEvent' from app_userevent now contains the channel state
fields. The channel state fields will come before the body fields.
+
+ * The deprecated use of | (pipe) as a separator in the channelvars setting in
+ manager.conf has been removed.
Channel Drivers
------------------
Modified: team/dlee/ASTERISK-21096/include/asterisk/channel.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-21096/include/asterisk/channel.h?view=diff&rev=383394&r1=383393&r2=383394
==============================================================================
--- team/dlee/ASTERISK-21096/include/asterisk/channel.h (original)
+++ team/dlee/ASTERISK-21096/include/asterisk/channel.h Tue Mar 19 15:48:54 2013
@@ -4139,6 +4139,8 @@
int caller_pres; /*!< Caller ID presentation. */
struct ast_flags flags; /*!< channel flags of AST_FLAG_ type */
+
+ struct varshead *manager_vars; /*!< Variables to be appended to manager events */
};
/*!
@@ -4152,6 +4154,27 @@
* \retval NULL on error
*/
struct ast_channel_snapshot *ast_channel_snapshot_create(struct ast_channel *chan);
+
+/*!
+ * \since 12
+ * \brief Sets the variables to be stored in the \a manager_vars field of all
+ * snapshots.
+ * \param vars Array of variable names.
+ * \param varc Number of variable names.
+ */
+void ast_channel_set_manager_vars(char **vars, size_t varc);
+
+/*!
+ * \since 12
+ * \brief Gets the variables for a given channel, as specified by ast_channel_set_manager_vars().
+ *
+ * The returned variable list is an AO2 object, so ao2_cleanup() to free it.
+ *
+ * \param chan Channel to get variables for.
+ * \return List of channel variables.
+ * \return \c NULL on error
+ */
+struct varshead *ast_channel_get_manager_vars(struct ast_channel *chan);
/*!
* \since 12
Modified: team/dlee/ASTERISK-21096/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-21096/main/channel.c?view=diff&rev=383394&r1=383393&r2=383394
==============================================================================
--- team/dlee/ASTERISK-21096/main/channel.c (original)
+++ team/dlee/ASTERISK-21096/main/channel.c Tue Mar 19 15:48:54 2013
@@ -8605,8 +8605,108 @@
prnt(where, "%s", ast_channel_name(chan));
}
+/*!
+ * \brief List of channel variables to append to all channel-related events.
+ */
+struct manager_channel_variable {
+ AST_LIST_ENTRY(manager_channel_variable) entry;
+ unsigned int isfunc:1;
+ char name[];
+};
+
+static AST_RWLIST_HEAD_STATIC(channelvars, manager_channel_variable);
+
+static void free_channelvars(void)
+{
+ struct manager_channel_variable *var;
+ AST_RWLIST_WRLOCK(&channelvars);
+ while ((var = AST_RWLIST_REMOVE_HEAD(&channelvars, entry))) {
+ ast_free(var);
+ }
+ AST_RWLIST_UNLOCK(&channelvars);
+}
+
+void ast_channel_set_manager_vars(char **vars, size_t varc)
+{
+ size_t i;
+
+ free_channelvars();
+ AST_RWLIST_WRLOCK(&channelvars);
+ for (i = 0; i < varc; ++i) {
+ const char *var = vars[i];
+ struct manager_channel_variable *mcv;
+ if (!(mcv = ast_calloc(1, sizeof(*mcv) + strlen(var) + 1))) {
+ break;
+ }
+ strcpy(mcv->name, var); /* SAFE */
+ if (strchr(var, '(')) {
+ mcv->isfunc = 1;
+ }
+ AST_RWLIST_INSERT_TAIL(&channelvars, mcv, entry);
+ }
+ AST_RWLIST_UNLOCK(&channelvars);
+}
+
+/*!
+ * \brief Destructor for the return value from ast_channel_get_manager_vars().
+ * \param obj AO2 object.
+ */
+static void varshead_dtor(void *obj)
+{
+ struct varshead *head = obj;
+ struct ast_var_t *var;
+
+ while ((var = AST_RWLIST_REMOVE_HEAD(head, entries))) {
+ ast_var_delete(var);
+ }
+}
+
+struct varshead *ast_channel_get_manager_vars(struct ast_channel *chan)
+{
+ RAII_VAR(struct varshead *, ret, NULL, ao2_cleanup);
+ RAII_VAR(struct ast_str *, tmp, NULL, ast_free);
+ struct manager_channel_variable *mcv;
+
+ ret = ao2_alloc(sizeof(*ret), varshead_dtor);
+ tmp = ast_str_create(16);
+
+ if (!ret || !tmp) {
+ return NULL;
+ }
+
+ AST_RWLIST_RDLOCK(&channelvars);
+ AST_LIST_TRAVERSE(&channelvars, mcv, entry) {
+ const char *val = NULL;
+ struct ast_var_t *var;
+
+ if (mcv->isfunc) {
+ if (ast_func_read2(chan, mcv->name, &tmp, 0) == 0) {
+ val = ast_str_buffer(tmp);
+ } else {
+ ast_log(LOG_ERROR,
+ "Error invoking function %s\n", mcv->name);
+ }
+ } else {
+ val = pbx_builtin_getvar_helper(chan, mcv->name);
+ }
+
+ var = ast_var_assign(mcv->name, val ? val : "");
+ if (!var) {
+ AST_RWLIST_UNLOCK(&channelvars);
+ return NULL;
+ }
+
+ AST_RWLIST_INSERT_TAIL(ret, var, entries);
+ }
+ AST_RWLIST_UNLOCK(&channelvars);
+
+ ao2_ref(ret, +1);
+ return ret;
+}
+
static void channels_shutdown(void)
{
+ free_channelvars();
ao2_cleanup(__channel_snapshot);
__channel_snapshot = NULL;
ao2_cleanup(__channel_blob);
@@ -11232,6 +11332,7 @@
{
struct ast_channel_snapshot *snapshot = obj;
ast_string_field_free_memory(snapshot);
+ ao2_cleanup(snapshot->manager_vars);
}
struct ast_channel_snapshot *ast_channel_snapshot_create(struct ast_channel *chan)
@@ -11277,6 +11378,8 @@
snapshot->hangupcause = ast_channel_hangupcause(chan);
snapshot->flags = *ast_channel_flags(chan);
snapshot->caller_pres = ast_party_id_presentation(&ast_channel_caller(chan)->id);
+
+ snapshot->manager_vars = ast_channel_get_manager_vars(chan);
ao2_ref(snapshot, +1);
return snapshot;
Modified: team/dlee/ASTERISK-21096/main/manager.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-21096/main/manager.c?view=diff&rev=383394&r1=383393&r2=383394
==============================================================================
--- team/dlee/ASTERISK-21096/main/manager.c (original)
+++ team/dlee/ASTERISK-21096/main/manager.c Tue Mar 19 15:48:54 2013
@@ -1041,6 +1041,8 @@
static struct ast_event_sub *acl_change_event_subscription;
#define MGR_SHOW_TERMINAL_WIDTH 80
+
+#define MAX_VARS 128
/*! \brief
* Descriptor for a manager session, either on the AMI socket or over HTTP.
@@ -1167,14 +1169,6 @@
static struct ao2_container *sessions = NULL;
-struct manager_channel_variable {
- AST_LIST_ENTRY(manager_channel_variable) entry;
- unsigned int isfunc:1;
- char name[0]; /* allocate off the end the real size. */
-};
-
-static AST_RWLIST_HEAD_STATIC(channelvars, manager_channel_variable);
-
/*! \brief user descriptor, as read from the config file.
*
* \note It is still missing some fields -- e.g. we can have multiple permit and deny
@@ -1208,8 +1202,6 @@
/*! \brief A container of event documentation nodes */
AO2_GLOBAL_OBJ_STATIC(event_docs);
-
-static void free_channelvars(void);
static enum add_filter_result manager_add_filter(const char *filter_pattern, struct ao2_container *whitefilters, struct ao2_container *blackfilters);
@@ -5650,30 +5642,16 @@
return 0;
}
-AST_THREADSTORAGE(manager_event_funcbuf);
-
static void append_channel_vars(struct ast_str **pbuf, struct ast_channel *chan)
{
- struct manager_channel_variable *var;
-
- AST_RWLIST_RDLOCK(&channelvars);
- AST_LIST_TRAVERSE(&channelvars, var, entry) {
- const char *val;
- struct ast_str *res;
-
- if (var->isfunc) {
- res = ast_str_thread_get(&manager_event_funcbuf, 16);
- if (res && ast_func_read2(chan, var->name, &res, 0) == 0) {
- val = ast_str_buffer(res);
- } else {
- val = NULL;
- }
- } else {
- val = pbx_builtin_getvar_helper(chan, var->name);
- }
- ast_str_append(pbuf, 0, "ChanVariable(%s): %s=%s\r\n", ast_channel_name(chan), var->name, val ? val : "");
- }
- AST_RWLIST_UNLOCK(&channelvars);
+ RAII_VAR(struct varshead *, vars, NULL, ao2_cleanup);
+ struct ast_var_t *var;
+
+ vars = ast_channel_get_manager_vars(chan);
+
+ AST_LIST_TRAVERSE(vars, var, entries) {
+ ast_str_append(pbuf, 0, "ChanVariable(%s): %s=%s\r\n", ast_channel_name(chan), var->name, var->value);
+ }
}
/* XXX see if can be moved inside the function */
@@ -7350,31 +7328,19 @@
*/
static void load_channelvars(struct ast_variable *var)
{
- struct manager_channel_variable *mcv;
- char *remaining = ast_strdupa(var->value);
- char *next;
+ char *parse = NULL;
+ AST_DECLARE_APP_ARGS(args,
+ AST_APP_ARG(vars)[MAX_VARS];
+ );
ast_free(manager_channelvars);
manager_channelvars = ast_strdup(var->value);
- /*
- * XXX TODO: To allow dialplan functions to have more than one
- * parameter requires eliminating the '|' as a separator so we
- * could use AST_STANDARD_APP_ARGS() to separate items.
- */
- free_channelvars();
- AST_RWLIST_WRLOCK(&channelvars);
- while ((next = strsep(&remaining, ",|"))) {
- if (!(mcv = ast_calloc(1, sizeof(*mcv) + strlen(next) + 1))) {
- break;
- }
- strcpy(mcv->name, next); /* SAFE */
- if (strchr(next, '(')) {
- mcv->isfunc = 1;
- }
- AST_RWLIST_INSERT_TAIL(&channelvars, mcv, entry);
- }
- AST_RWLIST_UNLOCK(&channelvars);
+ /* parse the setting */
+ parse = ast_strdupa(manager_channelvars);
+ AST_STANDARD_APP_ARGS(args, parse);
+
+ ast_channel_set_manager_vars(args.vars, args.argc);
}
/*! \internal \brief Free a user record. Should already be removed from the list */
@@ -7595,8 +7561,6 @@
}
ami_tls_cfg.cipher = ast_strdup("");
- free_channelvars();
-
for (var = ast_variable_browse(cfg, "general"); var; var = var->next) {
val = var->value;
@@ -7955,17 +7919,6 @@
__init_manager(1, 1);
}
-/* clear out every entry in the channelvar list */
-static void free_channelvars(void)
-{
- struct manager_channel_variable *var;
- AST_RWLIST_WRLOCK(&channelvars);
- while ((var = AST_RWLIST_REMOVE_HEAD(&channelvars, entry))) {
- ast_free(var);
- }
- AST_RWLIST_UNLOCK(&channelvars);
-}
-
int init_manager(void)
{
return __init_manager(0, 0);
Modified: team/dlee/ASTERISK-21096/main/manager_channels.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-21096/main/manager_channels.c?view=diff&rev=383394&r1=383393&r2=383394
==============================================================================
--- team/dlee/ASTERISK-21096/main/manager_channels.c (original)
+++ team/dlee/ASTERISK-21096/main/manager_channels.c Tue Mar 19 15:48:54 2013
@@ -109,19 +109,19 @@
<managerEvent language="en_US" name="HangupRequest">
<managerEventInstance class="EVENT_FLAG_CALL">
<synopsis>Raised when a hangup is requested.</synopsis>
- <syntax>
- <xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
- <xi:include xpointer="xpointer(/docs/managerEvent[@name='Hangup']/managerEventInstance/syntax/parameter[@name='Cause'])" />
- </syntax>
+ <syntax>
+ <xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
+ <xi:include xpointer="xpointer(/docs/managerEvent[@name='Hangup']/managerEventInstance/syntax/parameter[@name='Cause'])" />
+ </syntax>
</managerEventInstance>
</managerEvent>
<managerEvent language="en_US" name="SoftHangupRequest">
<managerEventInstance class="EVENT_FLAG_CALL">
<synopsis>Raised when a soft hangup is requested with a specific cause code.</synopsis>
- <syntax>
- <xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
- <xi:include xpointer="xpointer(/docs/managerEvent[@name='Hangup']/managerEventInstance/syntax/parameter[@name='Cause'])" />
- </syntax>
+ <syntax>
+ <xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
+ <xi:include xpointer="xpointer(/docs/managerEvent[@name='Hangup']/managerEventInstance/syntax/parameter[@name='Cause'])" />
+ </syntax>
</managerEventInstance>
</managerEvent>
***/
@@ -178,6 +178,15 @@
return NULL;
}
+ if (snapshot->manager_vars) {
+ struct ast_var_t *var;
+ AST_LIST_TRAVERSE(snapshot->manager_vars, var, entries) {
+ ast_str_append(&out, 0, "ChanVariable(%s): %s=%s\r\n",
+ snapshot->name,
+ var->name, var->value);
+ }
+ }
+
return out;
}
More information about the asterisk-commits
mailing list