Asterisk - The Open Source Telephony Project  21.4.1
Data Structures | Macros | Typedefs | Enumerations | Functions
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...
 
struct  ast_cel_general_config
 A structure to hold CEL global configuration options. More...
 

Macros

#define AST_CEL_EVENT_RECORD_VERSION   2
 struct ABI version More...
 

Typedefs

typedef void(* ast_cel_backend_cb) (struct ast_event *event)
 CEL backend callback.
 

Enumerations

enum  ast_cel_event_type {
  AST_CEL_INVALID_VALUE = -1, AST_CEL_ALL = 0, 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_ENTER = 7, AST_CEL_BRIDGE_EXIT = 8, AST_CEL_PARK_START = 9, AST_CEL_PARK_END = 10,
  AST_CEL_BLINDTRANSFER = 11, AST_CEL_ATTENDEDTRANSFER = 12, AST_CEL_USER_DEFINED = 13, AST_CEL_LINKEDID_END = 14,
  AST_CEL_PICKUP = 15, AST_CEL_FORWARD = 16, AST_CEL_LOCAL_OPTIMIZE = 17, AST_CEL_LOCAL_OPTIMIZE_BEGIN = 18
}
 CEL event types. More...
 

Functions

int ast_cel_backend_register (const char *name, ast_cel_backend_cb backend_callback)
 Register a CEL backend. More...
 
int ast_cel_backend_unregister (const char *name)
 Unregister a CEL backend. More...
 
unsigned int ast_cel_check_enabled (void)
 Check to see if CEL is enabled. More...
 
struct ast_eventast_cel_create_event (struct ast_channel_snapshot *snapshot, enum ast_cel_event_type event_type, const char *userdefevname, struct ast_json *extra, const char *peer_str)
 Allocate and populate a CEL event structure. More...
 
struct ast_eventast_cel_create_event_with_time (struct ast_channel_snapshot *snapshot, enum ast_cel_event_type event_type, const struct timeval *event_time, const char *userdefevname, struct ast_json *extra, const char *peer_str)
 Allocate and populate a CEL event structure. More...
 
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 *event, struct ast_cel_event_record *r)
 Fill in an ast_cel_event_record from a CEL event. More...
 
void * ast_cel_general_config_alloc (void)
 Allocate a CEL configuration object. More...
 
struct ast_cel_general_configast_cel_get_config (void)
 Obtain the current CEL configuration. More...
 
const char * ast_cel_get_type_name (enum ast_cel_event_type type)
 Get the name of a CEL event type. More...
 
void ast_cel_publish_event (struct ast_channel *chan, enum ast_cel_event_type event_type, struct ast_json *blob)
 Publish a CEL event. More...
 
void ast_cel_publish_user_event (struct ast_channel *chan, const char *event, const char *extra)
 Publish a CEL user event. More...
 
void ast_cel_set_config (struct ast_cel_general_config *config)
 Set the current CEL configuration. More...
 
enum ast_cel_event_type ast_cel_str_to_event_type (const char *name)
 Get the event type from a string. More...
 
struct stasis_topicast_cel_topic (void)
 Get the CEL topic. More...
 

Detailed Description

Call Event Logging API.

Todo:
TODO: There some event types that have been defined here, but are not yet used anywhere in the code. It would be really awesome if someone went through and had Asterisk generate these events where it is appropriate to do so. The defined, but unused events are: CONF_ENTER, CONF_EXIT, CONF_START, CONF_END, 3WAY_START, 3WAY_END, TRANSFER, and HOOKFLASH.

Definition in file cel.h.

Macro Definition Documentation

#define AST_CEL_EVENT_RECORD_VERSION   2

struct ABI version

Note
This must be incremented when the struct changes.

Definition at line 143 of file cel.h.

Referenced by ast_cel_fabricate_channel_from_event(), and ast_cel_fill_record().

Enumeration Type Documentation

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_ENTER 

channel enters a bridge

AST_CEL_BRIDGE_EXIT 

channel exits a bridge

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_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_PICKUP 

a directed pickup was performed on this channel

AST_CEL_FORWARD 

this call was forwarded somewhere else

AST_CEL_LOCAL_OPTIMIZE 

A local channel optimization occurred, this marks the end.

AST_CEL_LOCAL_OPTIMIZE_BEGIN 

