Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Macros | Typedefs | Functions | Variables
cel.c File Reference

Channel Event Logging API. More...

#include "asterisk.h"
#include "asterisk/module.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/config_options.h"
#include "asterisk/cli.h"
#include "asterisk/astobj2.h"
#include "asterisk/stasis_message_router.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/stasis_bridges.h"
#include "asterisk/bridge.h"
#include "asterisk/parking.h"
#include "asterisk/pickup.h"
#include "asterisk/core_local.h"
#include "asterisk/taskprocessor.h"
Include dependency graph for cel.c:

Go to the source code of this file.

Data Structures

struct  cel_backend
 
struct  cel_config
 A container that holds all config-related information. More...
 
struct  cel_dialstatus
 
struct  cel_linkedid
 

Macros

#define BACKEND_BUCKETS   13
 
#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...
 
#define NUM_DIALSTATUS_BUCKETS   251
 Number of buckets for the dialstatus container. More...
 

Typedefs

typedef void(* cel_channel_snapshot_monitor) (struct ast_channel_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot, const struct timeval *event_time)
 Typedef for callbacks that get called on channel snapshot updates. More...
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
static AO2_GLOBAL_OBJ_STATIC (cel_backends)
 
static AO2_GLOBAL_OBJ_STATIC (cel_dialstatus_store)
 
static AO2_GLOBAL_OBJ_STATIC (cel_linkedids)
 
static AO2_GLOBAL_OBJ_STATIC (cel_configs)
 
static int apps_handler (const struct aco_option *opt, struct ast_variable *var, void *obj)
 
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)
 Hashing function for cel_backend. 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)
 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)
 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 *e, 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_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...
 
static int ast_cel_track_event (enum ast_cel_event_type et)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static void cel_attended_transfer_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static int cel_backend_send_cb (void *obj, void *arg, int flags)
 
static void cel_blind_transfer_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void cel_bridge_enter_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void cel_bridge_leave_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void cel_channel_app_change (struct ast_channel_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot, const struct timeval *event_time)
 
static void cel_channel_linkedid_change (struct ast_channel_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot, const struct timeval *event_time)
 
static void cel_channel_state_change (struct ast_channel_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot, const struct timeval *event_time)
 Handle channel state changes. More...
 
static void * cel_config_alloc (void)
 
static void cel_config_dtor (void *obj)
 Destructor for cel_config. More...
 
static void cel_dial_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static int cel_filter_channel_snapshot (struct ast_channel_snapshot *snapshot)
 
static void cel_general_config_dtor (void *obj)
 Destructor for cel_config. More...
 
static struct ast_strcel_generate_peer_str (struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *chan)
 
static void cel_generic_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
struct stasis_message_typecel_generic_type (void)
 
static int cel_linkedid_ref (const char *linkedid)
 
static void cel_local_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void cel_parking_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void cel_pickup_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static int cel_pre_apply_config (void)
 
static int cel_report_event (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)
 
static void cel_snapshot_update_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static int cel_track_app (const char *const_app)
 
static void check_retire_linkedid (struct ast_channel_snapshot *snapshot, const struct timeval *event_time)
 
 CONFIG_INFO_CORE ("cel", cel_cfg_info, cel_configs, cel_config_alloc,.files=ACO_FILES(&cel_conf),.pre_apply_config=cel_pre_apply_config,)
 
static int create_routes (void)
 Create the Stasis message router and routes for CEL. More...
 
static int create_subscriptions (void)
 Create the Stasis subscriptions for CEL. More...
 
static void destroy_routes (void)
 
static void destroy_subscriptions (void)
 
static int events_handler (const struct aco_option *opt, struct ast_variable *var, void *obj)
 
static const char * get_blob_variable (struct ast_multi_channel_blob *blob, const char *varname)
 
static struct cel_dialstatusget_dialstatus (const char *uniqueid)
 
static char * handle_cli_status (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static int is_valid_dialstatus (struct ast_multi_channel_blob *blob)
 
static int load_module (void)
 
static int reload_module (void)
 
static void save_dialstatus (struct ast_multi_channel_blob *blob, struct ast_channel_snapshot *snapshot)
 
 STASIS_MESSAGE_TYPE_DEFN (cel_generic_type)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "CEL Engine" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload_module, .load_pri = AST_MODPRI_CORE, .requires = "extconfig", }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct stasis_topiccel_aggregation_topic
 
static struct stasis_forwardcel_bridge_forwarder
 
static struct stasis_forwardcel_cel_forwarder
 
static struct stasis_forwardcel_channel_forwarder
 
cel_channel_snapshot_monitor cel_channel_monitors []
 
static struct aco_file cel_conf
 The config file to be processed for the module. More...
 
static const char *const cel_event_types [CEL_MAX_EVENT_IDS]
 Map of ast_cel_event_type to strings. More...
 
static struct stasis_forwardcel_parking_forwarder
 
static struct stasis_message_routercel_state_router
 
static struct stasis_topiccel_topic
 
static struct ast_cli_entry cli_status = { .handler = handle_cli_status , .summary = "Display the CEL status" ,}
 
static const struct ast_datastore_info fabricated_channel_datastore
 
static struct aco_type general_option
 An aco_type structure to link the "general" category to the ast_cel_general_config type. More...
 
static struct aco_typegeneral_options [] = ACO_TYPES(&general_option)
 
static const char * ignore_categories []
 
static struct aco_type ignore_option
 

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

Definition in file cel.c.

Macro Definition Documentation

◆ BACKEND_BUCKETS

#define BACKEND_BUCKETS   13

The number of buckets into which backend names will be hashed

Definition at line 141 of file cel.c.

Referenced by load_module().

◆ CEL_MAX_EVENT_IDS

#define CEL_MAX_EVENT_IDS   64

Maximum possible CEL event IDs.

Note
This limit is currently imposed by the eventset definition

Definition at line 150 of file cel.c.

◆ NUM_APP_BUCKETS

#define NUM_APP_BUCKETS   97

Number of buckets for the appset container.

Definition at line 155 of file cel.c.

Referenced by ast_cel_general_config_alloc(), and load_module().

◆ NUM_DIALSTATUS_BUCKETS

#define NUM_DIALSTATUS_BUCKETS   251

Number of buckets for the dialstatus container.

Definition at line 160 of file cel.c.

Referenced by load_module().

Typedef Documentation

◆ cel_channel_snapshot_monitor

typedef void(* cel_channel_snapshot_monitor) (struct ast_channel_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot, const struct timeval *event_time)

Typedef for callbacks that get called on channel snapshot updates.

Definition at line 863 of file cel.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1770 of file cel.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1770 of file cel.c.

◆ AO2_GLOBAL_OBJ_STATIC() [1/4]

static AO2_GLOBAL_OBJ_STATIC ( cel_backends  )
static

Container for CEL backend information

◆ AO2_GLOBAL_OBJ_STATIC() [2/4]

static AO2_GLOBAL_OBJ_STATIC ( cel_dialstatus_store  )
static

Container for dial end multichannel blobs for holding on to dial statuses

◆ AO2_GLOBAL_OBJ_STATIC() [3/4]

static AO2_GLOBAL_OBJ_STATIC ( cel_linkedids  )
static

Container of channel references to a linkedid for CEL purposes.

◆ AO2_GLOBAL_OBJ_STATIC() [4/4]

static AO2_GLOBAL_OBJ_STATIC ( cel_configs  )
static

◆ apps_handler()

static int apps_handler ( const struct aco_option opt,
struct ast_variable var,
void *  obj 
)
static

Definition at line 472 of file cel.c.

References ast_cel_general_config::apps, ast_str_container_add(), ast_str_to_lower(), ast_strdupa, ast_strip(), ast_strlen_zero, strsep(), and ast_variable::value.

Referenced by load_module().

473 {
474  struct ast_cel_general_config *cfg = obj;
475  char *apps = ast_strdupa(var->value);
476  char *cur_app;
477 
478  while ((cur_app = strsep(&apps, ","))) {
479  cur_app = ast_strip(cur_app);
480  if (ast_strlen_zero(cur_app)) {
481  continue;
482  }
483 
484  cur_app = ast_str_to_lower(cur_app);
485  ast_str_container_add(cfg->apps, cur_app);
486  }
487 
488  return 0;
489 }
Registered applications container.
Definition: pbx_app.c:67
#define ast_strlen_zero(foo)
Definition: strings.h:52
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:219
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static force_inline char * ast_str_to_lower(char *str)
Convert a string to all lower-case.
Definition: strings.h:1268
struct ao2_container * apps
Definition: cel.h:214
A structure to hold CEL global configuration options.
Definition: cel.h:205
char * strsep(char **str, const char *delims)
int ast_str_container_add(struct ao2_container *str_container, const char *add)
Adds a string to a string container allocated by ast_str_container_alloc.
Definition: strings.c:206

◆ ast_cel_backend_register()

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 1740 of file cel.c.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_cleanup, ao2_global_obj_ref, ao2_link, ao2_ref, AST_MODFLAG_GLOBAL_SYMBOLS, AST_MODFLAG_LOAD_ORDER, AST_MODPRI_CORE, AST_MODULE_INFO(), AST_MODULE_SUPPORT_CORE, ast_strlen_zero, ASTERISK_GPL_KEY, cel_backend::callback, load_module(), cel_backend::name, NULL, RAII_VAR, reload(), reload_module(), and unload_module().

Referenced by load_config(), load_module(), my_load_module(), and test_cel_init_cb().

