Display a list of channel variables in each channel-oriented event.

(Closes AST-33)
Reviewboard:	https://reviewboard.asterisk.org/r/368/


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@230111 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Tilghman Lesher
2009-11-13 20:42:03 +00:00
parent 85dd68ca7a
commit 5e2aa190fe
18 changed files with 172 additions and 75 deletions

View File

@@ -844,6 +844,14 @@ struct mansession {
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);
#define NEW_EVENT(m) (AST_LIST_NEXT(m->session->last_ev, eq_next))
/*! \brief user descriptor, as read from the config file.
@@ -876,6 +884,7 @@ static AST_RWLIST_HEAD_STATIC(manager_hooks, manager_custom_hook);
static struct eventqent *unref_event(struct eventqent *e);
static void ref_event(struct eventqent *e);
static void free_channelvars(void);
/*! \brief Add a custom hook to be called when an event is fired */
void ast_manager_register_hook(struct manager_custom_hook *hook)
@@ -3292,7 +3301,7 @@ static void *fast_originate(void *data)
struct fast_originate_helper *in = data;
int res;
int reason = 0;
struct ast_channel *chan = NULL;
struct ast_channel *chan = NULL, *chans[1];
char requested_channel[AST_CHANNEL_NAME];
if (!ast_strlen_zero(in->app)) {
@@ -3311,7 +3320,8 @@ static void *fast_originate(void *data)
snprintf(requested_channel, AST_CHANNEL_NAME, "%s/%s", in->tech, in->data);
}
/* Tell the manager what happened with the channel */
manager_event(EVENT_FLAG_CALL, "OriginateResponse",
chans[0] = chan;
ast_manager_event_multichan(EVENT_FLAG_CALL, "OriginateResponse", chan ? 1 : 0, chans,
"%s%s"
"Response: %s\r\n"
"Channel: %s\r\n"
@@ -4211,13 +4221,34 @@ static int append_event(const char *str, int category)
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 = "";
if (var->isfunc) {
struct ast_str *res = ast_str_thread_get(&manager_event_funcbuf, 16);
int ret;
if (res && (ret = ast_func_read2(chan, var->name, &res, 0)) == 0) {
val = ast_str_buffer(res);
}
} else {
val = pbx_builtin_getvar_helper(chan, var->name);
}
ast_str_append(pbuf, 0, "ChanVariable(%s): %s=%s\r\n", chan->name, var->name, val ? val : "");
}
AST_RWLIST_UNLOCK(&channelvars);
}
/* XXX see if can be moved inside the function */
AST_THREADSTORAGE(manager_event_buf);
#define MANAGER_EVENT_BUF_INITSIZE 256
/*! \brief manager_event: Send AMI event to client */
int __manager_event(int category, const char *event,
const char *file, int line, const char *func, const char *fmt, ...)
int __ast_manager_event_multichan(int category, const char *event, int chancount, struct
ast_channel **chans, const char *file, int line, const char *func, const char *fmt, ...)
{
struct mansession_session *session;
struct manager_custom_hook *hook;
@@ -4226,6 +4257,7 @@ int __manager_event(int category, const char *event,
va_list ap;
struct timeval now;
struct ast_str *buf;
int i;
if (!(buf = ast_str_thread_get(&manager_event_buf, MANAGER_EVENT_BUF_INITSIZE))) {
return -1;
@@ -4254,6 +4286,9 @@ int __manager_event(int category, const char *event,
va_start(ap, fmt);
ast_str_append_va(&buf, 0, fmt, ap);
va_end(ap);
for (i = 0; i < chancount; i++) {
append_channel_vars(&buf, chans[i]);
}
ast_str_append(&buf, 0, "\r\n");
@@ -5559,6 +5594,8 @@ static int __init_manager(int reload)
}
ami_tls_cfg.cipher = ast_strdup("");
free_channelvars();
for (var = ast_variable_browse(cfg, "general"); var; var = var->next) {
val = var->value;
@@ -5589,6 +5626,21 @@ static int __init_manager(int reload)
manager_debug = ast_true(val);
} else if (!strcasecmp(var->name, "httptimeout")) {
newhttptimeout = atoi(val);
} else if (!strcasecmp(var->name, "channelvars")) {
struct manager_channel_variable *mcv;
char *remaining = ast_strdupa(val), *next;
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);
} else {
ast_log(LOG_NOTICE, "Invalid keyword <%s> = <%s> in manager.conf [general]\n",
var->name, val);
@@ -5830,6 +5882,17 @@ static int __init_manager(int reload)
return 0;
}
/* 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);