A local channel optimization has begun.

Definition at line 41 of file cel.h.

41  {
42  AST_CEL_INVALID_VALUE = -1,
43  AST_CEL_ALL = 0,
44  /*! \brief channel birth */
46  /*! \brief channel end */
48  /*! \brief hangup terminates connection */
49  AST_CEL_HANGUP = 3,
50  /*! \brief A ringing phone is answered */
51  AST_CEL_ANSWER = 4,
52  /*! \brief an app starts */
54  /*! \brief an app ends */
55  AST_CEL_APP_END = 6,
56  /*! \brief channel enters a bridge */
58  /*! \brief channel exits a bridge */
60  /*! \brief a channel is parked */
62  /*! \brief channel out of the park */
63  AST_CEL_PARK_END = 10,
64  /*! \brief a transfer occurs */
66  /*! \brief a transfer occurs */
68  /*! \brief a user-defined event, the event name field should be set */
70  /*! \brief the last channel with the given linkedid is retired */
72  /*! \brief a directed pickup was performed on this channel */
73  AST_CEL_PICKUP = 15,
74  /*! \brief this call was forwarded somewhere else */
75  AST_CEL_FORWARD = 16,
76  /*! \brief A local channel optimization occurred, this marks the end */
78  /*! \brief A local channel optimization has begun */
80 };
the last channel with the given linkedid is retired
Definition: cel.h:71
A local channel optimization occurred, this marks the end.
Definition: cel.h:77
channel birth
Definition: cel.h:45
A local channel optimization has begun.
Definition: cel.h:79
channel enters a bridge
Definition: cel.h:57
an app ends
Definition: cel.h:55
hangup terminates connection
Definition: cel.h:49
a transfer occurs
Definition: cel.h:65
a channel is parked
Definition: cel.h:61
a transfer occurs
Definition: cel.h:67
channel end
Definition: cel.h:47
A ringing phone is answered.
Definition: cel.h:51
channel out of the park
Definition: cel.h:63
a user-defined event, the event name field should be set
Definition: cel.h:69
channel exits a bridge
Definition: cel.h:59
an app starts
Definition: cel.h:53
a directed pickup was performed on this channel
Definition: cel.h:73
this call was forwarded somewhere else
Definition: cel.h:75

Function Documentation

int ast_cel_backend_register ( const char *  name,
ast_cel_backend_cb  backend_callback 
)

Register a CEL backend.

Parameters
nameName of backend to register
backend_callbackCallback to register
Return values
zeroon success
non-zeroon failure
Since
12

Definition at line 1781 of file cel.c.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_global_obj_ref, ao2_link, ao2_ref, cel_backend::callback, cel_backend::name, and RAII_VAR.