1741 {
1742  RAII_VAR(struct ao2_container *, backends, ao2_global_obj_ref(cel_backends), ao2_cleanup);
1743  struct cel_backend *backend;
1744 
1745  if (!backends || ast_strlen_zero(name) || !backend_callback) {
1746  return -1;
1747  }
1748 
1749  /* The backend object is immutable so it doesn't need a lock of its own. */
1750  backend = ao2_alloc_options(sizeof(*backend) + 1 + strlen(name), NULL,
1752  if (!backend) {
1753  return -1;
1754  }
1755  strcpy(backend->name, name);/* Safe */
1756  backend->callback = backend_callback;
1757 
1758  ao2_link(backends, backend);
1759  ao2_ref(backend, -1);
1760  return 0;
1761 }
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:406
#define NULL
Definition: resample.c:96
the list of registered channel types
Definition: channel.c:121
#define ast_strlen_zero(foo)
Definition: strings.h:52
#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:911
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static const char name[]
Definition: cdr_mysql.c:74
ast_cel_backend_cb callback
Definition: cel.c:327
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Generic container type.
char name[0]
Definition: cel.c:328
#define ao2_link(container, obj)
Definition: astobj2.h:1549

◆ ast_cel_backend_unregister()

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 1728 of file cel.c.

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

Referenced by cel_verify_and_cleanup_cb(), load_config(), my_unload_module(), tds_unload_module(), and unload_module().

1729 {
1730  struct ao2_container *backends = ao2_global_obj_ref(cel_backends);
1731 
1732  if (backends) {
1734  ao2_ref(backends, -1);
1735  }
1736 
1737  return 0;
1738 }
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
the list of registered channel types
Definition: channel.c:121
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static const char name[]
Definition: cdr_mysql.c:74
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
Generic container type.

◆ ast_cel_check_enabled()

unsigned int ast_cel_check_enabled ( void  )

Hashing function for cel_backend.

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 343 of file cel.c.

References ao2_cleanup, ao2_global_obj_ref, ast_cel_general_config::enable, enabled, and cel_config::general.

Referenced by ast_cel_set_config(), handle_cli_status(), load_module(), and reload_module().

344 {
345  unsigned int enabled;
346  struct cel_config *cfg = ao2_global_obj_ref(cel_configs);
347 
348  enabled = (!cfg || !cfg->general) ? 0 : cfg->general->enable;
349  ao2_cleanup(cfg);
350  return enabled;
351 }
A container that holds all config-related information.
Definition: cel_custom.c:56
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
struct ast_cel_general_config * general
Definition: cel.c:210
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static int enabled
Definition: dnsmgr.c:91

◆ ast_cel_create_event()

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 517 of file cel.c.

References ast_cel_create_event_with_time(), and ast_tvnow().

Referenced by append_expected_event_snapshot().

520 {
521  struct timeval eventtime = ast_tvnow();
522 
523  return ast_cel_create_event_with_time(snapshot, event_type, &eventtime,
524  userdefevname, extra, peer);
525 }
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:527
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150

◆ ast_cel_create_event_with_time()

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 527 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, NULL, 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(), and cel_report_event().

530 {
531  RAII_VAR(char *, extra_txt, NULL, ast_json_free);
532  if (extra) {
533  extra_txt = ast_json_dump_string(extra);
534  }
559 }
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:763
const ast_string_field accountcode
const ast_string_field uniqueid
#define NULL
Definition: resample.c:96
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
#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:911
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:79
struct ast_channel_snapshot_peer * peer
Channel Event AccountCode Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:205
const ast_string_field name

◆ ast_cel_fabricate_channel_from_event()

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 660 of file cel.c.

References ast_cel_event_record::account_code, ast_cel_event_record::amaflag, ast_party_caller::ani, ao2_cleanup, ao2_global_obj_ref, ast_cel_event_record::application_data, ast_cel_event_record::application_name, AST_CEL_EVENT_RECORD_VERSION, ast_cel_fill_record(), AST_CEL_USER_DEFINED, ast_channel_amaflags_set(), ast_channel_appl_set(), ast_channel_caller(), ast_channel_context_set(), ast_channel_data_set(), ast_channel_datastore_add(), ast_channel_dialed(), ast_channel_exten_set(), ast_channel_internal_set_fake_ids(), ast_channel_name_set(), ast_channel_redirecting(), ast_channel_unref, ast_channel_varshead(), ast_datastore_alloc, ast_datastore_free(), ast_dummy_channel_alloc, AST_LIST_INSERT_HEAD, ast_localtime(), ast_malloc, ast_strdup, ast_strftime(), ast_strlen_zero, ast_var_assign, 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_datastore::data, 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_party_redirecting::from, ast_party_caller::id, if(), ast_cel_event_record::linked_id, ast_party_id::name, NULL, ast_party_id::number, ast_party_dialed::number, ast_cel_event_record::peer, ast_cel_event_record::peer_account, RAII_VAR, 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, and ast_cel_event_record::version.

Referenced by custom_log(), and write_cel().

661 {
662  struct varshead *headp;
663  struct ast_var_t *newvariable;
664  const char *mixed_name;
665  char timebuf[30];
666  struct ast_channel *tchan;
667  struct ast_cel_event_record record = {
669  };
670  struct ast_datastore *datastore;
671  char *app_data;
672  RAII_VAR(struct cel_config *, cfg, ao2_global_obj_ref(cel_configs), ao2_cleanup);
673 
674  if (!cfg || !cfg->general) {
675  return NULL;
676  }
677 
678  /* do not call ast_channel_alloc because this is not really a real channel */
679  if (!(tchan = ast_dummy_channel_alloc())) {
680  return NULL;
681  }
682 
683  headp = ast_channel_varshead(tchan);
684 
685  /* first, get the variables from the event */
686  if (ast_cel_fill_record(event, &record)) {
687  ast_channel_unref(tchan);
688  return NULL;
689  }
690 
691  /* next, fill the channel with their data */
692  mixed_name = (record.event_type == AST_CEL_USER_DEFINED)
693  ? record.user_defined_name : record.event_name;
694  if ((newvariable = ast_var_assign("eventtype", mixed_name))) {
695  AST_LIST_INSERT_HEAD(headp, newvariable, entries);
696  }
697 
698  if (ast_strlen_zero(cfg->general->date_format)) {
699  snprintf(timebuf, sizeof(timebuf), "%ld.%06ld", (long) record.event_time.tv_sec,
700  (long) record.event_time.tv_usec);
701  } else {
702  struct ast_tm tm;
703  ast_localtime(&record.event_time, &tm, NULL);
704  ast_strftime(timebuf, sizeof(timebuf), cfg->general->date_format, &tm);
705  }
706 
707  if ((newvariable = ast_var_assign("eventtime", timebuf))) {
708  AST_LIST_INSERT_HEAD(headp, newvariable, entries);
709  }
710 
711  if ((newvariable = ast_var_assign("eventenum", record.event_name))) {
712  AST_LIST_INSERT_HEAD(headp, newvariable, entries);
713  }
714  if ((newvariable = ast_var_assign("userdeftype", record.user_defined_name))) {
715  AST_LIST_INSERT_HEAD(headp, newvariable, entries);
716  }
717  if ((newvariable = ast_var_assign("eventextra", record.extra))) {
718  AST_LIST_INSERT_HEAD(headp, newvariable, entries);
719  }
720 
721  ast_channel_caller(tchan)->id.name.valid = 1;
723  ast_channel_caller(tchan)->id.number.valid = 1;
725  ast_channel_caller(tchan)->ani.number.valid = 1;
730 
731  ast_channel_exten_set(tchan, record.extension);
732  ast_channel_context_set(tchan, record.context);
733  ast_channel_name_set(tchan, record.channel_name);
735  ast_channel_accountcode_set(tchan, record.account_code);
736  ast_channel_peeraccount_set(tchan, record.peer_account);
737  ast_channel_userfield_set(tchan, record.user_field);
738 
739  if ((newvariable = ast_var_assign("BRIDGEPEER", record.peer))) {
740  AST_LIST_INSERT_HEAD(headp, newvariable, entries);
741  }
742 
743  ast_channel_amaflags_set(tchan, record.amaflag);
744 
745  /* We need to store an 'application name' and 'application
746  * data' on the channel for logging purposes, but the channel
747  * structure only provides a place to store pointers, and it
748  * expects these pointers to be pointing to data that does not
749  * need to be freed. This means that the channel's destructor
750  * does not attempt to free any storage that these pointers
751  * point to. However, we can't provide data in that form directly for
752  * these structure members. In order to ensure that these data
753  * elements have a lifetime that matches the channel's
754  * lifetime, we'll put them in a datastore attached to the
755  * channel, and set's the channel's pointers to point into the
756  * datastore. The datastore will then be automatically destroyed
757  * when the channel is destroyed.
758  */
759 
760  if (!(datastore = ast_datastore_alloc(&fabricated_channel_datastore, NULL))) {
761  ast_channel_unref(tchan);
762  return NULL;
763  }
764 
765  if (!(app_data = ast_malloc(strlen(record.application_name) + strlen(record.application_data) + 2))) {
766  ast_datastore_free(datastore);
767  ast_channel_unref(tchan);
768  return NULL;
769  }
770 
771  ast_channel_appl_set(tchan, strcpy(app_data, record.application_name));
772  ast_channel_data_set(tchan, strcpy(app_data + strlen(record.application_name) + 1,
773  record.application_data));
774 
775  datastore->data = app_data;
776  ast_channel_datastore_add(tchan, datastore);
777 
778  return tchan;
779 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
const char * account_code
Definition: cel.h:161
const char * caller_id_name
Definition: cel.h:151
Helper struct for getting the fields out of a CEL event.
Definition: cel.h:136
const char * linked_id
Definition: cel.h:164
Main Channel structure associated with a channel.
struct ast_party_dialed::@246 number
Dialed/Called number.
char * str
Subscriber phone number (Malloced)
Definition: channel.h:292
A container that holds all config-related information.
Definition: cel_custom.c:56
char * str
Subscriber phone number (Malloced)
Definition: channel.h:387
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
struct ast_party_name name
Subscriber name.
Definition: channel.h:341
struct ast_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
Definition: channel.h:528
void ast_channel_appl_set(struct ast_channel *chan, const char *value)
const char * user_defined_name
Definition: cel.h:150
const char * application_data
Definition: cel.h:160
const char * application_name
Definition: cel.h:159
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
const char * extension
Definition: cel.h:156
if(!yyg->yy_init)
Definition: ast_expr2f.c:868
char * str
Subscriber name (Malloced)
Definition: channel.h:265
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
const char * caller_id_num
Definition: cel.h:152
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
Structure for a data store object.
Definition: datastore.h:68
struct varshead * ast_channel_varshead(struct ast_channel *chan)
#define NULL
Definition: resample.c:96
const char * extra
Definition: cel.h:168
static const struct ast_datastore_info fabricated_channel_datastore
Definition: cel.c:655
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
#define ast_strlen_zero(foo)
Definition: strings.h:52
struct ast_party_id id
Caller party ID.
Definition: channel.h:421
struct ast_party_id ani
Automatic Number Identification (ANI)
Definition: channel.h:428
#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:911
#define ast_dummy_channel_alloc()
Create a fake channel structure.
Definition: channel.h:1283
const char * context
Definition: cel.h:157
uint32_t version
struct ABI version
Definition: cel.h:146
void ast_channel_amaflags_set(struct ast_channel *chan, enum ama_flags value)
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
enum ast_cel_event_type event_type
Definition: cel.h:147
const char * caller_id_rdnis
Definition: cel.h:154
const char * peer
Definition: cel.h:167
struct ast_party_dialed * ast_channel_dialed(struct ast_channel *chan)
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:710
#define ast_var_assign(name, value)
Definition: chanvars.h:40
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
const char * caller_id_ani
Definition: cel.h:153
const char * user_field
Definition: cel.h:166
#define AST_CEL_EVENT_RECORD_VERSION
struct ABI version
Definition: cel.h:141
struct ast_party_redirecting * ast_channel_redirecting(struct ast_channel *chan)
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
const char * peer_account
Definition: cel.h:162
void * data
Definition: datastore.h:70
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
void ast_channel_context_set(struct ast_channel *chan, const char *value)
const char * unique_id
Definition: cel.h:163
a user-defined event, the event name field should be set
Definition: cel.h:69
const char * caller_id_dnid
Definition: cel.h:155
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:89
const char * channel_name
Definition: cel.h:158
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:819
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:280
const char * event_name
Definition: cel.h:149
void ast_channel_name_set(struct ast_channel *chan, const char *name)
Set the channel name.
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2390
struct timeval event_time
Definition: cel.h:148
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:298
void ast_channel_data_set(struct ast_channel *chan, const char *value)
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:343

◆ ast_cel_fill_record()

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 819 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_PEERACCT, 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(), cel_bs_put(), manager_log(), odbc_log(), pgsql_log(), radius_log(), and tds_log().

820 {
822  ast_log(LOG_ERROR, "Module ABI mismatch for ast_cel_event_record. "
823  "Please ensure all modules were compiled for "
824  "this version of Asterisk.\n");
825  return -1;
826  }
827 
829 
832 
834  if (r->event_type == AST_CEL_USER_DEFINED) {
836  } else {
837  r->user_defined_name = "";
838  }
839 
858 
859  return 0;
860 }
const char * account_code
Definition: cel.h:161
const char * caller_id_name
Definition: cel.h:151
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
const char * linked_id
Definition: cel.h:164
Channel Event extra data Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:259
const char * user_defined_name
Definition: cel.h:150
const char * application_data
Definition: cel.h:160
const char * application_name
Definition: cel.h:159
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
const char * extension
Definition: cel.h:156
Channel Event CID dnid Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:235
const char * caller_id_num
Definition: cel.h:152
const char * extra
Definition: cel.h:168
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
#define ast_log
Definition: astobj2.c:42
const char * context
Definition: cel.h:157
uint32_t version
struct ABI version
Definition: cel.h:146
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
enum ast_cel_event_type event_type
Definition: cel.h:147
#define LOG_ERROR
Definition: logger.h:285
Channel Event User Event Name Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:151
const char * caller_id_rdnis
Definition: cel.h:154
const char * peer
Definition: cel.h:167
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
const char * caller_id_ani
Definition: cel.h:153
const char * user_field
Definition: cel.h:166
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:141
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
const char * peer_account
Definition: cel.h:162
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:79
const char * unique_id
Definition: cel.h:163
a user-defined event, the event name field should be set
Definition: cel.h:69
const char * caller_id_dnid
Definition: cel.h:155
const char * channel_name
Definition: cel.h:158
const char * event_name
Definition: cel.h:149
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
struct timeval event_time
Definition: cel.h:148
const char * ast_cel_get_type_name(enum ast_cel_event_type type)
Get the name of a CEL event type.
Definition: cel.c:491
Channel Event AccountCode Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:205

◆ ast_cel_general_config_alloc()

void* ast_cel_general_config_alloc ( void  )

Allocate a CEL configuration object.

Return values
NULLon error
Thenew CEL configuration object

Definition at line 188 of file cel.c.

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

Referenced by cel_config_alloc(), and load_module().

189 {
191 
192  if (!(cfg = ao2_alloc(sizeof(*cfg), cel_general_config_dtor))) {
193  return NULL;
194  }
195 
196  if (ast_string_field_init(cfg, 64)) {
197  return NULL;
198  }
199 
200  if (!(cfg->apps = ast_str_container_alloc(NUM_APP_BUCKETS))) {
201  return NULL;
202  }
203 
204  ao2_ref(cfg, +1);
205  return cfg;
206 }
#define NUM_APP_BUCKETS
Number of buckets for the appset container.
Definition: cel.c:155
#define ast_str_container_alloc(buckets)
Allocates a hash container for bare strings.
Definition: strings.h:1312
#define NULL
Definition: resample.c:96
#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:911
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:353
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
A structure to hold CEL global configuration options.
Definition: cel.h:205
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static void cel_general_config_dtor(void *obj)
Destructor for cel_config.
Definition: cel.c:180

◆ ast_cel_get_config()

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 1690 of file cel.c.

References ao2_cleanup, ao2_global_obj_ref, ao2_ref, NULL, and RAII_VAR.

Referenced by test_cel_init_cb().

1691 {
1692  RAII_VAR(struct cel_config *, mod_cfg, ao2_global_obj_ref(cel_configs), ao2_cleanup);
1693 
1694  if (!mod_cfg || !mod_cfg->general) {
1695  return NULL;
1696  }
1697 
1698  ao2_ref(mod_cfg->general, +1);
1699  return mod_cfg->general;
1700 }
A container that holds all config-related information.
Definition: cel_custom.c:56
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define NULL
Definition: resample.c:96
#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:911
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ ast_cel_get_type_name()

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 491 of file cel.c.

References cel_event_types, and S_OR.

Referenced by ast_cel_fill_record(), cel_generic_cb(), dump_event(), and handle_cli_status().

492 {
493  return S_OR(cel_event_types[type], "Unknown");
494 }
static const char type[]
Definition: chan_ooh323.c:109
static const char *const cel_event_types[CEL_MAX_EVENT_IDS]
Map of ast_cel_event_type to strings.
Definition: cel.c:305
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79

◆ ast_cel_publish_event()

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 1666 of file cel.c.

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

Referenced by celgenuserevent_exec().

1669 {
1670  struct ast_json *cel_blob;
1671  struct stasis_message *message;
1672 
1673  cel_blob = ast_json_pack("{s: i, s: o}",
1674  "event_type", event_type,
1675  "event_details", ast_json_ref(blob));
1676 
1678  if (message) {
1679  stasis_publish(ast_cel_topic(), message);
1680  }
1681  ao2_cleanup(message);
1682  ast_json_unref(cel_blob);
1683 }
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:591
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:1685
const char * ast_channel_uniqueid(const struct ast_channel *chan)
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.
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Abstract JSON element (object, array, string, int, ...).
struct stasis_message_type * cel_generic_type(void)

◆ ast_cel_set_config()

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 1702 of file cel.c.

References ao2_bump, ao2_cleanup, ao2_global_obj_ref, ao2_ref, ast_cel_check_enabled(), config, create_routes(), destroy_routes(), cel_config::general, and is_enabled().

Referenced by cel_verify_and_cleanup_cb(), and test_cel_init_cb().

1703 {
1704  int was_enabled;
1705  int is_enabled;
1706  struct ast_cel_general_config *cleanup_config;
1707  struct cel_config *mod_cfg = ao2_global_obj_ref(cel_configs);
1708 
1709  if (mod_cfg) {
1710  was_enabled = ast_cel_check_enabled();
1711 
1712  cleanup_config = mod_cfg->general;
1713  ao2_bump(config);
1714  mod_cfg->general = config;
1715  ao2_cleanup(cleanup_config);
1716 
1717  is_enabled = ast_cel_check_enabled();
1718  if (!was_enabled && is_enabled) {
1719  create_routes();
1720  } else if (was_enabled && !is_enabled) {
1721  destroy_routes();
1722  }
1723 
1724  ao2_ref(mod_cfg, -1);
1725  }
1726 }
A container that holds all config-related information.
Definition: cel_custom.c:56
char * config
Definition: conf2ael.c:66
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define ao2_bump(obj)
Definition: astobj2.h:491
unsigned int ast_cel_check_enabled(void)
Hashing function for cel_backend.
Definition: cel.c:343
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_cel_general_config * general
Definition: cel.c:210
static int create_routes(void)
Create the Stasis message router and routes for CEL.
Definition: cel.c:1500
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:205
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static void destroy_routes(void)
Definition: cel.c:1416

◆ ast_cel_str_to_event_type()

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 418 of file cel.c.

References ARRAY_LEN, AST_CEL_INVALID_VALUE, ast_log, cel_event_types, and LOG_ERROR.

Referenced by events_handler().

419 {
420  unsigned int i;
421 
422  for (i = 0; i < ARRAY_LEN(cel_event_types); i++) {
423  if (cel_event_types[i] && !strcasecmp(name, cel_event_types[i])) {
424  return i;
425  }
426  }
427 
428  ast_log(LOG_ERROR, "Unknown event name '%s'\n", name);
429  return AST_CEL_INVALID_VALUE;
430 }
#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:305
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
static const char name[]
Definition: cdr_mysql.c:74

◆ ast_cel_topic()

struct stasis_topic* ast_cel_topic ( void  )

Get the CEL topic.

Return values
TheCEL topic
NULLif not allocated

Definition at line 1685 of file cel.c.

References cel_topic.

Referenced by ast_cel_publish_event(), and create_subscriptions().

1686 {
1687  return cel_topic;
1688 }
static struct stasis_topic * cel_topic
Definition: cel.c:117

◆ ast_cel_track_event()

static int ast_cel_track_event ( enum ast_cel_event_type  et)
static

Definition at line 432 of file cel.c.

References ao2_cleanup, ao2_global_obj_ref, and RAII_VAR.

Referenced by cel_channel_linkedid_change(), cel_channel_state_change(), and cel_report_event().

433 {
434  RAII_VAR(struct cel_config *, cfg, ao2_global_obj_ref(cel_configs), ao2_cleanup);
435 
436  if (!cfg || !cfg->general) {
437  return 0;
438  }
439 
440  return (cfg->general->events & ((int64_t) 1 << et)) ? 1 : 0;
441 }
A container that holds all config-related information.
Definition: cel_custom.c:56
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#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:911
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 1770 of file cel.c.

◆ cel_attended_transfer_cb()

static void cel_attended_transfer_cb ( void *  data,
struct stasis_subscription sub,
struct stasis_message message 
)
static

Definition at line 1305 of file cel.c.

References ast_attended_transfer_message::app, AST_ATTENDED_TRANSFER_DEST_APP, AST_ATTENDED_TRANSFER_DEST_BRIDGE_MERGE, AST_ATTENDED_TRANSFER_DEST_FAIL, AST_ATTENDED_TRANSFER_DEST_LINK, AST_ATTENDED_TRANSFER_DEST_LOCAL_APP, AST_ATTENDED_TRANSFER_DEST_THREEWAY, AST_CEL_ATTENDEDTRANSFER, ast_json_pack(), ast_json_unref(), ast_channel_snapshot::base, ast_bridge_channel_snapshot_pair::bridge_snapshot, cel_report_event(), ast_bridge_channel_snapshot_pair::channel_snapshot, ast_attended_transfer_message::dest, ast_attended_transfer_message::dest_type, ast_channel_snapshot_base::name, NULL, stasis_message_data(), stasis_message_timestamp(), ast_attended_transfer_message::target, ast_attended_transfer_message::to_transfer_target, ast_attended_transfer_message::to_transferee, ast_attended_transfer_message::transferee, ast_channel_snapshot_base::uniqueid, and ast_bridge_snapshot::uniqueid.

Referenced by create_routes().

1308 {
1309  struct ast_attended_transfer_message *xfer = stasis_message_data(message);
1310  struct ast_json *extra = NULL;
1311  struct ast_bridge_snapshot *bridge1, *bridge2;
1312  struct ast_channel_snapshot *channel1, *channel2;
1313 
1314  /* Make sure bridge1 is always non-NULL */
1315  if (!xfer->to_transferee.bridge_snapshot) {
1316  bridge1 = xfer->to_transfer_target.bridge_snapshot;
1317  bridge2 = xfer->to_transferee.bridge_snapshot;
1318  channel1 = xfer->to_transfer_target.channel_snapshot;
1319  channel2 = xfer->to_transferee.channel_snapshot;
1320  } else {
1321  bridge1 = xfer->to_transferee.bridge_snapshot;
1322  bridge2 = xfer->to_transfer_target.bridge_snapshot;
1323  channel1 = xfer->to_transferee.channel_snapshot;
1324  channel2 = xfer->to_transfer_target.channel_snapshot;
1325  }
1326 
1327  switch (xfer->dest_type) {
1329  return;
1330  /* handle these three the same */
1334  extra = ast_json_pack("{s: s, s: s, s: s, s: s, s: s, s: s, s: s, s: s}",
1335  "bridge1_id", bridge1->uniqueid,
1336  "channel2_name", channel2->base->name,
1337  "channel2_uniqueid", channel2->base->uniqueid,
1338  "bridge2_id", bridge2->uniqueid,
1339  "transferee_channel_name", xfer->transferee ? xfer->transferee->base->name : "N/A",
1340  "transferee_channel_uniqueid", xfer->transferee ? xfer->transferee->base->uniqueid : "N/A",
1341  "transfer_target_channel_name", xfer->target ? xfer->target->base->name : "N/A",
1342  "transfer_target_channel_uniqueid", xfer->target ? xfer->target->base->uniqueid : "N/A");
1343  if (!extra) {
1344  return;
1345  }
1346  break;
1349  extra = ast_json_pack("{s: s, s: s, s: s, s: s, s: s, s: s, s: s, s: s}",
1350  "bridge1_id", bridge1->uniqueid,
1351  "channel2_name", channel2->base->name,
1352  "channel2_uniqueid", channel2->base->uniqueid,
1353  "app", xfer->dest.app,
1354  "transferee_channel_name", xfer->transferee ? xfer->transferee->base->name : "N/A",
1355  "transferee_channel_uniqueid", xfer->transferee ? xfer->transferee->base->uniqueid : "N/A",
1356  "transfer_target_channel_name", xfer->target ? xfer->target->base->name : "N/A",
1357  "transfer_target_channel_uniqueid", xfer->target ? xfer->target->base->uniqueid : "N/A");
1358  if (!extra) {
1359  return;
1360  }
1361  break;
1362  }
1364  NULL, extra, NULL);
1365  ast_json_unref(extra);
1366 }
struct ast_channel_snapshot_base * base
union ast_attended_transfer_message::@324 dest
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
Message representing attended transfer.
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
Structure that contains a snapshot of information about a bridge.
Definition: bridge.h:322
Structure representing a snapshot of channel state.
struct ast_channel_snapshot * target
const ast_string_field uniqueid
#define NULL
Definition: resample.c:96
struct ast_bridge_channel_snapshot_pair to_transferee
struct ast_bridge_channel_snapshot_pair to_transfer_target
struct ast_channel_snapshot * transferee
const struct timeval * stasis_message_timestamp(const struct stasis_message *msg)
Get the time when a message was created.
enum ast_attended_transfer_dest_type dest_type
a transfer occurs
Definition: cel.h:67
struct ast_channel_snapshot * channel_snapshot
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
struct ast_bridge_snapshot * bridge_snapshot
const ast_string_field uniqueid
Definition: bridge.h:336
static int cel_report_event(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)
Definition: cel.c:569
Abstract JSON element (object, array, string, int, ...).
const ast_string_field name

