#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 | |
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. | |
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. |
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 | ) |
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 136 of file cel.c.
00137 { 00138 return cel_enabled; 00139 }
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 368 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_strlen_zero(), ast_channel::linkedid, linkedids, LOG_ERROR, and OBJ_POINTER.
Referenced by ast_channel_change_linkedid(), and ast_channel_destructor().
00369 { 00370 const char *linkedid = chan->linkedid; 00371 char *lid; 00372 00373 /* make sure we need to do all this work */ 00374 00375 if (ast_strlen_zero(linkedid) || !ast_cel_track_event(AST_CEL_LINKEDID_END)) { 00376 return; 00377 } 00378 00379 if (!(lid = ao2_find(linkedids, (void *) linkedid, OBJ_POINTER))) { 00380 ast_log(LOG_ERROR, "Something weird happened, couldn't find linkedid %s\n", linkedid); 00381 return; 00382 } 00383 00384 /* We have a ref for each channel with this linkedid, the link and the above find, so if 00385 * before unreffing the channel we have a refcount of 3, we're done. Unlink and report. */ 00386 if (ao2_ref(lid, -1) == 3) { 00387 ao2_unlink(linkedids, lid); 00388 ast_cel_report_event(chan, AST_CEL_LINKEDID_END, NULL, NULL, NULL); 00389 } 00390 ao2_ref(lid, -1); 00391 }
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 | ) |
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_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_channel::context, ast_cel_event_record::context, ast_channel::data, ast_datastore::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, fabricated_channel_datastore, ast_party_redirecting::from, ast_party_caller::id, ast_cel_event_record::linked_id, ast_party_id::name, name, ast_party_id::number, ast_party_dialed::number, 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_defined_name, ast_cel_event_record::user_field, ast_party_name::valid, ast_party_number::valid, ast_channel::varshead, and ast_cel_event_record::version.
00402 { 00403 struct varshead *headp; 00404 struct ast_var_t *newvariable; 00405 char timebuf[30]; 00406 struct ast_channel *tchan; 00407 struct ast_cel_event_record record = { 00408 .version = AST_CEL_EVENT_RECORD_VERSION, 00409 }; 00410 struct ast_datastore *datastore; 00411 char *app_data; 00412 00413 /* do not call ast_channel_alloc because this is not really a real channel */ 00414 if (!(tchan = ast_dummy_channel_alloc())) { 00415 return NULL; 00416 } 00417 00418 headp = &tchan->varshead; 00419 00420 /* first, get the variables from the event */ 00421 if (ast_cel_fill_record(event, &record)) { 00422 ast_channel_unref(tchan); 00423 return NULL; 00424 } 00425 00426 /* next, fill the channel with their data */ 00427 if ((newvariable = ast_var_assign("eventtype", record.event_name))) { 00428 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 00429 } 00430 00431 if (ast_strlen_zero(cel_dateformat)) { 00432 snprintf(timebuf, sizeof(timebuf), "%ld.%06ld", (long) record.event_time.tv_sec, 00433 (long) record.event_time.tv_usec); 00434 } else { 00435 struct ast_tm tm; 00436 ast_localtime(&record.event_time, &tm, NULL); 00437 ast_strftime(timebuf, sizeof(timebuf), cel_dateformat, &tm); 00438 } 00439 00440 if ((newvariable = ast_var_assign("eventtime", timebuf))) { 00441 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 00442 } 00443 00444 if ((newvariable = ast_var_assign("userdeftype", record.user_defined_name))) { 00445 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 00446 } 00447 if ((newvariable = ast_var_assign("eventextra", record.extra))) { 00448 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 00449 } 00450 00451 tchan->caller.id.name.valid = 1; 00452 tchan->caller.id.name.str = ast_strdup(record.caller_id_name); 00453 tchan->caller.id.number.valid = 1; 00454 tchan->caller.id.number.str = ast_strdup(record.caller_id_num); 00455 tchan->caller.ani.number.valid = 1; 00456 tchan->caller.ani.number.str = ast_strdup(record.caller_id_ani); 00457 tchan->redirecting.from.number.valid = 1; 00458 tchan->redirecting.from.number.str = ast_strdup(record.caller_id_rdnis); 00459 tchan->dialed.number.str = ast_strdup(record.caller_id_dnid); 00460 00461 ast_copy_string(tchan->exten, record.extension, sizeof(tchan->exten)); 00462 ast_copy_string(tchan->context, record.context, sizeof(tchan->context)); 00463 ast_string_field_set(tchan, name, record.channel_name); 00464 ast_string_field_set(tchan, uniqueid, record.unique_id); 00465 ast_string_field_set(tchan, linkedid, record.linked_id); 00466 ast_string_field_set(tchan, accountcode, record.account_code); 00467 ast_string_field_set(tchan, peeraccount, record.peer_account); 00468 ast_string_field_set(tchan, userfield, record.user_field); 00469 00470 if ((newvariable = ast_var_assign("BRIDGEPEER", record.peer))) { 00471 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 00472 } 00473 00474 tchan->amaflags = record.amaflag; 00475 00476 /* We need to store an 'application name' and 'application 00477 * data' on the channel for logging purposes, but the channel 00478 * structure only provides a place to store pointers, and it 00479 * expects these pointers to be pointing to data that does not 00480 * need to be freed. This means that the channel's destructor 00481 * does not attempt to free any storage that these pointers 00482 * point to. However, we can't provide data in that form directly for 00483 * these structure members. In order to ensure that these data 00484 * elements have a lifetime that matches the channel's 00485 * lifetime, we'll put them in a datastore attached to the 00486 * channel, and set's the channel's pointers to point into the 00487 * datastore. The datastore will then be automatically destroyed 00488 * when the channel is destroyed. 00489 */ 00490 00491 if (!(datastore = ast_datastore_alloc(&fabricated_channel_datastore, NULL))) { 00492 ast_channel_unref(tchan); 00493 return NULL; 00494 } 00495 00496 if (!(app_data = ast_malloc(strlen(record.application_name) + strlen(record.application_data) + 2))) { 00497 ast_datastore_free(datastore); 00498 ast_channel_unref(tchan); 00499 return NULL; 00500 } 00501 00502 tchan->appl = strcpy(app_data, record.application_name); 00503 tchan->data = strcpy(app_data + strlen(record.application_name) + 1, 00504 record.application_data); 00505 00506 datastore->data = app_data; 00507 ast_channel_datastore_add(tchan, datastore); 00508 00509 return tchan; 00510 }
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 648 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().
00649 { 00650 if (r->version != AST_CEL_EVENT_RECORD_VERSION) { 00651 ast_log(LOG_ERROR, "Module ABI mismatch for ast_cel_event_record. " 00652 "Please ensure all modules were compiled for " 00653 "this version of Asterisk.\n"); 00654 return -1; 00655 } 00656 00657 r->event_type = ast_event_get_ie_uint(e, AST_EVENT_IE_CEL_EVENT_TYPE); 00658 00659 r->event_time.tv_sec = ast_event_get_ie_uint(e, AST_EVENT_IE_CEL_EVENT_TIME); 00660 r->event_time.tv_usec = ast_event_get_ie_uint(e, AST_EVENT_IE_CEL_EVENT_TIME_USEC); 00661 00662 r->user_defined_name = ""; 00663 00664 if (r->event_type == AST_CEL_USER_DEFINED) { 00665 r->user_defined_name = ast_event_get_ie_str(e, AST_EVENT_IE_CEL_USEREVENT_NAME); 00666 r->event_name = r->user_defined_name; 00667 } else { 00668 r->event_name = ast_cel_get_type_name(r->event_type); 00669 } 00670 00671 r->caller_id_name = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_CIDNAME), ""); 00672 r->caller_id_num = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_CIDNUM), ""); 00673 r->caller_id_ani = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_CIDANI), ""); 00674 r->caller_id_rdnis = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_CIDRDNIS), ""); 00675 r->caller_id_dnid = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_CIDDNID), ""); 00676 r->extension = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_EXTEN), ""); 00677 r->context = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_CONTEXT), ""); 00678 r->channel_name = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_CHANNAME), ""); 00679 r->application_name = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_APPNAME), ""); 00680 r->application_data = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_APPDATA), ""); 00681 r->account_code = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_ACCTCODE), ""); 00682 r->peer_account = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_ACCTCODE), ""); 00683 r->unique_id = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_UNIQUEID), ""); 00684 r->linked_id = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_LINKEDID), ""); 00685 r->amaflag = ast_event_get_ie_uint(e, AST_EVENT_IE_CEL_AMAFLAGS); 00686 r->user_field = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_USERFIELD), ""); 00687 r->peer = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_PEER), ""); 00688 r->extra = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_EXTRA), ""); 00689 00690 return 0; 00691 }
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 356 of file cel.c.
References ARRAY_LEN, ast_log(), LOG_WARNING, and S_OR.
00357 { 00358 if (flag < 0 || flag >= ARRAY_LEN(cel_ama_flags)) { 00359 ast_log(LOG_WARNING, "Invalid AMA flag: %d\n", flag); 00360 return "Unknown"; 00361 } 00362 00363 return S_OR(cel_ama_flags[flag], "Unknown"); 00364 }
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 351 of file cel.c.
References S_OR.
Referenced by ast_cel_fill_record(), and handle_cli_status().
00352 { 00353 return S_OR(cel_event_types[type], "Unknown"); 00354 }
int ast_cel_linkedid_ref | ( | const char * | linkedid | ) |
Inform CEL that a new linkedid is being used.
-1 | error | |
0 | success |
Definition at line 512 of file cel.c.
References ao2_alloc, ao2_find, ao2_link, ao2_ref, ast_log(), ast_strlen_zero(), linkedids, LOG_ERROR, and OBJ_POINTER.
Referenced by ast_cel_report_event(), and ast_channel_change_linkedid().
00513 { 00514 char *lid; 00515 00516 if (ast_strlen_zero(linkedid)) { 00517 ast_log(LOG_ERROR, "The linkedid should never be empty\n"); 00518 return -1; 00519 } 00520 00521 if (!(lid = ao2_find(linkedids, (void *) linkedid, OBJ_POINTER))) { 00522 if (!(lid = ao2_alloc(strlen(linkedid) + 1, NULL))) { 00523 return -1; 00524 } 00525 strcpy(lid, linkedid); 00526 if (!ao2_link(linkedids, lid)) { 00527 ao2_ref(lid, -1); 00528 return -1; 00529 } 00530 /* Leave both the link and the alloc refs to show a count of 1 + the link */ 00531 } 00532 /* If we've found, go ahead and keep the ref to increment count of how many channels 00533 * have this linkedid. We'll clean it up in check_retire */ 00534 return 0; 00535 }
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 537 of file cel.c.
References ast_channel::accountcode, ast_channel::amaflags, ast_party_caller::ani, ao2_find, ao2_ref, app, ast_channel::appl, appset, 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_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(), and pbx_exec().
00539 { 00540 struct timeval eventtime; 00541 struct ast_event *ev; 00542 const char *peername = ""; 00543 struct ast_channel *peer; 00544 00545 /* Make sure a reload is not occurring while we're checking to see if this 00546 * is an event that we care about. We could lose an important event in this 00547 * process otherwise. */ 00548 ast_mutex_lock(&reload_lock); 00549 00550 /* Record the linkedid of new channels if we are tracking LINKEDID_END even if we aren't 00551 * reporting on CHANNEL_START so we can track when to send LINKEDID_END */ 00552 if (cel_enabled && ast_cel_track_event(AST_CEL_LINKEDID_END) && event_type == AST_CEL_CHANNEL_START && chan->linkedid) { 00553 if (ast_cel_linkedid_ref(chan->linkedid)) { 00554 ast_mutex_unlock(&reload_lock); 00555 return -1; 00556 } 00557 } 00558 00559 if (!cel_enabled || !ast_cel_track_event(event_type)) { 00560 ast_mutex_unlock(&reload_lock); 00561 return 0; 00562 } 00563 00564 if (event_type == AST_CEL_APP_START || event_type == AST_CEL_APP_END) { 00565 char *app; 00566 if (!(app = ao2_find(appset, (char *) chan->appl, OBJ_POINTER))) { 00567 ast_mutex_unlock(&reload_lock); 00568 return 0; 00569 } 00570 ao2_ref(app, -1); 00571 } 00572 00573 ast_mutex_unlock(&reload_lock); 00574 00575 ast_channel_lock(chan); 00576 peer = ast_bridged_channel(chan); 00577 if (peer) { 00578 ast_channel_ref(peer); 00579 } 00580 ast_channel_unlock(chan); 00581 00582 if (peer) { 00583 ast_channel_lock(peer); 00584 peername = ast_strdupa(peer->name); 00585 ast_channel_unlock(peer); 00586 } else if (peer2) { 00587 ast_channel_lock(peer2); 00588 peername = ast_strdupa(peer2->name); 00589 ast_channel_unlock(peer2); 00590 } 00591 00592 if (!userdefevname) { 00593 userdefevname = ""; 00594 } 00595 00596 if (!extra) { 00597 extra = ""; 00598 } 00599 00600 eventtime = ast_tvnow(); 00601 00602 ast_channel_lock(chan); 00603 00604 ev = ast_event_new(AST_EVENT_CEL, 00605 AST_EVENT_IE_CEL_EVENT_TYPE, AST_EVENT_IE_PLTYPE_UINT, event_type, 00606 AST_EVENT_IE_CEL_EVENT_TIME, AST_EVENT_IE_PLTYPE_UINT, eventtime.tv_sec, 00607 AST_EVENT_IE_CEL_EVENT_TIME_USEC, AST_EVENT_IE_PLTYPE_UINT, eventtime.tv_usec, 00608 AST_EVENT_IE_CEL_USEREVENT_NAME, AST_EVENT_IE_PLTYPE_STR, userdefevname, 00609 AST_EVENT_IE_CEL_CIDNAME, AST_EVENT_IE_PLTYPE_STR, 00610 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, ""), 00611 AST_EVENT_IE_CEL_CIDNUM, AST_EVENT_IE_PLTYPE_STR, 00612 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""), 00613 AST_EVENT_IE_CEL_CIDANI, AST_EVENT_IE_PLTYPE_STR, 00614 S_COR(chan->caller.ani.number.valid, chan->caller.ani.number.str, ""), 00615 AST_EVENT_IE_CEL_CIDRDNIS, AST_EVENT_IE_PLTYPE_STR, 00616 S_COR(chan->redirecting.from.number.valid, chan->redirecting.from.number.str, ""), 00617 AST_EVENT_IE_CEL_CIDDNID, AST_EVENT_IE_PLTYPE_STR, 00618 S_OR(chan->dialed.number.str, ""), 00619 AST_EVENT_IE_CEL_EXTEN, AST_EVENT_IE_PLTYPE_STR, chan->exten, 00620 AST_EVENT_IE_CEL_CONTEXT, AST_EVENT_IE_PLTYPE_STR, chan->context, 00621 AST_EVENT_IE_CEL_CHANNAME, AST_EVENT_IE_PLTYPE_STR, chan->name, 00622 AST_EVENT_IE_CEL_APPNAME, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->appl, ""), 00623 AST_EVENT_IE_CEL_APPDATA, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->data, ""), 00624 AST_EVENT_IE_CEL_AMAFLAGS, AST_EVENT_IE_PLTYPE_UINT, chan->amaflags, 00625 AST_EVENT_IE_CEL_ACCTCODE, AST_EVENT_IE_PLTYPE_STR, chan->accountcode, 00626 AST_EVENT_IE_CEL_PEERACCT, AST_EVENT_IE_PLTYPE_STR, chan->peeraccount, 00627 AST_EVENT_IE_CEL_UNIQUEID, AST_EVENT_IE_PLTYPE_STR, chan->uniqueid, 00628 AST_EVENT_IE_CEL_LINKEDID, AST_EVENT_IE_PLTYPE_STR, chan->linkedid, 00629 AST_EVENT_IE_CEL_USERFIELD, AST_EVENT_IE_PLTYPE_STR, chan->userfield, 00630 AST_EVENT_IE_CEL_EXTRA, AST_EVENT_IE_PLTYPE_STR, extra, 00631 AST_EVENT_IE_CEL_PEER, AST_EVENT_IE_PLTYPE_STR, peername, 00632 AST_EVENT_IE_END); 00633 00634 ast_channel_unlock(chan); 00635 00636 if (peer) { 00637 peer = ast_channel_unref(peer); 00638 } 00639 00640 if (ev && ast_event_queue(ev)) { 00641 ast_event_destroy(ev); 00642 return -1; 00643 } 00644 00645 return 0; 00646 }
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 214 of file cel.c.
References ARRAY_LEN.
Referenced by parse_events().
00215 { 00216 unsigned int i; 00217 00218 for (i = 0; i < ARRAY_LEN(cel_event_types); i++) { 00219 if (!cel_event_types[i]) { 00220 continue; 00221 } 00222 00223 if (!strcasecmp(name, cel_event_types[i])) { 00224 return i; 00225 } 00226 } 00227 00228 return -1; 00229 }