1782 {
1783  RAII_VAR(struct ao2_container *, backends, ao2_global_obj_ref(cel_backends), ao2_cleanup);
1784  struct cel_backend *backend;
1785 
1786  if (!backends || ast_strlen_zero(name) || !backend_callback) {
1787  return -1;
1788  }
1789 
1790  /* The backend object is immutable so it doesn't need a lock of its own. */
1791  backend = ao2_alloc_options(sizeof(*backend) + 1 + strlen(name), NULL,
1793  if (!backend) {
1794  return -1;
1795  }
1796  strcpy(backend->name, name);/* Safe */
1797  backend->callback = backend_callback;
1798 
1799  ao2_link(backends, backend);
1800  ao2_ref(backend, -1);
1801  return 0;
1802 }
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
the list of registered channel types
Definition: channel.c:121
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
ast_cel_backend_cb callback
Definition: cel.c:329
Generic container type.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
char name[0]
Definition: cel.c:330
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
int ast_cel_backend_unregister ( const char *  name)

Unregister a CEL backend.

Parameters
nameName of backend to unregister
Return values
zeroon success
non-zeroon failure
Since
12

Definition at line 1769 of file cel.c.

References ao2_global_obj_ref, ao2_ref, OBJ_NODATA, OBJ_SEARCH_KEY, and OBJ_UNLINK.

1770 {
1771  struct ao2_container *backends = ao2_global_obj_ref(cel_backends);
1772 
1773  if (backends) {
1774  ao2_find(backends, name, OBJ_SEARCH_KEY | OBJ_NODATA | OBJ_UNLINK);
1775  ao2_ref(backends, -1);
1776  }
1777 
1778  return 0;
1779 }
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1101
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
the list of registered channel types
Definition: channel.c:121
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
Generic container type.
unsigned int ast_cel_check_enabled ( void  )

Check to see if CEL is enabled.

Since
1.8
Return values
zeronot enabled
non-zeroenabled

Check to see if CEL is enabled.

Comparator function for cel_backend

Hashing function for dialstatus container

Comparator function for dialstatus container

Definition at line 345 of file cel.c.

References ao2_global_obj_ref, ast_cel_general_config::enable, and enabled.

Referenced by ast_cel_set_config().

346 {
347  unsigned int enabled;
348  struct cel_config *cfg = ao2_global_obj_ref(cel_configs);
349 
350  enabled = (!cfg || !cfg->general) ? 0 : cfg->general->enable;
351  ao2_cleanup(cfg);
352  return enabled;
353 }
A container that holds all config-related information.
Definition: cel_custom.c:53
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
static int enabled
Whether or not we are storing history.
struct ast_event* ast_cel_create_event ( struct ast_channel_snapshot snapshot,
enum ast_cel_event_type  event_type,
const char *  userdefevname,
struct ast_json extra,
const char *  peer_str 
)

Allocate and populate a CEL event structure.

Parameters
snapshotAn ast_channel_snapshot of the primary channel associated with this channel event.
event_typeThe type of call event being reported.
userdefevnameCustom name for the call event. (optional)
extraAn event-specific opaque JSON blob to be rendered and placed in the "CEL_EXTRA" information element of the call event. (optional)
peer_strA list of comma-separated peer channel names. (optional)
Since
12
Return values
Thecreated ast_event structure
NULLon failure

Definition at line 519 of file cel.c.

References ast_cel_create_event_with_time(), and ast_tvnow().

522 {
523  struct timeval eventtime = ast_tvnow();
524 
525  return ast_cel_create_event_with_time(snapshot, event_type, &eventtime,
526  userdefevname, extra, peer);
527 }
struct ast_event * ast_cel_create_event_with_time(struct ast_channel_snapshot *snapshot, enum ast_cel_event_type event_type, const struct timeval *event_time, const char *userdefevname, struct ast_json *extra, const char *peer)
Allocate and populate a CEL event structure.
Definition: cel.c:529
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
struct ast_event* ast_cel_create_event_with_time ( struct ast_channel_snapshot snapshot,
enum ast_cel_event_type  event_type,
const struct timeval *  event_time,
const char *  userdefevname,
struct ast_json extra,
const char *  peer_str 
)

Allocate and populate a CEL event structure.

Parameters
snapshotAn ast_channel_snapshot of the primary channel associated with this channel event.
event_typeThe type of call event being reported.
event_timeThe time at which the event occurred.
userdefevnameCustom name for the call event. (optional)
extraAn event-specific opaque JSON blob to be rendered and placed in the "CEL_EXTRA" information element of the call event. (optional)
peer_strA list of comma-separated peer channel names. (optional)
Since
13.29.0
16.6.0
Return values
Thecreated ast_event structure
NULLon failure

Definition at line 529 of file cel.c.

References ast_channel_snapshot_peer::account, ast_channel_snapshot_base::accountcode, ast_channel_snapshot::amaflags, ast_channel_snapshot_caller::ani, ast_channel_snapshot_dialplan::appl, AST_EVENT_CEL, 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_json_dump_string, ast_json_free(), ast_channel_snapshot::base, ast_channel_snapshot::caller, ast_channel_snapshot_dialplan::context, ast_channel_snapshot_dialplan::data, ast_channel_snapshot::dialplan, ast_channel_snapshot_caller::dnid, ast_channel_snapshot_dialplan::exten, ast_channel_snapshot_peer::linkedid, ast_channel_snapshot_caller::name, ast_channel_snapshot_base::name, ast_channel_snapshot_caller::number, ast_channel_snapshot::peer, RAII_VAR, ast_channel_snapshot_caller::rdnis, S_OR, ast_channel_snapshot_base::uniqueid, and ast_channel_snapshot_base::userfield.

Referenced by ast_cel_create_event().

532 {
533  RAII_VAR(char *, extra_txt, NULL, ast_json_free);
534  if (extra) {
535  extra_txt = ast_json_dump_string(extra);
536  }
561 }
const ast_string_field data
Channel Event CID name Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:157
Channel Event app name Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:187
struct ast_channel_snapshot_base * base
Channel Event extra data Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:259
const ast_string_field name
const ast_string_field rdnis
void ast_json_free(void *p)
Asterisk's custom JSON allocator. Exposed for use by unit tests.
Definition: json.c:52
Channel Event channel name Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:181
Channel Event UniqueID Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:211
Channel Event context name Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:175
Channel Event app args/data Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:193
Channel Event peeraccount Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:253
Channel Event Time (micro-seconds) Used by: AST_EVENT_CEL Payload type: UINT.
Definition: event_defs.h:145
Channel Event CID dnid Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:235
#define ast_json_dump_string(root)
Encode a JSON value to a compact string.
Definition: json.h:810
const ast_string_field accountcode
const ast_string_field uniqueid
struct ast_channel_snapshot_dialplan * dialplan
Channel Event Type Used by: AST_EVENT_CEL Payload type: UINT.
Definition: event_defs.h:133
Channel Event Time (seconds) Used by: AST_EVENT_CEL Payload type: UINT.
Definition: event_defs.h:139
Channel Event CID num Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:163
const ast_string_field context
Channel Event extension name Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:169
const ast_string_field appl
const ast_string_field exten
Channel Event Userfield Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:217
Channel Event CID RDNIS field Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:229
struct ast_channel_snapshot_caller * caller
const ast_string_field dnid
Channel Event User Event Name Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:151
const ast_string_field userfield
Channel Event Peer – for Things involving multiple channels, like BRIDGE Used by: AST_EVENT_CEL Payl...
Definition: event_defs.h:241
Channel Event CID ANI field Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:223
Channel Event AMA flags Used by: AST_EVENT_CEL Payload type: UINT.
Definition: event_defs.h:199
const ast_string_field ani
Channel Event LinkedID Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:247
struct ast_event * ast_event_new(enum ast_event_type event_type,...)
Create a new event.
Definition: event.c:402
const ast_string_field number
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:80
struct ast_channel_snapshot_peer * peer
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
Channel Event AccountCode Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:205
const ast_string_field name
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 662 of file cel.c.

References ast_party_caller::ani, ao2_global_obj_ref, AST_CEL_EVENT_RECORD_VERSION, ast_cel_fill_record(), AST_CEL_USER_DEFINED, ast_channel_amaflags_set(), ast_channel_datastore_add(), ast_channel_internal_set_fake_ids(), ast_channel_unref, ast_datastore_free(), ast_dummy_channel_alloc, AST_LIST_INSERT_HEAD, ast_localtime(), ast_malloc, ast_strdup, ast_strftime(), ast_datastore::data, ast_party_redirecting::from, ast_party_caller::id, ast_party_id::name, ast_party_id::number, ast_party_dialed::number, RAII_VAR, ast_party_name::str, ast_party_number::str, ast_party_dialed::str, ast_party_name::valid, ast_party_number::valid, and ast_cel_event_record::version.

663 {
664  struct varshead *headp;
665  struct ast_var_t *newvariable;
666  const char *mixed_name;
667  char timebuf[30];
668  struct ast_channel *tchan;
669  struct ast_cel_event_record record = {
671  };
672  struct ast_datastore *datastore;
673  char *app_data;
674  RAII_VAR(struct cel_config *, cfg, ao2_global_obj_ref(cel_configs), ao2_cleanup);
675 
676  if (!cfg || !cfg->general) {
677  return NULL;
678  }
679 
680  /* do not call ast_channel_alloc because this is not really a real channel */
681  if (!(tchan = ast_dummy_channel_alloc())) {
682  return NULL;
683  }
684 
685  headp = ast_channel_varshead(tchan);
686 
687  /* first, get the variables from the event */
688  if (ast_cel_fill_record(event, &record)) {
689  ast_channel_unref(tchan);
690  return NULL;
691  }
692 
693  /* next, fill the channel with their data */
694  mixed_name = (record.event_type == AST_CEL_USER_DEFINED)
695  ? record.user_defined_name : record.event_name;
696  if ((newvariable = ast_var_assign("eventtype", mixed_name))) {
697  AST_LIST_INSERT_HEAD(headp, newvariable, entries);
698  }
699 
700  if (ast_strlen_zero(cfg->general->date_format)) {
701  snprintf(timebuf, sizeof(timebuf), "%ld.%06ld", (long) record.event_time.tv_sec,
702  (long) record.event_time.tv_usec);
703  } else {
704  struct ast_tm tm;
705  ast_localtime(&record.event_time, &tm, NULL);
706  ast_strftime(timebuf, sizeof(timebuf), cfg->general->date_format, &tm);
707  }
708 
709  if ((newvariable = ast_var_assign("eventtime", timebuf))) {
710  AST_LIST_INSERT_HEAD(headp, newvariable, entries);
711  }
712 
713  if ((newvariable = ast_var_assign("eventenum", record.event_name))) {
714  AST_LIST_INSERT_HEAD(headp, newvariable, entries);
715  }
716  if ((newvariable = ast_var_assign("userdeftype", record.user_defined_name))) {
717  AST_LIST_INSERT_HEAD(headp, newvariable, entries);
718  }
719  if ((newvariable = ast_var_assign("eventextra", record.extra))) {
720  AST_LIST_INSERT_HEAD(headp, newvariable, entries);
721  }
722 
723  ast_channel_caller(tchan)->id.name.valid = 1;
724  ast_channel_caller(tchan)->id.name.str = ast_strdup(record.caller_id_name);
725  ast_channel_caller(tchan)->id.number.valid = 1;
726  ast_channel_caller(tchan)->id.number.str = ast_strdup(record.caller_id_num);
727  ast_channel_caller(tchan)->ani.number.valid = 1;
728  ast_channel_caller(tchan)->ani.number.str = ast_strdup(record.caller_id_ani);
729  ast_channel_redirecting(tchan)->from.number.valid = 1;
730  ast_channel_redirecting(tchan)->from.number.str = ast_strdup(record.caller_id_rdnis);
731  ast_channel_dialed(tchan)->number.str = ast_strdup(record.caller_id_dnid);
732 
733  ast_channel_exten_set(tchan, record.extension);
734  ast_channel_context_set(tchan, record.context);
735  ast_channel_name_set(tchan, record.channel_name);
736  ast_channel_internal_set_fake_ids(tchan, record.unique_id, record.linked_id);
737  ast_channel_accountcode_set(tchan, record.account_code);
738  ast_channel_peeraccount_set(tchan, record.peer_account);
739  ast_channel_userfield_set(tchan, record.user_field);
740 
741  if ((newvariable = ast_var_assign("BRIDGEPEER", record.peer))) {
742  AST_LIST_INSERT_HEAD(headp, newvariable, entries);
743  }
744 
745  ast_channel_amaflags_set(tchan, record.amaflag);
746 
747  /* We need to store an 'application name' and 'application
748  * data' on the channel for logging purposes, but the channel
749  * structure only provides a place to store pointers, and it
750  * expects these pointers to be pointing to data that does not
751  * need to be freed. This means that the channel's destructor
752  * does not attempt to free any storage that these pointers
753  * point to. However, we can't provide data in that form directly for
754  * these structure members. In order to ensure that these data
755  * elements have a lifetime that matches the channel's
756  * lifetime, we'll put them in a datastore attached to the
757  * channel, and set's the channel's pointers to point into the
758  * datastore. The datastore will then be automatically destroyed
759  * when the channel is destroyed.
760  */
761 
762  if (!(datastore = ast_datastore_alloc(&fabricated_channel_datastore, NULL))) {
763  ast_channel_unref(tchan);
764  return NULL;
765  }
766 
767  if (!(app_data = ast_malloc(strlen(record.application_name) + strlen(record.application_data) + 2))) {
768  ast_datastore_free(datastore);
769  ast_channel_unref(tchan);
770  return NULL;
771  }
772 
773  ast_channel_appl_set(tchan, strcpy(app_data, record.application_name));
774  ast_channel_data_set(tchan, strcpy(app_data + strlen(record.application_name) + 1,
775  record.application_data));
776 
777  datastore->data = app_data;
778  ast_channel_datastore_add(tchan, datastore);
779 
780  return tchan;
781 }
Helper struct for getting the fields out of a CEL event.
Definition: cel.h:138
Main Channel structure associated with a channel.
char * str
Subscriber phone number (Malloced)
Definition: channel.h:291
A container that holds all config-related information.
Definition: cel_custom.c:53
char * str
Subscriber phone number (Malloced)
Definition: channel.h:386
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2958
struct ast_party_name name
Subscriber name.
Definition: channel.h:340
struct ast_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
Definition: channel.h:527
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:1739
char * str
Subscriber name (Malloced)
Definition: channel.h:264
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
Structure for a data store object.
Definition: datastore.h:64
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
struct ast_party_id id
Caller party ID.
Definition: channel.h:420
struct ast_party_id ani
Automatic Number Identification (ANI)
Definition: channel.h:427
#define ast_dummy_channel_alloc()
Create a fake channel structure.
Definition: channel.h:1282
uint32_t version
struct ABI version
Definition: cel.h:148
void ast_channel_amaflags_set(struct ast_channel *chan, enum ama_flags value)
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:711
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:2524
#define AST_CEL_EVENT_RECORD_VERSION
struct ABI version
Definition: cel.h:143
void * data
Definition: datastore.h:66
struct ast_party_dialed::@206 number
Dialed/Called number.
a user-defined event, the event name field should be set
Definition: cel.h:69
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.
Definition: cel.c:821
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:279
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2385
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:297
void ast_channel_internal_set_fake_ids(struct ast_channel *chan, const char *uniqueid, const char *linkedid)
Set uniqueid and linkedid string value only (not time)
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:342
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 821 of file cel.c.

References 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_PEERACCT, AST_EVENT_IE_CEL_UNIQUEID, AST_EVENT_IE_CEL_USEREVENT_NAME, AST_EVENT_IE_CEL_USERFIELD, S_OR, and ast_cel_event_record::version.

Referenced by ast_cel_fabricate_channel_from_event().

822 {
824  ast_log(LOG_ERROR, "Module ABI mismatch for ast_cel_event_record. "
825  "Please ensure all modules were compiled for "
826  "this version of Asterisk.\n");
827  return -1;
828  }
829 
831 
832  r->event_time.tv_sec = ast_event_get_ie_uint(e, AST_EVENT_IE_CEL_EVENT_TIME);
833  r->event_time.tv_usec = ast_event_get_ie_uint(e, AST_EVENT_IE_CEL_EVENT_TIME_USEC);
834 
835  r->event_name = ast_cel_get_type_name(r->event_type);
836  if (r->event_type == AST_CEL_USER_DEFINED) {
837  r->user_defined_name = ast_event_get_ie_str(e, AST_EVENT_IE_CEL_USEREVENT_NAME);
838  } else {
839  r->user_defined_name = "";
840  }
841 
842  r->caller_id_name = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_CIDNAME), "");
843  r->caller_id_num = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_CIDNUM), "");
844  r->caller_id_ani = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_CIDANI), "");
845  r->caller_id_rdnis = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_CIDRDNIS), "");
846  r->caller_id_dnid = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_CIDDNID), "");
847  r->extension = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_EXTEN), "");
848  r->context = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_CONTEXT), "");
849  r->channel_name = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_CHANNAME), "");
850  r->application_name = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_APPNAME), "");
851  r->application_data = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_APPDATA), "");
852  r->account_code = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_ACCTCODE), "");
853  r->peer_account = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_PEERACCT), "");
854  r->unique_id = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_UNIQUEID), "");
855  r->linked_id = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_LINKEDID), "");
857  r->user_field = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_USERFIELD), "");
860 
861  return 0;
862 }
Channel Event CID name Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:157
Channel Event app name Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:187
Channel Event extra data Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:259
Channel Event channel name Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:181
Channel Event UniqueID Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:211
Channel Event context name Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:175
Channel Event app args/data Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:193
Channel Event peeraccount Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:253
Channel Event Time (micro-seconds) Used by: AST_EVENT_CEL Payload type: UINT.
Definition: event_defs.h:145
Channel Event CID dnid Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:235
Channel Event Type Used by: AST_EVENT_CEL Payload type: UINT.
Definition: event_defs.h:133
Channel Event Time (seconds) Used by: AST_EVENT_CEL Payload type: UINT.
Definition: event_defs.h:139
Channel Event CID num Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:163
Channel Event extension name Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:169
uint32_t version
struct ABI version
Definition: cel.h:148
Channel Event Userfield Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:217
Channel Event CID RDNIS field Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:229
Channel Event User Event Name Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:151
Channel Event Peer – for Things involving multiple channels, like BRIDGE Used by: AST_EVENT_CEL Payl...
Definition: event_defs.h:241
Channel Event CID ANI field Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:223
Channel Event AMA flags Used by: AST_EVENT_CEL Payload type: UINT.
Definition: event_defs.h:199
#define AST_CEL_EVENT_RECORD_VERSION
struct ABI version
Definition: cel.h:143
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:293
Channel Event LinkedID Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:247
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:80
a user-defined event, the event name field should be set
Definition: cel.h:69
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:302
const char * ast_cel_get_type_name(enum ast_cel_event_type type)
Get the name of a CEL event type.
Definition: cel.c:493
Channel Event AccountCode Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:205
void* ast_cel_general_config_alloc ( void  )