◆ cel_backend_send_cb()

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

Definition at line 561 of file cel.c.

References cel_backend::callback.

Referenced by cel_report_event().

562 {
563  struct cel_backend *backend = obj;
564 
565  backend->callback(arg);
566  return 0;
567 }
ast_cel_backend_cb callback
Definition: cel.c:327

◆ cel_blind_transfer_cb()

static void cel_blind_transfer_cb ( void *  data,
struct stasis_subscription sub,
struct stasis_message message 
)
static

Definition at line 1279 of file cel.c.

References AST_BRIDGE_TRANSFER_SUCCESS, AST_CEL_BLINDTRANSFER, ast_json_pack(), ast_json_unref(), ast_channel_snapshot::base, ast_blind_transfer_message::bridge, cel_report_event(), ast_blind_transfer_message::context, ast_blind_transfer_message::exten, ast_channel_snapshot_base::name, NULL, ast_blind_transfer_message::result, stasis_message_data(), stasis_message_timestamp(), ast_blind_transfer_message::transferee, ast_blind_transfer_message::transferer, ast_channel_snapshot_base::uniqueid, and ast_bridge_snapshot::uniqueid.

Referenced by create_routes().

1282 {
1283  struct ast_blind_transfer_message *transfer_msg = stasis_message_data(message);
1284  struct ast_channel_snapshot *chan_snapshot = transfer_msg->transferer;
1285  struct ast_bridge_snapshot *bridge_snapshot = transfer_msg->bridge;
1286  struct ast_json *extra;
1287 
1288  if (transfer_msg->result != AST_BRIDGE_TRANSFER_SUCCESS) {
1289  return;
1290  }
1291 
1292  extra = ast_json_pack("{s: s, s: s, s: s, s: s, s: s}",
1293  "extension", transfer_msg->exten,
1294  "context", transfer_msg->context,
1295  "bridge_id", bridge_snapshot->uniqueid,
1296  "transferee_channel_name", transfer_msg->transferee ? transfer_msg->transferee->base->name : "N/A",
1297  "transferee_channel_uniqueid", transfer_msg->transferee ? transfer_msg->transferee->base->uniqueid : "N/A");
1298  if (extra) {
1300  NULL, extra, NULL);
1301  ast_json_unref(extra);
1302  }
1303 }
struct ast_channel_snapshot_base * base
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
char exten[AST_MAX_EXTENSION]
Message published during a blind transfer.
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
Structure that contains a snapshot of information about a bridge.
Definition: bridge.h:322
Structure representing a snapshot of channel state.
const ast_string_field uniqueid
#define NULL
Definition: resample.c:96
const struct timeval * stasis_message_timestamp(const struct stasis_message *msg)
Get the time when a message was created.
struct ast_bridge_snapshot * bridge
a transfer occurs
Definition: cel.h:65
struct ast_channel_snapshot * transferer
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
char context[AST_MAX_CONTEXT]
const ast_string_field uniqueid
Definition: bridge.h:336
static int cel_report_event(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)
Definition: cel.c:569
Abstract JSON element (object, array, string, int, ...).
struct ast_channel_snapshot * transferee
enum ast_transfer_result result
const ast_string_field name

◆ cel_bridge_enter_cb()

static void cel_bridge_enter_cb ( void *  data,
struct stasis_subscription sub,
struct stasis_message message 
)
static

Definition at line 1047 of file cel.c.

References AST_CEL_BRIDGE_ENTER, ast_free, ast_json_pack(), ast_json_unref(), ast_str_buffer(), ast_bridge_blob::blob, ast_bridge_blob::bridge, cel_filter_channel_snapshot(), cel_generate_peer_str(), cel_report_event(), ast_bridge_blob::channel, NULL, RAII_VAR, stasis_message_data(), stasis_message_timestamp(), ast_bridge_snapshot::technology, and ast_bridge_snapshot::uniqueid.

Referenced by create_routes().

1050 {
1051  struct ast_bridge_blob *blob = stasis_message_data(message);
1052  struct ast_bridge_snapshot *snapshot = blob->bridge;
1053  struct ast_channel_snapshot *chan_snapshot = blob->channel;
1054  RAII_VAR(struct ast_json *, extra, NULL, ast_json_unref);
1055  RAII_VAR(struct ast_str *, peer_str, NULL, ast_free);
1056 
1057  if (cel_filter_channel_snapshot(chan_snapshot)) {
1058  return;
1059  }
1060 
1061  extra = ast_json_pack("{s: s, s: s}",
1062  "bridge_id", snapshot->uniqueid,
1063  "bridge_technology", snapshot->technology);
1064  if (!extra) {
1065  return;
1066  }
1067 
1068  peer_str = cel_generate_peer_str(snapshot, chan_snapshot);
1069  if (!peer_str) {
1070  return;
1071  }
1072 
1074  NULL, extra, ast_str_buffer(peer_str));
1075 }
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
struct ast_channel_snapshot * channel
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
Structure that contains a snapshot of information about a bridge.
Definition: bridge.h:322
Structure representing a snapshot of channel state.
struct ast_json * blob
#define NULL
Definition: resample.c:96
channel enters a bridge
Definition: cel.h:57
struct ast_bridge_snapshot * bridge
const ast_string_field technology
Definition: bridge.h:336
#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:911
const struct timeval * stasis_message_timestamp(const struct stasis_message *msg)
Get the time when a message was created.
Blob of data associated with a bridge.
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
static int cel_filter_channel_snapshot(struct ast_channel_snapshot *snapshot)
Definition: cel.c:986
#define ast_free(a)
Definition: astmm.h:182
const ast_string_field uniqueid
Definition: bridge.h:336
static struct ast_str * cel_generate_peer_str(struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *chan)
Definition: cel.c:1009
static int cel_report_event(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)
Definition: cel.c:569
Abstract JSON element (object, array, string, int, ...).

◆ cel_bridge_leave_cb()

static void cel_bridge_leave_cb ( void *  data,
struct stasis_subscription sub,
struct stasis_message message 
)
static

Definition at line 1077 of file cel.c.

References AST_CEL_BRIDGE_EXIT, ast_free, ast_json_pack(), ast_json_unref(), ast_str_buffer(), ast_bridge_blob::blob, ast_bridge_blob::bridge, cel_filter_channel_snapshot(), cel_generate_peer_str(), cel_report_event(), ast_bridge_blob::channel, NULL, RAII_VAR, stasis_message_data(), stasis_message_timestamp(), ast_bridge_snapshot::technology, and ast_bridge_snapshot::uniqueid.

