Mon Aug 31 12:30:21 2015

Asterisk developer's documentation


cel.h File Reference

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_channelast_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.

Detailed Description

Call Event Logging API.

Definition in file cel.h.


Define Documentation

#define AST_CEL_EVENT_RECORD_VERSION   2

struct ABI version

Note:
This must be incremented when the struct changes.

Definition at line 246 of file cel.h.

Referenced by ast_cel_fabricate_channel_from_event(), and ast_cel_fill_record().


Enumeration Type Documentation

AMA Flags.

Note:
This must much up with the AST_CDR_* defines for AMA flags.
Enumerator:
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 };

CEL event types.

Enumerator:
AST_CEL_CHANNEL_START 

channel birth

AST_CEL_CHANNEL_END 

channel end

AST_CEL_HANGUP 

hangup terminates connection

AST_CEL_ANSWER 

A ringing phone is answered.

AST_CEL_APP_START 

an app starts

AST_CEL_APP_END 

an app ends

AST_CEL_BRIDGE_START 

a bridge is established

AST_CEL_BRIDGE_END 

a bridge is torn down

AST_CEL_CONF_START 

a conference is started

AST_CEL_CONF_END 

a conference is ended

AST_CEL_PARK_START 

a channel is parked

AST_CEL_PARK_END 

channel out of the park

AST_CEL_BLINDTRANSFER 

a transfer occurs

AST_CEL_ATTENDEDTRANSFER 

a transfer occurs

AST_CEL_TRANSFER 

a transfer occurs

AST_CEL_HOOKFLASH 

a 3-way conference, usually part of a transfer

AST_CEL_3WAY_START 

a 3-way conference, usually part of a transfer

AST_CEL_3WAY_END 

a 3-way conference, usually part of a transfer

AST_CEL_CONF_ENTER 

channel enters a conference

AST_CEL_CONF_EXIT 

channel exits a conference

AST_CEL_USER_DEFINED 

a user-defined event, the event name field should be set

AST_CEL_LINKEDID_END 

the last channel with the given linkedid is retired

AST_CEL_BRIDGE_UPDATE 

a masquerade happened to alter the participants on a bridge

AST_CEL_PICKUP 

a directed pickup was performed on this channel

AST_CEL_FORWARD 

this call was forwarded somewhere else

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 };


Function Documentation

struct ast_cel* ast_cel_alloc ( void   )  [read]

Allocate a CEL record.

Since:
1.8
Note:
The CEL record must be destroyed with ast_cel_destroy().
Return values:
non-NULL an allocated ast_cel structure
NULL error
unsigned int ast_cel_check_enabled ( void   ) 

Check to see if CEL is enabled.

Since:
1.8
Return values:
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.

Parameters:
chan channel that is being destroyed or its linkedid is changing
Since:
1.8

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.

Returns:
nothing

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.

Parameters:
cel the record to destroy
Since:
1.8
Returns:
nothing.
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.

Note:
This function creates a fake channel containing the serialized channel data in the given cel event. It should be released with ast_channel_unref() but could be released with ast_channel_release().
Parameters:
event the CEL event
Since:
1.8
Returns:
a channel with the data filled in, or NULL on error
Todo:
This function is very expensive, especially given that some CEL backends use it on every CEL event. This function really needs to go away at some point.

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.

Parameters:
[in] event the CEL event
[out] r the ast_cel_event_record to fill in
Since:
1.8
Return values:
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.

Parameters:
[in] flag the flag to convert to a string
Since:
1.8
Returns:
the string representation of the flag

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.

Parameters:
type the type to get the name of
Since:
1.8
Returns:
the string representation of the type

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.

Since:
11
Return values:
-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.

Parameters:
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.
Since:
1.8
Precondition:
chan and peer2 are both unlocked
Return values:
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.

Parameters:
name the event type name as a string
Since:
1.8
Returns:
the ast_cel_event_type given by the 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 }


Generated on 31 Aug 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1