Allocate a CEL configuration object.

Return values
NULLon error
Thenew CEL configuration object

Definition at line 189 of file cel.c.

References ao2_ref, ast_str_container_alloc, ast_string_field_init, cel_general_config_dtor(), NUM_APP_BUCKETS, and RAII_VAR.

190 {
191  RAII_VAR(struct ast_cel_general_config *, cfg, NULL, ao2_cleanup);
192 
193  if (!(cfg = ao2_alloc(sizeof(*cfg), cel_general_config_dtor))) {
194  return NULL;
195  }
196 
197  if (ast_string_field_init(cfg, 64)) {
198  return NULL;
199  }
200 
201  if (!(cfg->apps = ast_str_container_alloc(NUM_APP_BUCKETS))) {
202  return NULL;
203  }
204 
205  ao2_ref(cfg, +1);
206  return cfg;
207 }
#define NUM_APP_BUCKETS
Number of buckets for the appset container.
Definition: cel.c:156
#define ast_str_container_alloc(buckets)
Allocates a hash container for bare strings.
Definition: strings.h:1365
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
A structure to hold CEL global configuration options.
Definition: cel.h:223
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
static void cel_general_config_dtor(void *obj)
Destructor for cel_config.
Definition: cel.c:181
struct ast_cel_general_config* ast_cel_get_config ( void  )