Referenced by create_routes().

1080 {
1081  struct ast_bridge_blob *blob = stasis_message_data(message);
1082  struct ast_bridge_snapshot *snapshot = blob->bridge;
1083  struct ast_channel_snapshot *chan_snapshot = blob->channel;
1084  RAII_VAR(struct ast_json *, extra, NULL, ast_json_unref);
1085  RAII_VAR(struct ast_str *, peer_str, NULL, ast_free);
1086 
1087  if (cel_filter_channel_snapshot(chan_snapshot)) {
1088  return;
1089  }
1090 
1091  extra = ast_json_pack("{s: s, s: s}",
1092  "bridge_id", snapshot->uniqueid,
1093  "bridge_technology", snapshot->technology);
1094  if (!extra) {
1095  return;
1096  }
1097 
1098  peer_str = cel_generate_peer_str(snapshot, chan_snapshot);
1099  if (!peer_str) {
1100  return;
1101  }
1102 
1104  NULL, extra, ast_str_buffer(peer_str));
1105 }
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
struct ast_channel_snapshot * channel
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
Structure that contains a snapshot of information about a bridge.
Definition: bridge.h:322
Structure representing a snapshot of channel state.
struct ast_json * blob
#define NULL
Definition: resample.c:96
struct ast_bridge_snapshot * bridge
const ast_string_field technology
Definition: bridge.h:336
#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:911
const struct timeval * stasis_message_timestamp(const struct stasis_message *msg)
Get the time when a message was created.
Blob of data associated with a bridge.
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
static int cel_filter_channel_snapshot(struct ast_channel_snapshot *snapshot)
Definition: cel.c:986
#define ast_free(a)
Definition: astmm.h:182
const ast_string_field uniqueid
Definition: bridge.h:336
static struct ast_str * cel_generate_peer_str(struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *chan)
Definition: cel.c:1009
static int cel_report_event(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)
Definition: cel.c:569
Abstract JSON element (object, array, string, int, ...).
channel exits a bridge
Definition: cel.h:59

◆ cel_channel_app_change()

static void cel_channel_app_change ( struct ast_channel_snapshot old_snapshot,
struct ast_channel_snapshot new_snapshot,
const struct timeval *  event_time 
)
static

Definition at line 955 of file cel.c.

References ast_channel_snapshot_dialplan::appl, AST_CEL_APP_END, AST_CEL_APP_START, ast_strlen_zero, cel_report_event(), ast_channel_snapshot::dialplan, and NULL.

959 {
960  if (old_snapshot && !strcmp(old_snapshot->dialplan->appl, new_snapshot->dialplan->appl)) {
961  return;
962  }
963 
964  /* old snapshot has an application, end it */
965  if (old_snapshot && !ast_strlen_zero(old_snapshot->dialplan->appl)) {
966  cel_report_event(old_snapshot, AST_CEL_APP_END, event_time, NULL, NULL, NULL);
967  }
968 
969  /* new snapshot has an application, start it */
970  if (!ast_strlen_zero(new_snapshot->dialplan->appl)) {
971  cel_report_event(new_snapshot, AST_CEL_APP_START, event_time, NULL, NULL, NULL);
972  }
973 }
#define NULL
Definition: resample.c:96
struct ast_channel_snapshot_dialplan * dialplan
#define ast_strlen_zero(foo)
Definition: strings.h:52
const ast_string_field appl
an app ends
Definition: cel.h:55
static int cel_report_event(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)
Definition: cel.c:569
an app starts
Definition: cel.h:53

◆ cel_channel_linkedid_change()

static void cel_channel_linkedid_change ( struct ast_channel_snapshot old_snapshot,
struct ast_channel_snapshot new_snapshot,
const struct timeval *  event_time 
)
static

Definition at line 936 of file cel.c.

References ast_assert, AST_CEL_LINKEDID_END, ast_cel_track_event(), ast_strlen_zero, cel_linkedid_ref(), check_retire_linkedid(), ast_channel_snapshot_peer::linkedid, and ast_channel_snapshot::peer.

940 {
941  if (!old_snapshot) {
942  return;
943  }
944 
945  ast_assert(!ast_strlen_zero(new_snapshot->peer->linkedid));
946  ast_assert(!ast_strlen_zero(old_snapshot->peer->linkedid));
947 
949  && strcmp(old_snapshot->peer->linkedid, new_snapshot->peer->linkedid)) {
950  cel_linkedid_ref(new_snapshot->peer->linkedid);
951  check_retire_linkedid(old_snapshot, event_time);
952  }
953 }
the last channel with the given linkedid is retired
Definition: cel.h:71
static int ast_cel_track_event(enum ast_cel_event_type et)
Definition: cel.c:432
#define ast_assert(a)
Definition: utils.h:695
static void check_retire_linkedid(struct ast_channel_snapshot *snapshot, const struct timeval *event_time)
Definition: cel.c:614
#define ast_strlen_zero(foo)
Definition: strings.h:52
static int cel_linkedid_ref(const char *linkedid)
Definition: cel.c:781
struct ast_channel_snapshot_peer * peer

◆ cel_channel_state_change()

static void cel_channel_state_change ( struct ast_channel_snapshot old_snapshot,
struct ast_channel_snapshot new_snapshot,
const struct timeval *  event_time 
)
static

Handle channel state changes.

Definition at line 896 of file cel.c.

References ao2_cleanup, AST_CEL_ANSWER, AST_CEL_CHANNEL_END, AST_CEL_CHANNEL_START, AST_CEL_HANGUP, AST_CEL_LINKEDID_END, ast_cel_track_event(), AST_FLAG_DEAD, ast_json_pack(), ast_json_unref(), AST_STATE_UP, ast_test_flag, ast_channel_snapshot::base, ast_channel_snapshot_hangup::cause, cel_report_event(), check_retire_linkedid(), cel_dialstatus::dialstatus, ast_channel_snapshot::flags, get_dialstatus(), ast_channel_snapshot::hangup, NULL, ast_channel_snapshot_hangup::source, ast_channel_snapshot::state, and ast_channel_snapshot_base::uniqueid.

900 {
901  int is_hungup, was_hungup;
902 
903  if (!old_snapshot) {
904  cel_report_event(new_snapshot, AST_CEL_CHANNEL_START, event_time, NULL, NULL, NULL);
905  return;
906  }
907 
908  was_hungup = ast_test_flag(&old_snapshot->flags, AST_FLAG_DEAD) ? 1 : 0;
909  is_hungup = ast_test_flag(&new_snapshot->flags, AST_FLAG_DEAD) ? 1 : 0;
910 
911  if (!was_hungup && is_hungup) {
912  struct ast_json *extra;
913  struct cel_dialstatus *dialstatus = get_dialstatus(new_snapshot->base->uniqueid);
914 
915  extra = ast_json_pack("{s: i, s: s, s: s}",
916  "hangupcause", new_snapshot->hangup->cause,
917  "hangupsource", new_snapshot->hangup->source,
918  "dialstatus", dialstatus ? dialstatus->dialstatus : "");
919  cel_report_event(new_snapshot, AST_CEL_HANGUP, event_time, NULL, extra, NULL);
920  ast_json_unref(extra);
921  ao2_cleanup(dialstatus);
922 
923  cel_report_event(new_snapshot, AST_CEL_CHANNEL_END, event_time, NULL, NULL, NULL);
925  check_retire_linkedid(new_snapshot, event_time);
926  }
927  return;
928  }
929 
930  if (old_snapshot->state != new_snapshot->state && new_snapshot->state == AST_STATE_UP) {
931  cel_report_event(new_snapshot, AST_CEL_ANSWER, event_time, NULL, NULL, NULL);
932  return;
933  }
934 }
the last channel with the given linkedid is retired
Definition: cel.h:71
struct ast_channel_snapshot_base * base
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
static int ast_cel_track_event(enum ast_cel_event_type et)
Definition: cel.c:432
#define ast_test_flag(p, flag)
Definition: utils.h:63
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
channel birth
Definition: cel.h:45
const ast_string_field uniqueid
static void check_retire_linkedid(struct ast_channel_snapshot *snapshot, const struct timeval *event_time)
Definition: cel.c:614
static struct cel_dialstatus * get_dialstatus(const char *uniqueid)
Definition: cel.c:868
#define NULL
Definition: resample.c:96
char dialstatus[0]
Definition: cel.c:176
struct ast_channel_snapshot_hangup * hangup
hangup terminates connection
Definition: cel.h:49
channel end
Definition: cel.h:47
enum ast_channel_state state
static int cel_report_event(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)
Definition: cel.c:569
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
A ringing phone is answered.
Definition: cel.h:51
struct ast_flags flags
Abstract JSON element (object, array, string, int, ...).

◆ cel_config_alloc()

static void* cel_config_alloc ( void  )
static

Definition at line 224 of file cel.c.

References ao2_alloc, ao2_cleanup, ao2_ref, ast_cel_general_config_alloc(), cel_config_dtor(), NULL, and RAII_VAR.

Referenced by load_module().

225 {
226  RAII_VAR(struct cel_config *, cfg, NULL, ao2_cleanup);
227 
228  if (!(cfg = ao2_alloc(sizeof(*cfg), cel_config_dtor))) {
229  return NULL;
230  }
231 
232  if (!(cfg->general = ast_cel_general_config_alloc())) {
233  return NULL;
234  }
235 
236  ao2_ref(cfg, +1);
237  return cfg;
238 }
static void cel_config_dtor(void *obj)
Destructor for cel_config.
Definition: cel.c:217
A container that holds all config-related information.
Definition: cel_custom.c:56
void * ast_cel_general_config_alloc(void)
Allocate a CEL configuration object.
Definition: cel.c:188
#define NULL
Definition: resample.c:96
#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:911
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ cel_config_dtor()

static void cel_config_dtor ( void *  obj)
static

Destructor for cel_config.

Definition at line 217 of file cel.c.

References ao2_cleanup, cel_config::general, and NULL.

Referenced by cel_config_alloc().

218 {
219  struct cel_config *cfg = obj;
220  ao2_cleanup(cfg->general);
221  cfg->general = NULL;
222 }
A container that holds all config-related information.
Definition: cel_custom.c:56
#define NULL
Definition: resample.c:96
struct ast_cel_general_config * general
Definition: cel.c:210
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ cel_dial_cb()

static void cel_dial_cb ( void *  data,
struct stasis_subscription sub,
struct stasis_message message 
)
static

Definition at line 1229 of file cel.c.

References AST_CEL_FORWARD, ast_json_pack(), ast_json_unref(), ast_multi_channel_blob_get_channel(), ast_strlen_zero, ast_multi_channel_blob::blob, cel_filter_channel_snapshot(), cel_report_event(), get_blob_variable(), is_valid_dialstatus(), NULL, save_dialstatus(), stasis_message_data(), and stasis_message_timestamp().

Referenced by create_routes().

1231 {
1232  struct ast_multi_channel_blob *blob = stasis_message_data(message);
1233  struct ast_channel_snapshot *snapshot;
1234 
1235  snapshot = ast_multi_channel_blob_get_channel(blob, "caller");
1236  if (!snapshot || cel_filter_channel_snapshot(snapshot)) {
1237  return;
1238  }
1239 
1240  if (!ast_strlen_zero(get_blob_variable(blob, "forward"))) {
1241  struct ast_json *extra;
1242 
1243  extra = ast_json_pack("{s: s}", "forward", get_blob_variable(blob, "forward"));
1244  if (extra) {
1246  NULL, extra, NULL);
1247  ast_json_unref(extra);
1248  }
1249  }
1250 
1251  if (is_valid_dialstatus(blob)) {
1252  save_dialstatus(blob, snapshot);
1253  }
1254 }
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
struct ast_json * blob
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
Structure representing a snapshot of channel state.
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
const struct timeval * stasis_message_timestamp(const struct stasis_message *msg)
Get the time when a message was created.
static int is_valid_dialstatus(struct ast_multi_channel_blob *blob)
Definition: cel.c:1200
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
static int cel_filter_channel_snapshot(struct ast_channel_snapshot *snapshot)
Definition: cel.c:986
static void save_dialstatus(struct ast_multi_channel_blob *blob, struct ast_channel_snapshot *snapshot)
Definition: cel.c:1156
static int cel_report_event(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)
Definition: cel.c:569
struct ast_channel_snapshot * ast_multi_channel_blob_get_channel(struct ast_multi_channel_blob *obj, const char *role)
Retrieve a channel snapshot associated with a specific role from a ast_multi_channel_blob.
A multi channel blob data structure for multi_channel_blob stasis messages.
static const char * get_blob_variable(struct ast_multi_channel_blob *blob, const char *varname)
Definition: cel.c:880
Abstract JSON element (object, array, string, int, ...).
this call was forwarded somewhere else
Definition: cel.h:75

◆ cel_filter_channel_snapshot()

static int cel_filter_channel_snapshot ( struct ast_channel_snapshot snapshot)
static

Definition at line 986 of file cel.c.

References AST_CHAN_TP_INTERNAL, ast_channel_snapshot::base, and ast_channel_snapshot_base::tech_properties.

Referenced by cel_bridge_enter_cb(), cel_bridge_leave_cb(), cel_dial_cb(), and cel_snapshot_update_cb().

987 {
988  if (!snapshot) {
989  return 0;
990  }
991  return snapshot->base->tech_properties & AST_CHAN_TP_INTERNAL;
992 }
struct ast_channel_snapshot_base * base
Channels with this particular technology are an implementation detail of Asterisk and should generall...
Definition: channel.h:972

◆ cel_general_config_dtor()

static void cel_general_config_dtor ( void *  obj)
static

Destructor for cel_config.

Definition at line 180 of file cel.c.

References ao2_cleanup, ast_cel_general_config::apps, ast_string_field_free_memory, and NULL.

Referenced by ast_cel_general_config_alloc().

181 {
182  struct ast_cel_general_config *cfg = obj;
184  ao2_cleanup(cfg->apps);
185  cfg->apps = NULL;
186 }
#define NULL
Definition: resample.c:96
struct ao2_container * apps
Definition: cel.h:214
A structure to hold CEL global configuration options.
Definition: cel.h:205
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:368

