Merge the new Channel Event Logging (CEL) subsystem.

CEL is the new system for logging channel events.  This was inspired after
facing many problems trying to represent what is possible to happen to a call
in Asterisk using CDR records.  For more information on CEL, see the built in
HTML or PDF documentation generated from the files in doc/tex/.

Many thanks to Steve Murphy (murf) and Brian Degenhardt (bmd) for their hard
work developing this code.  Also, thanks to Matt Nicholson (mnicholson) and
Sean Bright (seanbright) for their assistance in the final push to get this
code ready for Asterisk trunk.

Review: https://reviewboard.asterisk.org/r/239/


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@203638 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Russell Bryant
2009-06-26 15:28:53 +00:00
parent e06c6f97c4
commit 0264eef115
87 changed files with 6919 additions and 365 deletions

View File

@@ -29,6 +29,7 @@
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include <regex.h>
#include <ctype.h>
#include "asterisk/module.h"
#include "asterisk/channel.h"
@@ -271,13 +272,62 @@ static int func_channel_read(struct ast_channel *chan, const char *function,
locked_copy_string(chan, buf, ast_state2str(chan->_state), len);
else if (!strcasecmp(data, "channeltype"))
locked_copy_string(chan, buf, chan->tech->type, len);
else if (!strcasecmp(data, "transfercapability"))
else if (!strcasecmp(data, "accountcode"))
locked_copy_string(chan, buf, chan->accountcode, len);
else if (!strcasecmp(data, "peeraccount"))
locked_copy_string(chan, buf, chan->peeraccount, len);
else if (!strcasecmp(data, "hangupsource"))
locked_copy_string(chan, buf, chan->hangupsource, len);
else if (!strcasecmp(data, "appname") && chan->appl)
locked_copy_string(chan, buf, chan->appl, len);
else if (!strcasecmp(data, "appdata") && chan->data)
locked_copy_string(chan, buf, chan->data, len);
else if (!strcasecmp(data, "exten") && chan->data)
locked_copy_string(chan, buf, chan->exten, len);
else if (!strcasecmp(data, "context") && chan->data)
locked_copy_string(chan, buf, chan->context, len);
else if (!strcasecmp(data, "userfield") && chan->data)
locked_copy_string(chan, buf, chan->userfield, len);
else if (!strcasecmp(data, "channame") && chan->data)
locked_copy_string(chan, buf, chan->name, len);
else if (!strcasecmp(data, "linkedid")) {
ast_channel_lock(chan);
if (ast_strlen_zero(chan->linkedid)) {
/* fall back on the channel's uniqueid if linkedid is unset */
ast_copy_string(buf, chan->uniqueid, len);
}
else {
ast_copy_string(buf, chan->linkedid, len);
}
ast_channel_unlock(chan);
} else if (!strcasecmp(data, "peer")) {
struct ast_channel *p;
ast_channel_lock(chan);
p = ast_bridged_channel(chan);
if (p || chan->tech || chan->cdr) /* dummy channel? if so, we hid the peer name in the language */
ast_copy_string(buf, (p ? p->name : ""), len);
else {
/* a dummy channel can still pass along bridged peer info via
the BRIDGEPEER variable */
const char *pname = pbx_builtin_getvar_helper(chan, "BRIDGEPEER");
if (!ast_strlen_zero(pname))
ast_copy_string(buf, pname, len); /* a horrible kludge, but... how else? */
else
buf[0] = 0;
}
ast_channel_unlock(chan);
} else if (!strcasecmp(data, "uniqueid")) {
locked_copy_string(chan, buf, chan->uniqueid, len);
} else if (!strcasecmp(data, "transfercapability"))
locked_copy_string(chan, buf, transfercapability_table[chan->transfercapability & 0x1f], len);
else if (!strcasecmp(data, "callgroup")) {
char groupbuf[256];
locked_copy_string(chan, buf, ast_print_group(groupbuf, sizeof(groupbuf), chan->callgroup), len);
} else if (!chan->tech->func_channel_read
|| chan->tech->func_channel_read(chan, function, data, buf, len)) {
} else if (!strcasecmp(data, "amaflags")) {
char amabuf[256];
snprintf(amabuf,sizeof(amabuf), "%d", chan->amaflags);
locked_copy_string(chan, buf, amabuf, len);
} else if (!chan->tech || !chan->tech->func_channel_read || chan->tech->func_channel_read(chan, function, data, buf, len)) {
ast_log(LOG_WARNING, "Unknown or unavailable item requested: '%s'\n", data);
ret = -1;
}
@@ -297,12 +347,33 @@ static int func_channel_write(struct ast_channel *chan, const char *function,
locked_string_field_set(chan, parkinglot, value);
else if (!strcasecmp(data, "musicclass"))
locked_string_field_set(chan, musicclass, value);
else if (!strcasecmp(data, "accountcode"))
locked_string_field_set(chan, accountcode, value);
else if (!strcasecmp(data, "userfield"))
locked_string_field_set(chan, userfield, value);
else if (!strcasecmp(data, "amaflags")) {
ast_channel_lock(chan);
if(isdigit(*value)) {
sscanf(value, "%d", &chan->amaflags);
} else if (!strcasecmp(value,"OMIT")){
chan->amaflags = 1;
} else if (!strcasecmp(value,"BILLING")){
chan->amaflags = 2;
} else if (!strcasecmp(value,"DOCUMENTATION")){
chan->amaflags = 3;
}
ast_channel_unlock(chan);
} else if (!strcasecmp(data, "peeraccount"))
locked_string_field_set(chan, peeraccount, value);
else if (!strcasecmp(data, "hangupsource"))
/* XXX - should we be forcing this here? */
ast_set_hangupsource(chan, value, 0);
#ifdef CHANNEL_TRACE
else if (!strcasecmp(data, "trace")) {
ast_channel_lock(chan);
if (ast_true(value))
ret = ast_channel_trace_enable(chan);
else if (ast_false(value))
else if (ast_false(value))
ret = ast_channel_trace_disable(chan);
else {
ret = -1;