Obtain the current CEL configuration.

Since
12 The configuration is a ref counted object. The caller of this function must decrement the ref count when finished with the configuration.
Return values
NULLon error
Thecurrent CEL configuration

Definition at line 1731 of file cel.c.

References ao2_global_obj_ref, ao2_ref, and RAII_VAR.

1732 {
1733  RAII_VAR(struct cel_config *, mod_cfg, ao2_global_obj_ref(cel_configs), ao2_cleanup);
1734 
1735  if (!mod_cfg || !mod_cfg->general) {
1736  return NULL;
1737  }
1738 
1739  ao2_ref(mod_cfg->general, +1);
1740  return mod_cfg->general;
1741 }
A container that holds all config-related information.
Definition: cel_custom.c:53
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
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 493 of file cel.c.

References S_OR.

Referenced by ast_cel_fill_record().

494 {
495  return S_OR(cel_event_types[type], "Unknown");
496 }
static const char *const cel_event_types[CEL_MAX_EVENT_IDS]
Map of ast_cel_event_type to strings.
Definition: cel.c:306
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:80
void ast_cel_publish_event ( struct ast_channel chan,
enum ast_cel_event_type  event_type,
struct ast_json blob 
)

Publish a CEL event.

Since
12
Parameters
chanThis is the primary channel associated with this channel event.
event_typeThis is the type of call event being reported.
blobThis contains any additional parameters that need to be conveyed for this event.