◆ cel_generate_peer_str()

static struct ast_str* cel_generate_peer_str ( struct ast_bridge_snapshot bridge,
struct ast_channel_snapshot chan 
)
static

Definition at line 1009 of file cel.c.

References ao2_cleanup, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_channel_snapshot_get_latest(), ast_str_append(), ast_str_create, ast_str_truncate(), ast_channel_snapshot::base, ast_bridge_snapshot::channels, ast_channel_snapshot_base::name, NULL, and ast_channel_snapshot_base::uniqueid.

Referenced by cel_bridge_enter_cb(), and cel_bridge_leave_cb().

1012 {
1013  struct ast_str *peer_str = ast_str_create(32);
1014  struct ao2_iterator i;
1015  char *current_chan = NULL;
1016 
1017  if (!peer_str) {
1018  return NULL;
1019  }
1020 
1021  for (i = ao2_iterator_init(bridge->channels, 0);
1022  (current_chan = ao2_iterator_next(&i));
1023  ao2_cleanup(current_chan)) {
1024  struct ast_channel_snapshot *current_snapshot;
1025 
1026  /* Don't add the channel for which this message is being generated */
1027  if (!strcmp(current_chan, chan->base->uniqueid)) {
1028  continue;
1029  }
1030 
1031  current_snapshot = ast_channel_snapshot_get_latest(current_chan);
1032  if (!current_snapshot) {
1033  continue;
1034  }
1035 
1036  ast_str_append(&peer_str, 0, "%s,", current_snapshot->base->name);
1037  ao2_cleanup(current_snapshot);
1038  }
1040 
1041  /* Rip off the trailing comma */
1042  ast_str_truncate(peer_str, -1);
1043 
1044  return peer_str;
1045 }
struct ao2_container * channels
Definition: bridge.h:339
struct ast_channel_snapshot_base * base
Structure representing a snapshot of channel state.
const ast_string_field uniqueid
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define NULL
Definition: resample.c:96
char * ast_str_truncate(struct ast_str *buf, ssize_t len)
Truncates the enclosed string to the given length.
Definition: strings.h:738
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
struct ast_channel_snapshot * ast_channel_snapshot_get_latest(const char *uniqueid)
Obtain the latest ast_channel_snapshot from the Stasis Message Bus API cache. This is an ao2 object...
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
const ast_string_field name
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ cel_generic_cb()

static void cel_generic_cb ( void *  data,
struct stasis_subscription sub,
struct stasis_message message 
)
static

Definition at line 1256 of file cel.c.

References ast_cel_get_type_name(), AST_CEL_USER_DEFINED, ast_json_integer_get(), ast_json_object_get(), ast_json_string_get(), ast_log, ast_channel_blob::blob, cel_report_event(), LOG_ERROR, NULL, ast_channel_blob::snapshot, stasis_message_data(), and stasis_message_timestamp().

Referenced by create_routes().

1259 {
1260  struct ast_channel_blob *obj = stasis_message_data(message);
1261  int event_type = ast_json_integer_get(ast_json_object_get(obj->blob, "event_type"));
1262  struct ast_json *event_details = ast_json_object_get(obj->blob, "event_details");
1263 
1264  switch (event_type) {
1265  case AST_CEL_USER_DEFINED:
1266  {
1267  const char *event = ast_json_string_get(ast_json_object_get(event_details, "event"));
1268  struct ast_json *extra = ast_json_object_get(event_details, "extra");
1269  cel_report_event(obj->snapshot, event_type, stasis_message_timestamp(message),
1270  event, extra, NULL);
1271  break;
1272  }
1273  default:
1274  ast_log(LOG_ERROR, "Unhandled %s event blob\n", ast_cel_get_type_name(event_type));
1275  break;
1276  }
1277 }
struct ast_json * blob
struct ast_channel_snapshot * snapshot
Definition: astman.c:222
#define NULL
Definition: resample.c:96
Blob of data associated with a channel.
#define ast_log
Definition: astobj2.c:42
const struct timeval * stasis_message_timestamp(const struct stasis_message *msg)
Get the time when a message was created.
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
Definition: json.c:273
#define LOG_ERROR
Definition: logger.h:285
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
static int cel_report_event(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)
Definition: cel.c:569
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
Definition: json.c:397
Abstract JSON element (object, array, string, int, ...).
a user-defined event, the event name field should be set
Definition: cel.h:69
intmax_t ast_json_integer_get(const struct ast_json *integer)
Get the value from a JSON integer.
Definition: json.c:322
const char * ast_cel_get_type_name(enum ast_cel_event_type type)
Get the name of a CEL event type.
Definition: cel.c:491

◆ cel_generic_type()

struct stasis_message_type* cel_generic_type ( void  )

◆ cel_linkedid_ref()

static int cel_linkedid_ref ( const char *  linkedid)
static

Definition at line 781 of file cel.c.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_cleanup, ao2_find, ao2_global_obj_ref, ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_log, ast_strlen_zero, cel_linkedid::count, cel_linkedid::id, LOG_ERROR, NULL, OBJ_SEARCH_KEY, and RAII_VAR.

Referenced by cel_channel_linkedid_change(), cel_report_event(), and cel_track_app().

782 {
783  RAII_VAR(struct ao2_container *, linkedids, ao2_global_obj_ref(cel_linkedids), ao2_cleanup);
784  struct cel_linkedid *lid;
785 
786  if (ast_strlen_zero(linkedid)) {
787  ast_log(LOG_ERROR, "The linkedid should never be empty\n");
788  return -1;
789  }
790  if (!linkedids) {
791  /* The CEL module is shutdown. Abort. */
792  return -1;
793  }
794 
795  ao2_lock(linkedids);
796  lid = ao2_find(linkedids, (void *) linkedid, OBJ_SEARCH_KEY);
797  if (!lid) {
798  /*
799  * Changes to the lid->count member are protected by the
800  * container lock so the lid object does not need its own lock.
801  */
802  lid = ao2_alloc_options(sizeof(*lid) + strlen(linkedid) + 1, NULL,
804  if (!lid) {
805  ao2_unlock(linkedids);
806  return -1;
807  }
808  strcpy(lid->id, linkedid);/* Safe */
809 
810  ao2_link(linkedids, lid);
811  }
812  ++lid->count;
813  ao2_unlock(linkedids);
814  ao2_ref(lid, -1);
815 
816  return 0;
817 }
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:406
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
#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:911
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
#define LOG_ERROR
Definition: logger.h:285
char id[0]
Definition: cel.c:166
unsigned int count
Definition: cel.c:164
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Generic container type.
#define ao2_link(container, obj)
Definition: astobj2.h:1549

◆ cel_local_cb()

static void cel_local_cb ( void *  data,
struct stasis_subscription sub,
struct stasis_message message 
)
static

Definition at line 1392 of file cel.c.

References AST_CEL_LOCAL_OPTIMIZE, ast_json_pack(), ast_json_unref(), ast_multi_channel_blob_get_channel(), ast_channel_snapshot::base, cel_report_event(), ast_channel_snapshot_base::name, NULL, stasis_message_data(), stasis_message_timestamp(), and ast_channel_snapshot_base::uniqueid.

Referenced by create_routes().

1395 {
1396  struct ast_multi_channel_blob *obj = stasis_message_data(message);
1397  struct ast_channel_snapshot *localone = ast_multi_channel_blob_get_channel(obj, "1");
1398  struct ast_channel_snapshot *localtwo = ast_multi_channel_blob_get_channel(obj, "2");
1399  struct ast_json *extra;
1400 
1401  if (!localone || !localtwo) {
1402  return;
1403  }
1404 
1405  extra = ast_json_pack("{s: s, s: s}",
1406  "local_two", localtwo->base->name,
1407  "local_two_uniqueid", localtwo->base->uniqueid);
1408  if (!extra) {
1409  return;
1410  }
1411 
1413  ast_json_unref(extra);
1414 }
struct ast_channel_snapshot_base * base
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
A local channel optimization occurred.
Definition: cel.h:77
Structure representing a snapshot of channel state.
const ast_string_field uniqueid
#define NULL
Definition: resample.c:96
const struct timeval * stasis_message_timestamp(const struct stasis_message *msg)
Get the time when a message was created.
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
static int cel_report_event(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)
Definition: cel.c:569
struct ast_channel_snapshot * ast_multi_channel_blob_get_channel(struct ast_multi_channel_blob *obj, const char *role)
Retrieve a channel snapshot associated with a specific role from a ast_multi_channel_blob.
A multi channel blob data structure for multi_channel_blob stasis messages.
Abstract JSON element (object, array, string, int, ...).
const ast_string_field name

◆ cel_parking_cb()

static void cel_parking_cb ( void *  data,
struct stasis_subscription sub,
struct stasis_message message 
)
static

Definition at line 1107 of file cel.c.

References AST_CEL_PARK_END, AST_CEL_PARK_START, ast_json_pack(), ast_json_unref(), ast_channel_snapshot::base, cel_report_event(), ast_parked_call_payload::event_type, ast_channel_snapshot_base::name, NULL, PARKED_CALL, PARKED_CALL_FAILED, PARKED_CALL_GIVEUP, PARKED_CALL_SWAP, PARKED_CALL_TIMEOUT, PARKED_CALL_UNPARKED, ast_parked_call_payload::parkee, ast_parked_call_payload::parker_dial_string, ast_parked_call_payload::parkinglot, RAII_VAR, ast_parked_call_payload::retriever, stasis_message_data(), and stasis_message_timestamp().

Referenced by create_routes().

1110 {
1111  struct ast_parked_call_payload *parked_payload = stasis_message_data(message);
1112  RAII_VAR(struct ast_json *, extra, NULL, ast_json_unref);
1113  const char *reason = NULL;
1114 
1115  switch (parked_payload->event_type) {
1116  case PARKED_CALL:
1117  extra = ast_json_pack("{s: s, s: s}",
1118  "parker_dial_string", parked_payload->parker_dial_string,
1119  "parking_lot", parked_payload->parkinglot);
1120  if (extra) {
1122  NULL, extra, NULL);
1123  }
1124  return;
1125  case PARKED_CALL_TIMEOUT:
1126  reason = "ParkedCallTimeOut";
1127  break;
1128  case PARKED_CALL_GIVEUP:
1129  reason = "ParkedCallGiveUp";
1130  break;
1131  case PARKED_CALL_UNPARKED:
1132  reason = "ParkedCallUnparked";
1133  break;
1134  case PARKED_CALL_FAILED:
1135  reason = "ParkedCallFailed";
1136  break;
1137  case PARKED_CALL_SWAP:
1138  reason = "ParkedCallSwap";
1139  break;
1140  }
1141 
1142  if (parked_payload->retriever) {
1143  extra = ast_json_pack("{s: s, s: s}",
1144  "reason", reason ?: "",
1145  "retriever", parked_payload->retriever->base->name);
1146  } else {
1147  extra = ast_json_pack("{s: s}", "reason", reason ?: "");
1148  }
1149 
1150  if (extra) {
1152  NULL, extra, NULL);
1153  }
1154 }
struct ast_channel_snapshot_base * base
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
A parked call message payload.
Definition: parking.h:59
#define NULL
Definition: resample.c:96
enum ast_parked_call_event_type event_type
Definition: parking.h:62
struct ast_channel_snapshot * parkee
Definition: parking.h:60
#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:911
const struct timeval * stasis_message_timestamp(const struct stasis_message *msg)
Get the time when a message was created.
a channel is parked
Definition: cel.h:61
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
const ast_string_field parkinglot
Definition: parking.h:69
static int cel_report_event(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)
Definition: cel.c:569
channel out of the park
Definition: cel.h:63
const ast_string_field parker_dial_string
Definition: parking.h:69
Abstract JSON element (object, array, string, int, ...).
struct ast_channel_snapshot * retriever
Definition: parking.h:61
const ast_string_field name

◆ cel_pickup_cb()

static void cel_pickup_cb ( void *  data,
struct stasis_subscription sub,
struct stasis_message message 
)
static

Definition at line 1368 of file cel.c.

References AST_CEL_PICKUP, ast_json_pack(), ast_json_unref(), ast_multi_channel_blob_get_channel(), ast_channel_snapshot::base, cel_report_event(), ast_channel_snapshot_base::name, NULL, stasis_message_data(), stasis_message_timestamp(), and ast_channel_snapshot_base::uniqueid.

Referenced by create_routes().

1371 {
1372  struct ast_multi_channel_blob *obj = stasis_message_data(message);
1374  struct ast_channel_snapshot *target = ast_multi_channel_blob_get_channel(obj, "target");
1375  struct ast_json *extra;
1376 
1377  if (!channel || !target) {
1378  return;
1379  }
1380 
1381  extra = ast_json_pack("{s: s, s: s}",
1382  "pickup_channel", channel->base->name,
1383  "pickup_channel_uniqueid", channel->base->uniqueid);
1384  if (!extra) {
1385  return;
1386  }
1387 
1389  ast_json_unref(extra);
1390 }
struct ast_channel_snapshot_base * base
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
Structure representing a snapshot of channel state.
const ast_string_field uniqueid
Definition: muted.c:95
#define NULL
Definition: resample.c:96
const struct timeval * stasis_message_timestamp(const struct stasis_message *msg)
Get the time when a message was created.
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
static int cel_report_event(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)
Definition: cel.c:569
struct ast_channel_snapshot * ast_multi_channel_blob_get_channel(struct ast_multi_channel_blob *obj, const char *role)
Retrieve a channel snapshot associated with a specific role from a ast_multi_channel_blob.
A multi channel blob data structure for multi_channel_blob stasis messages.
Abstract JSON element (object, array, string, int, ...).
a directed pickup was performed on this channel
Definition: cel.h:73
const ast_string_field name

◆ cel_pre_apply_config()

static int cel_pre_apply_config ( void  )
static

Definition at line 276 of file cel.c.

References aco_pending_config(), ao2_container_count(), ast_cel_general_config::apps, AST_CEL_APP_END, AST_CEL_APP_START, ast_log, ast_cel_general_config::events, cel_config::general, and LOG_ERROR.

