#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 = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
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 612 of file cel.c.
References ast_str_case_hash().
Referenced by ast_cel_engine_init().
00613 { 00614 return ast_str_case_hash((const char *) obj); 00615 }
| unsigned int ast_cel_check_enabled | ( | void | ) |
Check to see if CEL is enabled.
| zero | not enabled | |
| non-zero | enabled |
Definition at line 130 of file cel.c.
00131 { 00132 return cel_enabled; 00133 }
| 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 |
Definition at line 376 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, ast_channel::linkedid, channel_find_data::linkedid, and linkedid_match().
Referenced by ast_channel_change_linkedid(), and ast_channel_destructor().
00377 { 00378 const char *linkedid = chan->linkedid; 00379 struct channel_find_data find_dat; 00380 00381 /* make sure we need to do all this work */ 00382 00383 if (!ast_strlen_zero(linkedid) && ast_cel_track_event(AST_CEL_LINKEDID_END)) { 00384 struct ast_channel *tmp = NULL; 00385 find_dat.chan = chan; 00386 find_dat.linkedid = linkedid; 00387 if ((tmp = ast_channel_callback(linkedid_match, NULL, &find_dat, 0))) { 00388 tmp = ast_channel_unref(tmp); 00389 } else { 00390 ast_cel_report_event(chan, AST_CEL_LINKEDID_END, NULL, NULL, NULL); 00391 } 00392 } 00393 }
| int ast_cel_engine_init | ( | void | ) |
Provided by cel.c
Definition at line 632 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().
00633 { 00634 if (!(appset = ao2_container_alloc(NUM_APP_BUCKETS, app_hash, app_cmp))) { 00635 return -1; 00636 } 00637 00638 if (do_reload()) { 00639 ao2_ref(appset, -1); 00640 appset = NULL; 00641 return -1; 00642 } 00643 00644 if (ast_cli_register(&cli_status)) { 00645 ao2_ref(appset, -1); 00646 appset = NULL; 00647 return -1; 00648 } 00649 00650 ast_register_atexit(ast_cel_engine_term); 00651 00652 return 0; 00653 }
| int ast_cel_engine_reload | ( | void | ) |
Provided by cel.c
Definition at line 655 of file cel.c.
References do_reload().
00656 { 00657 return do_reload(); 00658 }
| 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.
This function creates a fake channel containing the serialized channel data in the given cel event. It must be released with ast_channel_release.
| event | the CEL event |
Definition at line 395 of file cel.c.
References ast_cel_event_record::account_code, accountcode, ast_cel_event_record::amaflag, ast_channel::amaflags, 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_release(), 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_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_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_rdnis, ast_cel_event_record::context, ast_channel::context, ast_channel::data, 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_cel_event_record::linked_id, name, pbx_builtin_setvar_helper(), ast_cel_event_record::peer, ast_cel_event_record::peer_account, ast_cel_event_record::unique_id, ast_cel_event_record::user_field, ast_channel::varshead, and ast_cel_event_record::version.
00396 { 00397 struct varshead *headp; 00398 struct ast_var_t *newvariable; 00399 char timebuf[30]; 00400 struct ast_channel *tchan; 00401 struct ast_cel_event_record record = { 00402 .version = AST_CEL_EVENT_RECORD_VERSION, 00403 }; 00404 00405 /* do not call ast_channel_alloc because this is not really a real channel */ 00406 if (!(tchan = ast_dummy_channel_alloc())) { 00407 return NULL; 00408 } 00409 00410 headp = &tchan->varshead; 00411 00412 /* first, get the variables from the event */ 00413 if (ast_cel_fill_record(event, &record)) { 00414 ast_channel_release(tchan); 00415 return NULL; 00416 } 00417 00418 /* next, fill the channel with their data */ 00419 if ((newvariable = ast_var_assign("eventtype", record.event_name))) { 00420 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 00421 } 00422 00423 if (ast_strlen_zero(cel_dateformat)) { 00424 snprintf(timebuf, sizeof(timebuf), "%ld.%06ld", record.event_time.tv_sec, 00425 (long) record.event_time.tv_usec); 00426 } else { 00427 struct ast_tm tm; 00428 ast_localtime(&record.event_time, &tm, NULL); 00429 ast_strftime(timebuf, sizeof(timebuf), cel_dateformat, &tm); 00430 } 00431 00432 if ((newvariable = ast_var_assign("eventtime", timebuf))) { 00433 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 00434 } 00435 00436 if ((newvariable = ast_var_assign("eventextra", record.extra))) { 00437 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 00438 } 00439 00440 tchan->cid.cid_name = ast_strdup(record.caller_id_name); 00441 tchan->cid.cid_num = ast_strdup(record.caller_id_num); 00442 tchan->cid.cid_ani = ast_strdup(record.caller_id_ani); 00443 tchan->cid.cid_rdnis = ast_strdup(record.caller_id_rdnis); 00444 tchan->cid.cid_dnid = ast_strdup(record.caller_id_dnid); 00445 00446 ast_copy_string(tchan->exten, record.extension, sizeof(tchan->exten)); 00447 ast_copy_string(tchan->context, record.context, sizeof(tchan->context)); 00448 ast_string_field_set(tchan, name, record.channel_name); 00449 ast_string_field_set(tchan, uniqueid, record.unique_id); 00450 ast_string_field_set(tchan, linkedid, record.linked_id); 00451 ast_string_field_set(tchan, accountcode, record.account_code); 00452 ast_string_field_set(tchan, peeraccount, record.peer_account); 00453 ast_string_field_set(tchan, userfield, record.user_field); 00454 00455 pbx_builtin_setvar_helper(tchan, "BRIDGEPEER", record.peer); 00456 00457 tchan->appl = ast_strdup(record.application_name); 00458 tchan->data = ast_strdup(record.application_data); 00459 tchan->amaflags = record.amaflag; 00460 00461 return tchan; 00462 }
| 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 567 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().
00568 { 00569 if (r->version != AST_CEL_EVENT_RECORD_VERSION) { 00570 ast_log(LOG_ERROR, "Module ABI mismatch for ast_cel_event_record. " 00571 "Please ensure all modules were compiled for " 00572 "this version of Asterisk.\n"); 00573 return -1; 00574 } 00575 00576 r->event_type = ast_event_get_ie_uint(e, AST_EVENT_IE_CEL_EVENT_TYPE); 00577 00578 r->event_time.tv_sec = ast_event_get_ie_uint(e, AST_EVENT_IE_CEL_EVENT_TIME); 00579 r->event_time.tv_usec = ast_event_get_ie_uint(e, AST_EVENT_IE_CEL_EVENT_TIME_USEC); 00580 00581 r->user_defined_name = ""; 00582 00583 if (r->event_type == AST_CEL_USER_DEFINED) { 00584 r->user_defined_name = ast_event_get_ie_str(e, AST_EVENT_IE_CEL_USEREVENT_NAME); 00585 r->event_name = r->user_defined_name; 00586 } else { 00587 r->event_name = ast_cel_get_type_name(r->event_type); 00588 } 00589 00590 r->caller_id_name = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_CIDNAME), ""); 00591 r->caller_id_num = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_CIDNUM), ""); 00592 r->caller_id_ani = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_CIDANI), ""); 00593 r->caller_id_rdnis = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_CIDRDNIS), ""); 00594 r->caller_id_dnid = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_CIDDNID), ""); 00595 r->extension = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_EXTEN), ""); 00596 r->context = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_CONTEXT), ""); 00597 r->channel_name = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_CHANNAME), ""); 00598 r->application_name = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_APPNAME), ""); 00599 r->application_data = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_APPDATA), ""); 00600 r->account_code = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_ACCTCODE), ""); 00601 r->peer_account = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_ACCTCODE), ""); 00602 r->unique_id = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_UNIQUEID), ""); 00603 r->linked_id = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_LINKEDID), ""); 00604 r->amaflag = ast_event_get_ie_uint(e, AST_EVENT_IE_CEL_AMAFLAGS); 00605 r->user_field = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_USERFIELD), ""); 00606 r->peer = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_PEER), ""); 00607 r->extra = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_EXTRA), ""); 00608 00609 return 0; 00610 }
| 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 350 of file cel.c.
References S_OR.
00351 { 00352 return S_OR(cel_ama_flags[flag], "Unknown"); 00353 }
| 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 345 of file cel.c.
References S_OR.
Referenced by ast_cel_fill_record(), and handle_cli_status().
00346 { 00347 return S_OR(cel_event_types[type], "Unknown"); 00348 }
| 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 464 of file cel.c.
References ast_channel::accountcode, ast_channel::amaflags, 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::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_rdnis, ast_channel::context, ast_channel::data, ast_channel::exten, ast_channel::linkedid, ast_channel::name, OBJ_POINTER, ast_channel::peeraccount, reload_lock, S_OR, ast_channel::uniqueid, and ast_channel::userfield.
Referenced by __analog_handle_event(), __ast_channel_alloc_ap(), __ast_read(), analog_attempt_transfer(), ast_bridge_call(), ast_cel_check_retire_linkedid(), ast_channel_destructor(), ast_do_masquerade(), ast_hangup(), ast_raw_answer(), builtin_atxfer(), builtin_blindtransfer(), celgenuserevent_exec(), do_forward(), handle_request_refer(), local_attended_transfer(), manage_parkinglot(), park_call_full(), park_exec_full(), pbx_exec(), pickup_do(), and wait_for_answer().
00466 { 00467 struct timeval eventtime; 00468 struct ast_event *ev; 00469 const char *peername = ""; 00470 struct ast_channel *peer; 00471 00472 ast_channel_lock(chan); 00473 peer = ast_bridged_channel(chan); 00474 if (peer) { 00475 ast_channel_ref(peer); 00476 } 00477 ast_channel_unlock(chan); 00478 00479 /* Make sure a reload is not occurring while we're checking to see if this 00480 * is an event that we care about. We could lose an important event in this 00481 * process otherwise. */ 00482 ast_mutex_lock(&reload_lock); 00483 00484 if (!cel_enabled || !ast_cel_track_event(event_type)) { 00485 ast_mutex_unlock(&reload_lock); 00486 if (peer) { 00487 ast_channel_unref(peer); 00488 } 00489 return 0; 00490 } 00491 00492 if (event_type == AST_CEL_APP_START || event_type == AST_CEL_APP_END) { 00493 char *app; 00494 if (!(app = ao2_find(appset, (char *) chan->appl, OBJ_POINTER))) { 00495 ast_mutex_unlock(&reload_lock); 00496 if (peer) { 00497 ast_channel_unref(peer); 00498 } 00499 return 0; 00500 } 00501 ao2_ref(app, -1); 00502 } 00503 00504 ast_mutex_unlock(&reload_lock); 00505 00506 if (peer) { 00507 ast_channel_lock(peer); 00508 peername = ast_strdupa(peer->name); 00509 ast_channel_unlock(peer); 00510 } else if (peer2) { 00511 ast_channel_lock(peer2); 00512 peername = ast_strdupa(peer2->name); 00513 ast_channel_unlock(peer2); 00514 } 00515 00516 if (!userdefevname) { 00517 userdefevname = ""; 00518 } 00519 00520 if (!extra) { 00521 extra = ""; 00522 } 00523 00524 eventtime = ast_tvnow(); 00525 00526 ast_channel_lock(chan); 00527 00528 ev = ast_event_new(AST_EVENT_CEL, 00529 AST_EVENT_IE_CEL_EVENT_TYPE, AST_EVENT_IE_PLTYPE_UINT, event_type, 00530 AST_EVENT_IE_CEL_EVENT_TIME, AST_EVENT_IE_PLTYPE_UINT, eventtime.tv_sec, 00531 AST_EVENT_IE_CEL_EVENT_TIME_USEC, AST_EVENT_IE_PLTYPE_UINT, eventtime.tv_usec, 00532 AST_EVENT_IE_CEL_USEREVENT_NAME, AST_EVENT_IE_PLTYPE_STR, userdefevname, 00533 AST_EVENT_IE_CEL_CIDNAME, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->cid.cid_name, ""), 00534 AST_EVENT_IE_CEL_CIDNUM, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->cid.cid_num, ""), 00535 AST_EVENT_IE_CEL_CIDANI, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->cid.cid_ani, ""), 00536 AST_EVENT_IE_CEL_CIDRDNIS, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->cid.cid_rdnis, ""), 00537 AST_EVENT_IE_CEL_CIDDNID, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->cid.cid_dnid, ""), 00538 AST_EVENT_IE_CEL_EXTEN, AST_EVENT_IE_PLTYPE_STR, chan->exten, 00539 AST_EVENT_IE_CEL_CONTEXT, AST_EVENT_IE_PLTYPE_STR, chan->context, 00540 AST_EVENT_IE_CEL_CHANNAME, AST_EVENT_IE_PLTYPE_STR, chan->name, 00541 AST_EVENT_IE_CEL_APPNAME, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->appl, ""), 00542 AST_EVENT_IE_CEL_APPDATA, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->data, ""), 00543 AST_EVENT_IE_CEL_AMAFLAGS, AST_EVENT_IE_PLTYPE_UINT, chan->amaflags, 00544 AST_EVENT_IE_CEL_ACCTCODE, AST_EVENT_IE_PLTYPE_STR, chan->accountcode, 00545 AST_EVENT_IE_CEL_PEERACCT, AST_EVENT_IE_PLTYPE_STR, chan->peeraccount, 00546 AST_EVENT_IE_CEL_UNIQUEID, AST_EVENT_IE_PLTYPE_STR, chan->uniqueid, 00547 AST_EVENT_IE_CEL_LINKEDID, AST_EVENT_IE_PLTYPE_STR, chan->linkedid, 00548 AST_EVENT_IE_CEL_USERFIELD, AST_EVENT_IE_PLTYPE_STR, chan->userfield, 00549 AST_EVENT_IE_CEL_EXTRA, AST_EVENT_IE_PLTYPE_STR, extra, 00550 AST_EVENT_IE_CEL_PEER, AST_EVENT_IE_PLTYPE_STR, peername, 00551 AST_EVENT_IE_END); 00552 00553 ast_channel_unlock(chan); 00554 00555 if (peer) { 00556 peer = ast_channel_unref(peer); 00557 } 00558 00559 if (ev && ast_event_queue(ev)) { 00560 ast_event_destroy(ev); 00561 return -1; 00562 } 00563 00564 return 0; 00565 }
| 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 208 of file cel.c.
References ARRAY_LEN.
Referenced by parse_events().
00209 { 00210 unsigned int i; 00211 00212 for (i = 0; i < ARRAY_LEN(cel_event_types); i++) { 00213 if (!cel_event_types[i]) { 00214 continue; 00215 } 00216 00217 if (!strcasecmp(name, cel_event_types[i])) { 00218 return i; 00219 } 00220 } 00221 00222 return -1; 00223 }
| static int ast_cel_track_event | ( | enum ast_cel_event_type | et | ) | [static] |
Definition at line 225 of file cel.c.
Referenced by ast_cel_check_retire_linkedid(), ast_cel_report_event(), and parse_apps().
00226 { 00227 return (eventset & ((int64_t) 1 << et)); 00228 }
| static int do_reload | ( | void | ) | [static] |
Definition at line 288 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, config, CONFIG_STATUS_FILEMISSING, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, parse_apps(), parse_events(), reload_lock, and s.
00289 { 00290 struct ast_config *config; 00291 const char *enabled_value; 00292 const char *val; 00293 int res = 0; 00294 struct ast_flags config_flags = { 0, }; 00295 const char *s; 00296 00297 ast_mutex_lock(&reload_lock); 00298 00299 /* Reset all settings before reloading configuration */ 00300 cel_enabled = CEL_ENALBED_DEFAULT; 00301 eventset = CEL_DEFAULT_EVENTS; 00302 *cel_dateformat = '\0'; 00303 ao2_callback(appset, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL); 00304 00305 config = ast_config_load2("cel.conf", "cel", config_flags); 00306 00307 if (config == CONFIG_STATUS_FILEMISSING) { 00308 config = NULL; 00309 goto return_cleanup; 00310 } 00311 00312 if ((enabled_value = ast_variable_retrieve(config, "general", "enable"))) { 00313 cel_enabled = ast_true(enabled_value); 00314 } 00315 00316 if (!cel_enabled) { 00317 goto return_cleanup; 00318 } 00319 00320 /* get the date format for logging */ 00321 if ((s = ast_variable_retrieve(config, "general", "dateformat"))) { 00322 ast_copy_string(cel_dateformat, s, sizeof(cel_dateformat)); 00323 } 00324 00325 if ((val = ast_variable_retrieve(config, "general", "events"))) { 00326 parse_events(val); 00327 } 00328 00329 if ((val = ast_variable_retrieve(config, "general", "apps"))) { 00330 parse_apps(val); 00331 } 00332 00333 return_cleanup: 00334 ast_verb(3, "CEL logging %sabled.\n", cel_enabled ? "en" : "dis"); 00335 00336 ast_mutex_unlock(&reload_lock); 00337 00338 if (config) { 00339 ast_config_destroy(config); 00340 } 00341 00342 return res; 00343 }
| static char* handle_cli_status | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 152 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, ast_cli_args::fd, name, OBJ_NODATA, print_app(), print_cel_sub(), and ast_cli_entry::usage.
00153 { 00154 unsigned int i; 00155 struct ast_event_sub *sub; 00156 00157 switch (cmd) { 00158 case CLI_INIT: 00159 e->command = "cel show status"; 00160 e->usage = 00161 "Usage: cel show status\n" 00162 " Displays the Channel Event Logging system status.\n"; 00163 return NULL; 00164 case CLI_GENERATE: 00165 return NULL; 00166 case CLI_HANDLER: 00167 break; 00168 } 00169 00170 if (a->argc > 3) { 00171 return CLI_SHOWUSAGE; 00172 } 00173 00174 ast_cli(a->fd, "CEL Logging: %s\n", cel_enabled ? "Enabled" : "Disabled"); 00175 00176 if (!cel_enabled) { 00177 return CLI_SUCCESS; 00178 } 00179 00180 for (i = 0; i < (sizeof(eventset) * 8); i++) { 00181 const char *name; 00182 00183 if (!(eventset & ((int64_t) 1 << i))) { 00184 continue; 00185 } 00186 00187 name = ast_cel_get_type_name(i); 00188 if (strcasecmp(name, "Unknown")) { 00189 ast_cli(a->fd, "CEL Tracking Event: %s\n", name); 00190 } 00191 } 00192 00193 ao2_callback(appset, OBJ_NODATA, print_app, a); 00194 00195 if (!(sub = ast_event_subscribe_new(AST_EVENT_SUB, print_cel_sub, a))) { 00196 return CLI_FAILURE; 00197 } 00198 ast_event_sub_append_ie_uint(sub, AST_EVENT_IE_EVENTTYPE, AST_EVENT_CEL); 00199 ast_event_report_subs(sub); 00200 ast_event_sub_destroy(sub); 00201 sub = NULL; 00202 00203 return CLI_SUCCESS; 00204 }
| static int linkedid_match | ( | void * | obj, | |
| void * | arg, | |||
| void * | data, | |||
| int | flags | |||
| ) | [static] |
Definition at line 363 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().
00364 { 00365 struct ast_channel *c = obj; 00366 struct channel_find_data *find_dat = data; 00367 int res; 00368 00369 ast_channel_lock(c); 00370 res = (c != find_dat->chan && c->linkedid && !strcmp(find_dat->linkedid, c->linkedid)); 00371 ast_channel_unlock(c); 00372 00373 return res ? CMP_MATCH | CMP_STOP : 0; 00374 }
| static void parse_apps | ( | const char * | val | ) | [static] |
Definition at line 257 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().
00258 { 00259 char *apps = ast_strdupa(val); 00260 char *cur_app; 00261 00262 if (!ast_cel_track_event(AST_CEL_APP_START) && !ast_cel_track_event(AST_CEL_APP_END)) { 00263 ast_log(LOG_WARNING, "An apps= config line, but not tracking APP events\n"); 00264 return; 00265 } 00266 00267 while ((cur_app = strsep(&apps, ","))) { 00268 char *app; 00269 00270 cur_app = ast_strip(cur_app); 00271 if (ast_strlen_zero(cur_app)) { 00272 continue; 00273 } 00274 00275 if (!(app = ao2_alloc(strlen(cur_app) + 1, NULL))) { 00276 continue; 00277 } 00278 strcpy(app, cur_app); 00279 00280 ao2_link(appset, app); 00281 ao2_ref(app, -1); 00282 app = NULL; 00283 } 00284 }
| static void parse_events | ( | const char * | val | ) | [static] |
Definition at line 230 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().
00231 { 00232 char *events = ast_strdupa(val); 00233 char *cur_event; 00234 00235 while ((cur_event = strsep(&events, ","))) { 00236 enum ast_cel_event_type event_type; 00237 00238 cur_event = ast_strip(cur_event); 00239 if (ast_strlen_zero(cur_event)) { 00240 continue; 00241 } 00242 00243 event_type = ast_cel_str_to_event_type(cur_event); 00244 00245 if (event_type == 0) { 00246 /* All events */ 00247 eventset = (int64_t) -1; 00248 } else if (event_type == -1) { 00249 ast_log(LOG_WARNING, "Unknown event name '%s'\n", 00250 cur_event); 00251 } else { 00252 eventset |= ((int64_t) 1 << event_type); 00253 } 00254 } 00255 }
| static int print_app | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 135 of file cel.c.
References ast_cli(), and ast_cli_args::fd.
Referenced by handle_cli_status().
00136 { 00137 struct ast_cli_args *a = arg; 00138 00139 ast_cli(a->fd, "CEL Tracking Application: %s\n", (const char *) obj); 00140 00141 return 0; 00142 }
| static void print_cel_sub | ( | const struct ast_event * | event, | |
| void * | data | |||
| ) | [static] |
Definition at line 144 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().
00145 { 00146 struct ast_cli_args *a = data; 00147 00148 ast_cli(a->fd, "CEL Event Subscriber: %s\n", 00149 ast_event_get_ie_str(event, AST_EVENT_IE_DESCRIPTION)); 00150 }
struct ao2_container* appset [static] |
const char* const cel_ama_flags[AST_CEL_AMA_FLAG_TOTAL] [static] |
Initial value:
{
[AST_CEL_AMA_FLAG_OMIT] = "OMIT",
[AST_CEL_AMA_FLAG_BILLING] = "BILLING",
[AST_CEL_AMA_FLAG_DOCUMENTATION] = "DOCUMENTATION",
}
char cel_dateformat[256] [static] |
const int64_t CEL_DEFAULT_EVENTS = 0 [static] |
unsigned char cel_enabled [static] |
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] |
const int NUM_APP_BUCKETS = 97 [static] |
ast_mutex_t reload_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
1.5.6