Definition at line 1707 of file cel.c.

References ast_cel_topic(), ast_channel_blob_create_from_cache(), ast_json_pack(), ast_json_ref(), ast_json_unref(), and stasis_publish().

Referenced by ast_cel_publish_user_event().

1710 {
1711  struct ast_json *cel_blob;
1712  struct stasis_message *message;
1713 
1714  cel_blob = ast_json_pack("{s: i, s: o}",
1715  "event_type", event_type,
1716  "event_details", ast_json_ref(blob));
1717 
1718  message = ast_channel_blob_create_from_cache(ast_channel_uniqueid(chan), cel_generic_type(), cel_blob);
1719  if (message) {
1720  stasis_publish(ast_cel_topic(), message);
1721  }
1722  ao2_cleanup(message);
1723  ast_json_unref(cel_blob);
1724 }
struct ast_json * ast_json_ref(struct ast_json *value)
Increase refcount on value.
Definition: json.c:67
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:612
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
struct stasis_topic * ast_cel_topic(void)
Get the CEL topic.
Definition: cel.c:1726
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic's subscribers.
Definition: stasis.c:1511
struct stasis_message * ast_channel_blob_create_from_cache(const char *uniqueid, struct stasis_message_type *type, struct ast_json *blob)
Create a ast_channel_blob message, pulling channel state from the cache.
Abstract JSON element (object, array, string, int, ...).
void ast_cel_publish_user_event ( struct ast_channel chan,
const char *  event,
const char *  extra 
)