277 {
278  struct cel_config *cfg = aco_pending_config(&cel_cfg_info);
279 
280  if (!cfg->general) {
281  return -1;
282  }
283 
284  if (!ao2_container_count(cfg->general->apps)) {
285  return 0;
286  }
287 
288  if (cfg->general->events & ((int64_t) 1 << AST_CEL_APP_START)) {
289  return 0;
290  }
291 
292  if (cfg->general->events & ((int64_t) 1 << AST_CEL_APP_END)) {
293  return 0;
294  }
295 
296  ast_log(LOG_ERROR, "Applications are listed to be tracked, but APP events are not tracked\n");
297  return -1;
298 }
A container that holds all config-related information.
Definition: cel_custom.c:56
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
int64_t events
Definition: cel.h:210
#define ast_log
Definition: astobj2.c:42
void * aco_pending_config(struct aco_info *info)
Get pending config changes.
an app ends
Definition: cel.h:55
#define LOG_ERROR
Definition: logger.h:285
struct ast_cel_general_config * general
Definition: cel.c:210
struct ao2_container * apps
Definition: cel.h:214
an app starts
Definition: cel.h:53

◆ cel_report_event()

static int cel_report_event ( 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 
)
static

Definition at line 569 of file cel.c.

References ao2_callback, ao2_cleanup, ao2_global_obj_ref, ast_channel_snapshot_dialplan::appl, AST_CEL_APP_END, AST_CEL_APP_START, AST_CEL_CHANNEL_START, ast_cel_create_event_with_time(), AST_CEL_LINKEDID_END, ast_cel_track_event(), ast_event_destroy(), cel_backend_send_cb(), cel_linkedid_ref(), cel_track_app(), ast_channel_snapshot::dialplan, ast_channel_snapshot_peer::linkedid, OBJ_MULTIPLE, OBJ_NODATA, ast_channel_snapshot::peer, and RAII_VAR.

Referenced by cel_attended_transfer_cb(), cel_blind_transfer_cb(), cel_bridge_enter_cb(), cel_bridge_leave_cb(), cel_channel_app_change(), cel_channel_state_change(), cel_dial_cb(), cel_generic_cb(), cel_local_cb(), cel_parking_cb(), cel_pickup_cb(), and check_retire_linkedid().

573 {
574  struct ast_event *ev;
575  RAII_VAR(struct cel_config *, cfg, ao2_global_obj_ref(cel_configs), ao2_cleanup);
576  RAII_VAR(struct ao2_container *, backends, ao2_global_obj_ref(cel_backends), ao2_cleanup);
577 
578  if (!cfg || !cfg->general || !cfg->general->enable || !backends) {
579  return 0;
580  }
581 
582  /* Record the linkedid of new channels if we are tracking LINKEDID_END even if we aren't
583  * reporting on CHANNEL_START so we can track when to send LINKEDID_END */
584  if (event_type == AST_CEL_CHANNEL_START
586  if (cel_linkedid_ref(snapshot->peer->linkedid)) {
587  return -1;
588  }
589  }
590 
591  if (!ast_cel_track_event(event_type)) {
592  return 0;
593  }
594 
595  if ((event_type == AST_CEL_APP_START || event_type == AST_CEL_APP_END)
596  && !cel_track_app(snapshot->dialplan->appl)) {
597  return 0;
598  }
599 
600  ev = ast_cel_create_event_with_time(snapshot, event_type, event_time, userdefevname, extra, peer_str);
601  if (!ev) {
602  return -1;
603  }
604 
605  /* Distribute event to backends */
607  ast_event_destroy(ev);
608 
609  return 0;
610 }
the last channel with the given linkedid is retired
Definition: cel.h:71
An event.
Definition: event.c:81
A container that holds all config-related information.
Definition: cel_custom.c:56
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:527
static int ast_cel_track_event(enum ast_cel_event_type et)
Definition: cel.c:432
static int cel_backend_send_cb(void *obj, void *arg, int flags)
Definition: cel.c:561
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
channel birth
Definition: cel.h:45
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
struct ast_channel_snapshot_dialplan * dialplan
the list of registered channel types
Definition: channel.c:121
const ast_string_field appl
#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:911
an app ends
Definition: cel.h:55
static int cel_linkedid_ref(const char *linkedid)
Definition: cel.c:781
static int cel_track_app(const char *const_app)
Definition: cel.c:496
void ast_event_destroy(struct ast_event *event)
Destroy an event.
Definition: event.c:524
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Generic container type.
an app starts
Definition: cel.h:53
struct ast_channel_snapshot_peer * peer

◆ cel_snapshot_update_cb()

static void cel_snapshot_update_cb ( void *  data,
struct stasis_subscription sub,
struct stasis_message message 
)
static

Definition at line 994 of file cel.c.

References ARRAY_LEN, cel_channel_monitors, cel_filter_channel_snapshot(), ast_channel_snapshot_update::new_snapshot, ast_channel_snapshot_update::old_snapshot, stasis_message_data(), stasis_message_timestamp(), and update().

Referenced by create_routes().

996 {
998  size_t i;
999 
1001  return;
1002  }
1003 
1004  for (i = 0; i < ARRAY_LEN(cel_channel_monitors); ++i) {
1006  }
1007 }
cel_channel_snapshot_monitor cel_channel_monitors[]
Definition: cel.c:980
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static void update(int code_size, int y, int wi, int fi, int dq, int sr, int dqsez, struct g726_state *state_ptr)
Definition: codec_g726.c:367
Structure representing a change of snapshot of channel state.
const struct timeval * stasis_message_timestamp(const struct stasis_message *msg)
Get the time when a message was created.
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
static int cel_filter_channel_snapshot(struct ast_channel_snapshot *snapshot)
Definition: cel.c:986
struct ast_channel_snapshot * new_snapshot
struct ast_channel_snapshot * old_snapshot

◆ cel_track_app()

static int cel_track_app ( const char *  const_app)
static

Definition at line 496 of file cel.c.

References ao2_cleanup, ao2_find, ao2_global_obj_ref, app, ast_str_to_lower(), ast_strdupa, cel_linkedid_ref(), NULL, OBJ_SEARCH_KEY, and RAII_VAR.

Referenced by cel_report_event().

497 {
498  RAII_VAR(struct cel_config *, cfg, ao2_global_obj_ref(cel_configs), ao2_cleanup);
499  RAII_VAR(char *, app, NULL, ao2_cleanup);
500  char *app_lower;
501 
502  if (!cfg || !cfg->general) {
503  return 0;
504  }
505 
506  app_lower = ast_str_to_lower(ast_strdupa(const_app));
507  app = ao2_find(cfg->general->apps, app_lower, OBJ_SEARCH_KEY);
508  if (!app) {
509  return 0;
510  }
511 
512  return 1;
513 }
A container that holds all config-related information.
Definition: cel_custom.c:56
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define NULL
Definition: resample.c:96
#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:911
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static force_inline char * ast_str_to_lower(char *str)
Convert a string to all lower-case.
Definition: strings.h:1268
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static const char app[]
Definition: app_mysql.c:62

◆ check_retire_linkedid()

static void check_retire_linkedid ( struct ast_channel_snapshot snapshot,
const struct timeval *  event_time 
)
static

Definition at line 614 of file cel.c.

References ao2_cleanup, ao2_find, ao2_global_obj_ref, ao2_lock, ao2_ref, ao2_unlink, ao2_unlock, AST_CEL_LINKEDID_END, ast_log, ast_strlen_zero, cel_report_event(), cel_linkedid::count, ast_channel_snapshot_peer::linkedid, LOG_ERROR, NULL, OBJ_SEARCH_KEY, ast_channel_snapshot::peer, and RAII_VAR.

Referenced by cel_channel_linkedid_change(), and cel_channel_state_change().

615 {
616  RAII_VAR(struct ao2_container *, linkedids, ao2_global_obj_ref(cel_linkedids), ao2_cleanup);
617  struct cel_linkedid *lid;
618 
619  if (!linkedids || ast_strlen_zero(snapshot->peer->linkedid)) {
620  /* The CEL module is shutdown. Abort. */
621  return;
622  }
623 
624  ao2_lock(linkedids);
625 
626  lid = ao2_find(linkedids, (void *) snapshot->peer->linkedid, OBJ_SEARCH_KEY);
627  if (!lid) {
628  ao2_unlock(linkedids);
629 
630  /*
631  * The user may have done a reload to start tracking linkedids
632  * when a call was already in progress. This is an unusual kind
633  * of change to make after starting Asterisk.
634  */
635  ast_log(LOG_ERROR, "Something weird happened, couldn't find linkedid %s\n",
636  snapshot->peer->linkedid);
637  return;
638  }
639 
640  if (!--lid->count) {
641  /* No channels use this linkedid anymore. */
642  ao2_unlink(linkedids, lid);
643  ao2_unlock(linkedids);
644 
645  cel_report_event(snapshot, AST_CEL_LINKEDID_END, event_time, NULL, NULL, NULL);
646  } else {
647  ao2_unlock(linkedids);
648  }
649  ao2_ref(lid, -1);
650 }
the last channel with the given linkedid is retired
Definition: cel.h:71
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
#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:911
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
#define LOG_ERROR
Definition: logger.h:285
#define ao2_unlink(container, obj)
Definition: astobj2.h:1598
unsigned int count
Definition: cel.c:164
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
static int cel_report_event(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)
Definition: cel.c:569
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Generic container type.
struct ast_channel_snapshot_peer * peer

◆ CONFIG_INFO_CORE()

CONFIG_INFO_CORE ( "cel"  ,
cel_cfg_info  ,
cel_configs  ,
cel_config_alloc  ,
files = ACO_FILES(&cel_conf),
pre_apply_config = cel_pre_apply_config 
)

◆ create_routes()

static int create_routes ( void  )
static

Create the Stasis message router and routes for CEL.

Definition at line 1500 of file cel.c.

References AO2_STRING_FIELD_CMP_FN, AO2_STRING_FIELD_HASH_FN, ast_attended_transfer_type(), ast_blind_transfer_type(), ast_call_pickup_type(), ast_channel_dial_type(), ast_channel_entered_bridge_type(), ast_channel_left_bridge_type(), ast_channel_snapshot_type(), ast_local_optimization_end_type(), ast_log, AST_LOG_ERROR, ast_parked_call_type(), AST_TASKPROCESSOR_HIGH_WATER_LEVEL, cel_attended_transfer_cb(), cel_blind_transfer_cb(), cel_bridge_enter_cb(), cel_bridge_leave_cb(), cel_dial_cb(), cel_generic_cb(), cel_generic_type(), cel_local_cb(), cel_parking_cb(), cel_pickup_cb(), cel_snapshot_update_cb(), NULL, stasis_message_router_add(), stasis_message_router_create, and stasis_message_router_set_congestion_limits().

Referenced by ast_cel_set_config(), load_module(), and reload_module().

1501 {
1502  int ret = 0;
1503 
1505  if (!cel_state_router) {
1506  return -1;
1507  }
1510 
1514  NULL);
1515 
1518  cel_dial_cb,
1519  NULL);
1520 
1524  NULL);
1525 
1529  NULL);
1530 
1534  NULL);
1535 
1537  cel_generic_type(),
1539  NULL);
1540 
1544  NULL);
1545 
1549  NULL);
1550 
1553  cel_pickup_cb,
1554  NULL);
1555 
1558  cel_local_cb,
1559  NULL);
1560 
1561  if (ret) {
1562  ast_log(AST_LOG_ERROR, "Failed to register for Stasis messages\n");
1563  }
1564 
1565  return ret;
1566 }
struct stasis_message_type * ast_blind_transfer_type(void)
Message type for ast_blind_transfer_message.
static void cel_parking_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: cel.c:1107
struct stasis_message_type * ast_channel_entered_bridge_type(void)
Message type for channel enter bridge blob messages.
int stasis_message_router_add(struct stasis_message_router *router, struct stasis_message_type *message_type, stasis_subscription_cb callback, void *data)
Add a route to a message router.
static void cel_dial_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: cel.c:1229
struct stasis_message_type * ast_channel_left_bridge_type(void)
Message type for channel leave bridge blob messages.
static void cel_blind_transfer_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: cel.c:1279
static void cel_snapshot_update_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: cel.c:994
struct stasis_message_type * ast_parked_call_type(void)
accessor for the parked call stasis message type
#define AST_TASKPROCESSOR_HIGH_WATER_LEVEL
Definition: taskprocessor.h:63
static struct stasis_topic * cel_aggregation_topic
Definition: cel.c:120
static void cel_local_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: cel.c:1392
#define NULL
Definition: resample.c:96
static void cel_attended_transfer_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: cel.c:1305
#define ast_log
Definition: astobj2.c:42
#define AST_LOG_ERROR
Definition: logger.h:290
static void cel_pickup_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: cel.c:1368
#define stasis_message_router_create(topic)
struct stasis_message_type * ast_local_optimization_end_type(void)
Message type for when a local channel optimization completes.
struct stasis_message_type * ast_call_pickup_type(void)
accessor for call pickup message type
static struct stasis_message_router * cel_state_router
Definition: cel.c:114
static void cel_bridge_leave_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: cel.c:1077
struct stasis_message_type * ast_attended_transfer_type(void)
Message type for ast_attended_transfer_message.
struct stasis_message_type * ast_channel_snapshot_type(void)
Message type for ast_channel_snapshot_update.
static void cel_bridge_enter_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: cel.c:1047
struct stasis_message_type * ast_channel_dial_type(void)
Message type for when a channel dials another channel.
struct stasis_message_type * cel_generic_type(void)
int stasis_message_router_set_congestion_limits(struct stasis_message_router *router, long low_water, long high_water)
Set the high and low alert water marks of the stasis message router.
static void cel_generic_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: cel.c:1256

◆ create_subscriptions()

static int create_subscriptions ( void  )
static

Create the Stasis subscriptions for CEL.

Definition at line 1454 of file cel.c.

References ast_bridge_topic_all(), ast_cel_topic(), ast_channel_topic_all(), ast_parking_topic(), stasis_forward_all(), and stasis_topic_create().

Referenced by load_module().

