Wed Jan 8 2020 09:49:59

Asterisk developer's documentation


cel.c File Reference

Channel Event Logging API. More...

#include "asterisk.h"
#include "asterisk/_private.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/cel.h"
#include "asterisk/logger.h"
#include "asterisk/linkedlists.h"
#include "asterisk/utils.h"
#include "asterisk/config.h"
#include "asterisk/cli.h"
#include "asterisk/astobj2.h"

Go to the source code of this file.

Data Structures

struct  cel_linkedid
 

Macros

#define CEL_DEFAULT_EVENTS   0
 Track no events by default. More...
 
#define CEL_ENABLED_DEFAULT   0
 CEL is off by default. More...
 
#define CEL_MAX_EVENT_IDS   64
 Maximum possible CEL event IDs. More...
 
#define NUM_APP_BUCKETS   97
 Number of buckets for the appset container. More...
 

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. More...
 
void ast_cel_check_retire_linkedid (struct ast_channel *chan)
 Check and potentially retire a Linked ID. More...
 
int ast_cel_engine_init (void)
 
int ast_cel_engine_reload (void)
 
static void ast_cel_engine_term (void)
 
struct ast_channelast_cel_fabricate_channel_from_event (const struct ast_event *event)
 Create a fake channel from data in a CEL event. More...
 
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. More...
 
const char * ast_cel_get_ama_flag_name (enum ast_cel_ama_flag flag)
 Convert AMA flag to printable string. More...
 
const char * ast_cel_get_type_name (enum ast_cel_event_type type)
 Get the name of a CEL event type. More...
 
int ast_cel_linkedid_ref (const char *linkedid)
 Inform CEL that a new linkedid is being used. More...
 
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. More...
 
enum ast_cel_event_type ast_cel_str_to_event_type (const char *name)
 Get the event type from a string. More...
 
static int ast_cel_track_event (enum ast_cel_event_type et)
 
static int do_reload (int is_reload)
 
static char * handle_cli_status (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static int lid_cmp (void *obj, void *arg, int flags)
 
static int lid_hash (const void *obj, const int flags)
 
static void parse_apps (const char *val)
 
static void parse_events (const char *val)
 
static void print_cel_sub (const struct ast_event *event, void *data)
 
static void set_defaults (void)
 

Variables

static struct ao2_containerappset
 Container of Asterisk application names. More...
 
static const char *const cel_ama_flags [AST_CEL_AMA_FLAG_TOTAL]
 Map of ast_cel_ama_flags to strings. More...
 
static const char cel_conf_file [] = "cel.conf"
 
static char cel_dateformat [256]
 Configured date format for event timestamps. More...
 
static unsigned char cel_enabled
 
static const char *const cel_event_types [CEL_MAX_EVENT_IDS]
 Map of ast_cel_event_type to strings. More...
 
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 More...
 
static struct ast_datastore_info fabricated_channel_datastore
 
static struct ao2_containerlinkedids
 Container of channel references to a linkedid for CEL purposes. More...
 
static ast_mutex_t reload_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
 Lock protecting CEL. More...
 

Detailed Description

Channel Event Logging API.

Author
Steve Murphy murf@.nosp@m.digi.nosp@m.um.co.nosp@m.m
Russell Bryant russe.nosp@m.ll@d.nosp@m.igium.nosp@m..com
Todo:
Do thorough testing of all transfer methods to ensure that BLINDTRANSFER, ATTENDEDTRANSFER, BRIDGE_START, and BRIDGE_END events are all reported as expected.

Definition in file cel.c.

Macro Definition Documentation

#define CEL_DEFAULT_EVENTS   0

Track no events by default.

Definition at line 75 of file cel.c.

Referenced by set_defaults().

#define CEL_ENABLED_DEFAULT   0

CEL is off by default.

Definition at line 57 of file cel.c.

Referenced by set_defaults().

#define CEL_MAX_EVENT_IDS   64

Maximum possible CEL event IDs.

Note
This limit is currently imposed by the eventset definition

Definition at line 70 of file cel.c.

#define NUM_APP_BUCKETS   97

Number of buckets for the appset container.

Definition at line 80 of file cel.c.

Referenced by ast_cel_engine_init().

Function Documentation

static int app_cmp ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 812 of file cel.c.

References app1, app2, and CMP_MATCH.

Referenced by ast_cel_engine_init().

813 {
814  const char *app1 = obj;
815  const char *app2 = arg;
816 
817  return !strcasecmp(app1, app2) ? CMP_MATCH : 0;
818 }
static const char app1[]
static const char app2[]
static int app_hash ( const void *  obj,
const int  flags 
)
static

Definition at line 807 of file cel.c.

References ast_str_case_hash().

Referenced by ast_cel_engine_init().

808 {
809  return ast_str_case_hash((const char *) obj);
810 }
static force_inline int attribute_pure ast_str_case_hash(const char *str)
Compute a hash value on a case-insensitive string.
Definition: strings.h:989
unsigned int ast_cel_check_enabled ( void  )

Check to see if CEL is enabled.

Since
1.8
Return values
zeronot enabled
non-zeroenabled

Definition at line 164 of file cel.c.

References cel_enabled.

165 {
166  return cel_enabled;
167 }
static unsigned char cel_enabled
Definition: cel.c:54
void ast_cel_check_retire_linkedid ( struct ast_channel chan)

Check and potentially retire a Linked ID.

Parameters
chanchannel 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, ast_channel::linkedid, LOG_ERROR, OBJ_POINTER, and reload_lock.

Referenced by ast_channel_change_linkedid(), and ast_channel_destructor().

430 {
431  const char *linkedid = chan->linkedid;
432  struct cel_linkedid *lid;
433  struct cel_linkedid find_lid;
434 
435  if (ast_strlen_zero(linkedid)) {
436  return;
437  }
438 
439  /* Get the lock in case any CEL events are still in flight when we shutdown. */
441 
443  || !linkedids) {
444  /*
445  * CEL is disabled or we are not tracking linkedids
446  * or the CEL module is shutdown.
447  */
449  return;
450  }
451 
452  find_lid.id = linkedid;
453  lid = ao2_find(linkedids, &find_lid, OBJ_POINTER);
454  if (!lid) {
456 
457  /*
458  * The user may have done a reload to start tracking linkedids
459  * when a call was already in progress. This is an unusual kind
460  * of change to make after starting Asterisk.
461  */
462  ast_log(LOG_ERROR, "Something weird happened, couldn't find linkedid %s\n", linkedid);
463  return;
464  }
465 
466  if (!--lid->count) {
467  /* No channels use this linkedid anymore. */
468  ao2_unlink(linkedids, lid);
470 
471  ast_cel_report_event(chan, AST_CEL_LINKEDID_END, NULL, NULL, NULL);
472  } else {
474  }
475  ao2_ref(lid, -1);
476 }
the last channel with the given linkedid is retired
Definition: cel.h:92
static int ast_cel_track_event(enum ast_cel_event_type et)
Definition: cel.c:271
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.
Definition: cel.c:645
#define ast_mutex_lock(a)
Definition: lock.h:155
const ast_string_field linkedid
Definition: channel.h:787
static ast_mutex_t reload_lock
Lock protecting CEL.
Definition: cel.c:88
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
unsigned int count
Definition: cel.c:106
#define ao2_find(arg1, arg2, arg3)
Definition: astobj2.h:964
static struct ao2_container * linkedids
Container of channel references to a linkedid for CEL purposes.
Definition: cel.c:115
static unsigned char cel_enabled
Definition: cel.c:54
#define ao2_unlink(arg1, arg2)
Definition: astobj2.h:817
#define ast_mutex_unlock(a)
Definition: lock.h:156
int ast_cel_engine_init ( void  )

