Channel Event Logging API. More...
#include "asterisk.h"#include "asterisk/_private.h"#include "asterisk/channel.h"#include "asterisk/pbx.h"#include "asterisk/cel.h"#include "asterisk/logger.h"#include "asterisk/linkedlists.h"#include "asterisk/utils.h"#include "asterisk/config.h"#include "asterisk/cli.h"#include "asterisk/astobj2.h"
Go to the source code of this file.
Data Structures | |
| struct | channel_find_data |
Defines | |
| #define | CEL_MAX_EVENT_IDS 64 |
| Maximum possible CEL event IDs. | |
Functions | |
| static int | app_cmp (void *obj, void *arg, int flags) |
| static int | app_hash (const void *obj, const int flags) |
| unsigned int | ast_cel_check_enabled (void) |
| Check to see if CEL is enabled. | |
| void | ast_cel_check_retire_linkedid (struct ast_channel *chan) |
| Check and potentially retire a Linked ID. | |
| int | ast_cel_engine_init (void) |
| int | ast_cel_engine_reload (void) |
| static void | ast_cel_engine_term (void) |
| struct ast_channel * | ast_cel_fabricate_channel_from_event (const struct ast_event *event) |
| Create a fake channel from data in a CEL event. | |
| int | ast_cel_fill_record (const struct ast_event *e, struct ast_cel_event_record *r) |
| Fill in an ast_cel_event_record from a CEL event. | |
| const char * | ast_cel_get_ama_flag_name (enum ast_cel_ama_flag flag) |
| Convert AMA flag to printable string. | |
| const char * | ast_cel_get_type_name (enum ast_cel_event_type type) |
| Get the name of a CEL event type. | |
| int | ast_cel_report_event (struct ast_channel *chan, enum ast_cel_event_type event_type, const char *userdefevname, const char *extra, struct ast_channel *peer2) |
| Report a channel event. | |
| enum ast_cel_event_type | ast_cel_str_to_event_type (const char *name) |
| Get the event type from a string. | |
| static int | ast_cel_track_event (enum ast_cel_event_type et) |
| static int | do_reload (void) |
| static char * | handle_cli_status (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static int | linkedid_match (void *obj, void *arg, void *data, int flags) |
| static void | parse_apps (const char *val) |
| static void | parse_events (const char *val) |
| static int | print_app (void *obj, void *arg, int flags) |
| static void | print_cel_sub (const struct ast_event *event, void *data) |
Variables | |
| static struct ao2_container * | appset |
| Container of Asterisk application names. | |
| static const char *const | cel_ama_flags [AST_CEL_AMA_FLAG_TOTAL] |
| Map of ast_cel_ama_flags to strings. | |
| static char | cel_dateformat [256] |
| Configured date format for event timestamps. | |
| static const int64_t | CEL_DEFAULT_EVENTS = 0 |
| Track no events by default. | |
| static unsigned char | cel_enabled |
| static const unsigned char | CEL_ENALBED_DEFAULT = 0 |
| CEL is off by default. | |
| static const char *const | cel_event_types [CEL_MAX_EVENT_IDS] |
| Map of ast_cel_event_type to strings. | |
| static struct ast_cli_entry | cli_status = AST_CLI_DEFINE(handle_cli_status, "Display the CEL status") |
| static int64_t | eventset |
| which events we want to track | |
| static const int | NUM_APP_BUCKETS = 97 |
| Number of buckets for the appset container. | |
| static ast_mutex_t | reload_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } |
Channel Event Logging API.
Definition in file cel.c.
| #define CEL_MAX_EVENT_IDS 64 |
| static int app_cmp | ( | void * | obj, |
| void * | arg, | ||
| int | flags | ||
| ) | [static] |
| static int app_hash | ( | const void * | obj, |
| const int | flags | ||
| ) | [static] |
Definition at line 627 of file cel.c.
References ast_str_case_hash().
Referenced by ast_cel_engine_init().
{
return ast_str_case_hash((const char *) obj);
}
| unsigned int ast_cel_check_enabled | ( | void | ) |
Check to see if CEL is enabled.
| zero | not enabled |
| non-zero | enabled |
Definition at line 131 of file cel.c.
References cel_enabled.
{
return cel_enabled;
}
| void ast_cel_check_retire_linkedid | ( | struct ast_channel * | chan | ) |
Check and potentially retire a Linked ID.
| chan | channel that is being destroyed or its linkedid is changing |
If at least one CEL backend is looking for CEL_LINKEDID_END events, this function will check if the given channel is the last active channel with that linkedid, and if it is, emit a CEL_LINKEDID_END event.
Definition at line 382 of file cel.c.
References AST_CEL_LINKEDID_END, ast_cel_report_event(), ast_cel_track_event(), ast_channel_callback(), ast_channel_unref, ast_strlen_zero(), channel_find_data::chan, channel_find_data::linkedid, ast_channel::linkedid, and linkedid_match().
Referenced by ast_channel_change_linkedid(), and ast_channel_destructor().
{
const char *linkedid = chan->linkedid;
struct channel_find_data find_dat;
/* make sure we need to do all this work */
if (!ast_strlen_zero(linkedid) && ast_cel_track_event(AST_CEL_LINKEDID_END)) {
struct ast_channel *tmp = NULL;
find_dat.chan = chan;
find_dat.linkedid = linkedid;
if ((tmp = ast_channel_callback(linkedid_match, NULL, &find_dat, 0))) {
tmp = ast_channel_unref(tmp);
} else {
ast_cel_report_event(chan, AST_CEL_LINKEDID_END, NULL, NULL, NULL);
}
}
}
| int ast_cel_engine_init | ( | void | ) |
Provided by cel.c
Definition at line 647 of file cel.c.
References ao2_container_alloc, ao2_ref, app_cmp(), app_hash(), ast_cel_engine_term(), ast_cli_register(), ast_register_atexit(), and do_reload().
Referenced by main().
{
if (!(appset = ao2_container_alloc(NUM_APP_BUCKETS, app_hash, app_cmp))) {
return -1;
}
if (do_reload()) {
ao2_ref(appset, -1);
appset = NULL;
return -1;
}
if (ast_cli_register(&cli_status)) {
ao2_ref(appset, -1);
appset = NULL;
return -1;
}
ast_register_atexit(ast_cel_engine_term);
return 0;
}
| int ast_cel_engine_reload | ( | void | ) |
Provided by cel.c
Definition at line 670 of file cel.c.
References do_reload().
{
return do_reload();
}
| static void ast_cel_engine_term | ( | void | ) | [static] |
| struct ast_channel* ast_cel_fabricate_channel_from_event | ( | const struct ast_event * | event | ) | [read] |
Create a fake channel from data in a CEL event.
| event | the CEL event |
Definition at line 401 of file cel.c.
References ast_cel_event_record::account_code, accountcode, ast_cel_event_record::amaflag, ast_channel::amaflags, ast_party_caller::ani, ast_channel::appl, ast_cel_event_record::application_data, ast_cel_event_record::application_name, AST_CEL_EVENT_RECORD_VERSION, ast_cel_fill_record(), ast_channel_unref, ast_copy_string(), ast_dummy_channel_alloc(), AST_LIST_INSERT_HEAD, ast_localtime(), ast_strdup, ast_strftime(), ast_string_field_set, ast_strlen_zero(), ast_var_assign(), ast_channel::caller, ast_cel_event_record::caller_id_ani, ast_cel_event_record::caller_id_dnid, ast_cel_event_record::caller_id_name, ast_cel_event_record::caller_id_num, ast_cel_event_record::caller_id_rdnis, ast_cel_event_record::channel_name, ast_cel_event_record::context, ast_channel::context, ast_channel::data, ast_channel::dialed, ast_cel_event_record::event_name, ast_cel_event_record::event_time, ast_channel::exten, ast_cel_event_record::extension, ast_cel_event_record::extra, ast_party_redirecting::from, ast_party_caller::id, ast_cel_event_record::linked_id, name, ast_party_id::name, ast_party_id::number, ast_party_dialed::number, pbx_builtin_setvar_helper(), ast_cel_event_record::peer, ast_cel_event_record::peer_account, ast_channel::redirecting, ast_party_name::str, ast_party_number::str, ast_party_dialed::str, ast_cel_event_record::unique_id, ast_cel_event_record::user_field, ast_party_name::valid, ast_party_number::valid, ast_channel::varshead, and ast_cel_event_record::version.
{
struct varshead *headp;
struct ast_var_t *newvariable;
char timebuf[30];
struct ast_channel *tchan;
struct ast_cel_event_record record = {
.version = AST_CEL_EVENT_RECORD_VERSION,
};
/* do not call ast_channel_alloc because this is not really a real channel */
if (!(tchan = ast_dummy_channel_alloc())) {
return NULL;
}
headp = &tchan->varshead;
/* first, get the variables from the event */
if (ast_cel_fill_record(event, &record)) {
ast_channel_unref(tchan);
return NULL;
}
/* next, fill the channel with their data */
if ((newvariable = ast_var_assign("eventtype", record.event_name))) {
AST_LIST_INSERT_HEAD(headp, newvariable, entries);
}
if (ast_strlen_zero(cel_dateformat)) {
snprintf(timebuf, sizeof(timebuf), "%ld.%06ld", (long) record.event_time.tv_sec,
(long) record.event_time.tv_usec);
} else {
struct ast_tm tm;
ast_localtime(&record.event_time, &tm, NULL);
ast_strftime(timebuf, sizeof(timebuf), cel_dateformat, &tm);
}
if ((newvariable = ast_var_assign("eventtime", timebuf))) {
AST_LIST_INSERT_HEAD(headp, newvariable, entries);
}
if ((newvariable = ast_var_assign("eventextra", record.extra))) {
AST_LIST_INSERT_HEAD(headp, newvariable, entries);
}
tchan->caller.id.name.valid = 1;
tchan->caller.id.name.str = ast_strdup(record.caller_id_name);
tchan->caller.id.number.valid = 1;
tchan->caller.id.number.str = ast_strdup(record.caller_id_num);
tchan->caller.ani.number.valid = 1;
tchan->caller.ani.number.str = ast_strdup(record.caller_id_ani);
tchan->redirecting.from.number.valid = 1;
tchan->redirecting.from.number.str = ast_strdup(record.caller_id_rdnis);
tchan->dialed.number.str = ast_strdup(record.caller_id_dnid);
ast_copy_string(tchan->exten, record.extension, sizeof(tchan->exten));
ast_copy_string(tchan->context, record.context, sizeof(tchan->context));
ast_string_field_set(tchan, name, record.channel_name);
ast_string_field_set(tchan, uniqueid, record.unique_id);
ast_string_field_set(tchan, linkedid, record.linked_id);
ast_string_field_set(tchan, accountcode, record.account_code);
ast_string_field_set(tchan, peeraccount, record.peer_account);
ast_string_field_set(tchan, userfield, record.user_field);
pbx_builtin_setvar_helper(tchan, "BRIDGEPEER", record.peer);
tchan->appl = ast_strdup(record.application_name);
tchan->data = ast_strdup(record.application_data);
tchan->amaflags = record.amaflag;
return tchan;
}
| int ast_cel_fill_record | ( | const struct ast_event * | event, |
| struct ast_cel_event_record * | r | ||
| ) |
Fill in an ast_cel_event_record from a CEL event.
| [in] | event | the CEL event |
| [out] | r | the ast_cel_event_record to fill in |
| 0 | success |
| non-zero | failure |
Definition at line 582 of file cel.c.
References ast_cel_event_record::account_code, ast_cel_event_record::amaflag, ast_cel_event_record::application_data, ast_cel_event_record::application_name, AST_CEL_EVENT_RECORD_VERSION, ast_cel_get_type_name(), AST_CEL_USER_DEFINED, ast_event_get_ie_str(), ast_event_get_ie_uint(), AST_EVENT_IE_CEL_ACCTCODE, AST_EVENT_IE_CEL_AMAFLAGS, AST_EVENT_IE_CEL_APPDATA, AST_EVENT_IE_CEL_APPNAME, AST_EVENT_IE_CEL_CHANNAME, AST_EVENT_IE_CEL_CIDANI, AST_EVENT_IE_CEL_CIDDNID, AST_EVENT_IE_CEL_CIDNAME, AST_EVENT_IE_CEL_CIDNUM, AST_EVENT_IE_CEL_CIDRDNIS, AST_EVENT_IE_CEL_CONTEXT, AST_EVENT_IE_CEL_EVENT_TIME, AST_EVENT_IE_CEL_EVENT_TIME_USEC, AST_EVENT_IE_CEL_EVENT_TYPE, AST_EVENT_IE_CEL_EXTEN, AST_EVENT_IE_CEL_EXTRA, AST_EVENT_IE_CEL_LINKEDID, AST_EVENT_IE_CEL_PEER, AST_EVENT_IE_CEL_UNIQUEID, AST_EVENT_IE_CEL_USEREVENT_NAME, AST_EVENT_IE_CEL_USERFIELD, ast_log(), ast_cel_event_record::caller_id_ani, ast_cel_event_record::caller_id_dnid, ast_cel_event_record::caller_id_name, ast_cel_event_record::caller_id_num, ast_cel_event_record::caller_id_rdnis, ast_cel_event_record::channel_name, ast_cel_event_record::context, ast_cel_event_record::event_name, ast_cel_event_record::event_time, ast_cel_event_record::event_type, ast_cel_event_record::extension, ast_cel_event_record::extra, ast_cel_event_record::linked_id, LOG_ERROR, ast_cel_event_record::peer, ast_cel_event_record::peer_account, S_OR, ast_cel_event_record::unique_id, ast_cel_event_record::user_defined_name, ast_cel_event_record::user_field, and ast_cel_event_record::version.
Referenced by ast_cel_fabricate_channel_from_event().
{
if (r->version != AST_CEL_EVENT_RECORD_VERSION) {
ast_log(LOG_ERROR, "Module ABI mismatch for ast_cel_event_record. "
"Please ensure all modules were compiled for "
"this version of Asterisk.\n");
return -1;
}
r->event_type = ast_event_get_ie_uint(e, AST_EVENT_IE_CEL_EVENT_TYPE);
r->event_time.tv_sec = ast_event_get_ie_uint(e, AST_EVENT_IE_CEL_EVENT_TIME);
r->event_time.tv_usec = ast_event_get_ie_uint(e, AST_EVENT_IE_CEL_EVENT_TIME_USEC);
r->user_defined_name = "";
if (r->event_type == AST_CEL_USER_DEFINED) {
r->user_defined_name = ast_event_get_ie_str(e, AST_EVENT_IE_CEL_USEREVENT_NAME);
r->event_name = r->user_defined_name;
} else {
r->event_name = ast_cel_get_type_name(r->event_type);
}
r->caller_id_name = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_CIDNAME), "");
r->caller_id_num = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_CIDNUM), "");
r->caller_id_ani = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_CIDANI), "");
r->caller_id_rdnis = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_CIDRDNIS), "");
r->caller_id_dnid = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_CIDDNID), "");
r->extension = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_EXTEN), "");
r->context = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_CONTEXT), "");
r->channel_name = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_CHANNAME), "");
r->application_name = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_APPNAME), "");
r->application_data = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_APPDATA), "");
r->account_code = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_ACCTCODE), "");
r->peer_account = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_ACCTCODE), "");
r->unique_id = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_UNIQUEID), "");
r->linked_id = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_LINKEDID), "");
r->amaflag = ast_event_get_ie_uint(e, AST_EVENT_IE_CEL_AMAFLAGS);
r->user_field = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_USERFIELD), "");
r->peer = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_PEER), "");
r->extra = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_EXTRA), "");
return 0;
}
| const char* ast_cel_get_ama_flag_name | ( | enum ast_cel_ama_flag | flag | ) |
Convert AMA flag to printable string.
| [in] | flag | the flag to convert to a string |
Definition at line 351 of file cel.c.
References ARRAY_LEN, ast_log(), LOG_WARNING, and S_OR.
{
if (flag < 0 || flag >= ARRAY_LEN(cel_ama_flags)) {
ast_log(LOG_WARNING, "Invalid AMA flag: %d\n", flag);
return "Unknown";
}
return S_OR(cel_ama_flags[flag], "Unknown");
}
| const char* ast_cel_get_type_name | ( | enum ast_cel_event_type | type | ) |
Get the name of a CEL event type.
| type | the type to get the name of |
Definition at line 346 of file cel.c.
References S_OR.
Referenced by ast_cel_fill_record(), and handle_cli_status().
{
return S_OR(cel_event_types[type], "Unknown");
}
| int ast_cel_report_event | ( | struct ast_channel * | chan, |
| enum ast_cel_event_type | event_type, | ||
| const char * | userdefevname, | ||
| const char * | extra, | ||
| struct ast_channel * | peer2 | ||
| ) |
Report a channel event.
| chan | This argument is required. This is the primary channel associated with this channel event. |
| event_type | This is the type of call event being reported. |
| userdefevname | This is an optional custom name for the call event. |
| extra | This is an optional opaque field that will go into the "CEL_EXTRA" information element of the call event. |
| peer2 | All CEL events contain a "peer name" information element. The first place the code will look to get a peer name is from the bridged channel to chan. If chan has no bridged channel and peer2 is specified, then the name of peer2 will go into the "peer name" field. If neither are available, the peer name field will be blank. |
| 0 | success |
| non-zero | failure |
Definition at line 474 of file cel.c.
References ast_channel::accountcode, ast_channel::amaflags, ast_party_caller::ani, ao2_find, ao2_ref, app, ast_channel::appl, ast_bridged_channel(), AST_CEL_APP_END, AST_CEL_APP_START, ast_cel_track_event(), ast_channel_lock, ast_channel_ref, ast_channel_unlock, ast_channel_unref, AST_EVENT_CEL, ast_event_destroy(), AST_EVENT_IE_CEL_ACCTCODE, AST_EVENT_IE_CEL_AMAFLAGS, AST_EVENT_IE_CEL_APPDATA, AST_EVENT_IE_CEL_APPNAME, AST_EVENT_IE_CEL_CHANNAME, AST_EVENT_IE_CEL_CIDANI, AST_EVENT_IE_CEL_CIDDNID, AST_EVENT_IE_CEL_CIDNAME, AST_EVENT_IE_CEL_CIDNUM, AST_EVENT_IE_CEL_CIDRDNIS, AST_EVENT_IE_CEL_CONTEXT, AST_EVENT_IE_CEL_EVENT_TIME, AST_EVENT_IE_CEL_EVENT_TIME_USEC, AST_EVENT_IE_CEL_EVENT_TYPE, AST_EVENT_IE_CEL_EXTEN, AST_EVENT_IE_CEL_EXTRA, AST_EVENT_IE_CEL_LINKEDID, AST_EVENT_IE_CEL_PEER, AST_EVENT_IE_CEL_PEERACCT, AST_EVENT_IE_CEL_UNIQUEID, AST_EVENT_IE_CEL_USEREVENT_NAME, AST_EVENT_IE_CEL_USERFIELD, AST_EVENT_IE_END, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, ast_event_new(), ast_event_queue(), ast_mutex_lock, ast_mutex_unlock, ast_strdupa, ast_tvnow(), ast_channel::caller, ast_channel::context, ast_channel::data, ast_channel::dialed, ast_channel::exten, ast_party_redirecting::from, ast_party_caller::id, ast_channel::linkedid, ast_party_id::name, ast_channel::name, ast_party_id::number, ast_party_dialed::number, OBJ_POINTER, ast_channel::peeraccount, ast_channel::redirecting, reload_lock, S_COR, S_OR, ast_party_name::str, ast_party_number::str, ast_party_dialed::str, ast_channel::uniqueid, ast_channel::userfield, ast_party_name::valid, and ast_party_number::valid.
Referenced by __ast_channel_alloc_ap(), __ast_read(), analog_attempt_transfer(), ast_bridge_call(), ast_cel_check_retire_linkedid(), ast_channel_destructor(), ast_do_masquerade(), ast_do_pickup(), ast_hangup(), ast_raw_answer(), builtin_atxfer(), builtin_blindtransfer(), celgenuserevent_exec(), do_forward(), handle_request_refer(), local_attended_transfer(), manage_parked_call(), park_call_full(), parked_call_exec(), pbx_exec(), and wait_for_answer().
{
struct timeval eventtime;
struct ast_event *ev;
const char *peername = "";
struct ast_channel *peer;
ast_channel_lock(chan);
peer = ast_bridged_channel(chan);
if (peer) {
ast_channel_ref(peer);
}
ast_channel_unlock(chan);
/* Make sure a reload is not occurring while we're checking to see if this
* is an event that we care about. We could lose an important event in this
* process otherwise. */
ast_mutex_lock(&reload_lock);
if (!cel_enabled || !ast_cel_track_event(event_type)) {
ast_mutex_unlock(&reload_lock);
if (peer) {
ast_channel_unref(peer);
}
return 0;
}
if (event_type == AST_CEL_APP_START || event_type == AST_CEL_APP_END) {
char *app;
if (!(app = ao2_find(appset, (char *) chan->appl, OBJ_POINTER))) {
ast_mutex_unlock(&reload_lock);
if (peer) {
ast_channel_unref(peer);
}
return 0;
}
ao2_ref(app, -1);
}
ast_mutex_unlock(&reload_lock);
if (peer) {
ast_channel_lock(peer);
peername = ast_strdupa(peer->name);
ast_channel_unlock(peer);
} else if (peer2) {
ast_channel_lock(peer2);
peername = ast_strdupa(peer2->name);
ast_channel_unlock(peer2);
}
if (!userdefevname) {
userdefevname = "";
}
if (!extra) {
extra = "";
}
eventtime = ast_tvnow();
ast_channel_lock(chan);
ev = ast_event_new(AST_EVENT_CEL,
AST_EVENT_IE_CEL_EVENT_TYPE, AST_EVENT_IE_PLTYPE_UINT, event_type,
AST_EVENT_IE_CEL_EVENT_TIME, AST_EVENT_IE_PLTYPE_UINT, eventtime.tv_sec,
AST_EVENT_IE_CEL_EVENT_TIME_USEC, AST_EVENT_IE_PLTYPE_UINT, eventtime.tv_usec,
AST_EVENT_IE_CEL_USEREVENT_NAME, AST_EVENT_IE_PLTYPE_STR, userdefevname,
AST_EVENT_IE_CEL_CIDNAME, AST_EVENT_IE_PLTYPE_STR,
S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, ""),
AST_EVENT_IE_CEL_CIDNUM, AST_EVENT_IE_PLTYPE_STR,
S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""),
AST_EVENT_IE_CEL_CIDANI, AST_EVENT_IE_PLTYPE_STR,
S_COR(chan->caller.ani.number.valid, chan->caller.ani.number.str, ""),
AST_EVENT_IE_CEL_CIDRDNIS, AST_EVENT_IE_PLTYPE_STR,
S_COR(chan->redirecting.from.number.valid, chan->redirecting.from.number.str, ""),
AST_EVENT_IE_CEL_CIDDNID, AST_EVENT_IE_PLTYPE_STR,
S_OR(chan->dialed.number.str, ""),
AST_EVENT_IE_CEL_EXTEN, AST_EVENT_IE_PLTYPE_STR, chan->exten,
AST_EVENT_IE_CEL_CONTEXT, AST_EVENT_IE_PLTYPE_STR, chan->context,
AST_EVENT_IE_CEL_CHANNAME, AST_EVENT_IE_PLTYPE_STR, chan->name,
AST_EVENT_IE_CEL_APPNAME, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->appl, ""),
AST_EVENT_IE_CEL_APPDATA, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->data, ""),
AST_EVENT_IE_CEL_AMAFLAGS, AST_EVENT_IE_PLTYPE_UINT, chan->amaflags,
AST_EVENT_IE_CEL_ACCTCODE, AST_EVENT_IE_PLTYPE_STR, chan->accountcode,
AST_EVENT_IE_CEL_PEERACCT, AST_EVENT_IE_PLTYPE_STR, chan->peeraccount,
AST_EVENT_IE_CEL_UNIQUEID, AST_EVENT_IE_PLTYPE_STR, chan->uniqueid,
AST_EVENT_IE_CEL_LINKEDID, AST_EVENT_IE_PLTYPE_STR, chan->linkedid,
AST_EVENT_IE_CEL_USERFIELD, AST_EVENT_IE_PLTYPE_STR, chan->userfield,
AST_EVENT_IE_CEL_EXTRA, AST_EVENT_IE_PLTYPE_STR, extra,
AST_EVENT_IE_CEL_PEER, AST_EVENT_IE_PLTYPE_STR, peername,
AST_EVENT_IE_END);
ast_channel_unlock(chan);
if (peer) {
peer = ast_channel_unref(peer);
}
if (ev && ast_event_queue(ev)) {
ast_event_destroy(ev);
return -1;
}
return 0;
}
| enum ast_cel_event_type ast_cel_str_to_event_type | ( | const char * | name | ) |
Get the event type from a string.
| name | the event type name as a string |
Definition at line 209 of file cel.c.
References ARRAY_LEN.
Referenced by parse_events().
{
unsigned int i;
for (i = 0; i < ARRAY_LEN(cel_event_types); i++) {
if (!cel_event_types[i]) {
continue;
}
if (!strcasecmp(name, cel_event_types[i])) {
return i;
}
}
return -1;
}
| static int ast_cel_track_event | ( | enum ast_cel_event_type | et | ) | [static] |
Definition at line 226 of file cel.c.
Referenced by ast_cel_check_retire_linkedid(), ast_cel_report_event(), and parse_apps().
{
return (eventset & ((int64_t) 1 << et));
}
| static int do_reload | ( | void | ) | [static] |
Definition at line 289 of file cel.c.
References ao2_callback, ast_config_destroy(), ast_config_load2(), ast_copy_string(), ast_mutex_lock, ast_mutex_unlock, ast_true(), ast_variable_retrieve(), ast_verb, CEL_DEFAULT_EVENTS, CEL_ENALBED_DEFAULT, config, CONFIG_STATUS_FILEMISSING, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, parse_apps(), parse_events(), and reload_lock.
Referenced by ast_cel_engine_init(), and ast_cel_engine_reload().
{
struct ast_config *config;
const char *enabled_value;
const char *val;
int res = 0;
struct ast_flags config_flags = { 0, };
const char *s;
ast_mutex_lock(&reload_lock);
/* Reset all settings before reloading configuration */
cel_enabled = CEL_ENALBED_DEFAULT;
eventset = CEL_DEFAULT_EVENTS;
*cel_dateformat = '\0';
ao2_callback(appset, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL);
config = ast_config_load2("cel.conf", "cel", config_flags);
if (config == CONFIG_STATUS_FILEMISSING) {
config = NULL;
goto return_cleanup;
}
if ((enabled_value = ast_variable_retrieve(config, "general", "enable"))) {
cel_enabled = ast_true(enabled_value);
}
if (!cel_enabled) {
goto return_cleanup;
}
/* get the date format for logging */
if ((s = ast_variable_retrieve(config, "general", "dateformat"))) {
ast_copy_string(cel_dateformat, s, sizeof(cel_dateformat));
}
if ((val = ast_variable_retrieve(config, "general", "events"))) {
parse_events(val);
}
if ((val = ast_variable_retrieve(config, "general", "apps"))) {
parse_apps(val);
}
return_cleanup:
ast_verb(3, "CEL logging %sabled.\n", cel_enabled ? "en" : "dis");
ast_mutex_unlock(&reload_lock);
if (config) {
ast_config_destroy(config);
}
return res;
}
| static char* handle_cli_status | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
Definition at line 153 of file cel.c.
References ao2_callback, ast_cli_args::argc, ast_cel_get_type_name(), ast_cli(), AST_EVENT_CEL, AST_EVENT_IE_EVENTTYPE, ast_event_report_subs(), AST_EVENT_SUB, ast_event_sub_append_ie_uint(), ast_event_sub_destroy(), ast_event_subscribe_new(), CLI_FAILURE, CLI_GENERATE, CLI_HANDLER, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, eventset, ast_cli_args::fd, name, OBJ_NODATA, print_app(), print_cel_sub(), and ast_cli_entry::usage.
{
unsigned int i;
struct ast_event_sub *sub;
switch (cmd) {
case CLI_INIT:
e->command = "cel show status";
e->usage =
"Usage: cel show status\n"
" Displays the Channel Event Logging system status.\n";
return NULL;
case CLI_GENERATE:
return NULL;
case CLI_HANDLER:
break;
}
if (a->argc > 3) {
return CLI_SHOWUSAGE;
}
ast_cli(a->fd, "CEL Logging: %s\n", cel_enabled ? "Enabled" : "Disabled");
if (!cel_enabled) {
return CLI_SUCCESS;
}
for (i = 0; i < (sizeof(eventset) * 8); i++) {
const char *name;
if (!(eventset & ((int64_t) 1 << i))) {
continue;
}
name = ast_cel_get_type_name(i);
if (strcasecmp(name, "Unknown")) {
ast_cli(a->fd, "CEL Tracking Event: %s\n", name);
}
}
ao2_callback(appset, OBJ_NODATA, print_app, a);
if (!(sub = ast_event_subscribe_new(AST_EVENT_SUB, print_cel_sub, a))) {
return CLI_FAILURE;
}
ast_event_sub_append_ie_uint(sub, AST_EVENT_IE_EVENTTYPE, AST_EVENT_CEL);
ast_event_report_subs(sub);
ast_event_sub_destroy(sub);
sub = NULL;
return CLI_SUCCESS;
}
| static int linkedid_match | ( | void * | obj, |
| void * | arg, | ||
| void * | data, | ||
| int | flags | ||
| ) | [static] |
Definition at line 369 of file cel.c.
References ast_channel_lock, ast_channel_unlock, channel_find_data::chan, CMP_MATCH, CMP_STOP, channel_find_data::linkedid, and ast_channel::linkedid.
Referenced by ast_cel_check_retire_linkedid().
{
struct ast_channel *c = obj;
struct channel_find_data *find_dat = data;
int res;
ast_channel_lock(c);
res = (c != find_dat->chan && c->linkedid && !strcmp(find_dat->linkedid, c->linkedid));
ast_channel_unlock(c);
return res ? CMP_MATCH | CMP_STOP : 0;
}
| static void parse_apps | ( | const char * | val | ) | [static] |
Definition at line 258 of file cel.c.
References ao2_alloc, ao2_link, ao2_ref, app, AST_CEL_APP_END, AST_CEL_APP_START, ast_cel_track_event(), ast_log(), ast_strdupa, ast_strip(), ast_strlen_zero(), LOG_WARNING, and strsep().
Referenced by do_reload().
{
char *apps = ast_strdupa(val);
char *cur_app;
if (!ast_cel_track_event(AST_CEL_APP_START) && !ast_cel_track_event(AST_CEL_APP_END)) {
ast_log(LOG_WARNING, "An apps= config line, but not tracking APP events\n");
return;
}
while ((cur_app = strsep(&apps, ","))) {
char *app;
cur_app = ast_strip(cur_app);
if (ast_strlen_zero(cur_app)) {
continue;
}
if (!(app = ao2_alloc(strlen(cur_app) + 1, NULL))) {
continue;
}
strcpy(app, cur_app);
ao2_link(appset, app);
ao2_ref(app, -1);
app = NULL;
}
}
| static void parse_events | ( | const char * | val | ) | [static] |
Definition at line 231 of file cel.c.
References ast_cel_str_to_event_type(), ast_log(), ast_strdupa, ast_strip(), ast_strlen_zero(), events, LOG_WARNING, and strsep().
Referenced by do_reload().
{
char *events = ast_strdupa(val);
char *cur_event;
while ((cur_event = strsep(&events, ","))) {
enum ast_cel_event_type event_type;
cur_event = ast_strip(cur_event);
if (ast_strlen_zero(cur_event)) {
continue;
}
event_type = ast_cel_str_to_event_type(cur_event);
if (event_type == 0) {
/* All events */
eventset = (int64_t) -1;
} else if (event_type == -1) {
ast_log(LOG_WARNING, "Unknown event name '%s'\n",
cur_event);
} else {
eventset |= ((int64_t) 1 << event_type);
}
}
}
| static int print_app | ( | void * | obj, |
| void * | arg, | ||
| int | flags | ||
| ) | [static] |
Definition at line 136 of file cel.c.
References ast_cli(), and ast_cli_args::fd.
Referenced by handle_cli_status().
{
struct ast_cli_args *a = arg;
ast_cli(a->fd, "CEL Tracking Application: %s\n", (const char *) obj);
return 0;
}
| static void print_cel_sub | ( | const struct ast_event * | event, |
| void * | data | ||
| ) | [static] |
Definition at line 145 of file cel.c.
References ast_cli(), ast_event_get_ie_str(), AST_EVENT_IE_DESCRIPTION, and ast_cli_args::fd.
Referenced by handle_cli_status().
{
struct ast_cli_args *a = data;
ast_cli(a->fd, "CEL Event Subscriber: %s\n",
ast_event_get_ie_str(event, AST_EVENT_IE_DESCRIPTION));
}
struct ao2_container* appset [static] |
const char* const cel_ama_flags[AST_CEL_AMA_FLAG_TOTAL] [static] |
char cel_dateformat[256] [static] |
const int64_t CEL_DEFAULT_EVENTS = 0 [static] |
unsigned char cel_enabled [static] |
Is the CEL subsystem enabled ?
Definition at line 47 of file cel.c.
Referenced by ast_cel_check_enabled().
const unsigned char CEL_ENALBED_DEFAULT = 0 [static] |
const char* const cel_event_types[CEL_MAX_EVENT_IDS] [static] |
struct ast_cli_entry cli_status = AST_CLI_DEFINE(handle_cli_status, "Display the CEL status") [static] |
int64_t eventset [static] |
which events we want to track
Definition at line 57 of file cel.c.
Referenced by handle_cli_status().
const int NUM_APP_BUCKETS = 97 [static] |
ast_mutex_t reload_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static] |
Definition at line 287 of file cel.c.
Referenced by ast_cel_report_event(), and do_reload().