1455 {
1456  cel_aggregation_topic = stasis_topic_create("cel:aggregator");
1457  if (!cel_aggregation_topic) {
1458  return -1;
1459  }
1460 
1461  cel_topic = stasis_topic_create("cel:misc");
1462  if (!cel_topic) {
1463  return -1;
1464  }
1465 
1469  if (!cel_channel_forwarder) {
1470  return -1;
1471  }
1472 
1476  if (!cel_bridge_forwarder) {
1477  return -1;
1478  }
1479 
1483  if (!cel_parking_forwarder) {
1484  return -1;
1485  }
1486 
1488  ast_cel_topic(),
1490  if (!cel_cel_forwarder) {
1491  return -1;
1492  }
1493 
1494  return 0;
1495 }
static struct stasis_forward * cel_parking_forwarder
Definition: cel.c:129
static struct stasis_topic * cel_aggregation_topic
Definition: cel.c:120
static struct stasis_forward * cel_channel_forwarder
Definition: cel.c:123
struct stasis_topic * ast_channel_topic_all(void)
A topic which publishes the events for all channels.
static struct stasis_forward * cel_bridge_forwarder
Definition: cel.c:126
struct stasis_topic * stasis_topic_create(const char *name)
Create a new topic.
Definition: stasis.c:618
struct stasis_topic * ast_cel_topic(void)
Get the CEL topic.
Definition: cel.c:1685
static struct stasis_topic * cel_topic
Definition: cel.c:117
struct stasis_topic * ast_bridge_topic_all(void)
A topic which publishes the events for all bridges.
struct stasis_topic * ast_parking_topic(void)
accessor for the parking stasis topic
Definition: parking.c:67
static struct stasis_forward * cel_cel_forwarder
Definition: cel.c:132
struct stasis_forward * stasis_forward_all(struct stasis_topic *from_topic, struct stasis_topic *to_topic)
Create a subscription which forwards all messages from one topic to another.
Definition: stasis.c:1578

◆ destroy_routes()

static void destroy_routes ( void  )
static

Definition at line 1416 of file cel.c.

References NULL, and stasis_message_router_unsubscribe_and_join().

Referenced by ast_cel_set_config(), reload_module(), and unload_module().

1417 {
1420 }
void stasis_message_router_unsubscribe_and_join(struct stasis_message_router *router)
Unsubscribe the router from the upstream topic, blocking until the final message has been processed...
#define NULL
Definition: resample.c:96
static struct stasis_message_router * cel_state_router
Definition: cel.c:114

◆ destroy_subscriptions()

static void destroy_subscriptions ( void  )
static

Definition at line 1422 of file cel.c.

References ao2_cleanup, NULL, and stasis_forward_cancel().

Referenced by unload_module().

1423 {
1427  cel_topic = NULL;
1428 
1433 }
static struct stasis_forward * cel_parking_forwarder
Definition: cel.c:129
static struct stasis_topic * cel_aggregation_topic
Definition: cel.c:120
static struct stasis_forward * cel_channel_forwarder
Definition: cel.c:123
#define NULL
Definition: resample.c:96
static struct stasis_forward * cel_bridge_forwarder
Definition: cel.c:126
static struct stasis_topic * cel_topic
Definition: cel.c:117
struct stasis_forward * stasis_forward_cancel(struct stasis_forward *forward)
Definition: stasis.c:1548
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static struct stasis_forward * cel_cel_forwarder
Definition: cel.c:132

◆ events_handler()

static int events_handler ( const struct aco_option opt,
struct ast_variable var,
void *  obj 
)
static

Definition at line 443 of file cel.c.

References AST_CEL_ALL, AST_CEL_INVALID_VALUE, ast_cel_str_to_event_type(), ast_strdupa, ast_strip(), ast_strlen_zero, events, ast_cel_general_config::events, strsep(), and ast_variable::value.

Referenced by load_module().

444 {
445  struct ast_cel_general_config *cfg = obj;
446  char *events = ast_strdupa(var->value);
447  char *cur_event;
448 
449  while ((cur_event = strsep(&events, ","))) {
450  enum ast_cel_event_type event_type;
451 
452  cur_event = ast_strip(cur_event);
453  if (ast_strlen_zero(cur_event)) {
454  continue;
455  }
456 
457  event_type = ast_cel_str_to_event_type(cur_event);
458 
459  if (event_type == AST_CEL_ALL) {
460  /* All events */
461  cfg->events = (int64_t) -1;
462  } else if (event_type == AST_CEL_INVALID_VALUE) {
463  return -1;
464  } else {
465  cfg->events |= ((int64_t) 1 << event_type);
466  }
467  }
468 
469  return 0;
470 }
enum ast_cel_event_type ast_cel_str_to_event_type(const char *name)
Get the event type from a string.
Definition: cel.c:418
static const struct adsi_event events[]
Definition: app_adsiprog.c:85
int64_t events
Definition: cel.h:210
#define ast_strlen_zero(foo)
Definition: strings.h:52
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:219
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
A structure to hold CEL global configuration options.
Definition: cel.h:205
char * strsep(char **str, const char *delims)
ast_cel_event_type
CEL event types.
Definition: cel.h:41

◆ get_blob_variable()

static const char* get_blob_variable ( struct ast_multi_channel_blob blob,
const char *  varname 
)
static

Definition at line 880 of file cel.c.

References ast_json_object_get(), ast_json_string_get(), ast_multi_channel_blob_get_json(), and NULL.

Referenced by cel_dial_cb(), is_valid_dialstatus(), and save_dialstatus().

881 {
882  struct ast_json *json = ast_multi_channel_blob_get_json(blob);
883  if (!json) {
884  return NULL;
885  }
886 
887  json = ast_json_object_get(json, varname);
888  if (!json) {
889  return NULL;
890  }
891 
892  return ast_json_string_get(json);
893 }
#define NULL
Definition: resample.c:96
struct ast_json * ast_multi_channel_blob_get_json(struct ast_multi_channel_blob *obj)
Retrieve the JSON blob from a ast_multi_channel_blob. Returned ast_json is still owned by obj...
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
Definition: json.c:273
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
Definition: json.c:397
Abstract JSON element (object, array, string, int, ...).

◆ get_dialstatus()

static struct cel_dialstatus* get_dialstatus ( const char *  uniqueid)
static

Definition at line 868 of file cel.c.

References ao2_find, ao2_global_obj_ref, ao2_ref, cel_dialstatus::dialstatus, NULL, OBJ_SEARCH_KEY, and OBJ_UNLINK.

Referenced by cel_channel_state_change().

869 {
870  struct ao2_container *dial_statuses = ao2_global_obj_ref(cel_dialstatus_store);
871  struct cel_dialstatus *dialstatus = NULL;
872 
873  if (dial_statuses) {
874  dialstatus = ao2_find(dial_statuses, uniqueid, OBJ_SEARCH_KEY | OBJ_UNLINK);
875  ao2_ref(dial_statuses, -1);
876  }
877  return dialstatus;
878 }
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define NULL
Definition: resample.c:96
char dialstatus[0]
Definition: cel.c:176
#define ao2_ref(o, delta)
Definition: astobj2.h:464
char uniqueid[AST_MAX_UNIQUEID]
Definition: cel.c:174
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
Generic container type.

◆ handle_cli_status()

static char* handle_cli_status ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 353 of file cel.c.

References ao2_cleanup, ao2_global_obj_ref, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, app, ast_cli_args::argc, ast_cel_check_enabled(), ast_cel_get_type_name(), ast_cli(), CLI_GENERATE, CLI_HANDLER, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, name, cel_backend::name, NULL, RAII_VAR, and ast_cli_entry::usage.

354 {
355  unsigned int i;
356  RAII_VAR(struct cel_config *, cfg, ao2_global_obj_ref(cel_configs), ao2_cleanup);
357  RAII_VAR(struct ao2_container *, backends, ao2_global_obj_ref(cel_backends), ao2_cleanup);
358  struct ao2_iterator iter;
359  char *app;
360 
361  switch (cmd) {
362  case CLI_INIT:
363  e->command = "cel show status";
364  e->usage =
365  "Usage: cel show status\n"
366  " Displays the Channel Event Logging system status.\n";
367  return NULL;
368  case CLI_GENERATE:
369  return NULL;
370  case CLI_HANDLER:
371  break;
372  }
373 
374  if (a->argc > 3) {
375  return CLI_SHOWUSAGE;
376  }
377 
378  ast_cli(a->fd, "CEL Logging: %s\n", ast_cel_check_enabled() ? "Enabled" : "Disabled");
379 
380  if (!cfg || !cfg->general || !cfg->general->enable) {
381  return CLI_SUCCESS;
382  }
383 
384  for (i = 0; i < (sizeof(cfg->general->events) * 8); i++) {
385  const char *name;
386 
387  if (!(cfg->general->events & ((int64_t) 1 << i))) {
388  continue;
389  }
390 
391  name = ast_cel_get_type_name(i);
392  if (strcasecmp(name, "Unknown")) {
393  ast_cli(a->fd, "CEL Tracking Event: %s\n", name);
394  }
395  }
396 
397  iter = ao2_iterator_init(cfg->general->apps, 0);
398  for (; (app = ao2_iterator_next(&iter)); ao2_ref(app, -1)) {
399  ast_cli(a->fd, "CEL Tracking Application: %s\n", app);
400  }
401  ao2_iterator_destroy(&iter);
402 
403  if (backends) {
404  struct cel_backend *backend;
405 
406  iter = ao2_iterator_init(backends, 0);
407  for (; (backend = ao2_iterator_next(&iter)); ao2_ref(backend, -1)) {
408  ast_cli(a->fd, "CEL Event Subscriber: %s\n", backend->name);
409  }
410  ao2_iterator_destroy(&iter);
411  }
412 
413  return CLI_SUCCESS;
414 }
A container that holds all config-related information.
Definition: cel_custom.c:56
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
the list of registered channel types
Definition: channel.c:121
#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:911
const int fd
Definition: cli.h:159
unsigned int ast_cel_check_enabled(void)
Hashing function for cel_backend.
Definition: cel.c:343
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
static const char name[]
Definition: cdr_mysql.c:74
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Generic container type.
static const char app[]
Definition: app_mysql.c:62
char name[0]
Definition: cel.c:328
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
const char * ast_cel_get_type_name(enum ast_cel_event_type type)
Get the name of a CEL event type.
Definition: cel.c:491

◆ is_valid_dialstatus()

static int is_valid_dialstatus ( struct ast_multi_channel_blob blob)
static

Definition at line 1200 of file cel.c.

References ast_strlen_zero, cel_dialstatus::dialstatus, and get_blob_variable().

Referenced by cel_dial_cb().

1201 {
1202  const char *dialstatus = get_blob_variable(blob, "dialstatus");
1203  int res = 0;
1204 
1205  if (ast_strlen_zero(dialstatus)) {
1206  res = 0;
1207  } else if (!strcasecmp(dialstatus, "CHANUNAVAIL")) {
1208  res = 1;
1209  } else if (!strcasecmp(dialstatus, "CONGESTION")) {
1210  res = 1;
1211  } else if (!strcasecmp(dialstatus, "NOANSWER")) {
1212  res = 1;
1213  } else if (!strcasecmp(dialstatus, "BUSY")) {
1214  res = 1;
1215  } else if (!strcasecmp(dialstatus, "ANSWER")) {
1216  res = 1;
1217  } else if (!strcasecmp(dialstatus, "CANCEL")) {
1218  res = 1;
1219  } else if (!strcasecmp(dialstatus, "DONTCALL")) {
1220  res = 1;
1221  } else if (!strcasecmp(dialstatus, "TORTURE")) {
1222  res = 1;
1223  } else if (!strcasecmp(dialstatus, "INVALIDARGS")) {
1224  res = 1;
1225  }
1226  return res;
1227 }
#define ast_strlen_zero(foo)
Definition: strings.h:52
static const char * get_blob_variable(struct ast_multi_channel_blob *blob, const char *varname)
Definition: cel.c:880

◆ load_module()

static int load_module ( void  )
static

Definition at line 1571 of file cel.c.

References ACO_EXACT, aco_info_init(), aco_option_register, aco_option_register_custom, aco_process_config(), aco_set_defaults(), AO2_ALLOC_OPT_LOCK_MUTEX, ao2_cleanup, ao2_container_alloc_hash, ao2_global_obj_replace_unref, ao2_ref, apps_handler(), ast_cel_check_enabled(), ast_cli_register, ast_log, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, BACKEND_BUCKETS, cel_config_alloc(), cel_generic_type(), container, create_routes(), create_subscriptions(), date_format, events_handler(), FLDSET, cel_config::general, LOG_NOTICE, NULL, NUM_APP_BUCKETS, NUM_DIALSTATUS_BUCKETS, OPT_BOOL_T, OPT_STRINGFIELD_T, STASIS_MESSAGE_TYPE_INIT, and STRFLDSET.

Referenced by ast_cel_backend_register().