Provided by cel.c

Definition at line 860 of file cel.c.

References ao2_container_alloc, app_cmp(), app_hash(), ast_cel_engine_term(), ast_cli_register(), ast_register_atexit(), do_reload(), lid_cmp(), lid_hash(), and NUM_APP_BUCKETS.

Referenced by main().

861 {
862  /*
863  * Accesses to the appset and linkedids containers have to be
864  * protected by the reload_lock so they don't need a lock of
865  * their own.
866  */
868  if (!appset) {
869  return -1;
870  }
872  if (!linkedids) {
874  return -1;
875  }
876 
877  if (do_reload(0) || ast_cli_register(&cli_status)) {
879  return -1;
880  }
881 
883 
884  return 0;
885 }
#define NUM_APP_BUCKETS
Number of buckets for the appset container.
Definition: cel.c:80
static int do_reload(int is_reload)
Definition: cel.c:342
static int app_cmp(void *obj, void *arg, int flags)
Definition: cel.c:812
static struct ast_cli_entry cli_status
Definition: cel.c:252
int ast_cli_register(struct ast_cli_entry *e)
Registers a command or an array of commands.
Definition: cli.c:2159
static int app_hash(const void *obj, const int flags)
Definition: cel.c:807
static void ast_cel_engine_term(void)
Definition: cel.c:841
static struct ao2_container * appset
Container of Asterisk application names.
Definition: cel.c:100
static int lid_hash(const void *obj, const int flags)
Definition: cel.c:820
int ast_register_atexit(void(*func)(void))
Register a function to be executed before Asterisk exits.
Definition: asterisk.c:998
static int lid_cmp(void *obj, void *arg, int flags)
Definition: cel.c:830
static struct ao2_container * linkedids
Container of channel references to a linkedid for CEL purposes.
Definition: cel.c:115
#define ao2_container_alloc(arg1, arg2, arg3)
Definition: astobj2.h:734
int ast_cel_engine_reload ( void  )

Provided by cel.c

Definition at line 887 of file cel.c.

References do_reload().

888 {
889  return do_reload(1);
890 }
static int do_reload(int is_reload)
Definition: cel.c:342
static void ast_cel_engine_term ( void  )
static

Definition at line 841 of file cel.c.

References ao2_ref, ast_cli_unregister(), ast_mutex_lock, ast_mutex_unlock, and reload_lock.

Referenced by ast_cel_engine_init().

842 {
843  /* Get the lock in case any CEL events are still in flight when we shutdown. */
845 
846  if (appset) {
847  ao2_ref(appset, -1);
848  appset = NULL;
849  }
850  if (linkedids) {
851  ao2_ref(linkedids, -1);
852  linkedids = NULL;
853  }
854 
856 
858 }
static struct ast_cli_entry cli_status
Definition: cel.c:252
int ast_cli_unregister(struct ast_cli_entry *e)
Unregisters a command or an array of commands.
Definition: cli.c:2153
#define ast_mutex_lock(a)
Definition: lock.h:155
static ast_mutex_t reload_lock
Lock protecting CEL.
Definition: cel.c:88
static struct ao2_container * appset
Container of Asterisk application names.
Definition: cel.c:100
#define ao2_ref(o, delta)
Definition: astobj2.h:472
static struct ao2_container * linkedids
Container of channel references to a linkedid for CEL purposes.
Definition: cel.c:115
#define ast_mutex_unlock(a)
Definition: lock.h:156
struct ast_channel* ast_cel_fabricate_channel_from_event ( const struct ast_event event)

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
eventthe 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_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.