Publish a CEL user event.

Since
18
Note
This serves as a wrapper function around ast_cel_publish_event() to help pack the extra details before publishing.
Parameters
chanThis is the primary channel associated with this channel event.
eventThis is the user event being reported.
extraThis contains any extra parameters that need to be conveyed for this event.

Definition at line 1692 of file cel.c.

References ast_cel_publish_event(), AST_CEL_USER_DEFINED, ast_json_pack(), ast_json_unref(), RAII_VAR, and S_OR.

1695 {
1696  RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
1697 
1698  blob = ast_json_pack("{s: s, s: {s: s}}",
1699  "event", event,
1700  "extra", "extra", S_OR(extra, ""));
1701  if (!blob) {
1702  return;
1703  }
1705 }
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:612
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
Definition: astman.c:222
void ast_cel_publish_event(struct ast_channel *chan, enum ast_cel_event_type event_type, struct ast_json *blob)
Publish a CEL event.
Definition: cel.c:1707
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:80
Abstract JSON element (object, array, string, int, ...).
a user-defined event, the event name field should be set
Definition: cel.h:69
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
void ast_cel_set_config ( struct ast_cel_general_config config)

Set the current CEL configuration.

Since
12
Parameters
configThe new CEL configuration

Definition at line 1743 of file cel.c.

