Call Event Logging API. More...
#include "asterisk/event.h"
Go to the source code of this file.
Data Structures | |
struct | ast_cel_event_record |
Helper struct for getting the fields out of a CEL event. More... | |
Defines | |
#define | AST_CEL_EVENT_RECORD_VERSION 2 |
struct ABI version | |
Enumerations | |
enum | ast_cel_ama_flag { AST_CEL_AMA_FLAG_NONE, AST_CEL_AMA_FLAG_OMIT, AST_CEL_AMA_FLAG_BILLING, AST_CEL_AMA_FLAG_DOCUMENTATION, AST_CEL_AMA_FLAG_TOTAL } |
AMA Flags. More... | |
enum | ast_cel_event_type { AST_CEL_CHANNEL_START = 1, AST_CEL_CHANNEL_END = 2, AST_CEL_HANGUP = 3, AST_CEL_ANSWER = 4, AST_CEL_APP_START = 5, AST_CEL_APP_END = 6, AST_CEL_BRIDGE_START = 7, AST_CEL_BRIDGE_END = 8, AST_CEL_CONF_START = 9, AST_CEL_CONF_END = 10, AST_CEL_PARK_START = 11, AST_CEL_PARK_END = 12, AST_CEL_BLINDTRANSFER = 13, AST_CEL_ATTENDEDTRANSFER = 14, AST_CEL_TRANSFER = 15, AST_CEL_HOOKFLASH = 16, AST_CEL_3WAY_START = 17, AST_CEL_3WAY_END = 18, AST_CEL_CONF_ENTER = 19, AST_CEL_CONF_EXIT = 20, AST_CEL_USER_DEFINED = 21, AST_CEL_LINKEDID_END = 22, AST_CEL_BRIDGE_UPDATE = 23, AST_CEL_PICKUP = 24, AST_CEL_FORWARD = 25 } |
CEL event types. More... | |
Functions | |
struct ast_cel * | ast_cel_alloc (void) |
Allocate a CEL record. | |
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. | |
void | ast_cel_destroy (struct ast_cel *cel) |
Destroy a CEL record. | |
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 *event, 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_linkedid_ref (const char *linkedid) |
Inform CEL that a new linkedid is being used. | |
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. |
Call Event Logging API.
Definition in file cel.h.
#define AST_CEL_EVENT_RECORD_VERSION 2 |
struct ABI version
Definition at line 246 of file cel.h.
Referenced by ast_cel_fabricate_channel_from_event(), and ast_cel_fill_record().
enum ast_cel_ama_flag |
AMA Flags.
AST_CEL_AMA_FLAG_NONE | |
AST_CEL_AMA_FLAG_OMIT | |
AST_CEL_AMA_FLAG_BILLING | |
AST_CEL_AMA_FLAG_DOCUMENTATION | |
AST_CEL_AMA_FLAG_TOTAL |
Must be final entry. |
Definition at line 36 of file cel.h.
00036 { 00037 AST_CEL_AMA_FLAG_NONE, 00038 AST_CEL_AMA_FLAG_OMIT, 00039 AST_CEL_AMA_FLAG_BILLING, 00040 AST_CEL_AMA_FLAG_DOCUMENTATION, 00041 /*! \brief Must be final entry */ 00042 AST_CEL_AMA_FLAG_TOTAL, 00043 };
enum ast_cel_event_type |
CEL event types.
Definition at line 48 of file cel.h.
00048 { 00049 /*! \brief channel birth */ 00050 AST_CEL_CHANNEL_START = 1, 00051 /*! \brief channel end */ 00052 AST_CEL_CHANNEL_END = 2, 00053 /*! \brief hangup terminates connection */ 00054 AST_CEL_HANGUP = 3, 00055 /*! \brief A ringing phone is answered */ 00056 AST_CEL_ANSWER = 4, 00057 /*! \brief an app starts */ 00058 AST_CEL_APP_START = 5, 00059 /*! \brief an app ends */ 00060 AST_CEL_APP_END = 6, 00061 /*! \brief a bridge is established */ 00062 AST_CEL_BRIDGE_START = 7, 00063 /*! \brief a bridge is torn down */ 00064 AST_CEL_BRIDGE_END = 8, 00065 /*! \brief a conference is started */ 00066 AST_CEL_CONF_START = 9, 00067 /*! \brief a conference is ended */ 00068 AST_CEL_CONF_END = 10, 00069 /*! \brief a channel is parked */ 00070 AST_CEL_PARK_START = 11, 00071 /*! \brief channel out of the park */ 00072 AST_CEL_PARK_END = 12, 00073 /*! \brief a transfer occurs */ 00074 AST_CEL_BLINDTRANSFER = 13, 00075 /*! \brief a transfer occurs */ 00076 AST_CEL_ATTENDEDTRANSFER = 14, 00077 /*! \brief a transfer occurs */ 00078 AST_CEL_TRANSFER = 15, 00079 /*! \brief a 3-way conference, usually part of a transfer */ 00080 AST_CEL_HOOKFLASH = 16, 00081 /*! \brief a 3-way conference, usually part of a transfer */ 00082 AST_CEL_3WAY_START = 17, 00083 /*! \brief a 3-way conference, usually part of a transfer */ 00084 AST_CEL_3WAY_END = 18, 00085 /*! \brief channel enters a conference */ 00086 AST_CEL_CONF_ENTER = 19, 00087 /*! \brief channel exits a conference */ 00088 AST_CEL_CONF_EXIT = 20, 00089 /*! \brief a user-defined event, the event name field should be set */ 00090 AST_CEL_USER_DEFINED = 21, 00091 /*! \brief the last channel with the given linkedid is retired */ 00092 AST_CEL_LINKEDID_END = 22, 00093 /*! \brief a masquerade happened to alter the participants on a bridge */ 00094 AST_CEL_BRIDGE_UPDATE = 23, 00095 /*! \brief a directed pickup was performed on this channel */ 00096 AST_CEL_PICKUP = 24, 00097 /*! \brief this call was forwarded somewhere else */ 00098 AST_CEL_FORWARD = 25, 00099 };
struct ast_cel* ast_cel_alloc | ( | void | ) | [read] |
Allocate a CEL record.
non-NULL | an allocated ast_cel structure | |
NULL | error |
unsigned int ast_cel_check_enabled | ( | void | ) |
Check to see if CEL is enabled.
zero | not enabled | |
non-zero | enabled |
Definition at line 164 of file cel.c.
00165 { 00166 return cel_enabled; 00167 }
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 429 of file cel.c.
References ao2_find, ao2_ref, ao2_unlink, AST_CEL_LINKEDID_END, ast_cel_report_event(), ast_cel_track_event(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_strlen_zero(), cel_linkedid::count, cel_linkedid::id, LOG_ERROR, OBJ_POINTER, and reload_lock.
Referenced by ast_channel_change_linkedid(), and ast_channel_destructor().
00430 { 00431 const char *linkedid = chan->linkedid; 00432 struct cel_linkedid *lid; 00433 struct cel_linkedid find_lid; 00434 00435 if (ast_strlen_zero(linkedid)) { 00436 return; 00437 } 00438 00439 /* Get the lock in case any CEL events are still in flight when we shutdown. */ 00440 ast_mutex_lock(&reload_lock); 00441 00442 if (!cel_enabled || !ast_cel_track_event(AST_CEL_LINKEDID_END) 00443 || !linkedids) { 00444 /* 00445 * CEL is disabled or we are not tracking linkedids 00446 * or the CEL module is shutdown. 00447 */ 00448 ast_mutex_unlock(&reload_lock); 00449 return; 00450 } 00451 00452 find_lid.id = linkedid; 00453 lid = ao2_find(linkedids, &find_lid, OBJ_POINTER); 00454 if (!lid) { 00455 ast_mutex_unlock(&reload_lock); 00456 00457 /* 00458 * The user may have done a reload to start tracking linkedids 00459 * when a call was already in progress. This is an unusual kind 00460 * of change to make after starting Asterisk. 00461 */ 00462 ast_log(LOG_ERROR, "Something weird happened, couldn't find linkedid %s\n", linkedid); 00463 return; 00464 } 00465 00466 if (!--lid->count) { 00467 /* No channels use this linkedid anymore. */ 00468 ao2_unlink(linkedids, lid); 00469 ast_mutex_unlock(&reload_lock); 00470 00471 ast_cel_report_event(chan, AST_CEL_LINKEDID_END, NULL, NULL, NULL); 00472 } else { 00473 ast_mutex_unlock(&reload_lock); 00474 } 00475 ao2_ref(lid, -1); 00476 }
void ast_cel_destroy | ( | struct ast_cel * | cel | ) |
Destroy a CEL record.
cel | the record to destroy |
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 486 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_datastore_add(), ast_channel_unref, ast_copy_string(), ast_datastore_alloc, ast_datastore_free(), ast_dummy_channel_alloc, AST_LIST_INSERT_HEAD, ast_localtime(), ast_malloc, 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_datastore::data, 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_dialed::number, ast_party_id::number, ast_cel_event_record::peer, ast_cel_event_record::peer_account, ast_channel::redirecting, ast_party_dialed::str, ast_party_number::str, ast_party_name::str, ast_cel_event_record::unique_id, ast_cel_event_record::user_defined_name, ast_cel_event_record::user_field, ast_party_number::valid, ast_party_name::valid, ast_channel::varshead, and ast_cel_event_record::version.
00487 { 00488 struct varshead *headp; 00489 struct ast_var_t *newvariable; 00490 char timebuf[30]; 00491 struct ast_channel *tchan; 00492 struct ast_cel_event_record record = { 00493 .version = AST_CEL_EVENT_RECORD_VERSION, 00494 }; 00495 struct ast_datastore *datastore; 00496 char *app_data; 00497 00498 /* do not call ast_channel_alloc because this is not really a real channel */ 00499 if (!(tchan = ast_dummy_channel_alloc())) { 00500 return NULL; 00501 } 00502 00503 headp = &tchan->varshead; 00504 00505 /* first, get the variables from the event */ 00506 if (ast_cel_fill_record(event, &record)) { 00507 ast_channel_unref(tchan); 00508 return NULL; 00509 } 00510 00511 /* next, fill the channel with their data */ 00512 if ((newvariable = ast_var_assign("eventtype", record.event_name))) { 00513 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 00514 } 00515 00516 if (ast_strlen_zero(cel_dateformat)) { 00517 snprintf(timebuf, sizeof(timebuf), "%ld.%06ld", (long) record.event_time.tv_sec, 00518 (long) record.event_time.tv_usec); 00519 } else { 00520 struct ast_tm tm; 00521 ast_localtime(&record.event_time, &tm, NULL); 00522 ast_strftime(timebuf, sizeof(timebuf), cel_dateformat, &tm); 00523 } 00524 00525 if ((newvariable = ast_var_assign("eventtime", timebuf))) { 00526 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 00527 } 00528 00529 if ((newvariable = ast_var_assign("userdeftype", record.user_defined_name))) { 00530 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 00531 } 00532 if ((newvariable = ast_var_assign("eventextra", record.extra))) { 00533 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 00534 } 00535 00536 tchan->caller.id.name.valid = 1; 00537 tchan->caller.id.name.str = ast_strdup(record.caller_id_name); 00538 tchan->caller.id.number.valid = 1; 00539 tchan->caller.id.number.str = ast_strdup(record.caller_id_num); 00540 tchan->caller.ani.number.valid = 1; 00541 tchan->caller.ani.number.str = ast_strdup(record.caller_id_ani); 00542 tchan->redirecting.from.number.valid = 1; 00543 tchan->redirecting.from.number.str = ast_strdup(record.caller_id_rdnis); 00544 tchan->dialed.number.str = ast_strdup(record.caller_id_dnid); 00545 00546 ast_copy_string(tchan->exten, record.extension, sizeof(tchan->exten)); 00547 ast_copy_string(tchan->context, record.context, sizeof(tchan->context)); 00548 ast_string_field_set(tchan, name, record.channel_name); 00549 ast_string_field_set(tchan, uniqueid, record.unique_id); 00550 ast_string_field_set(tchan, linkedid, record.linked_id); 00551 ast_string_field_set(tchan, accountcode, record.account_code); 00552 ast_string_field_set(tchan, peeraccount, record.peer_account); 00553 ast_string_field_set(tchan, userfield, record.user_field); 00554 00555 if ((newvariable = ast_var_assign("BRIDGEPEER", record.peer))) { 00556 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 00557 } 00558 00559 tchan->amaflags = record.amaflag; 00560 00561 /* We need to store an 'application name' and 'application 00562 * data' on the channel for logging purposes, but the channel 00563 * structure only provides a place to store pointers, and it 00564 * expects these pointers to be pointing to data that does not 00565 * need to be freed. This means that the channel's destructor 00566 * does not attempt to free any storage that these pointers 00567 * point to. However, we can't provide data in that form directly for 00568 * these structure members. In order to ensure that these data 00569 * elements have a lifetime that matches the channel's 00570 * lifetime, we'll put them in a datastore attached to the 00571 * channel, and set's the channel's pointers to point into the 00572 * datastore. The datastore will then be automatically destroyed 00573 * when the channel is destroyed. 00574 */ 00575 00576 if (!(datastore = ast_datastore_alloc(&fabricated_channel_datastore, NULL))) { 00577 ast_channel_unref(tchan); 00578 return NULL; 00579 } 00580 00581 if (!(app_data = ast_malloc(strlen(record.application_name) + strlen(record.application_data) + 2))) { 00582 ast_datastore_free(datastore); 00583 ast_channel_unref(tchan); 00584 return NULL; 00585 } 00586 00587 tchan->appl = strcpy(app_data, record.application_name); 00588 tchan->data = strcpy(app_data + strlen(record.application_name) + 1, 00589 record.application_data); 00590 00591 datastore->data = app_data; 00592 ast_channel_datastore_add(tchan, datastore); 00593 00594 return tchan; 00595 }
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 762 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().
00763 { 00764 if (r->version != AST_CEL_EVENT_RECORD_VERSION) { 00765 ast_log(LOG_ERROR, "Module ABI mismatch for ast_cel_event_record. " 00766 "Please ensure all modules were compiled for " 00767 "this version of Asterisk.\n"); 00768 return -1; 00769 } 00770 00771 r->event_type = ast_event_get_ie_uint(e, AST_EVENT_IE_CEL_EVENT_TYPE); 00772 00773 r->event_time.tv_sec = ast_event_get_ie_uint(e, AST_EVENT_IE_CEL_EVENT_TIME); 00774 r->event_time.tv_usec = ast_event_get_ie_uint(e, AST_EVENT_IE_CEL_EVENT_TIME_USEC); 00775 00776 r->user_defined_name = ""; 00777 00778 if (r->event_type == AST_CEL_USER_DEFINED) { 00779 r->user_defined_name = ast_event_get_ie_str(e, AST_EVENT_IE_CEL_USEREVENT_NAME); 00780 r->event_name = r->user_defined_name; 00781 } else { 00782 r->event_name = ast_cel_get_type_name(r->event_type); 00783 } 00784 00785 r->caller_id_name = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_CIDNAME), ""); 00786 r->caller_id_num = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_CIDNUM), ""); 00787 r->caller_id_ani = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_CIDANI), ""); 00788 r->caller_id_rdnis = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_CIDRDNIS), ""); 00789 r->caller_id_dnid = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_CIDDNID), ""); 00790 r->extension = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_EXTEN), ""); 00791 r->context = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_CONTEXT), ""); 00792 r->channel_name = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_CHANNAME), ""); 00793 r->application_name = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_APPNAME), ""); 00794 r->application_data = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_APPDATA), ""); 00795 r->account_code = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_ACCTCODE), ""); 00796 r->peer_account = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_ACCTCODE), ""); 00797 r->unique_id = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_UNIQUEID), ""); 00798 r->linked_id = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_LINKEDID), ""); 00799 r->amaflag = ast_event_get_ie_uint(e, AST_EVENT_IE_CEL_AMAFLAGS); 00800 r->user_field = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_USERFIELD), ""); 00801 r->peer = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_PEER), ""); 00802 r->extra = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_EXTRA), ""); 00803 00804 return 0; 00805 }
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 417 of file cel.c.
References ARRAY_LEN, ast_log(), LOG_WARNING, and S_OR.
00418 { 00419 if (flag < 0 || flag >= ARRAY_LEN(cel_ama_flags)) { 00420 ast_log(LOG_WARNING, "Invalid AMA flag: %u\n", flag); 00421 return "Unknown"; 00422 } 00423 00424 return S_OR(cel_ama_flags[flag], "Unknown"); 00425 }
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 412 of file cel.c.
References S_OR.
Referenced by ast_cel_fill_record(), and handle_cli_status().
00413 { 00414 return S_OR(cel_event_types[type], "Unknown"); 00415 }
int ast_cel_linkedid_ref | ( | const char * | linkedid | ) |
Inform CEL that a new linkedid is being used.
-1 | error | |
0 | success |
Definition at line 597 of file cel.c.
References ao2_alloc, ao2_find, ao2_link, ao2_ref, AST_CEL_LINKEDID_END, ast_cel_track_event(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_strlen_zero(), cel_linkedid::count, cel_linkedid::id, LOG_ERROR, OBJ_POINTER, and reload_lock.
Referenced by ast_cel_report_event(), and ast_channel_change_linkedid().
00598 { 00599 struct cel_linkedid *lid; 00600 struct cel_linkedid find_lid; 00601 00602 if (ast_strlen_zero(linkedid)) { 00603 ast_log(LOG_ERROR, "The linkedid should never be empty\n"); 00604 return -1; 00605 } 00606 00607 /* Get the lock in case any CEL events are still in flight when we shutdown. */ 00608 ast_mutex_lock(&reload_lock); 00609 00610 if (!cel_enabled || !ast_cel_track_event(AST_CEL_LINKEDID_END)) { 00611 /* CEL is disabled or we are not tracking linkedids. */ 00612 ast_mutex_unlock(&reload_lock); 00613 return 0; 00614 } 00615 if (!linkedids) { 00616 /* The CEL module is shutdown. Abort. */ 00617 ast_mutex_unlock(&reload_lock); 00618 return -1; 00619 } 00620 00621 find_lid.id = linkedid; 00622 lid = ao2_find(linkedids, &find_lid, OBJ_POINTER); 00623 if (!lid) { 00624 /* 00625 * Changes to the lid->count member are protected by the 00626 * reload_lock so the lid object does not need its own lock. 00627 */ 00628 lid = ao2_alloc(sizeof(*lid) + strlen(linkedid) + 1, NULL); 00629 if (!lid) { 00630 ast_mutex_unlock(&reload_lock); 00631 return -1; 00632 } 00633 lid->id = (char *) (lid + 1); 00634 strcpy((char *) lid->id, linkedid);/* Safe */ 00635 00636 ao2_link(linkedids, lid); 00637 } 00638 ++lid->count; 00639 ast_mutex_unlock(&reload_lock); 00640 ao2_ref(lid, -1); 00641 00642 return 0; 00643 }
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 645 of file cel.c.
References 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_CHANNEL_START, AST_CEL_LINKEDID_END, ast_cel_linkedid_ref(), 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_party_id::name, ast_party_dialed::number, ast_party_id::number, OBJ_POINTER, ast_channel::redirecting, reload_lock, S_COR, S_OR, ast_party_dialed::str, ast_party_number::str, ast_party_name::str, ast_party_number::valid, and ast_party_name::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_invite_replaces(), handle_request_refer(), local_attended_transfer(), manage_parked_call(), park_call_full(), parked_call_exec(), pbx_exec(), and wait_for_answer().
00647 { 00648 struct timeval eventtime; 00649 struct ast_event *ev; 00650 const char *peername = ""; 00651 struct ast_channel *peer; 00652 00653 /* Make sure a reload is not occurring while we're checking to see if this 00654 * is an event that we care about. We could lose an important event in this 00655 * process otherwise. */ 00656 ast_mutex_lock(&reload_lock); 00657 00658 if (!appset) { 00659 /* The CEL module is shutdown. Abort. */ 00660 ast_mutex_unlock(&reload_lock); 00661 return -1; 00662 } 00663 00664 /* Record the linkedid of new channels if we are tracking LINKEDID_END even if we aren't 00665 * reporting on CHANNEL_START so we can track when to send LINKEDID_END */ 00666 if (cel_enabled && ast_cel_track_event(AST_CEL_LINKEDID_END) && event_type == AST_CEL_CHANNEL_START && chan->linkedid) { 00667 if (ast_cel_linkedid_ref(chan->linkedid)) { 00668 ast_mutex_unlock(&reload_lock); 00669 return -1; 00670 } 00671 } 00672 00673 if (!cel_enabled || !ast_cel_track_event(event_type)) { 00674 ast_mutex_unlock(&reload_lock); 00675 return 0; 00676 } 00677 00678 if (event_type == AST_CEL_APP_START || event_type == AST_CEL_APP_END) { 00679 char *app; 00680 if (!(app = ao2_find(appset, (char *) chan->appl, OBJ_POINTER))) { 00681 ast_mutex_unlock(&reload_lock); 00682 return 0; 00683 } 00684 ao2_ref(app, -1); 00685 } 00686 00687 ast_mutex_unlock(&reload_lock); 00688 00689 ast_channel_lock(chan); 00690 peer = ast_bridged_channel(chan); 00691 if (peer) { 00692 ast_channel_ref(peer); 00693 } 00694 ast_channel_unlock(chan); 00695 00696 if (peer) { 00697 ast_channel_lock(peer); 00698 peername = ast_strdupa(peer->name); 00699 ast_channel_unlock(peer); 00700 } else if (peer2) { 00701 ast_channel_lock(peer2); 00702 peername = ast_strdupa(peer2->name); 00703 ast_channel_unlock(peer2); 00704 } 00705 00706 if (!userdefevname) { 00707 userdefevname = ""; 00708 } 00709 00710 if (!extra) { 00711 extra = ""; 00712 } 00713 00714 eventtime = ast_tvnow(); 00715 00716 ast_channel_lock(chan); 00717 00718 ev = ast_event_new(AST_EVENT_CEL, 00719 AST_EVENT_IE_CEL_EVENT_TYPE, AST_EVENT_IE_PLTYPE_UINT, event_type, 00720 AST_EVENT_IE_CEL_EVENT_TIME, AST_EVENT_IE_PLTYPE_UINT, eventtime.tv_sec, 00721 AST_EVENT_IE_CEL_EVENT_TIME_USEC, AST_EVENT_IE_PLTYPE_UINT, eventtime.tv_usec, 00722 AST_EVENT_IE_CEL_USEREVENT_NAME, AST_EVENT_IE_PLTYPE_STR, userdefevname, 00723 AST_EVENT_IE_CEL_CIDNAME, AST_EVENT_IE_PLTYPE_STR, 00724 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, ""), 00725 AST_EVENT_IE_CEL_CIDNUM, AST_EVENT_IE_PLTYPE_STR, 00726 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""), 00727 AST_EVENT_IE_CEL_CIDANI, AST_EVENT_IE_PLTYPE_STR, 00728 S_COR(chan->caller.ani.number.valid, chan->caller.ani.number.str, ""), 00729 AST_EVENT_IE_CEL_CIDRDNIS, AST_EVENT_IE_PLTYPE_STR, 00730 S_COR(chan->redirecting.from.number.valid, chan->redirecting.from.number.str, ""), 00731 AST_EVENT_IE_CEL_CIDDNID, AST_EVENT_IE_PLTYPE_STR, 00732 S_OR(chan->dialed.number.str, ""), 00733 AST_EVENT_IE_CEL_EXTEN, AST_EVENT_IE_PLTYPE_STR, chan->exten, 00734 AST_EVENT_IE_CEL_CONTEXT, AST_EVENT_IE_PLTYPE_STR, chan->context, 00735 AST_EVENT_IE_CEL_CHANNAME, AST_EVENT_IE_PLTYPE_STR, chan->name, 00736 AST_EVENT_IE_CEL_APPNAME, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->appl, ""), 00737 AST_EVENT_IE_CEL_APPDATA, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->data, ""), 00738 AST_EVENT_IE_CEL_AMAFLAGS, AST_EVENT_IE_PLTYPE_UINT, chan->amaflags, 00739 AST_EVENT_IE_CEL_ACCTCODE, AST_EVENT_IE_PLTYPE_STR, chan->accountcode, 00740 AST_EVENT_IE_CEL_PEERACCT, AST_EVENT_IE_PLTYPE_STR, chan->peeraccount, 00741 AST_EVENT_IE_CEL_UNIQUEID, AST_EVENT_IE_PLTYPE_STR, chan->uniqueid, 00742 AST_EVENT_IE_CEL_LINKEDID, AST_EVENT_IE_PLTYPE_STR, chan->linkedid, 00743 AST_EVENT_IE_CEL_USERFIELD, AST_EVENT_IE_PLTYPE_STR, chan->userfield, 00744 AST_EVENT_IE_CEL_EXTRA, AST_EVENT_IE_PLTYPE_STR, extra, 00745 AST_EVENT_IE_CEL_PEER, AST_EVENT_IE_PLTYPE_STR, peername, 00746 AST_EVENT_IE_END); 00747 00748 ast_channel_unlock(chan); 00749 00750 if (peer) { 00751 peer = ast_channel_unref(peer); 00752 } 00753 00754 if (ev && ast_event_queue(ev)) { 00755 ast_event_destroy(ev); 00756 return -1; 00757 } 00758 00759 return 0; 00760 }
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 254 of file cel.c.
References ARRAY_LEN.
Referenced by parse_events().
00255 { 00256 unsigned int i; 00257 00258 for (i = 0; i < ARRAY_LEN(cel_event_types); i++) { 00259 if (!cel_event_types[i]) { 00260 continue; 00261 } 00262 00263 if (!strcasecmp(name, cel_event_types[i])) { 00264 return i; 00265 } 00266 } 00267 00268 return -1; 00269 }