487 {
488  struct varshead *headp;
489  struct ast_var_t *newvariable;
490  char timebuf[30];
491  struct ast_channel *tchan;
492  struct ast_cel_event_record record = {
494  };
495  struct ast_datastore *datastore;
496  char *app_data;
497 
498  /* do not call ast_channel_alloc because this is not really a real channel */
499  if (!(tchan = ast_dummy_channel_alloc())) {
500  return NULL;
501  }
502 
503  headp = &tchan->varshead;
504 
505  /* first, get the variables from the event */
506  if (ast_cel_fill_record(event, &record)) {
507  ast_channel_unref(tchan);
508  return NULL;
509  }
510 
511  /* next, fill the channel with their data */
512  if ((newvariable = ast_var_assign("eventtype", record.event_name))) {
513  AST_LIST_INSERT_HEAD(headp, newvariable, entries);
514  }
515 
517  snprintf(timebuf, sizeof(timebuf), "%ld.%06ld", (long) record.event_time.tv_sec,
518  (long) record.event_time.tv_usec);
519  } else {
520  struct ast_tm tm;
521  ast_localtime(&record.event_time, &tm, NULL);
522  ast_strftime(timebuf, sizeof(timebuf), cel_dateformat, &tm);
523  }
524 
525  if ((newvariable = ast_var_assign("eventtime", timebuf))) {
526  AST_LIST_INSERT_HEAD(headp, newvariable, entries);
527  }
528 
529  if ((newvariable = ast_var_assign("userdeftype", record.user_defined_name))) {
530  AST_LIST_INSERT_HEAD(headp, newvariable, entries);
531  }
532  if ((newvariable = ast_var_assign("eventextra", record.extra))) {
533  AST_LIST_INSERT_HEAD(headp, newvariable, entries);
534  }
535 
536  tchan->caller.id.name.valid = 1;
537  tchan->caller.id.name.str = ast_strdup(record.caller_id_name);
538  tchan->caller.id.number.valid = 1;
539  tchan->caller.id.number.str = ast_strdup(record.caller_id_num);
540  tchan->caller.ani.number.valid = 1;
541  tchan->caller.ani.number.str = ast_strdup(record.caller_id_ani);
542  tchan->redirecting.from.number.valid = 1;
544  tchan->dialed.number.str = ast_strdup(record.caller_id_dnid);
545 
546  ast_copy_string(tchan->exten, record.extension, sizeof(tchan->exten));
547  ast_copy_string(tchan->context, record.context, sizeof(tchan->context));
548  ast_string_field_set(tchan, name, record.channel_name);
549  ast_string_field_set(tchan, uniqueid, record.unique_id);
550  ast_string_field_set(tchan, linkedid, record.linked_id);
552  ast_string_field_set(tchan, peeraccount, record.peer_account);
553  ast_string_field_set(tchan, userfield, record.user_field);
554 
555  if ((newvariable = ast_var_assign("BRIDGEPEER", record.peer))) {
556  AST_LIST_INSERT_HEAD(headp, newvariable, entries);
557  }
558 
559  tchan->amaflags = record.amaflag;
560 
561  /* We need to store an 'application name' and 'application
562  * data' on the channel for logging purposes, but the channel
563  * structure only provides a place to store pointers, and it
564  * expects these pointers to be pointing to data that does not
565  * need to be freed. This means that the channel's destructor
566  * does not attempt to free any storage that these pointers
567  * point to. However, we can't provide data in that form directly for
568  * these structure members. In order to ensure that these data
569  * elements have a lifetime that matches the channel's
570  * lifetime, we'll put them in a datastore attached to the
571  * channel, and set's the channel's pointers to point into the
572  * datastore. The datastore will then be automatically destroyed
573  * when the channel is destroyed.
574  */
575 
576  if (!(datastore = ast_datastore_alloc(&fabricated_channel_datastore, NULL))) {
577  ast_channel_unref(tchan);
578  return NULL;
579  }
580 
581  if (!(app_data = ast_malloc(strlen(record.application_name) + strlen(record.application_data) + 2))) {
582  ast_datastore_free(datastore);
583  ast_channel_unref(tchan);
584  return NULL;
585  }
586 
587  tchan->appl = strcpy(app_data, record.application_name);
588  tchan->data = strcpy(app_data + strlen(record.application_name) + 1,
589  record.application_data);
590 
591  datastore->data = app_data;
592  ast_channel_datastore_add(tchan, datastore);
593 
594  return tchan;
595 }
const char * account_code
Definition: cel.h:266
const char * caller_id_name
Definition: cel.h:256
Helper struct for getting the fields out of a CEL event.
Definition: cel.h:241
static char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: chan_iax2.c:383
const char * linked_id
Definition: cel.h:269
Main Channel structure associated with a channel.
Definition: channel.h:742
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
char * str
Subscriber phone number (Malloced)
Definition: channel.h:336
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
#define ast_strdup(a)
Definition: astmm.h:109
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
struct ast_party_name name
Subscriber name.
Definition: channel.h:290
struct ast_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
Definition: channel.h:449
struct ast_var_t * ast_var_assign(const char *name, const char *value)
Definition: chanvars.c:41
const char * user_defined_name
Definition: cel.h:255
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
const char * application_data
Definition: cel.h:265
const char * application_name
Definition: cel.h:264
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1570
const char * extension
Definition: cel.h:261
struct ast_party_redirecting redirecting
Redirecting/Diversion information.
Definition: channel.h:814
char * str
Subscriber name (Malloced)
Definition: channel.h:214
const char * caller_id_num
Definition: cel.h:257
Structure for a data store object.
Definition: datastore.h:54
const char * data
Definition: channel.h:755
const char * extra
Definition: cel.h:273
const char * appl
Definition: channel.h:754
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:65
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
static char cel_dateformat[256]
Configured date format for event timestamps.
Definition: cel.c:120
struct ast_party_id ani
Automatic Number Identification (ANI)
Definition: channel.h:377
struct ast_party_dialed::@155 number
Dialed/Called number.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
const char * context
Definition: cel.h:262
uint32_t version
struct ABI version
Definition: cel.h:251
struct ast_party_dialed dialed
Dialed/Called information.
Definition: channel.h:797
const char * caller_id_rdnis
Definition: cel.h:259
static struct ast_datastore_info fabricated_channel_datastore
Definition: cel.c:481
const char * peer
Definition: cel.h:272
struct ast_datastore * ast_datastore_alloc(const struct ast_datastore_info *info, const char *uid)
Definition: datastore.c:98
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:696
static const char name[]
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Definition: localtime.c:2351
const char * caller_id_ani
Definition: cel.h:258
const char * user_field
Definition: cel.h:271
#define AST_CEL_EVENT_RECORD_VERSION
struct ABI version
Definition: cel.h:246
const char * peer_account
Definition: cel.h:267
void * data
Definition: datastore.h:56
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
const char * unique_id
Definition: cel.h:268
const char * caller_id_dnid
Definition: cel.h:260
const char * channel_name
Definition: cel.h:263
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:229
const char * event_name
Definition: cel.h:254
struct ast_channel * ast_dummy_channel_alloc(void)
Create a fake channel structure.
Definition: channel.c:1391
#define ast_malloc(a)
Definition: astmm.h:91
int amaflags
Definition: channel.h:843
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2590
struct timeval event_time
Definition: cel.h:253
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
struct varshead varshead
Definition: channel.h:817
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
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.
Definition: cel.c:762
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:344
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
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]eventthe CEL event
[out]rthe ast_cel_event_record to fill in
Since
1.8
Return values
0success
non-zerofailure

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().