References ao2_bump, ao2_global_obj_ref, ao2_ref, ast_cel_check_enabled(), create_routes(), and is_enabled().

1744 {
1745  int was_enabled;
1746  int is_enabled;
1747  struct ast_cel_general_config *cleanup_config;
1748  struct cel_config *mod_cfg = ao2_global_obj_ref(cel_configs);
1749 
1750  if (mod_cfg) {
1751  was_enabled = ast_cel_check_enabled();
1752 
1753  cleanup_config = mod_cfg->general;
1754  ao2_bump(config);
1755  mod_cfg->general = config;
1756  ao2_cleanup(cleanup_config);
1757 
1758  is_enabled = ast_cel_check_enabled();
1759  if (!was_enabled && is_enabled) {
1760  create_routes();
1761  } else if (was_enabled && !is_enabled) {
1762  destroy_routes();
1763  }
1764 
1765  ao2_ref(mod_cfg, -1);
1766  }
1767 }
A container that holds all config-related information.
Definition: cel_custom.c:53
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
unsigned int ast_cel_check_enabled(void)
Hashing function for cel_backend.
Definition: cel.c:345
static int create_routes(void)
Create the Stasis message router and routes for CEL.
Definition: cel.c:1521
static int is_enabled(void)
Helper function to check if module is enabled.
Definition: res_ari.c:159
A structure to hold CEL global configuration options.
Definition: cel.h:223
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 420 of file cel.c.

421 {
422  unsigned int i;
423 
424  for (i = 0; i < ARRAY_LEN(cel_event_types); i++) {
425  if (cel_event_types[i] && !strcasecmp(name, cel_event_types[i])) {
426  return i;
427  }
428  }
429 
430  ast_log(LOG_ERROR, "Unknown event name '%s'\n", name);
431  return AST_CEL_INVALID_VALUE;
432 }
static const char *const cel_event_types[CEL_MAX_EVENT_IDS]
Map of ast_cel_event_type to strings.
Definition: cel.c:306
struct stasis_topic* ast_cel_topic ( void  )

Get the CEL topic.

Return values
TheCEL topic
NULLif not allocated

Definition at line 1726 of file cel.c.

References cel_topic.

Referenced by ast_cel_publish_event(), and create_subscriptions().

1727 {
1728  return cel_topic;
1729 }
static struct stasis_topic * cel_topic
Definition: cel.c:118