1572 {
1573  struct ao2_container *container;
1574 
1576  NUM_APP_BUCKETS, cel_linkedid_hash_fn, NULL, cel_linkedid_cmp_fn);
1577  ao2_global_obj_replace_unref(cel_linkedids, container);
1578  ao2_cleanup(container);
1579  if (!container) {
1580  return AST_MODULE_LOAD_FAILURE;
1581  }
1582 
1584  NUM_DIALSTATUS_BUCKETS, cel_dialstatus_hash_fn, NULL, cel_dialstatus_cmp_fn);
1585  ao2_global_obj_replace_unref(cel_dialstatus_store, container);
1586  ao2_cleanup(container);
1587  if (!container) {
1588  return AST_MODULE_LOAD_FAILURE;
1589  }
1590 
1592  return AST_MODULE_LOAD_FAILURE;
1593  }
1594 
1595  if (ast_cli_register(&cli_status)) {
1596  return AST_MODULE_LOAD_FAILURE;
1597  }
1598 
1600  cel_backend_hash_fn, NULL, cel_backend_cmp_fn);
1601  ao2_global_obj_replace_unref(cel_backends, container);
1602  ao2_cleanup(container);
1603  if (!container) {
1604  return AST_MODULE_LOAD_FAILURE;
1605  }
1606 
1607  if (aco_info_init(&cel_cfg_info)) {
1608  return AST_MODULE_LOAD_FAILURE;
1609  }
1610 
1611  aco_option_register(&cel_cfg_info, "enable", ACO_EXACT, general_options, "no", OPT_BOOL_T, 1, FLDSET(struct ast_cel_general_config, enable));
1613  aco_option_register_custom(&cel_cfg_info, "apps", ACO_EXACT, general_options, "", apps_handler, 0);
1614  aco_option_register_custom(&cel_cfg_info, "events", ACO_EXACT, general_options, "", events_handler, 0);
1615 
1616  if (aco_process_config(&cel_cfg_info, 0)) {
1617  struct cel_config *cel_cfg = cel_config_alloc();
1618 
1619  if (!cel_cfg) {
1620  return AST_MODULE_LOAD_FAILURE;
1621  }
1622 
1623  /* We couldn't process the configuration so create a default config. */
1624  if (!aco_set_defaults(&general_option, "general", cel_cfg->general)) {
1625  ast_log(LOG_NOTICE, "Failed to process CEL configuration; using defaults\n");
1626  ao2_global_obj_replace_unref(cel_configs, cel_cfg);
1627  }
1628  ao2_ref(cel_cfg, -1);
1629  }
1630 
1631  if (create_subscriptions()) {
1632  return AST_MODULE_LOAD_FAILURE;
1633  }
1634 
1635  if (ast_cel_check_enabled() && create_routes()) {
1636  return AST_MODULE_LOAD_FAILURE;
1637  }
1638 
1639  return AST_MODULE_LOAD_SUCCESS;
1640 }
#define NUM_APP_BUCKETS
Number of buckets for the appset container.
Definition: cel.c:155
A container that holds all config-related information.
Definition: cel_custom.c:56
static struct ast_cli_entry cli_status
Definition: cel.c:416
#define aco_option_register_custom(info, name, matchtype, types, default_val, handler, flags)
Register a config option.
static struct aco_type general_option
An aco_type structure to link the "general" category to the ast_cel_general_config type...
Definition: cel.c:241
#define BACKEND_BUCKETS
Definition: cel.c:141
#define STASIS_MESSAGE_TYPE_INIT(name)
Boiler-plate messaging macro for initializing message types.
Definition: stasis.h:1501
#define aco_option_register(info, name, matchtype, types, default_val, opt_type, flags,...)
Register a config option.
static int events_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
Definition: cel.c:443
static char date_format[6]
Definition: chan_skinny.c:209
enum aco_process_status aco_process_config(struct aco_info *info, int reload)
Process a config info via the options registered with an aco_info.
#define NULL
Definition: resample.c:96
#define ast_cli_register(e)
Registers a command or an array of commands.
Definition: cli.h:256
#define ast_log
Definition: astobj2.c:42
#define FLDSET(type,...)
Convert a struct and list of fields to an argument list of field offsets.
int aco_info_init(struct aco_info *info)
Initialize an aco_info structure.
unsigned int ast_cel_check_enabled(void)
Hashing function for cel_backend.
Definition: cel.c:343
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ao2_container * container
Definition: res_fax.c:502
static void * cel_config_alloc(void)
Definition: cel.c:224
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Definition: astobj2.h:1310
struct ast_cel_general_config * general
Definition: cel.c:210
static int apps_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
Definition: cel.c:472
Type for default option handler for bools (ast_true/ast_false)
#define LOG_NOTICE
Definition: logger.h:263
static int create_routes(void)
Create the Stasis message router and routes for CEL.
Definition: cel.c:1500
int aco_set_defaults(struct aco_type *type, const char *category, void *obj)
Set all default options of obj.
Module could not be loaded properly.
Definition: module.h:102
#define STRFLDSET(type,...)
Convert a struct and a list of stringfield fields to an argument list of field offsets.
A structure to hold CEL global configuration options.
Definition: cel.h:205
#define ao2_global_obj_replace_unref(holder, obj)
Definition: astobj2.h:908
#define NUM_DIALSTATUS_BUCKETS
Number of buckets for the dialstatus container.
Definition: cel.c:160
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Type for default option handler for stringfields.
Generic container type.
struct stasis_message_type * cel_generic_type(void)
static struct aco_type * general_options[]
Definition: cel.c:300
static int create_subscriptions(void)
Create the Stasis subscriptions for CEL.
Definition: cel.c:1454

◆ reload_module()

static int reload_module ( void  )
static

Definition at line 1642 of file cel.c.

References aco_process_config(), ACO_PROCESS_ERROR, ast_cel_check_enabled(), ast_verb, create_routes(), destroy_routes(), and is_enabled().

Referenced by ast_cel_backend_register().

1643 {
1644  unsigned int was_enabled = ast_cel_check_enabled();
1645  unsigned int is_enabled;
1646 
1647  if (aco_process_config(&cel_cfg_info, 1) == ACO_PROCESS_ERROR) {
1648  return -1;
1649  }
1650 
1651  is_enabled = ast_cel_check_enabled();
1652 
1653  if (!was_enabled && is_enabled) {
1654  if (create_routes()) {
1655  return -1;
1656  }
1657  } else if (was_enabled && !is_enabled) {
1658  destroy_routes();
1659  }
1660 
1661  ast_verb(3, "CEL logging %sabled.\n", is_enabled ? "en" : "dis");
1662 
1663  return 0;
1664 }
enum aco_process_status aco_process_config(struct aco_info *info, int reload)
Process a config info via the options registered with an aco_info.
#define ast_verb(level,...)
Definition: logger.h:463
unsigned int ast_cel_check_enabled(void)
Hashing function for cel_backend.
Definition: cel.c:343
Their was an error and no changes were applied.
static int create_routes(void)
Create the Stasis message router and routes for CEL.
Definition: cel.c:1500
static int is_enabled(void)
Helper function to check if module is enabled.
Definition: res_ari.c:159
static void destroy_routes(void)
Definition: cel.c:1416

◆ save_dialstatus()

static void save_dialstatus ( struct ast_multi_channel_blob blob,
struct ast_channel_snapshot snapshot 
)
static

Definition at line 1156 of file cel.c.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_cleanup, ao2_find, ao2_global_obj_ref, ao2_link, ao2_ref, ao2_unlink, ast_copy_string(), ast_strlen_zero, ast_channel_snapshot::base, cel_dialstatus::dialstatus, get_blob_variable(), NULL, OBJ_SEARCH_KEY, ast_channel_snapshot_base::uniqueid, and cel_dialstatus::uniqueid.

Referenced by cel_dial_cb().

1157 {
1158  struct ao2_container *dial_statuses = ao2_global_obj_ref(cel_dialstatus_store);
1159  const char *dialstatus_string = get_blob_variable(blob, "dialstatus");
1160  struct cel_dialstatus *dialstatus;
1161  size_t dialstatus_string_len;
1162 
1163  if (!dial_statuses || ast_strlen_zero(dialstatus_string)) {
1164  ao2_cleanup(dial_statuses);
1165  return;
1166  }
1167 
1168  dialstatus = ao2_find(dial_statuses, snapshot->base->uniqueid, OBJ_SEARCH_KEY);
1169  if (dialstatus) {
1170  if (!strcasecmp(dialstatus_string, "ANSWER") && strcasecmp(dialstatus->dialstatus, "ANSWER")) {
1171  /* In the case of an answer after we already have a dial status we give
1172  * priority to the answer since the call was, well, answered. In the case of
1173  * failure dial status results we simply let the first failure be the status.
1174  */
1175  ao2_unlink(dial_statuses, dialstatus);
1176  ao2_ref(dialstatus, -1);
1177  } else {
1178  ao2_ref(dialstatus, -1);
1179  ao2_ref(dial_statuses, -1);
1180  return;
1181  }
1182  }
1183 
1184  dialstatus_string_len = strlen(dialstatus_string) + 1;
1185  dialstatus = ao2_alloc_options(sizeof(*dialstatus) + dialstatus_string_len, NULL,
1187  if (!dialstatus) {
1188  ao2_ref(dial_statuses, -1);
1189  return;
1190  }
1191 
1192  ast_copy_string(dialstatus->uniqueid, snapshot->base->uniqueid, sizeof(dialstatus->uniqueid));
1193  ast_copy_string(dialstatus->dialstatus, dialstatus_string, dialstatus_string_len);
1194 
1195  ao2_link(dial_statuses, dialstatus);
1196  ao2_ref(dialstatus, -1);
1197  ao2_ref(dial_statuses, -1);
1198 }
struct ast_channel_snapshot_base * base
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
const ast_string_field uniqueid
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:406
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
char dialstatus[0]
Definition: cel.c:176
#define ao2_ref(o, delta)
Definition: astobj2.h:464
char uniqueid[AST_MAX_UNIQUEID]
Definition: cel.c:174
#define ao2_unlink(container, obj)
Definition: astobj2.h:1598
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
static const char * get_blob_variable(struct ast_multi_channel_blob *blob, const char *varname)
Definition: cel.c:880
Generic container type.
#define ao2_link(container, obj)
Definition: astobj2.h:1549

◆ STASIS_MESSAGE_TYPE_DEFN()

STASIS_MESSAGE_TYPE_DEFN ( cel_generic_type  )

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 1435 of file cel.c.

References aco_info_destroy(), ao2_global_obj_release, ast_cli_unregister(), cel_generic_type(), destroy_routes(), destroy_subscriptions(), and STASIS_MESSAGE_TYPE_CLEANUP.

Referenced by ast_cel_backend_register().

1436 {
1437  destroy_routes();
1440 
1442  aco_info_destroy(&cel_cfg_info);
1443  ao2_global_obj_release(cel_configs);
1444  ao2_global_obj_release(cel_dialstatus_store);
1445  ao2_global_obj_release(cel_linkedids);
1446  ao2_global_obj_release(cel_backends);
1447 
1448  return 0;
1449 }
static struct ast_cli_entry cli_status
Definition: cel.c:416
int ast_cli_unregister(struct ast_cli_entry *e)
Unregisters a command or an array of commands.
Definition: main/cli.c:2397
#define STASIS_MESSAGE_TYPE_CLEANUP(name)
Boiler-plate messaging macro for cleaning up message types.
Definition: stasis.h:1523
static void destroy_subscriptions(void)
Definition: cel.c:1422
void aco_info_destroy(struct aco_info *info)
Destroy an initialized aco_info struct.
#define ao2_global_obj_release(holder)
Definition: astobj2.h:865
static void destroy_routes(void)
Definition: cel.c:1416
struct stasis_message_type * cel_generic_type(void)

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "CEL Engine" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload_module, .load_pri = AST_MODPRI_CORE, .requires = "extconfig", }
static

Definition at line 1770 of file cel.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 1770 of file cel.c.

◆ cel_aggregation_topic

struct stasis_topic* cel_aggregation_topic
static

Aggregation topic for all topics CEL needs to know about

Definition at line 120 of file cel.c.

◆ cel_bridge_forwarder

struct stasis_forward* cel_bridge_forwarder
static

Subscription for forwarding the channel caching topic

Definition at line 126 of file cel.c.

◆ cel_cel_forwarder

struct stasis_forward* cel_cel_forwarder
static

Subscription for forwarding the CEL-specific topic

Definition at line 132 of file cel.c.

◆ cel_channel_forwarder

struct stasis_forward* cel_channel_forwarder
static

Subscription for forwarding the channel caching topic

Definition at line 123 of file cel.c.

◆ cel_channel_monitors

cel_channel_snapshot_monitor cel_channel_monitors[]
Initial value:
= {
}
static void cel_channel_linkedid_change(struct ast_channel_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot, const struct timeval *event_time)
Definition: cel.c:936
static void cel_channel_state_change(struct ast_channel_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot, const struct timeval *event_time)
Handle channel state changes.
Definition: cel.c:896
static void cel_channel_app_change(struct ast_channel_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot, const struct timeval *event_time)
Definition: cel.c:955

Definition at line 980 of file cel.c.

Referenced by cel_snapshot_update_cb().

◆ cel_conf

struct aco_file cel_conf
static
Initial value:
= {
.filename = "cel.conf",
}
static struct aco_type general_option
An aco_type structure to link the "general" category to the ast_cel_general_config type...
Definition: cel.c:241
#define ACO_TYPES(...)
A helper macro to ensure that aco_info types always have a sentinel.
static struct aco_type ignore_option
Definition: cel.c:256

The config file to be processed for the module.

Definition at line 264 of file cel.c.

◆ cel_event_types

const char* const cel_event_types[CEL_MAX_EVENT_IDS]
static

Map of ast_cel_event_type to strings.

Definition at line 305 of file cel.c.

Referenced by ast_cel_get_type_name(), and ast_cel_str_to_event_type().

◆ cel_parking_forwarder

struct stasis_forward* cel_parking_forwarder
static

Subscription for forwarding the parking topic

Definition at line 129 of file cel.c.

◆ cel_state_router

struct stasis_message_router* cel_state_router
static

Message router for state that CEL needs to know about

Definition at line 114 of file cel.c.

◆ cel_topic

struct stasis_topic* cel_topic
static

Topic for CEL-specific messages

Definition at line 117 of file cel.c.

Referenced by ast_cel_topic().

◆ cli_status

struct ast_cli_entry cli_status = { .handler = handle_cli_status , .summary = "Display the CEL status" ,}
static

Definition at line 416 of file cel.c.

◆ fabricated_channel_datastore

const struct ast_datastore_info fabricated_channel_datastore
static
Initial value:
= {
.type = "CEL fabricated channel",
.destroy = ast_free_ptr,
}
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1771

Definition at line 655 of file cel.c.

◆ general_option

struct aco_type general_option
static

An aco_type structure to link the "general" category to the ast_cel_general_config type.

Definition at line 241 of file cel.c.

◆ general_options

struct aco_type* general_options[] = ACO_TYPES(&general_option)
static

Definition at line 300 of file cel.c.

◆ ignore_categories

const char* ignore_categories[]
static
Initial value:
= {
"manager",
"radius",
}
#define NULL
Definition: resample.c:96

Config sections used by existing modules. Do not add to this list.

Definition at line 250 of file cel.c.

◆ ignore_option

struct aco_type ignore_option
static

Definition at line 256 of file cel.c.