763 {
765  ast_log(LOG_ERROR, "Module ABI mismatch for ast_cel_event_record. "
766  "Please ensure all modules were compiled for "
767  "this version of Asterisk.\n");
768  return -1;
769  }
770 
772 
775 
776  r->user_defined_name = "";
777 
778  if (r->event_type == AST_CEL_USER_DEFINED) {
781  } else {
783  }
784 
803 
804  return 0;
805 }
const char * account_code
Definition: cel.h:266
const char * caller_id_name
Definition: cel.h:256
Channel Event CID name Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:151
Channel Event app name Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:181
const char * linked_id
Definition: cel.h:269
Channel Event extra data Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:253
const char * user_defined_name
Definition: cel.h:255
const char * application_data
Definition: cel.h:265
const char * application_name
Definition: cel.h:264
Channel Event channel name Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:175
Channel Event UniqueID Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:205
Channel Event context name Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:169
Channel Event app args/data Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:187
Channel Event Time (micro-seconds) Used by: AST_EVENT_CEL Payload type: UINT.
Definition: event_defs.h:139
const char * extension
Definition: cel.h:261
Channel Event CID dnid Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:229
const char * caller_id_num
Definition: cel.h:257
const char * extra
Definition: cel.h:273
Channel Event Type Used by: AST_EVENT_CEL Payload type: UINT.
Definition: event_defs.h:127
Channel Event Time (seconds) Used by: AST_EVENT_CEL Payload type: UINT.
Definition: event_defs.h:133
Channel Event CID num Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:157
const char * ast_cel_get_type_name(enum ast_cel_event_type type)
Get the name of a CEL event type.
Definition: cel.c:412
Channel Event extension name Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:163
const char * context
Definition: cel.h:262
uint32_t version
struct ABI version
Definition: cel.h:251
Channel Event Userfield Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:211
Channel Event CID RDNIS field Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:223
enum ast_cel_event_type event_type
Definition: cel.h:252
#define LOG_ERROR
Definition: logger.h:155
Channel Event User Event Name Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:145
const char * caller_id_rdnis
Definition: cel.h:259
const char * peer
Definition: cel.h:272
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
Channel Event Peer – for Things involving multiple channels, like BRIDGE Used by: AST_EVENT_CEL Paylo...
Definition: event_defs.h:235
Channel Event CID ANI field Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:217
const char * caller_id_ani
Definition: cel.h:258
const char * user_field
Definition: cel.h:271
Channel Event AMA flags Used by: AST_EVENT_CEL Payload type: UINT.
Definition: event_defs.h:193
#define AST_CEL_EVENT_RECORD_VERSION
struct ABI version
Definition: cel.h:246
uint32_t ast_event_get_ie_uint(const struct ast_event *event, enum ast_event_ie_type ie_type)
Get the value of an information element that has an integer payload.
Definition: event.c:1075
const char * peer_account
Definition: cel.h:267
Channel Event LinkedID Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:241
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
const char * unique_id
Definition: cel.h:268
a user-defined event, the event name field should be set
Definition: cel.h:90
const char * caller_id_dnid
Definition: cel.h:260
const char * channel_name
Definition: cel.h:263
const char * event_name
Definition: cel.h:254
const char * ast_event_get_ie_str(const struct ast_event *event, enum ast_event_ie_type ie_type)
Get the value of an information element that has a string payload.
Definition: event.c:1102
struct timeval event_time
Definition: cel.h:253
Channel Event AccountCode Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:199
const char* ast_cel_get_ama_flag_name ( enum ast_cel_ama_flag  flag)

Convert AMA flag to printable string.

Parameters
[in]flagthe 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.

418 {
419  if (flag < 0 || flag >= ARRAY_LEN(cel_ama_flags)) {
420  ast_log(LOG_WARNING, "Invalid AMA flag: %u\n", flag);
421  return "Unknown";
422  }
423 
424  return S_OR(cel_ama_flags[flag], "Unknown");
425 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
#define LOG_WARNING
Definition: logger.h:144
static const char *const cel_ama_flags[AST_CEL_AMA_FLAG_TOTAL]
Map of ast_cel_ama_flags to strings.
Definition: cel.c:157
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
const char* ast_cel_get_type_name ( enum ast_cel_event_type  type)

Get the name of a CEL event type.

Parameters
typethe 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().

413 {
414  return S_OR(cel_event_types[type], "Unknown");
415 }
static const char *const cel_event_types[CEL_MAX_EVENT_IDS]
Map of ast_cel_event_type to strings.
Definition: cel.c:125
static const char type[]
Definition: chan_nbs.c:57
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
int ast_cel_linkedid_ref ( const char *  linkedid)

Inform CEL that a new linkedid is being used.

Since
11
Return values
-1error
0success

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().

598 {
599  struct cel_linkedid *lid;
600  struct cel_linkedid find_lid;
601 
602  if (ast_strlen_zero(linkedid)) {
603  ast_log(LOG_ERROR, "The linkedid should never be empty\n");
604  return -1;
605  }
606 
607  /* Get the lock in case any CEL events are still in flight when we shutdown. */
609 
611  /* CEL is disabled or we are not tracking linkedids. */
613  return 0;
614  }
615  if (!linkedids) {
616  /* The CEL module is shutdown. Abort. */
618  return -1;
619  }
620 
621  find_lid.id = linkedid;
622  lid = ao2_find(linkedids, &find_lid, OBJ_POINTER);
623  if (!lid) {
624  /*
625  * Changes to the lid->count member are protected by the
626  * reload_lock so the lid object does not need its own lock.
627  */
628  lid = ao2_alloc(sizeof(*lid) + strlen(linkedid) + 1, NULL);
629  if (!lid) {
631  return -1;
632  }
633  lid->id = (char *) (lid + 1);
634  strcpy((char *) lid->id, linkedid);/* Safe */
635 
636  ao2_link(linkedids, lid);
637  }
638  ++lid->count;
640  ao2_ref(lid, -1);
641 
642  return 0;
643 }
the last channel with the given linkedid is retired
Definition: cel.h:92
#define ao2_link(arg1, arg2)
Definition: astobj2.h:785
static int ast_cel_track_event(enum ast_cel_event_type et)
Definition: cel.c:271
#define ast_mutex_lock(a)
Definition: lock.h:155
static ast_mutex_t reload_lock
Lock protecting CEL.
Definition: cel.c:88
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:430
const char * id
Definition: cel.c:104
unsigned int count
Definition: cel.c:106
#define ao2_find(arg1, arg2, arg3)
Definition: astobj2.h:964
static struct ao2_container * linkedids
Container of channel references to a linkedid for CEL purposes.
Definition: cel.c:115
static unsigned char cel_enabled
Definition: cel.c:54
#define ast_mutex_unlock(a)
Definition: lock.h:156
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
chanThis argument is required. This is the primary channel associated with this channel event.
event_typeThis is the type of call event being reported.
userdefevnameThis is an optional custom name for the call event.
extraThis is an optional opaque field that will go into the "CEL_EXTRA" information element of the call event.
peer2All 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
0success
non-zerofailure

Definition at line 645 of file cel.c.

References ast_channel::accountcode, ast_channel::amaflags, ast_party_caller::ani, ao2_find, ao2_ref, app, ast_channel::appl, ast_bridged_channel(), AST_CEL_APP_END, AST_CEL_APP_START, AST_CEL_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_invite_replaces(), handle_request_refer(), local_attended_transfer(), manage_parked_call(), park_call_full(), parked_call_exec(), pbx_exec(), and wait_for_answer().

647 {
648  struct timeval eventtime;
649  struct ast_event *ev;
650  const char *peername = "";
651  struct ast_channel *peer;
652 
653  /* Make sure a reload is not occurring while we're checking to see if this
654  * is an event that we care about. We could lose an important event in this
655  * process otherwise. */
657 
658  if (!appset) {
659  /* The CEL module is shutdown. Abort. */
661  return -1;
662  }
663 
664  /* Record the linkedid of new channels if we are tracking LINKEDID_END even if we aren't
665  * reporting on CHANNEL_START so we can track when to send LINKEDID_END */
667  if (ast_cel_linkedid_ref(chan->linkedid)) {
669  return -1;
670  }
671  }
672 
673  if (!cel_enabled || !ast_cel_track_event(event_type)) {
675  return 0;
676  }
677 
678  if (event_type == AST_CEL_APP_START || event_type == AST_CEL_APP_END) {
679  char *app;
680  if (!(app = ao2_find(appset, (char *) chan->appl, OBJ_POINTER))) {
682  return 0;
683  }
684  ao2_ref(app, -1);
685  }
686 
688 
689  ast_channel_lock(chan);
690  peer = ast_bridged_channel(chan);
691  if (peer) {
692  ast_channel_ref(peer);
693  }
694  ast_channel_unlock(chan);
695 
696  if (peer) {
697  ast_channel_lock(peer);
698  peername = ast_strdupa(peer->name);
699  ast_channel_unlock(peer);
700  } else if (peer2) {
701  ast_channel_lock(peer2);
702  peername = ast_strdupa(peer2->name);
703  ast_channel_unlock(peer2);
704  }
705 
706  if (!userdefevname) {
707  userdefevname = "";
708  }
709 
710  if (!extra) {
711  extra = "";
712  }
713 
714  eventtime = ast_tvnow();
715 
716  ast_channel_lock(chan);
717 
724  S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, ""),
726  S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""),
728  S_COR(chan->caller.ani.number.valid, chan->caller.ani.number.str, ""),
732  S_OR(chan->dialed.number.str, ""),
747 
748  ast_channel_unlock(chan);
749 
750  if (peer) {
751  peer = ast_channel_unref(peer);
752  }
753 
754  if (ev && ast_event_queue(ev)) {
755  ast_event_destroy(ev);
756  return -1;
757  }
758 
759  return 0;
760 }
const ast_string_field peeraccount
Definition: channel.h:787
the last channel with the given linkedid is retired
Definition: cel.h:92
Channel Event CID name Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:151
Channel Event app name Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:181
#define ast_channel_lock(chan)
Definition: channel.h:2466
Main Channel structure associated with a channel.
Definition: channel.h:742
An event.
Definition: event.c:85
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
char * str
Subscriber phone number (Malloced)
Definition: channel.h:336
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
const ast_string_field uniqueid
Definition: channel.h:787
static int ast_cel_track_event(enum ast_cel_event_type et)
Definition: cel.c:271
Channel Event extra data Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:253
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
struct ast_party_name name
Subscriber name.
Definition: channel.h:290
struct ast_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
Definition: channel.h:449
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
Channel Event channel name Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:175
Channel Event UniqueID Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:205
Channel Event context name Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:169
Channel Event app args/data Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:187
Channel Event peeraccount Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:247
Channel Event Time (micro-seconds) Used by: AST_EVENT_CEL Payload type: UINT.
Definition: event_defs.h:139
Channel Event CID dnid Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:229
struct ast_party_redirecting redirecting
Redirecting/Diversion information.
Definition: channel.h:814
channel birth
Definition: cel.h:50
char * str
Subscriber name (Malloced)
Definition: channel.h:214
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
#define ast_mutex_lock(a)
Definition: lock.h:155
const char * data
Definition: channel.h:755
const ast_string_field linkedid
Definition: channel.h:787
const char * appl
Definition: channel.h:754
Channel Event Type Used by: AST_EVENT_CEL Payload type: UINT.
Definition: event_defs.h:127
static ast_mutex_t reload_lock
Lock protecting CEL.
Definition: cel.c:88
Channel Event Time (seconds) Used by: AST_EVENT_CEL Payload type: UINT.
Definition: event_defs.h:133
static struct ao2_container * appset
Container of Asterisk application names.
Definition: cel.c:100
Channel Event CID num Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:157
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
Channel Event extension name Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:163
int ast_event_queue(struct ast_event *event)
Queue an event.
Definition: event.c:1517
static const char app[]
Definition: app_adsiprog.c:49
struct ast_party_id ani
Automatic Number Identification (ANI)
Definition: channel.h:377
struct ast_party_dialed::@155 number
Dialed/Called number.
an app ends
Definition: cel.h:60
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:83
Channel Event Userfield Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:211
int ast_cel_linkedid_ref(const char *linkedid)
Inform CEL that a new linkedid is being used.
Definition: cel.c:597
Channel Event CID RDNIS field Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:223
struct ast_party_dialed dialed
Dialed/Called information.
Definition: channel.h:797
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
Channel Event User Event Name Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:145
struct ast_channel * ast_bridged_channel(struct ast_channel *chan)
Find bridged channel.
Definition: channel.c:7160
const ast_string_field name
Definition: channel.h:787
#define ao2_find(arg1, arg2, arg3)
Definition: astobj2.h:964
#define ast_channel_unlock(chan)
Definition: channel.h:2467
Channel Event Peer – for Things involving multiple channels, like BRIDGE Used by: AST_EVENT_CEL Paylo...
Definition: event_defs.h:235
Channel Event CID ANI field Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:217
const ast_string_field userfield
Definition: channel.h:787
Channel Event AMA flags Used by: AST_EVENT_CEL Payload type: UINT.
Definition: event_defs.h:193
Channel Event LinkedID Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:241
void ast_event_destroy(struct ast_event *event)
Destroy an event.
Definition: event.c:1314
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2491
struct ast_event * ast_event_new(enum ast_event_type event_type,...)
Create a new event.
Definition: event.c:1202
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
const ast_string_field accountcode
Definition: channel.h:787
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:229
an app starts
Definition: cel.h:58
static unsigned char cel_enabled
Definition: cel.c:54
int amaflags
Definition: channel.h:843
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
Channel Event AccountCode Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:199
#define ast_mutex_unlock(a)
Definition: lock.h:156
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
enum ast_cel_event_type ast_cel_str_to_event_type ( const char *  name)

Get the event type from a string.

Parameters
namethe 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().

255 {
256  unsigned int i;
257 
258  for (i = 0; i < ARRAY_LEN(cel_event_types); i++) {
259  if (!cel_event_types[i]) {
260  continue;
261  }
262 
263  if (!strcasecmp(name, cel_event_types[i])) {
264  return i;
265  }
266  }
267 
268  return -1;
269 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static const char *const cel_event_types[CEL_MAX_EVENT_IDS]
Map of ast_cel_event_type to strings.
Definition: cel.c:125
static const char name[]
static int ast_cel_track_event ( enum ast_cel_event_type  et)
static

Definition at line 271 of file cel.c.

Referenced by ast_cel_check_retire_linkedid(), ast_cel_linkedid_ref(), ast_cel_report_event(), and parse_apps().

272 {
273  return (eventset & ((int64_t) 1 << et));
274 }
static int64_t eventset
which events we want to track
Definition: cel.c:64
static int do_reload ( int  is_reload)
static

Definition at line 342 of file cel.c.

References ast_config_destroy(), ast_config_load2(), ast_copy_string(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_true(), ast_variable_retrieve(), ast_verb, config, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, LOG_WARNING, parse_apps(), parse_events(), reload_lock, and set_defaults().

Referenced by ast_cel_engine_init(), and ast_cel_engine_reload().

343 {
344  struct ast_config *config;
345  const char *enabled_value;
346  const char *val;
347  int res = 0;
348  struct ast_flags config_flags = { 0, };
349  const char *s;
350 
352 
353  if (!is_reload) {
354  /* Initialize all settings before first configuration load. */
355  set_defaults();
356  }
357 
358  /*
359  * Unfortunately we have to always load the config file because
360  * other modules read the same file.
361  */
362  config = ast_config_load2(cel_conf_file, "cel", config_flags);
363  if (!config || config == CONFIG_STATUS_FILEINVALID) {
364  ast_log(LOG_WARNING, "Could not load %s\n", cel_conf_file);
365  config = NULL;
366  goto return_cleanup;
367  }
368  if (config == CONFIG_STATUS_FILEUNCHANGED) {
369  /* This should never happen because we always load the config file. */
370  config = NULL;
371  goto return_cleanup;
372  }
373 
374  if (is_reload) {
375  /* Reset all settings before reloading configuration */
376  set_defaults();
377  }
378 
379  if ((enabled_value = ast_variable_retrieve(config, "general", "enable"))) {
380  cel_enabled = ast_true(enabled_value);
381  }
382 
383  if (!cel_enabled) {
384  goto return_cleanup;
385  }
386 
387  /* get the date format for logging */
388  if ((s = ast_variable_retrieve(config, "general", "dateformat"))) {
390  }
391 
392  if ((val = ast_variable_retrieve(config, "general", "events"))) {
393  parse_events(val);
394  }
395 
396  if ((val = ast_variable_retrieve(config, "general", "apps"))) {
397  parse_apps(val);
398  }
399 
400 return_cleanup:
401  ast_verb(3, "CEL logging %sabled.\n", cel_enabled ? "en" : "dis");
402 
404 
405  if (config) {
406  ast_config_destroy(config);
407  }
408 
409  return res;
410 }
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
Definition: config.c:625
static const char config[]
Definition: cdr_csv.c:57
Definition: ast_expr2.c:325
#define LOG_WARNING
Definition: logger.h:144
#define ast_mutex_lock(a)
Definition: lock.h:155
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
Definition: config.c:2499
#define ast_verb(level,...)
Definition: logger.h:243
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
static ast_mutex_t reload_lock
Lock protecting CEL.
Definition: cel.c:88
static char cel_dateformat[256]
Configured date format for event timestamps.
Definition: cel.c:120
static void parse_apps(const char *val)
Definition: cel.c:303
static const char cel_conf_file[]
Definition: cel.c:51
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is &quot;true&quot;. This function checks to see whether a string passed to it is an indication of an &quot;true&quot; value. It checks to see if the string is &quot;yes&quot;, &quot;true&quot;, &quot;y&quot;, &quot;t&quot;, &quot;on&quot; or &quot;1&quot;.
Definition: utils.c:1533
static void parse_events(const char *val)
Definition: cel.c:276
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static void set_defaults(void)
Definition: cel.c:334
Structure used to handle boolean flags.
Definition: utils.h:200
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define CONFIG_STATUS_FILEINVALID
Definition: config.h:52
static unsigned char cel_enabled
Definition: cel.c:54
#define CONFIG_STATUS_FILEUNCHANGED
Definition: config.h:51
#define ast_mutex_unlock(a)
Definition: lock.h:156
static char* handle_cli_status ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 177 of file cel.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, app, 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(), ast_mutex_lock, ast_mutex_unlock, CLI_FAILURE, CLI_GENERATE, CLI_HANDLER, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, eventset, ast_cli_args::fd, name, print_cel_sub(), reload_lock, and ast_cli_entry::usage.

178 {
179  unsigned int i;
180  struct ast_event_sub *sub;
181 
182  switch (cmd) {
183  case CLI_INIT:
184  e->command = "cel show status";
185  e->usage =
186  "Usage: cel show status\n"
187  " Displays the Channel Event Logging system status.\n";
188  return NULL;
189  case CLI_GENERATE:
190  return NULL;
191  case CLI_HANDLER:
192  break;
193  }
194 
195  if (a->argc > 3) {
196  return CLI_SHOWUSAGE;
197  }
198 
199  ast_cli(a->fd, "CEL Logging: %s\n", cel_enabled ? "Enabled" : "Disabled");
200 
201  if (!cel_enabled) {
202  return CLI_SUCCESS;
203  }
204 
205  for (i = 0; i < (sizeof(eventset) * 8); i++) {
206  const char *name;
207 
208  if (!(eventset & ((int64_t) 1 << i))) {
209  continue;
210  }
211 
212  name = ast_cel_get_type_name(i);
213  if (strcasecmp(name, "Unknown")) {
214  ast_cli(a->fd, "CEL Tracking Event: %s\n", name);
215  }
216  }
217 
218  /* Accesses to the appset container must be done while holding the reload_lock. */
220  if (appset) {
221  struct ao2_iterator iter;
222  char *app;
223 
224  iter = ao2_iterator_init(appset, 0);
225  for (;;) {
226  app = ao2_iterator_next(&iter);
227  if (!app) {
228  break;
229  }
231 
232  ast_cli(a->fd, "CEL Tracking Application: %s\n", app);
233 
234  ao2_ref(app, -1);
236  }
237  ao2_iterator_destroy(&iter);
238  }
240 
242  return CLI_FAILURE;
243  }
247  sub = NULL;
248 
249  return CLI_SUCCESS;
250 }
#define ao2_iterator_next(arg1)
Definition: astobj2.h:1126
void ast_event_report_subs(const struct ast_event_sub *sub)
Report current subscriptions to a subscription subscriber.
Definition: event.c:701
const int argc
Definition: cli.h:154
Definition: cli.h:146
#define ast_mutex_lock(a)
Definition: lock.h:155
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
Definition: astobj2.c:818
void ast_event_sub_destroy(struct ast_event_sub *sub)
Destroy an allocated subscription.
Definition: event.c:971
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
static int64_t eventset
which events we want to track
Definition: cel.c:64
static ast_mutex_t reload_lock
Lock protecting CEL.
Definition: cel.c:88
static void print_cel_sub(const struct ast_event *event, void *data)
Definition: cel.c:169
static struct ao2_container * appset
Container of Asterisk application names.
Definition: cel.c:100
const char * ast_cel_get_type_name(enum ast_cel_event_type type)
Get the name of a CEL event type.
Definition: cel.c:412
static const char app[]
Definition: app_adsiprog.c:49
const int fd
Definition: cli.h:153
#define ao2_ref(o, delta)
Definition: astobj2.h:472
Event type Used by: AST_EVENT_SUB, AST_EVENT_UNSUB Payload type: UINT.
Definition: event_defs.h:95
#define CLI_SHOWUSAGE
Definition: cli.h:44
Event subscription.
Definition: event.c:124
#define CLI_FAILURE
Definition: cli.h:45
static const char name[]
char * command
Definition: cli.h:180
int ast_event_sub_append_ie_uint(struct ast_event_sub *sub, enum ast_event_ie_type ie_type, uint32_t uint)
Append a uint parameter to a subscription.
Definition: event.c:761
void ao2_iterator_destroy(struct ao2_iterator *i)
Destroy a container iterator.
Definition: astobj2.c:833
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1053
static unsigned char cel_enabled
Definition: cel.c:54
struct ast_event_sub * ast_event_subscribe_new(enum ast_event_type type, ast_event_cb_t cb, void *userdata)
Allocate a subscription, but do not activate it.
Definition: event.c:739
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int lid_cmp ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 830 of file cel.c.

References CMP_MATCH, and cel_linkedid::id.

Referenced by ast_cel_engine_init().

831 {
832  struct cel_linkedid *lid1 = obj;
833  struct cel_linkedid *lid2 = arg;
834  const char *key;
835 
836  key = lid2->id;
837 
838  return !strcasecmp(lid1->id, key) ? CMP_MATCH : 0;
839 }
const char * id
Definition: cel.c:104
static int lid_hash ( const void *  obj,
const int  flags 
)
static

Definition at line 820 of file cel.c.

References ast_str_case_hash(), and cel_linkedid::id.

Referenced by ast_cel_engine_init().

821 {
822  const struct cel_linkedid *lid = obj;
823  const char *key;
824 
825  key = lid->id;
826 
827  return ast_str_case_hash(key);
828 }
const char * id
Definition: cel.c:104
static force_inline int attribute_pure ast_str_case_hash(const char *str)
Compute a hash value on a case-insensitive string.
Definition: strings.h:989
static void parse_apps ( const char *  val)
static

Definition at line 303 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().

304 {
305  char *apps = ast_strdupa(val);
306  char *cur_app;
307 
309  ast_log(LOG_WARNING, "An apps= config line, but not tracking APP events\n");
310  return;
311  }
312 
313  while ((cur_app = strsep(&apps, ","))) {
314  char *app;
315 
316  cur_app = ast_strip(cur_app);
317  if (ast_strlen_zero(cur_app)) {
318  continue;
319  }
320 
321  /* The app object is immutable so it doesn't need a lock of its own. */
322  app = ao2_alloc(strlen(cur_app) + 1, NULL);
323  if (!app) {
324  continue;
325  }
326  strcpy(app, cur_app);/* Safe */
327 
328  ao2_link(appset, app);
329  ao2_ref(app, -1);
330  app = NULL;
331  }
332 }
#define ao2_link(arg1, arg2)
Definition: astobj2.h:785
char * strsep(char **str, const char *delims)
static int ast_cel_track_event(enum ast_cel_event_type et)
Definition: cel.c:271
Definition: ast_expr2.c:325
Definition: pbx.c:1301
#define LOG_WARNING
Definition: logger.h:144
static struct ao2_container * appset
Container of Asterisk application names.
Definition: cel.c:100
static const char app[]
Definition: app_adsiprog.c:49
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
an app ends
Definition: cel.h:60
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:155
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:430
an app starts
Definition: cel.h:58
static void parse_events ( const char *  val)
static

Definition at line 276 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().

277 {
278  char *events = ast_strdupa(val);
279  char *cur_event;
280 
281  while ((cur_event = strsep(&events, ","))) {
282  enum ast_cel_event_type event_type;
283 
284  cur_event = ast_strip(cur_event);
285  if (ast_strlen_zero(cur_event)) {
286  continue;
287  }
288 
289  event_type = ast_cel_str_to_event_type(cur_event);
290 
291  if (event_type == 0) {
292  /* All events */
293  eventset = (int64_t) -1;
294  } else if (event_type == -1) {
295  ast_log(LOG_WARNING, "Unknown event name '%s'\n",
296  cur_event);
297  } else {
298  eventset |= ((int64_t) 1 << event_type);
299  }
300  }
301 }
char * strsep(char **str, const char *delims)
Definition: ast_expr2.c:325
#define LOG_WARNING
Definition: logger.h:144
static int64_t eventset
which events we want to track
Definition: cel.c:64
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:155
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
enum ast_cel_event_type ast_cel_str_to_event_type(const char *name)
Get the event type from a string.
Definition: cel.c:254
ast_cel_event_type
CEL event types.
Definition: cel.h:48
static struct adsi_event events[]
Definition: app_adsiprog.c:78
static void print_cel_sub ( const struct ast_event event,
void *  data 
)
static

Definition at line 169 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().

170 {
171  struct ast_cli_args *a = data;
172 
173  ast_cli(a->fd, "CEL Event Subscriber: %s\n",
175 }
Description Used by: AST_EVENT_SUB, AST_EVENT_UNSUB Payload type: STR.
Definition: event_defs.h:259
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const int fd
Definition: cli.h:153
const char * ast_event_get_ie_str(const struct ast_event *event, enum ast_event_ie_type ie_type)
Get the value of an information element that has a string payload.
Definition: event.c:1102
static void set_defaults ( void  )
static

Definition at line 334 of file cel.c.

References ao2_callback, CEL_DEFAULT_EVENTS, CEL_ENABLED_DEFAULT, OBJ_MULTIPLE, OBJ_NODATA, and OBJ_UNLINK.

Referenced by do_reload().

335 {
338  *cel_dateformat = '\0';
340 }
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:910
static int64_t eventset
which events we want to track
Definition: cel.c:64
static struct ao2_container * appset
Container of Asterisk application names.
Definition: cel.c:100
#define CEL_ENABLED_DEFAULT
CEL is off by default.
Definition: cel.c:57
static char cel_dateformat[256]
Configured date format for event timestamps.
Definition: cel.c:120
#define CEL_DEFAULT_EVENTS
Track no events by default.
Definition: cel.c:75
static unsigned char cel_enabled
Definition: cel.c:54

Variable Documentation

struct ao2_container* appset
static

Container of Asterisk application names.

The apps in this container are the applications that were specified in the configuration as applications that CEL events should be generated for when they start and end on a channel.

Note
Accesses to the appset container must be done while holding the reload_lock.

Definition at line 100 of file cel.c.

const char* const cel_ama_flags[AST_CEL_AMA_FLAG_TOTAL]
static

Map of ast_cel_ama_flags to strings.

Definition at line 157 of file cel.c.

const char cel_conf_file[] = "cel.conf"
static

Config file to load for the CEL feature.

Definition at line 51 of file cel.c.

char cel_dateformat[256]
static

Configured date format for event timestamps.

Definition at line 120 of file cel.c.

unsigned char cel_enabled
static

Is the CEL subsystem enabled ?

Definition at line 54 of file cel.c.

Referenced by ast_cel_check_enabled().

const char* const cel_event_types[CEL_MAX_EVENT_IDS]
static

Map of ast_cel_event_type to strings.

Definition at line 125 of file cel.c.

struct ast_cli_entry cli_status = AST_CLI_DEFINE(handle_cli_status, "Display the CEL status")
static

Definition at line 252 of file cel.c.

int64_t eventset
static

which events we want to track

Note
bit field, up to 64 events

Definition at line 64 of file cel.c.

Referenced by handle_cli_status().

struct ast_datastore_info fabricated_channel_datastore
static
Initial value:
= {
.type = "CEL fabricated channel",
.destroy = ast_free_ptr,
}
void ast_free_ptr(void *ptr)

Definition at line 481 of file cel.c.

struct ao2_container* linkedids
static

Container of channel references to a linkedid for CEL purposes.

Note
Accesses to the linkedids container must be done while holding the reload_lock.

Definition at line 115 of file cel.c.

ast_mutex_t reload_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
static

Lock protecting CEL.

Note
It protects during reloads, shutdown, and accesses to the appset and linkedids containers.

Definition at line 88 of file cel.c.

Referenced by ast_cel_check_retire_linkedid(), ast_cel_engine_term(), ast_cel_linkedid_ref(), ast_cel_report_event(), do_reload(), and handle_cli_status().