Asterisk - The Open Source Telephony Project GIT-master-0a46be9
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_configs)
 
static AO2_GLOBAL_OBJ_STATIC (cel_dialstatus_store)
 
static AO2_GLOBAL_OBJ_STATIC (cel_linkedids)
 
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_publish_user_event (struct ast_channel *chan, const char *event, const char *extra)
 Publish a CEL user event. More...
 
void ast_cel_set_config (struct ast_cel_general_config *config)
 Set the current CEL configuration. More...
 
enum ast_cel_event_type ast_cel_str_to_event_type (const char *name)
 Get the event type from a string. More...
 
struct stasis_topicast_cel_topic (void)
 Get the CEL topic. More...
 
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_optimization_begin_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void cel_local_optimization_cb_helper (void *data, struct stasis_subscription *sub, struct stasis_message *message, enum ast_cel_event_type event_type)
 
static void cel_local_optimization_end_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 = AST_BUILDOPT_SUM, .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 []
 Handlers for channel snapshot changes. More...
 
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 160 of file cel.c.

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

◆ NUM_APP_BUCKETS

#define NUM_APP_BUCKETS   97

Number of buckets for the appset container.

Definition at line 174 of file cel.c.

◆ NUM_DIALSTATUS_BUCKETS

#define NUM_DIALSTATUS_BUCKETS   251

Number of buckets for the dialstatus container.

Definition at line 179 of file cel.c.

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

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1839 of file cel.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1839 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_configs  )
static

◆ AO2_GLOBAL_OBJ_STATIC() [3/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() [4/4]

static AO2_GLOBAL_OBJ_STATIC ( cel_linkedids  )
static

Container of channel references to a linkedid for CEL purposes.

◆ apps_handler()

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

Definition at line 495 of file cel.c.

496{
497 struct ast_cel_general_config *cfg = obj;
498 char *apps = ast_strdupa(var->value);
499 char *cur_app;
500
501 while ((cur_app = strsep(&apps, ","))) {
502 cur_app = ast_strip(cur_app);
503 if (ast_strlen_zero(cur_app)) {
504 continue;
505 }
506
507 cur_app = ast_str_to_lower(cur_app);
508 ast_str_container_add(cfg->apps, cur_app);
509 }
510
511 return 0;
512}
#define var
Definition: ast_expr2f.c:605
char * strsep(char **str, const char *delims)
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
static force_inline char * ast_str_to_lower(char *str)
Convert a string to all lower-case.
Definition: strings.h:1321
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:223
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:205
Registered applications container.
Definition: pbx_app.c:68
A structure to hold CEL global configuration options.
Definition: cel.h:230
struct ao2_container * apps
Definition: cel.h:239

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

Referenced by load_module().

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

1810{
1812 struct cel_backend *backend;
1813
1814 if (!backends || ast_strlen_zero(name) || !backend_callback) {
1815 return -1;
1816 }
1817
1818 /* The backend object is immutable so it doesn't need a lock of its own. */
1819 backend = ao2_alloc_options(sizeof(*backend) + 1 + strlen(name), NULL,
1821 if (!backend) {
1822 return -1;
1823 }
1824 strcpy(backend->name, name);/* Safe */
1825 backend->callback = backend_callback;
1826
1827 ao2_link(backends, backend);
1828 ao2_ref(backend, -1);
1829 return 0;
1830}
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition: astobj2.h:367
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:404
static const char name[]
Definition: format_mp3.c:68
#define NULL
Definition: resample.c:96
Generic container type.
the list of registered channel types
Definition: channel.c:124
ast_cel_backend_cb callback
Definition: cel.c:350
char name[0]
Definition: cel.c:351
#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:978

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_cleanup, ao2_global_obj_ref, ao2_link, ao2_ref, ast_strlen_zero(), cel_backend::callback, cel_backend::name, name, NULL, and RAII_VAR.

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

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

1798{
1799 struct ao2_container *backends = ao2_global_obj_ref(cel_backends);
1800
1801 if (backends) {
1803 ao2_ref(backends, -1);
1804 }
1805
1806 return 0;
1807}
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1736
@ OBJ_NODATA
Definition: astobj2.h:1044
@ OBJ_UNLINK
Definition: astobj2.h:1039
@ OBJ_SEARCH_KEY
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1101

References ao2_find, ao2_global_obj_ref, ao2_ref, name, 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().

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

367{
368 unsigned int enabled;
369 struct cel_config *cfg = ao2_global_obj_ref(cel_configs);
370
371 enabled = (!cfg || !cfg->general) ? 0 : cfg->general->enable;
372 ao2_cleanup(cfg);
373 return enabled;
374}
static int enabled
Definition: dnsmgr.c:91
A container that holds all config-related information.
Definition: cel_custom.c:52
struct ast_cel_general_config * general
Definition: cel.c:229

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

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

543{
544 struct timeval eventtime = ast_tvnow();
545
546 return ast_cel_create_event_with_time(snapshot, event_type, &eventtime,
547 userdefevname, extra, peer);
548}
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:550
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159

References ast_cel_create_event_with_time(), and ast_tvnow().

Referenced by append_expected_event_snapshot().

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

553{
554 RAII_VAR(char *, extra_txt, NULL, ast_json_free);
555 if (extra) {
556 extra_txt = ast_json_dump_string(extra);
557 }
583}
struct ast_event * ast_event_new(enum ast_event_type event_type,...)
Create a new event.
Definition: event.c:403
@ AST_EVENT_IE_CEL_ACCTCODE
Channel Event AccountCode Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:205
@ AST_EVENT_IE_END
Definition: event_defs.h:70
@ AST_EVENT_IE_CEL_EXTRA
Channel Event extra data Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:259
@ AST_EVENT_IE_CEL_CONTEXT
Channel Event context name Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:175
@ AST_EVENT_IE_CEL_PEERACCT
Channel Event peeraccount Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:253
@ AST_EVENT_IE_CEL_CIDRDNIS
Channel Event CID RDNIS field Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:229
@ AST_EVENT_IE_CEL_EVENT_TIME
Channel Event Time (seconds) Used by: AST_EVENT_CEL Payload type: UINT.
Definition: event_defs.h:139
@ AST_EVENT_IE_CEL_CHANNAME
Channel Event channel name Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:181
@ AST_EVENT_IE_CEL_CIDANI
Channel Event CID ANI field Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:223
@ AST_EVENT_IE_CEL_CIDDNID
Channel Event CID dnid Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:235
@ AST_EVENT_IE_CEL_EXTEN
Channel Event extension name Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:169
@ AST_EVENT_IE_CEL_CIDNAME
Channel Event CID name Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:157
@ AST_EVENT_IE_CEL_AMAFLAGS
Channel Event AMA flags Used by: AST_EVENT_CEL Payload type: UINT.
Definition: event_defs.h:199
@ AST_EVENT_IE_CEL_USEREVENT_NAME
Channel Event User Event Name Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:151
@ AST_EVENT_IE_CEL_TENANTID
Channel Event TenantID Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:320
@ AST_EVENT_IE_CEL_LINKEDID
Channel Event LinkedID Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:247
@ AST_EVENT_IE_CEL_EVENT_TIME_USEC
Channel Event Time (micro-seconds) Used by: AST_EVENT_CEL Payload type: UINT.
Definition: event_defs.h:145
@ AST_EVENT_IE_CEL_EVENT_TYPE
Channel Event Type Used by: AST_EVENT_CEL Payload type: UINT.
Definition: event_defs.h:133
@ AST_EVENT_IE_CEL_UNIQUEID
Channel Event UniqueID Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:211
@ AST_EVENT_IE_CEL_APPNAME
Channel Event app name Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:187
@ AST_EVENT_IE_CEL_APPDATA
Channel Event app args/data Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:193
@ AST_EVENT_IE_CEL_PEER
Channel Event Peer – for Things involving multiple channels, like BRIDGE Used by: AST_EVENT_CEL Paylo...
Definition: event_defs.h:241
@ AST_EVENT_IE_CEL_CIDNUM
Channel Event CID num Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:163
@ AST_EVENT_IE_CEL_USERFIELD
Channel Event Userfield Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:217
@ AST_EVENT_CEL
Definition: event_defs.h:50
@ AST_EVENT_IE_PLTYPE_UINT
Definition: event_defs.h:333
@ AST_EVENT_IE_PLTYPE_STR
Definition: event_defs.h:335
void ast_json_free(void *p)
Asterisk's custom JSON allocator. Exposed for use by unit tests.
Definition: json.c:52
#define ast_json_dump_string(root)
Encode a JSON value to a compact string.
Definition: json.h:810
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
const ast_string_field tenantid
const ast_string_field accountcode
const ast_string_field userfield
const ast_string_field uniqueid
const ast_string_field name
const ast_string_field number
const ast_string_field rdnis
const ast_string_field ani
const ast_string_field name
const ast_string_field dnid
const ast_string_field data
const ast_string_field context
const ast_string_field exten
const ast_string_field appl
struct ast_channel_snapshot_dialplan * dialplan
struct ast_channel_snapshot_peer * peer
struct ast_channel_snapshot_base * base
struct ast_channel_snapshot_caller * caller

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_TENANTID, 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::tenantid, ast_channel_snapshot_base::uniqueid, and ast_channel_snapshot_base::userfield.

Referenced by ast_cel_create_event(), and cel_report_event().

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

685{
686 struct varshead *headp;
687 struct ast_var_t *newvariable;
688 const char *mixed_name;
689 char timebuf[30];
690 struct ast_channel *tchan;
691 struct ast_cel_event_record record = {
693 };
694 struct ast_datastore *datastore;
695 char *app_data;
696 RAII_VAR(struct cel_config *, cfg, ao2_global_obj_ref(cel_configs), ao2_cleanup);
697
698 if (!cfg || !cfg->general) {
699 return NULL;
700 }
701
702 /* do not call ast_channel_alloc because this is not really a real channel */
703 if (!(tchan = ast_dummy_channel_alloc())) {
704 return NULL;
705 }
706
707 headp = ast_channel_varshead(tchan);
708
709 /* first, get the variables from the event */
710 if (ast_cel_fill_record(event, &record)) {
711 ast_channel_unref(tchan);
712 return NULL;
713 }
714
715 /* next, fill the channel with their data */
716 mixed_name = (record.event_type == AST_CEL_USER_DEFINED)
717 ? record.user_defined_name : record.event_name;
718 if ((newvariable = ast_var_assign("eventtype", mixed_name))) {
719 AST_LIST_INSERT_HEAD(headp, newvariable, entries);
720 }
721
722 if (ast_strlen_zero(cfg->general->date_format)) {
723 snprintf(timebuf, sizeof(timebuf), "%ld.%06ld", (long) record.event_time.tv_sec,
724 (long) record.event_time.tv_usec);
725 } else {
726 struct ast_tm tm;
727 ast_localtime(&record.event_time, &tm, NULL);
728 ast_strftime(timebuf, sizeof(timebuf), cfg->general->date_format, &tm);
729 }
730
731 if ((newvariable = ast_var_assign("eventtime", timebuf))) {
732 AST_LIST_INSERT_HEAD(headp, newvariable, entries);
733 }
734
735 if ((newvariable = ast_var_assign("eventenum", record.event_name))) {
736 AST_LIST_INSERT_HEAD(headp, newvariable, entries);
737 }
738 if ((newvariable = ast_var_assign("userdeftype", record.user_defined_name))) {
739 AST_LIST_INSERT_HEAD(headp, newvariable, entries);
740 }
741 if ((newvariable = ast_var_assign("eventextra", record.extra))) {
742 AST_LIST_INSERT_HEAD(headp, newvariable, entries);
743 }
744
745 ast_channel_caller(tchan)->id.name.valid = 1;
747 ast_channel_caller(tchan)->id.number.valid = 1;
754
755 ast_channel_exten_set(tchan, record.extension);
756 ast_channel_context_set(tchan, record.context);
757 ast_channel_name_set(tchan, record.channel_name);
759 ast_channel_accountcode_set(tchan, record.account_code);
760 ast_channel_peeraccount_set(tchan, record.peer_account);
761 ast_channel_userfield_set(tchan, record.user_field);
762
763 if ((newvariable = ast_var_assign("BRIDGEPEER", record.peer))) {
764 AST_LIST_INSERT_HEAD(headp, newvariable, entries);
765 }
766
767 ast_channel_amaflags_set(tchan, record.amaflag);
768
769 /* We need to store an 'application name' and 'application
770 * data' on the channel for logging purposes, but the channel
771 * structure only provides a place to store pointers, and it
772 * expects these pointers to be pointing to data that does not
773 * need to be freed. This means that the channel's destructor
774 * does not attempt to free any storage that these pointers
775 * point to. However, we can't provide data in that form directly for
776 * these structure members. In order to ensure that these data
777 * elements have a lifetime that matches the channel's
778 * lifetime, we'll put them in a datastore attached to the
779 * channel, and set's the channel's pointers to point into the
780 * datastore. The datastore will then be automatically destroyed
781 * when the channel is destroyed.
782 */
783
785 ast_channel_unref(tchan);
786 return NULL;
787 }
788
789 if (!(app_data = ast_malloc(strlen(record.application_name) + strlen(record.application_data) + 2))) {
790 ast_datastore_free(datastore);
791 ast_channel_unref(tchan);
792 return NULL;
793 }
794
795 ast_channel_appl_set(tchan, strcpy(app_data, record.application_name));
796 ast_channel_data_set(tchan, strcpy(app_data + strlen(record.application_name) + 1,
797 record.application_data));
798
799 datastore->data = app_data;
800 ast_channel_datastore_add(tchan, datastore);
801
802 return tchan;
803}
if(!yyg->yy_init)
Definition: ast_expr2f.c:854
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
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:843
static const struct ast_datastore_info fabricated_channel_datastore
Definition: cel.c:679
@ AST_CEL_USER_DEFINED
a user-defined event, the event name field should be set
Definition: cel.h:69
#define AST_CEL_EVENT_RECORD_VERSION
struct ABI version
Definition: cel.h:149
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
void ast_channel_appl_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)
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2355
struct varshead * ast_channel_varshead(struct ast_channel *chan)
void ast_channel_data_set(struct ast_channel *chan, const char *value)
struct ast_party_redirecting * ast_channel_redirecting(struct ast_channel *chan)
struct ast_party_dialed * ast_channel_dialed(struct ast_channel *chan)
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:3008
void ast_channel_amaflags_set(struct ast_channel *chan, enum ama_flags value)
void ast_channel_context_set(struct ast_channel *chan, const char *value)
#define ast_dummy_channel_alloc()
Create a fake channel structure.
Definition: channel.h:1328
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
void ast_channel_name_set(struct ast_channel *chan, const char *value)
#define ast_var_assign(name, value)
Definition: chanvars.h:40
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:85
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:711
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
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
Helper struct for getting the fields out of a CEL event.
Definition: cel.h:144
const char * caller_id_dnid
Definition: cel.h:163
const char * application_data
Definition: cel.h:168
const char * account_code
Definition: cel.h:169
const char * caller_id_rdnis
Definition: cel.h:162
const char * extra
Definition: cel.h:177
const char * extension
Definition: cel.h:164
const char * caller_id_num
Definition: cel.h:160
const char * channel_name
Definition: cel.h:166
const char * linked_id
Definition: cel.h:172
const char * peer_account
Definition: cel.h:170
const char * peer
Definition: cel.h:176
enum ast_cel_event_type event_type
Definition: cel.h:155
const char * unique_id
Definition: cel.h:171
const char * user_defined_name
Definition: cel.h:158
const char * context
Definition: cel.h:165
const char * application_name
Definition: cel.h:167
struct timeval event_time
Definition: cel.h:156
uint32_t version
struct ABI version
Definition: cel.h:154
const char * user_field
Definition: cel.h:175
const char * caller_id_ani
Definition: cel.h:161
const char * caller_id_name
Definition: cel.h:159
const char * event_name
Definition: cel.h:157
Main Channel structure associated with a channel.
Structure for a data store object.
Definition: datastore.h:64
void * data
Definition: datastore.h:66
struct ast_party_id id
Caller party ID.
Definition: channel.h:422
struct ast_party_id ani
Automatic Number Identification (ANI)
Definition: channel.h:429
char * str
Subscriber phone number (Malloced)
Definition: channel.h:388
struct ast_party_dialed::@213 number
Dialed/Called number.
struct ast_party_name name
Subscriber name.
Definition: channel.h:342
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:344
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:281
char * str
Subscriber name (Malloced)
Definition: channel.h:266
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:299
char * str
Subscriber phone number (Malloced)
Definition: channel.h:293
struct ast_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
Definition: channel.h:529
Definition: astman.c:222

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

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

844{
846 ast_log(LOG_ERROR, "Module ABI mismatch for ast_cel_event_record. "
847 "Please ensure all modules were compiled for "
848 "this version of Asterisk.\n");
849 return -1;
850 }
851
853
856
858
879
880 return 0;
881}
#define ast_log
Definition: astobj2.c:42
const char * ast_cel_get_type_name(enum ast_cel_event_type type)
Get the name of a CEL event type.
Definition: cel.c:514
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:294
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:303
#define LOG_ERROR
const char * tenant_id
Definition: cel.h:173

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_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_TENANTID, 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::tenant_id, 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().

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

208{
210
211 if (!(cfg = ao2_alloc(sizeof(*cfg), cel_general_config_dtor))) {
212 return NULL;
213 }
214
215 if (ast_string_field_init(cfg, 64)) {
216 return NULL;
217 }
218
219 if (!(cfg->apps = ast_str_container_alloc(NUM_APP_BUCKETS))) {
220 return NULL;
221 }
222
223 ao2_ref(cfg, +1);
224 return cfg;
225}
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
static void cel_general_config_dtor(void *obj)
Destructor for cel_config.
Definition: cel.c:199
#define NUM_APP_BUCKETS
Number of buckets for the appset container.
Definition: cel.c:174
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
#define ast_str_container_alloc(buckets)
Allocates a hash container for bare strings.
Definition: strings.h:1365

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

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

1760{
1761 RAII_VAR(struct cel_config *, mod_cfg, ao2_global_obj_ref(cel_configs), ao2_cleanup);
1762
1763 if (!mod_cfg || !mod_cfg->general) {
1764 return NULL;
1765 }
1766
1767 ao2_ref(mod_cfg->general, +1);
1768 return mod_cfg->general;
1769}

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

Referenced by test_cel_init_cb().

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

515{
516 return S_OR(cel_event_types[type], "Unknown");
517}
static const char *const cel_event_types[CEL_MAX_EVENT_IDS]
Map of ast_cel_event_type to strings.
Definition: cel.c:324
static const char type[]
Definition: chan_ooh323.c:109

References cel_event_types, S_OR, and type.

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

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

1738{
1739 struct ast_json *cel_blob;
1740 struct stasis_message *message;
1741
1742 cel_blob = ast_json_pack("{s: i, s: o}",
1743 "event_type", event_type,
1744 "event_details", ast_json_ref(blob));
1745
1747 if (message) {
1749 }
1751 ast_json_unref(cel_blob);
1752}
struct stasis_topic * ast_cel_topic(void)
Get the CEL topic.
Definition: cel.c:1754
struct stasis_message_type * cel_generic_type(void)
const char * ast_channel_uniqueid(const struct ast_channel *chan)
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.
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:612
struct ast_json * ast_json_ref(struct ast_json *value)
Increase refcount on value.
Definition: json.c:67
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic's subscribers.
Definition: stasis.c:1538
Abstract JSON element (object, array, string, int, ...).

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 ast_cel_publish_user_event(), ast_stopstream(), ast_streamfile(), celgenuserevent_exec(), moh_post_start(), moh_post_stop(), and send_dtmf_end_event().

◆ ast_cel_publish_user_event()

void ast_cel_publish_user_event ( struct ast_channel chan,
const char *  event,
const char *  extra 
)

Publish a CEL user event.

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

Definition at line 1720 of file cel.c.

1723{
1724 RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
1725
1726 blob = ast_json_pack("{s: s, s: {s: s}}",
1727 "event", event,
1728 "extra", "extra", S_OR(extra, ""));
1729 if (!blob) {
1730 return;
1731 }
1733}
void ast_cel_publish_event(struct ast_channel *chan, enum ast_cel_event_type event_type, struct ast_json *blob)
Publish a CEL event.
Definition: cel.c:1735

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

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

1772{
1773 int was_enabled;
1774 int is_enabled;
1775 struct ast_cel_general_config *cleanup_config;
1776 struct cel_config *mod_cfg = ao2_global_obj_ref(cel_configs);
1777
1778 if (mod_cfg) {
1779 was_enabled = ast_cel_check_enabled();
1780
1781 cleanup_config = mod_cfg->general;
1783 mod_cfg->general = config;
1784 ao2_cleanup(cleanup_config);
1785
1787 if (!was_enabled && is_enabled) {
1788 create_routes();
1789 } else if (was_enabled && !is_enabled) {
1791 }
1792
1793 ao2_ref(mod_cfg, -1);
1794 }
1795}
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
static void destroy_routes(void)
Definition: cel.c:1465
static int create_routes(void)
Create the Stasis message router and routes for CEL.
Definition: cel.c:1549
unsigned int ast_cel_check_enabled(void)
Hashing function for cel_backend.
Definition: cel.c:366
static const char config[]
Definition: chan_ooh323.c:111
static int is_enabled(void)
Helper function to check if module is enabled.
Definition: res_ari.c:96

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

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

442{
443 unsigned int i;
444
445 for (i = 0; i < ARRAY_LEN(cel_event_types); i++) {
446 if (cel_event_types[i] && !strcasecmp(name, cel_event_types[i])) {
447 return i;
448 }
449 }
450
451 ast_log(LOG_ERROR, "Unknown event name '%s'\n", name);
453}
@ AST_CEL_INVALID_VALUE
Definition: cel.h:42
#define ARRAY_LEN(a)
Definition: utils.h:703

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

Referenced by events_handler().

◆ ast_cel_topic()

struct stasis_topic * ast_cel_topic ( void  )

Get the CEL topic.

Return values
TheCEL topic
NULLif not allocated

Definition at line 1754 of file cel.c.

1755{
1756 return cel_topic;
1757}
static struct stasis_topic * cel_topic
Definition: cel.c:136

References cel_topic.

Referenced by ast_cel_publish_event(), and create_subscriptions().

◆ ast_cel_track_event()

static int ast_cel_track_event ( enum ast_cel_event_type  et)
static

Definition at line 455 of file cel.c.

456{
457 RAII_VAR(struct cel_config *, cfg, ao2_global_obj_ref(cel_configs), ao2_cleanup);
458
459 if (!cfg || !cfg->general) {
460 return 0;
461 }
462
463 return (cfg->general->events & ((int64_t) 1 << et)) ? 1 : 0;
464}

References ao2_cleanup, ao2_global_obj_ref, and RAII_VAR.

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

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 1839 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 1335 of file cel.c.

1338{
1340 struct ast_json *extra = NULL;
1341 struct ast_bridge_snapshot *bridge1, *bridge2;
1342 struct ast_channel_snapshot *channel1, *channel2;
1343
1344 /* Make sure bridge1 is always non-NULL */
1345 if (!xfer->to_transferee.bridge_snapshot) {
1346 bridge1 = xfer->to_transfer_target.bridge_snapshot;
1347 bridge2 = xfer->to_transferee.bridge_snapshot;
1348 channel1 = xfer->to_transfer_target.channel_snapshot;
1349 channel2 = xfer->to_transferee.channel_snapshot;
1350 } else {
1351 bridge1 = xfer->to_transferee.bridge_snapshot;
1352 bridge2 = xfer->to_transfer_target.bridge_snapshot;
1353 channel1 = xfer->to_transferee.channel_snapshot;
1354 channel2 = xfer->to_transfer_target.channel_snapshot;
1355 }
1356
1357 switch (xfer->dest_type) {
1359 return;
1360 /* handle these three the same */
1364 extra = ast_json_pack("{s: s, s: s, s: s, s: s, s: s, s: s, s: s, s: s}",
1365 "bridge1_id", bridge1->uniqueid,
1366 "channel2_name", channel2->base->name,
1367 "channel2_uniqueid", channel2->base->uniqueid,
1368 "bridge2_id", bridge2->uniqueid,
1369 "transferee_channel_name", xfer->transferee ? xfer->transferee->base->name : "N/A",
1370 "transferee_channel_uniqueid", xfer->transferee ? xfer->transferee->base->uniqueid : "N/A",
1371 "transfer_target_channel_name", xfer->target ? xfer->target->base->name : "N/A",
1372 "transfer_target_channel_uniqueid", xfer->target ? xfer->target->base->uniqueid : "N/A");
1373 if (!extra) {
1374 return;
1375 }
1376 break;
1379 extra = ast_json_pack("{s: s, s: s, s: s, s: s, s: s, s: s, s: s, s: s}",
1380 "bridge1_id", bridge1->uniqueid,
1381 "channel2_name", channel2->base->name,
1382 "channel2_uniqueid", channel2->base->uniqueid,
1383 "app", xfer->dest.app,
1384 "transferee_channel_name", xfer->transferee ? xfer->transferee->base->name : "N/A",
1385 "transferee_channel_uniqueid", xfer->transferee ? xfer->transferee->base->uniqueid : "N/A",
1386 "transfer_target_channel_name", xfer->target ? xfer->target->base->name : "N/A",
1387 "transfer_target_channel_uniqueid", xfer->target ? xfer->target->base->uniqueid : "N/A");
1388 if (!extra) {
1389 return;
1390 }
1391 break;
1392 }
1394 NULL, extra, NULL);
1395 ast_json_unref(extra);
1396}
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:593
@ AST_CEL_ATTENDEDTRANSFER
a transfer occurs
Definition: cel.h:67
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
const struct timeval * stasis_message_timestamp(const struct stasis_message *msg)
Get the time when a message was created.
@ AST_ATTENDED_TRANSFER_DEST_FAIL
@ AST_ATTENDED_TRANSFER_DEST_BRIDGE_MERGE
@ AST_ATTENDED_TRANSFER_DEST_LOCAL_APP
@ AST_ATTENDED_TRANSFER_DEST_LINK
@ AST_ATTENDED_TRANSFER_DEST_APP
@ AST_ATTENDED_TRANSFER_DEST_THREEWAY
Message representing attended transfer.
enum ast_attended_transfer_dest_type dest_type
struct ast_bridge_channel_snapshot_pair to_transfer_target
struct ast_channel_snapshot * transferee
union ast_attended_transfer_message::@289 dest
struct ast_bridge_channel_snapshot_pair to_transferee
struct ast_channel_snapshot * target
struct ast_bridge_snapshot * bridge_snapshot
struct ast_channel_snapshot * channel_snapshot
Structure that contains a snapshot of information about a bridge.
Definition: bridge.h:318
const ast_string_field uniqueid
Definition: bridge.h:332
Structure representing a snapshot of channel state.

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_bridge_snapshot::uniqueid, and ast_channel_snapshot_base::uniqueid.

Referenced by create_routes().

◆ cel_backend_send_cb()

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

Definition at line 585 of file cel.c.

586{
587 struct cel_backend *backend = obj;
588
589 backend->callback(arg);
590 return 0;
591}

References cel_backend::callback.

Referenced by cel_report_event().

◆ cel_blind_transfer_cb()

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

Definition at line 1309 of file cel.c.

1312{
1314 struct ast_channel_snapshot *chan_snapshot = transfer_msg->transferer;
1315 struct ast_bridge_snapshot *bridge_snapshot = transfer_msg->bridge;
1316 struct ast_json *extra;
1317
1318 if (transfer_msg->result != AST_BRIDGE_TRANSFER_SUCCESS) {
1319 return;
1320 }
1321
1322 extra = ast_json_pack("{s: s, s: s, s: s, s: s, s: s}",
1323 "extension", transfer_msg->exten,
1324 "context", transfer_msg->context,
1325 "bridge_id", bridge_snapshot->uniqueid,
1326 "transferee_channel_name", transfer_msg->transferee ? transfer_msg->transferee->base->name : "N/A",
1327 "transferee_channel_uniqueid", transfer_msg->transferee ? transfer_msg->transferee->base->uniqueid : "N/A");
1328 if (extra) {
1330 NULL, extra, NULL);
1331 ast_json_unref(extra);
1332 }
1333}
@ AST_BRIDGE_TRANSFER_SUCCESS
Definition: bridge.h:1104
@ AST_CEL_BLINDTRANSFER
a transfer occurs
Definition: cel.h:65
Message published during a blind transfer.
char exten[AST_MAX_EXTENSION]
struct ast_bridge_snapshot * bridge
struct ast_channel_snapshot * transferer
struct ast_channel_snapshot * transferee
enum ast_transfer_result result
char context[AST_MAX_CONTEXT]

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_bridge_snapshot::uniqueid, and ast_channel_snapshot_base::uniqueid.

Referenced by create_routes().

◆ cel_bridge_enter_cb()

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

Definition at line 1068 of file cel.c.

1071{
1073 struct ast_bridge_snapshot *snapshot = blob->bridge;
1074 struct ast_channel_snapshot *chan_snapshot = blob->channel;
1075 RAII_VAR(struct ast_json *, extra, NULL, ast_json_unref);
1076 RAII_VAR(struct ast_str *, peer_str, NULL, ast_free);
1077
1078 if (cel_filter_channel_snapshot(chan_snapshot)) {
1079 return;
1080 }
1081
1082 extra = ast_json_pack("{s: s, s: s}",
1083 "bridge_id", snapshot->uniqueid,
1084 "bridge_technology", snapshot->technology);
1085 if (!extra) {
1086 return;
1087 }
1088
1089 peer_str = cel_generate_peer_str(snapshot, chan_snapshot);
1090 if (!peer_str) {
1091 return;
1092 }
1093
1095 NULL, extra, ast_str_buffer(peer_str));
1096}
#define ast_free(a)
Definition: astmm.h:180
static int cel_filter_channel_snapshot(struct ast_channel_snapshot *snapshot)
Definition: cel.c:1007
static struct ast_str * cel_generate_peer_str(struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *chan)
Definition: cel.c:1030
@ AST_CEL_BRIDGE_ENTER
channel enters a bridge
Definition: cel.h:57
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
Blob of data associated with a bridge.
struct ast_bridge_snapshot * bridge
struct ast_channel_snapshot * channel
struct ast_json * blob
const ast_string_field technology
Definition: bridge.h:332
Support for dynamic strings.
Definition: strings.h:623

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

◆ cel_bridge_leave_cb()

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

Definition at line 1098 of file cel.c.

1101{
1103 struct ast_bridge_snapshot *snapshot = blob->bridge;
1104 struct ast_channel_snapshot *chan_snapshot = blob->channel;
1105 RAII_VAR(struct ast_json *, extra, NULL, ast_json_unref);
1106 RAII_VAR(struct ast_str *, peer_str, NULL, ast_free);
1107
1108 if (cel_filter_channel_snapshot(chan_snapshot)) {
1109 return;
1110 }
1111
1112 extra = ast_json_pack("{s: s, s: s}",
1113 "bridge_id", snapshot->uniqueid,
1114 "bridge_technology", snapshot->technology);
1115 if (!extra) {
1116 return;
1117 }
1118
1119 peer_str = cel_generate_peer_str(snapshot, chan_snapshot);
1120 if (!peer_str) {
1121 return;
1122 }
1123
1125 NULL, extra, ast_str_buffer(peer_str));
1126}
@ AST_CEL_BRIDGE_EXIT
channel exits a bridge
Definition: cel.h:59

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

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

980{
981 if (old_snapshot && !strcmp(old_snapshot->dialplan->appl, new_snapshot->dialplan->appl)) {
982 return;
983 }
984
985 /* old snapshot has an application, end it */
986 if (old_snapshot && !ast_strlen_zero(old_snapshot->dialplan->appl)) {
987 cel_report_event(old_snapshot, AST_CEL_APP_END, event_time, NULL, NULL, NULL);
988 }
989
990 /* new snapshot has an application, start it */
991 if (!ast_strlen_zero(new_snapshot->dialplan->appl)) {
992 cel_report_event(new_snapshot, AST_CEL_APP_START, event_time, NULL, NULL, NULL);
993 }
994}
@ AST_CEL_APP_END
an app ends
Definition: cel.h:55
@ AST_CEL_APP_START
an app starts
Definition: cel.h:53

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.

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

961{
962 if (!old_snapshot) {
963 return;
964 }
965
966 ast_assert(!ast_strlen_zero(new_snapshot->peer->linkedid));
967 ast_assert(!ast_strlen_zero(old_snapshot->peer->linkedid));
968
970 && strcmp(old_snapshot->peer->linkedid, new_snapshot->peer->linkedid)) {
971 cel_linkedid_ref(new_snapshot->peer->linkedid);
972 check_retire_linkedid(old_snapshot, event_time);
973 }
974}
static int cel_linkedid_ref(const char *linkedid)
Definition: cel.c:805
static int ast_cel_track_event(enum ast_cel_event_type et)
Definition: cel.c:455
static void check_retire_linkedid(struct ast_channel_snapshot *snapshot, const struct timeval *event_time)
Definition: cel.c:638
@ AST_CEL_LINKEDID_END
the last channel with the given linkedid is retired
Definition: cel.h:71
#define ast_assert(a)
Definition: utils.h:776

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.

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

921{
922 int is_hungup, was_hungup;
923
924 if (!old_snapshot) {
925 cel_report_event(new_snapshot, AST_CEL_CHANNEL_START, event_time, NULL, NULL, NULL);
926 return;
927 }
928
929 was_hungup = ast_test_flag(&old_snapshot->flags, AST_FLAG_DEAD) ? 1 : 0;
930 is_hungup = ast_test_flag(&new_snapshot->flags, AST_FLAG_DEAD) ? 1 : 0;
931
932 if (!was_hungup && is_hungup) {
933 struct ast_json *extra;
934 struct cel_dialstatus *dialstatus = get_dialstatus(new_snapshot->base->uniqueid);
935
936 extra = ast_json_pack("{s: i, s: s, s: s}",
937 "hangupcause", new_snapshot->hangup->cause,
938 "hangupsource", new_snapshot->hangup->source,
939 "dialstatus", dialstatus ? dialstatus->dialstatus : "");
940 cel_report_event(new_snapshot, AST_CEL_HANGUP, event_time, NULL, extra, NULL);
941 ast_json_unref(extra);
943
944 cel_report_event(new_snapshot, AST_CEL_CHANNEL_END, event_time, NULL, NULL, NULL);
946 check_retire_linkedid(new_snapshot, event_time);
947 }
948 return;
949 }
950
951 if (old_snapshot->state != new_snapshot->state && new_snapshot->state == AST_STATE_UP) {
952 cel_report_event(new_snapshot, AST_CEL_ANSWER, event_time, NULL, NULL, NULL);
953 return;
954 }
955}
static struct cel_dialstatus * get_dialstatus(const char *uniqueid)
Definition: cel.c:889
@ AST_CEL_CHANNEL_END
channel end
Definition: cel.h:47
@ AST_CEL_ANSWER
A ringing phone is answered.
Definition: cel.h:51
@ AST_CEL_HANGUP
hangup terminates connection
Definition: cel.h:49
@ AST_CEL_CHANNEL_START
channel birth
Definition: cel.h:45
@ AST_FLAG_DEAD
Definition: channel.h:1065
@ AST_STATE_UP
Definition: channelstate.h:42
enum ast_channel_state state
struct ast_flags flags
struct ast_channel_snapshot_hangup * hangup
char dialstatus[0]
Definition: cel.c:195
#define ast_test_flag(p, flag)
Definition: utils.h:63

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.

◆ cel_config_alloc()

static void * cel_config_alloc ( void  )
static

Definition at line 243 of file cel.c.

244{
245 RAII_VAR(struct cel_config *, cfg, NULL, ao2_cleanup);
246
247 if (!(cfg = ao2_alloc(sizeof(*cfg), cel_config_dtor))) {
248 return NULL;
249 }
250
251 if (!(cfg->general = ast_cel_general_config_alloc())) {
252 return NULL;
253 }
254
255 ao2_ref(cfg, +1);
256 return cfg;
257}
void * ast_cel_general_config_alloc(void)
Allocate a CEL configuration object.
Definition: cel.c:207
static void cel_config_dtor(void *obj)
Destructor for cel_config.
Definition: cel.c:236

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

Referenced by load_module().

◆ cel_config_dtor()

static void cel_config_dtor ( void *  obj)
static

Destructor for cel_config.

Definition at line 236 of file cel.c.

237{
238 struct cel_config *cfg = obj;
239 ao2_cleanup(cfg->general);
240 cfg->general = NULL;
241}

References ao2_cleanup, cel_config::general, and NULL.

Referenced by cel_config_alloc().

◆ cel_dial_cb()

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

Definition at line 1250 of file cel.c.

1252{
1254 struct ast_channel_snapshot *snapshot;
1255
1256 snapshot = ast_multi_channel_blob_get_channel(blob, "caller");
1257 if (!snapshot || cel_filter_channel_snapshot(snapshot)) {
1258 return;
1259 }
1260
1261 if (!ast_strlen_zero(get_blob_variable(blob, "forward"))) {
1262 struct ast_json *extra;
1263
1264 extra = ast_json_pack("{s: s}", "forward", get_blob_variable(blob, "forward"));
1265 if (extra) {
1267 NULL, extra, NULL);
1268 ast_json_unref(extra);
1269 }
1270 }
1271
1272 if (is_valid_dialstatus(blob)) {
1273 save_dialstatus(blob, snapshot);
1274 }
1275}
static int is_valid_dialstatus(struct ast_multi_channel_blob *blob)
Definition: cel.c:1221
static void save_dialstatus(struct ast_multi_channel_blob *blob, struct ast_channel_snapshot *snapshot)
Definition: cel.c:1177
static const char * get_blob_variable(struct ast_multi_channel_blob *blob, const char *varname)
Definition: cel.c:901
@ AST_CEL_FORWARD
this call was forwarded somewhere else
Definition: cel.h:75
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.
struct ast_json * blob

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

◆ cel_filter_channel_snapshot()

static int cel_filter_channel_snapshot ( struct ast_channel_snapshot snapshot)
static

Definition at line 1007 of file cel.c.

1008{
1009 if (!snapshot) {
1010 return 0;
1011 }
1012 return snapshot->base->tech_properties & AST_CHAN_TP_INTERNAL;
1013}
@ AST_CHAN_TP_INTERNAL
Channels with this particular technology are an implementation detail of Asterisk and should generall...
Definition: channel.h:991

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

◆ cel_general_config_dtor()

static void cel_general_config_dtor ( void *  obj)
static

Destructor for cel_config.

Definition at line 199 of file cel.c.

200{
201 struct ast_cel_general_config *cfg = obj;
203 ao2_cleanup(cfg->apps);
204 cfg->apps = NULL;
205}
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:374

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

Referenced by ast_cel_general_config_alloc().

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

1033{
1034 struct ast_str *peer_str = ast_str_create(32);
1035 struct ao2_iterator i;
1036 char *current_chan = NULL;
1037
1038 if (!peer_str) {
1039 return NULL;
1040 }
1041
1042 for (i = ao2_iterator_init(bridge->channels, 0);
1043 (current_chan = ao2_iterator_next(&i));
1044 ao2_cleanup(current_chan)) {
1045 struct ast_channel_snapshot *current_snapshot;
1046
1047 /* Don't add the channel for which this message is being generated */
1048 if (!strcmp(current_chan, chan->base->uniqueid)) {
1049 continue;
1050 }
1051
1052 current_snapshot = ast_channel_snapshot_get_latest(current_chan);
1053 if (!current_snapshot) {
1054 continue;
1055 }
1056
1057 ast_str_append(&peer_str, 0, "%s,", current_snapshot->base->name);
1058 ao2_cleanup(current_snapshot);
1059 }
1061
1062 /* Rip off the trailing comma */
1063 ast_str_truncate(peer_str, -1);
1064
1065 return peer_str;
1066}
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
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,...
char * ast_str_truncate(struct ast_str *buf, ssize_t len)
Truncates the enclosed string to the given length.
Definition: strings.h:786
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:1139
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
struct ao2_container * channels
Definition: bridge.h:335

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

◆ cel_generic_cb()

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

Definition at line 1277 of file cel.c.

1280{
1282 int event_type = ast_json_integer_get(ast_json_object_get(obj->blob, "event_type"));
1283 struct ast_json *event_details = ast_json_object_get(obj->blob, "event_details");
1284
1285 switch (event_type) {
1287 case AST_CEL_DTMF:
1289 {
1290 const char *event = ast_json_string_get(ast_json_object_get(event_details, "event"));
1291 struct ast_json *extra = ast_json_object_get(event_details, "extra");
1293 event, extra, NULL);
1294 break;
1295 }
1296 case AST_CEL_STREAM_END:
1297 {
1298 const char *event = ast_json_string_get(ast_json_object_get(event_details, "event"));
1300 event, NULL, NULL);
1301 break;
1302 }
1303 default:
1304 ast_log(LOG_ERROR, "Unhandled %s event blob\n", ast_cel_get_type_name(event_type));
1305 break;
1306 }
1307}
@ AST_CEL_DTMF
A DTMF digit was processed.
Definition: cel.h:85
@ AST_CEL_STREAM_BEGIN
A stream started.
Definition: cel.h:81
@ AST_CEL_STREAM_END
A stream ended.
Definition: cel.h:83
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
Definition: json.c:283
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
Definition: json.c:407
intmax_t ast_json_integer_get(const struct ast_json *integer)
Get the value from a JSON integer.
Definition: json.c:332
Blob of data associated with a channel.
struct ast_channel_snapshot * snapshot
struct ast_json * blob

References AST_CEL_DTMF, ast_cel_get_type_name(), AST_CEL_STREAM_BEGIN, AST_CEL_STREAM_END, 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().

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

806{
807 RAII_VAR(struct ao2_container *, linkedids, ao2_global_obj_ref(cel_linkedids), ao2_cleanup);
808 struct cel_linkedid *lid;
809
810 if (ast_strlen_zero(linkedid)) {
811 ast_log(LOG_ERROR, "The linkedid should never be empty\n");
812 return -1;
813 }
814 if (!linkedids) {
815 /* The CEL module is shutdown. Abort. */
816 return -1;
817 }
818
819 ao2_lock(linkedids);
820 lid = ao2_find(linkedids, (void *) linkedid, OBJ_SEARCH_KEY);
821 if (!lid) {
822 /*
823 * Changes to the lid->count member are protected by the
824 * container lock so the lid object does not need its own lock.
825 */
826 lid = ao2_alloc_options(sizeof(*lid) + strlen(linkedid) + 1, NULL,
828 if (!lid) {
829 ao2_unlock(linkedids);
830 return -1;
831 }
832 strcpy(lid->id, linkedid);/* Safe */
833
834 ao2_link(linkedids, lid);
835 }
836 ++lid->count;
837 ao2_unlock(linkedids);
838 ao2_ref(lid, -1);
839
840 return 0;
841}
#define ao2_unlock(a)
Definition: astobj2.h:729
#define ao2_lock(a)
Definition: astobj2.h:717
unsigned int count
Definition: cel.c:183
char id[0]
Definition: cel.c:185

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

◆ cel_local_optimization_begin_cb()

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

Definition at line 1458 of file cel.c.

1461{
1463}
static void cel_local_optimization_cb_helper(void *data, struct stasis_subscription *sub, struct stasis_message *message, enum ast_cel_event_type event_type)
Definition: cel.c:1423
@ AST_CEL_LOCAL_OPTIMIZE_BEGIN
A local channel optimization has begun.
Definition: cel.h:79
struct stasis_forward * sub
Definition: res_corosync.c:240

References AST_CEL_LOCAL_OPTIMIZE_BEGIN, cel_local_optimization_cb_helper(), and sub.

Referenced by create_routes().

◆ cel_local_optimization_cb_helper()

static void cel_local_optimization_cb_helper ( void *  data,
struct stasis_subscription sub,
struct stasis_message message,
enum ast_cel_event_type  event_type 
)
static

Definition at line 1423 of file cel.c.

1427{
1429 struct ast_channel_snapshot *localone = ast_multi_channel_blob_get_channel(obj, "1");
1430 struct ast_channel_snapshot *localtwo = ast_multi_channel_blob_get_channel(obj, "2");
1431 struct ast_json *extra;
1432
1433 if (!localone || !localtwo) {
1434 return;
1435 }
1436
1437 extra = ast_json_pack("{s: s, s: s}",
1438 "local_two", localtwo->base->name,
1439 "local_two_uniqueid", localtwo->base->uniqueid);
1440 if (!extra) {
1441 return;
1442 }
1443
1444 cel_report_event(localone, event_type, stasis_message_timestamp(message), NULL, extra, NULL);
1445 ast_json_unref(extra);
1446}

References 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 cel_local_optimization_begin_cb(), and cel_local_optimization_end_cb().

◆ cel_local_optimization_end_cb()

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

Definition at line 1448 of file cel.c.

1451{
1452 /* The AST_CEL_LOCAL_OPTIMIZE event has always been triggered by the end of optimization.
1453 This can either be used as an indication that the call was locally optimized, or as
1454 the END event in combination with the subsequently added BEGIN event. */
1456}
@ AST_CEL_LOCAL_OPTIMIZE
A local channel optimization occurred, this marks the end.
Definition: cel.h:77

References AST_CEL_LOCAL_OPTIMIZE, cel_local_optimization_cb_helper(), and sub.

Referenced by create_routes().

◆ cel_parking_cb()

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

Definition at line 1128 of file cel.c.

1131{
1132 struct ast_parked_call_payload *parked_payload = stasis_message_data(message);
1133 RAII_VAR(struct ast_json *, extra, NULL, ast_json_unref);
1134 const char *reason = NULL;
1135
1136 switch (parked_payload->event_type) {
1137 case PARKED_CALL:
1138 extra = ast_json_pack("{s: s, s: s}",
1139 "parker_dial_string", parked_payload->parker_dial_string,
1140 "parking_lot", parked_payload->parkinglot);
1141 if (extra) {
1143 NULL, extra, NULL);
1144 }
1145 return;
1147 reason = "ParkedCallTimeOut";
1148 break;
1149 case PARKED_CALL_GIVEUP:
1150 reason = "ParkedCallGiveUp";
1151 break;
1153 reason = "ParkedCallUnparked";
1154 break;
1155 case PARKED_CALL_FAILED:
1156 reason = "ParkedCallFailed";
1157 break;
1158 case PARKED_CALL_SWAP:
1159 reason = "ParkedCallSwap";
1160 break;
1161 }
1162
1163 if (parked_payload->retriever) {
1164 extra = ast_json_pack("{s: s, s: s}",
1165 "reason", reason ?: "",
1166 "retriever", parked_payload->retriever->base->name);
1167 } else {
1168 extra = ast_json_pack("{s: s}", "reason", reason ?: "");
1169 }
1170
1171 if (extra) {
1173 NULL, extra, NULL);
1174 }
1175}
@ AST_CEL_PARK_START
a channel is parked
Definition: cel.h:61
@ AST_CEL_PARK_END
channel out of the park
Definition: cel.h:63
@ PARKED_CALL
Definition: parking.h:47
@ PARKED_CALL_TIMEOUT
Definition: parking.h:48
@ PARKED_CALL_UNPARKED
Definition: parking.h:50
@ PARKED_CALL_FAILED
Definition: parking.h:51
@ PARKED_CALL_GIVEUP
Definition: parking.h:49
@ PARKED_CALL_SWAP
Definition: parking.h:52
A parked call message payload.
Definition: parking.h:59
const ast_string_field parkinglot
Definition: parking.h:69
struct ast_channel_snapshot * retriever
Definition: parking.h:61
struct ast_channel_snapshot * parkee
Definition: parking.h:60
enum ast_parked_call_event_type event_type
Definition: parking.h:62
const ast_string_field parker_dial_string
Definition: parking.h:69

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

◆ cel_pickup_cb()

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

Definition at line 1398 of file cel.c.

1401{
1403 struct ast_channel_snapshot *channel = ast_multi_channel_blob_get_channel(obj, "channel");
1404 struct ast_channel_snapshot *target = ast_multi_channel_blob_get_channel(obj, "target");
1405 struct ast_json *extra;
1406
1407 if (!channel || !target) {
1408 return;
1409 }
1410
1411 extra = ast_json_pack("{s: s, s: s}",
1412 "pickup_channel", channel->base->name,
1413 "pickup_channel_uniqueid", channel->base->uniqueid);
1414 if (!extra) {
1415 return;
1416 }
1417
1419 ast_json_unref(extra);
1420}
@ AST_CEL_PICKUP
a directed pickup was performed on this channel
Definition: cel.h:73

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

◆ cel_pre_apply_config()

static int cel_pre_apply_config ( void  )
static

Definition at line 295 of file cel.c.

296{
297 struct cel_config *cfg = aco_pending_config(&cel_cfg_info);
298
299 if (!cfg->general) {
300 return -1;
301 }
302
303 if (!ao2_container_count(cfg->general->apps)) {
304 return 0;
305 }
306
307 if (cfg->general->events & ((int64_t) 1 << AST_CEL_APP_START)) {
308 return 0;
309 }
310
311 if (cfg->general->events & ((int64_t) 1 << AST_CEL_APP_END)) {
312 return 0;
313 }
314
315 ast_log(LOG_ERROR, "Applications are listed to be tracked, but APP events are not tracked\n");
316 return -1;
317}
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
void * aco_pending_config(struct aco_info *info)
Get pending config changes.
int64_t events
Definition: cel.h:235

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.

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

597{
598 struct ast_event *ev;
599 RAII_VAR(struct cel_config *, cfg, ao2_global_obj_ref(cel_configs), ao2_cleanup);
601
602 if (!cfg || !cfg->general || !cfg->general->enable || !backends) {
603 return 0;
604 }
605
606 /* Record the linkedid of new channels if we are tracking LINKEDID_END even if we aren't
607 * reporting on CHANNEL_START so we can track when to send LINKEDID_END */
608 if (event_type == AST_CEL_CHANNEL_START
610 if (cel_linkedid_ref(snapshot->peer->linkedid)) {
611 return -1;
612 }
613 }
614
615 if (!ast_cel_track_event(event_type)) {
616 return 0;
617 }
618
619 if ((event_type == AST_CEL_APP_START || event_type == AST_CEL_APP_END)
620 && !cel_track_app(snapshot->dialplan->appl)) {
621 return 0;
622 }
623
624 ev = ast_cel_create_event_with_time(snapshot, event_type, event_time, userdefevname, extra, peer_str);
625 if (!ev) {
626 return -1;
627 }
628
629 /* Distribute event to backends */
632
633 return 0;
634}
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
Definition: astobj2.h:1693
@ OBJ_MULTIPLE
Definition: astobj2.h:1049
static int cel_track_app(const char *const_app)
Definition: cel.c:519
static int cel_backend_send_cb(void *obj, void *arg, int flags)
Definition: cel.c:585
void ast_event_destroy(struct ast_event *event)
Destroy an event.
Definition: event.c:525
An event.
Definition: event.c:81

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_optimization_cb_helper(), cel_parking_cb(), cel_pickup_cb(), and check_retire_linkedid().

◆ cel_snapshot_update_cb()

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

Definition at line 1015 of file cel.c.

1017{
1019 size_t i;
1020
1021 if (cel_filter_channel_snapshot(update->old_snapshot) || cel_filter_channel_snapshot(update->new_snapshot)) {
1022 return;
1023 }
1024
1025 for (i = 0; i < ARRAY_LEN(cel_channel_monitors); ++i) {
1026 cel_channel_monitors[i](update->old_snapshot, update->new_snapshot, stasis_message_timestamp(message));
1027 }
1028}
cel_channel_snapshot_monitor cel_channel_monitors[]
Handlers for channel snapshot changes.
Definition: cel.c:1001
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.

References ARRAY_LEN, cel_channel_monitors, cel_filter_channel_snapshot(), stasis_message_data(), stasis_message_timestamp(), and update().

Referenced by create_routes().

◆ cel_track_app()

static int cel_track_app ( const char *  const_app)
static

Definition at line 519 of file cel.c.

520{
521 RAII_VAR(struct cel_config *, cfg, ao2_global_obj_ref(cel_configs), ao2_cleanup);
522 RAII_VAR(char *, app, NULL, ao2_cleanup);
523 char *app_lower;
524
525 if (!cfg || !cfg->general) {
526 return 0;
527 }
528
529 app_lower = ast_str_to_lower(ast_strdupa(const_app));
530 app = ao2_find(cfg->general->apps, app_lower, OBJ_SEARCH_KEY);
531 if (!app) {
532 return 0;
533 }
534
535 return 1;
536}
static const char app[]
Definition: app_adsiprog.c:56

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

Referenced by cel_report_event().

◆ check_retire_linkedid()

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

Definition at line 638 of file cel.c.

639{
640 RAII_VAR(struct ao2_container *, linkedids, ao2_global_obj_ref(cel_linkedids), ao2_cleanup);
641 struct cel_linkedid *lid;
642
643 if (!linkedids || ast_strlen_zero(snapshot->peer->linkedid)) {
644 /* The CEL module is shutdown. Abort. */
645 return;
646 }
647
648 ao2_lock(linkedids);
649
650 lid = ao2_find(linkedids, (void *) snapshot->peer->linkedid, OBJ_SEARCH_KEY);
651 if (!lid) {
652 ao2_unlock(linkedids);
653
654 /*
655 * The user may have done a reload to start tracking linkedids
656 * when a call was already in progress. This is an unusual kind
657 * of change to make after starting Asterisk.
658 */
659 ast_log(LOG_ERROR, "Something weird happened, couldn't find linkedid %s\n",
660 snapshot->peer->linkedid);
661 return;
662 }
663
664 if (!--lid->count) {
665 /* No channels use this linkedid anymore. */
666 ao2_unlink(linkedids, lid);
667 ao2_unlock(linkedids);
668
669 cel_report_event(snapshot, AST_CEL_LINKEDID_END, event_time, NULL, NULL, NULL);
670 } else {
671 ao2_unlock(linkedids);
672 }
673 ao2_ref(lid, -1);
674}
#define ao2_unlink(container, obj)
Remove an object from a container.
Definition: astobj2.h:1578

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

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

1550{
1551 int ret = 0;
1552
1554 if (!cel_state_router) {
1555 return -1;
1556 }
1559
1563 NULL);
1564
1568 NULL);
1569
1573 NULL);
1574
1578 NULL);
1579
1583 NULL);
1584
1588 NULL);
1589
1593 NULL);
1594
1598 NULL);
1599
1603 NULL);
1604
1608 NULL);
1609
1613 NULL);
1614
1615 if (ret) {
1616 ast_log(AST_LOG_ERROR, "Failed to register for Stasis messages\n");
1617 }
1618
1619 return ret;
1620}
static void cel_local_optimization_end_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: cel.c:1448
static void cel_bridge_leave_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: cel.c:1098
static void cel_dial_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: cel.c:1250
static void cel_snapshot_update_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: cel.c:1015
static void cel_pickup_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: cel.c:1398
static void cel_blind_transfer_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: cel.c:1309
static void cel_attended_transfer_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: cel.c:1335
static void cel_generic_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: cel.c:1277
static void cel_parking_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: cel.c:1128
static struct stasis_message_router * cel_state_router
Definition: cel.c:133
static void cel_local_optimization_begin_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: cel.c:1458
static void cel_bridge_enter_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: cel.c:1068
static struct stasis_topic * cel_aggregation_topic
Definition: cel.c:139
struct stasis_message_type * ast_local_optimization_end_type(void)
Message type for when a local channel optimization completes.
struct stasis_message_type * ast_local_optimization_begin_type(void)
Message type for when a local channel optimization begins.
struct stasis_message_type * ast_parked_call_type(void)
accessor for the parked call stasis message type
struct stasis_message_type * ast_channel_dial_type(void)
Message type for when a channel dials another channel.
struct stasis_message_type * ast_channel_snapshot_type(void)
Message type for ast_channel_snapshot_update.
#define AST_LOG_ERROR
struct stasis_message_type * ast_call_pickup_type(void)
accessor for call pickup message type
struct stasis_message_type * ast_channel_entered_bridge_type(void)
Message type for ast_channel enter bridge blob messages.
struct stasis_message_type * ast_blind_transfer_type(void)
Message type for ast_blind_transfer_message.
struct stasis_message_type * ast_attended_transfer_type(void)
Message type for ast_attended_transfer_message.
struct stasis_message_type * ast_channel_left_bridge_type(void)
Message type for ast_channel leave bridge blob messages.
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.
#define stasis_message_router_create(topic)
Create a new message router object.
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.
#define AST_TASKPROCESSOR_HIGH_WATER_LEVEL
Definition: taskprocessor.h:64

References 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_begin_type(), ast_local_optimization_end_type(), ast_log, AST_LOG_ERROR, ast_parked_call_type(), AST_TASKPROCESSOR_HIGH_WATER_LEVEL, cel_aggregation_topic, 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_optimization_begin_cb(), cel_local_optimization_end_cb(), cel_parking_cb(), cel_pickup_cb(), cel_snapshot_update_cb(), cel_state_router, 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().

◆ create_subscriptions()

static int create_subscriptions ( void  )
static

Create the Stasis subscriptions for CEL.

Definition at line 1503 of file cel.c.

1504{
1505 cel_aggregation_topic = stasis_topic_create("cel:aggregator");
1506 if (!cel_aggregation_topic) {
1507 return -1;
1508 }
1509
1510 cel_topic = stasis_topic_create("cel:misc");
1511 if (!cel_topic) {
1512 return -1;
1513 }
1514
1518 if (!cel_channel_forwarder) {
1519 return -1;
1520 }
1521
1525 if (!cel_bridge_forwarder) {
1526 return -1;
1527 }
1528
1532 if (!cel_parking_forwarder) {
1533 return -1;
1534 }
1535
1537 ast_cel_topic(),
1539 if (!cel_cel_forwarder) {
1540 return -1;
1541 }
1542
1543 return 0;
1544}
static struct stasis_forward * cel_cel_forwarder
Definition: cel.c:151
static struct stasis_forward * cel_channel_forwarder
Definition: cel.c:142
static struct stasis_forward * cel_bridge_forwarder
Definition: cel.c:145
static struct stasis_forward * cel_parking_forwarder
Definition: cel.c:148
struct stasis_topic * ast_parking_topic(void)
accessor for the parking stasis topic
Definition: parking.c:67
struct stasis_topic * ast_channel_topic_all(void)
A topic which publishes the events for all channels.
struct stasis_topic * stasis_topic_create(const char *name)
Create a new topic.
Definition: stasis.c:644
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:1605
struct stasis_topic * ast_bridge_topic_all(void)
A topic which publishes the events for all bridges.

References ast_bridge_topic_all(), ast_cel_topic(), ast_channel_topic_all(), ast_parking_topic(), cel_aggregation_topic, cel_bridge_forwarder, cel_cel_forwarder, cel_channel_forwarder, cel_parking_forwarder, cel_topic, stasis_forward_all(), and stasis_topic_create().

Referenced by load_module().

◆ destroy_routes()

static void destroy_routes ( void  )
static

Definition at line 1465 of file cel.c.

1466{
1469}
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.

References cel_state_router, NULL, and stasis_message_router_unsubscribe_and_join().

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

◆ destroy_subscriptions()

static void destroy_subscriptions ( void  )
static

◆ events_handler()

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

Definition at line 466 of file cel.c.

467{
468 struct ast_cel_general_config *cfg = obj;
469 char *events = ast_strdupa(var->value);
470 char *cur_event;
471
472 while ((cur_event = strsep(&events, ","))) {
473 enum ast_cel_event_type event_type;
474
475 cur_event = ast_strip(cur_event);
476 if (ast_strlen_zero(cur_event)) {
477 continue;
478 }
479
480 event_type = ast_cel_str_to_event_type(cur_event);
481
482 if (event_type == AST_CEL_ALL) {
483 /* All events */
484 cfg->events = (int64_t) -1;
485 } else if (event_type == AST_CEL_INVALID_VALUE) {
486 return -1;
487 } else {
488 cfg->events |= ((int64_t) 1 << event_type);
489 }
490 }
491
492 return 0;
493}
static const struct adsi_event events[]
Definition: app_adsiprog.c:88
enum ast_cel_event_type ast_cel_str_to_event_type(const char *name)
Get the event type from a string.
Definition: cel.c:441
ast_cel_event_type
CEL event types.
Definition: cel.h:41
@ AST_CEL_ALL
Definition: cel.h:43

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

Referenced by load_module().

◆ get_blob_variable()

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

Definition at line 901 of file cel.c.

902{
903 struct ast_json *json = ast_multi_channel_blob_get_json(blob);
904 if (!json) {
905 return NULL;
906 }
907
908 json = ast_json_object_get(json, varname);
909 if (!json) {
910 return NULL;
911 }
912
913 return ast_json_string_get(json);
914}
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.

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

◆ get_dialstatus()

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

Definition at line 889 of file cel.c.

890{
891 struct ao2_container *dial_statuses = ao2_global_obj_ref(cel_dialstatus_store);
893
894 if (dial_statuses) {
896 ao2_ref(dial_statuses, -1);
897 }
898 return dialstatus;
899}
char uniqueid[AST_MAX_UNIQUEID]
Definition: cel.c:193

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

Referenced by cel_channel_state_change().

◆ handle_cli_status()

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

Definition at line 376 of file cel.c.

377{
378 unsigned int i;
379 RAII_VAR(struct cel_config *, cfg, ao2_global_obj_ref(cel_configs), ao2_cleanup);
381 struct ao2_iterator iter;
382 char *app;
383
384 switch (cmd) {
385 case CLI_INIT:
386 e->command = "cel show status";
387 e->usage =
388 "Usage: cel show status\n"
389 " Displays the Channel Event Logging system status.\n";
390 return NULL;
391 case CLI_GENERATE:
392 return NULL;
393 case CLI_HANDLER:
394 break;
395 }
396
397 if (a->argc > 3) {
398 return CLI_SHOWUSAGE;
399 }
400
401 ast_cli(a->fd, "CEL Logging: %s\n", ast_cel_check_enabled() ? "Enabled" : "Disabled");
402
403 if (!cfg || !cfg->general || !cfg->general->enable) {
404 return CLI_SUCCESS;
405 }
406
407 for (i = 0; i < (sizeof(cfg->general->events) * 8); i++) {
408 const char *name;
409
410 if (!(cfg->general->events & ((int64_t) 1 << i))) {
411 continue;
412 }
413
415 if (strcasecmp(name, "Unknown")) {
416 ast_cli(a->fd, "CEL Tracking Event: %s\n", name);
417 }
418 }
419
420 iter = ao2_iterator_init(cfg->general->apps, 0);
421 for (; (app = ao2_iterator_next(&iter)); ao2_ref(app, -1)) {
422 ast_cli(a->fd, "CEL Tracking Application: %s\n", app);
423 }
425
426 if (backends) {
427 struct cel_backend *backend;
428
429 iter = ao2_iterator_init(backends, 0);
430 for (; (backend = ao2_iterator_next(&iter)); ao2_ref(backend, -1)) {
431 ast_cli(a->fd, "CEL Event Subscriber: %s\n", backend->name);
432 }
434 }
435
436 return CLI_SUCCESS;
437}
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define CLI_SUCCESS
Definition: cli.h:44
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
@ CLI_HANDLER
Definition: cli.h:154
@ CLI_INIT
Definition: cli.h:152
@ CLI_GENERATE
Definition: cli.h:153
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
static struct test_val a

References a, ao2_cleanup, ao2_global_obj_ref, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, app, 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, cel_backend::name, name, NULL, RAII_VAR, and ast_cli_entry::usage.

◆ is_valid_dialstatus()

static int is_valid_dialstatus ( struct ast_multi_channel_blob blob)
static

Definition at line 1221 of file cel.c.

1222{
1223 const char *dialstatus = get_blob_variable(blob, "dialstatus");
1224 int res = 0;
1225
1226 if (ast_strlen_zero(dialstatus)) {
1227 res = 0;
1228 } else if (!strcasecmp(dialstatus, "CHANUNAVAIL")) {
1229 res = 1;
1230 } else if (!strcasecmp(dialstatus, "CONGESTION")) {
1231 res = 1;
1232 } else if (!strcasecmp(dialstatus, "NOANSWER")) {
1233 res = 1;
1234 } else if (!strcasecmp(dialstatus, "BUSY")) {
1235 res = 1;
1236 } else if (!strcasecmp(dialstatus, "ANSWER")) {
1237 res = 1;
1238 } else if (!strcasecmp(dialstatus, "CANCEL")) {
1239 res = 1;
1240 } else if (!strcasecmp(dialstatus, "DONTCALL")) {
1241 res = 1;
1242 } else if (!strcasecmp(dialstatus, "TORTURE")) {
1243 res = 1;
1244 } else if (!strcasecmp(dialstatus, "INVALIDARGS")) {
1245 res = 1;
1246 }
1247 return res;
1248}

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

Referenced by cel_dial_cb().

◆ load_module()

static int load_module ( void  )
static

Definition at line 1625 of file cel.c.

1626{
1627 struct ao2_container *container;
1628
1630 NUM_APP_BUCKETS, cel_linkedid_hash_fn, NULL, cel_linkedid_cmp_fn);
1633 if (!container) {
1635 }
1636
1638 NUM_DIALSTATUS_BUCKETS, cel_dialstatus_hash_fn, NULL, cel_dialstatus_cmp_fn);
1639 ao2_global_obj_replace_unref(cel_dialstatus_store, container);
1641 if (!container) {
1643 }
1644
1647 }
1648
1651 }
1652
1654 cel_backend_hash_fn, NULL, cel_backend_cmp_fn);
1657 if (!container) {
1659 }
1660
1661 if (aco_info_init(&cel_cfg_info)) {
1663 }
1664
1665 aco_option_register(&cel_cfg_info, "enable", ACO_EXACT, general_options, "no", OPT_BOOL_T, 1, FLDSET(struct ast_cel_general_config, enable));
1666 aco_option_register(&cel_cfg_info, "dateformat", ACO_EXACT, general_options, "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_cel_general_config, date_format));
1667 aco_option_register_custom(&cel_cfg_info, "apps", ACO_EXACT, general_options, "", apps_handler, 0);
1668 aco_option_register_custom(&cel_cfg_info, "events", ACO_EXACT, general_options, "", events_handler, 0);
1669
1670 if (aco_process_config(&cel_cfg_info, 0)) {
1671 struct cel_config *cel_cfg = cel_config_alloc();
1672
1673 if (!cel_cfg) {
1675 }
1676
1677 /* We couldn't process the configuration so create a default config. */
1678 if (!aco_set_defaults(&general_option, "general", cel_cfg->general)) {
1679 ast_log(LOG_NOTICE, "Failed to process CEL configuration; using defaults\n");
1680 ao2_global_obj_replace_unref(cel_configs, cel_cfg);
1681 }
1682 ao2_ref(cel_cfg, -1);
1683 }
1684
1685 if (create_subscriptions()) {
1687 }
1688
1691 }
1692
1694}
@ AO2_ALLOC_OPT_LOCK_MUTEX
Definition: astobj2.h:363
#define ao2_global_obj_replace_unref(holder, obj)
Replace an ao2 object in the global holder, throwing away any old object.
Definition: astobj2.h:901
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
Definition: astobj2.h:1303
#define BACKEND_BUCKETS
Definition: cel.c:160
static struct ast_cli_entry cli_status
Definition: cel.c:439
static int create_subscriptions(void)
Create the Stasis subscriptions for CEL.
Definition: cel.c:1503
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:260
static int events_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
Definition: cel.c:466
#define NUM_DIALSTATUS_BUCKETS
Number of buckets for the dialstatus container.
Definition: cel.c:179
static struct aco_type * general_options[]
Definition: cel.c:319
static int apps_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
Definition: cel.c:495
static void * cel_config_alloc(void)
Definition: cel.c:243
#define ast_cli_register(e)
Registers a command or an array of commands.
Definition: cli.h:256
@ ACO_EXACT
int aco_set_defaults(struct aco_type *type, const char *category, void *obj)
Set all default options of obj.
#define STRFLDSET(type,...)
Convert a struct and a list of stringfield fields to an argument list of field offsets.
int aco_info_init(struct aco_info *info)
Initialize an aco_info structure.
#define FLDSET(type,...)
Convert a struct and list of fields to an argument list of field offsets.
#define aco_option_register(info, name, matchtype, types, default_val, opt_type, flags,...)
Register a config option.
@ OPT_BOOL_T
Type for default option handler for bools (ast_true/ast_false)
@ OPT_STRINGFIELD_T
Type for default option handler for stringfields.
#define aco_option_register_custom(info, name, matchtype, types, default_val, handler, flags)
Register a config option.
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 LOG_NOTICE
@ AST_MODULE_LOAD_FAILURE
Module could not be loaded properly.
Definition: module.h:102
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
struct ao2_container * container
Definition: res_fax.c:531
#define STASIS_MESSAGE_TYPE_INIT(name)
Boiler-plate messaging macro for initializing message types.
Definition: stasis.h:1493

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(), cli_status, container, create_routes(), create_subscriptions(), events_handler(), FLDSET, cel_config::general, general_option, general_options, LOG_NOTICE, NULL, NUM_APP_BUCKETS, NUM_DIALSTATUS_BUCKETS, OPT_BOOL_T, OPT_STRINGFIELD_T, STASIS_MESSAGE_TYPE_INIT, and STRFLDSET.

◆ reload_module()

static int reload_module ( void  )
static

Definition at line 1696 of file cel.c.

1697{
1698 unsigned int was_enabled = ast_cel_check_enabled();
1699 unsigned int is_enabled;
1700
1701 if (aco_process_config(&cel_cfg_info, 1) == ACO_PROCESS_ERROR) {
1702 return -1;
1703 }
1704
1706
1707 if (!was_enabled && is_enabled) {
1708 if (create_routes()) {
1709 return -1;
1710 }
1711 } else if (was_enabled && !is_enabled) {
1713 }
1714
1715 ast_verb(3, "CEL logging %sabled.\n", is_enabled ? "en" : "dis");
1716
1717 return 0;
1718}
@ ACO_PROCESS_ERROR
Their was an error and no changes were applied.
#define ast_verb(level,...)

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

◆ save_dialstatus()

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

Definition at line 1177 of file cel.c.

1178{
1179 struct ao2_container *dial_statuses = ao2_global_obj_ref(cel_dialstatus_store);
1180 const char *dialstatus_string = get_blob_variable(blob, "dialstatus");
1181 struct cel_dialstatus *dialstatus;
1182 size_t dialstatus_string_len;
1183
1184 if (!dial_statuses || ast_strlen_zero(dialstatus_string)) {
1185 ao2_cleanup(dial_statuses);
1186 return;
1187 }
1188
1189 dialstatus = ao2_find(dial_statuses, snapshot->base->uniqueid, OBJ_SEARCH_KEY);
1190 if (dialstatus) {
1191 if (!strcasecmp(dialstatus_string, "ANSWER") && strcasecmp(dialstatus->dialstatus, "ANSWER")) {
1192 /* In the case of an answer after we already have a dial status we give
1193 * priority to the answer since the call was, well, answered. In the case of
1194 * failure dial status results we simply let the first failure be the status.
1195 */
1196 ao2_unlink(dial_statuses, dialstatus);
1197 ao2_ref(dialstatus, -1);
1198 } else {
1199 ao2_ref(dialstatus, -1);
1200 ao2_ref(dial_statuses, -1);
1201 return;
1202 }
1203 }
1204
1205 dialstatus_string_len = strlen(dialstatus_string) + 1;
1206 dialstatus = ao2_alloc_options(sizeof(*dialstatus) + dialstatus_string_len, NULL,
1208 if (!dialstatus) {
1209 ao2_ref(dial_statuses, -1);
1210 return;
1211 }
1212
1213 ast_copy_string(dialstatus->uniqueid, snapshot->base->uniqueid, sizeof(dialstatus->uniqueid));
1214 ast_copy_string(dialstatus->dialstatus, dialstatus_string, dialstatus_string_len);
1215
1216 ao2_link(dial_statuses, dialstatus);
1217 ao2_ref(dialstatus, -1);
1218 ao2_ref(dial_statuses, -1);
1219}
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425

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, and ast_channel_snapshot_base::uniqueid.

Referenced by cel_dial_cb().

◆ STASIS_MESSAGE_TYPE_DEFN()

STASIS_MESSAGE_TYPE_DEFN ( cel_generic_type  )

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 1484 of file cel.c.

1485{
1489
1491 aco_info_destroy(&cel_cfg_info);
1492 ao2_global_obj_release(cel_configs);
1493 ao2_global_obj_release(cel_dialstatus_store);
1494 ao2_global_obj_release(cel_linkedids);
1495 ao2_global_obj_release(cel_backends);
1496
1497 return 0;
1498}
#define ao2_global_obj_release(holder)
Release the ao2 object held in the global holder.
Definition: astobj2.h:859
static void destroy_subscriptions(void)
Definition: cel.c:1471
int ast_cli_unregister(struct ast_cli_entry *e)
Unregisters a command or an array of commands.
Definition: main/cli.c:2408
void aco_info_destroy(struct aco_info *info)
Destroy an initialized aco_info struct.
#define STASIS_MESSAGE_TYPE_CLEANUP(name)
Boiler-plate messaging macro for cleaning up message types.
Definition: stasis.h:1515

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

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 = AST_BUILDOPT_SUM, .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 1839 of file cel.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 1839 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 139 of file cel.c.

Referenced by create_routes(), create_subscriptions(), and destroy_subscriptions().

◆ cel_bridge_forwarder

struct stasis_forward* cel_bridge_forwarder
static

Subscription for forwarding the channel caching topic

Definition at line 145 of file cel.c.

Referenced by create_subscriptions(), and destroy_subscriptions().

◆ cel_cel_forwarder

struct stasis_forward* cel_cel_forwarder
static

Subscription for forwarding the CEL-specific topic

Definition at line 151 of file cel.c.

Referenced by create_subscriptions(), and destroy_subscriptions().

◆ cel_channel_forwarder

struct stasis_forward* cel_channel_forwarder
static

Subscription for forwarding the channel caching topic

Definition at line 142 of file cel.c.

Referenced by create_subscriptions(), and destroy_subscriptions().

◆ 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:957
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:917
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:976

Handlers for channel snapshot changes.

Note
Order of the handlers matters. Application changes must come before state changes to ensure that hangup notifications occur after application changes. Linkedid checking should always come last.

Definition at line 1001 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 ignore_option
Definition: cel.c:275
#define ACO_TYPES(...)
A helper macro to ensure that aco_info types always have a sentinel.

The config file to be processed for the module.

Definition at line 283 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 324 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 148 of file cel.c.

Referenced by create_subscriptions(), and destroy_subscriptions().

◆ cel_state_router

struct stasis_message_router* cel_state_router
static

Message router for state that CEL needs to know about

Definition at line 133 of file cel.c.

Referenced by create_routes(), and destroy_routes().

◆ cel_topic

struct stasis_topic* cel_topic
static

Topic for CEL-specific messages

Definition at line 136 of file cel.c.

Referenced by ast_cel_topic(), create_subscriptions(), and destroy_subscriptions().

◆ cli_status

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

Definition at line 439 of file cel.c.

Referenced by load_module(), and unload_module().

◆ 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:1739

Definition at line 679 of file cel.c.

Referenced by ast_cel_fabricate_channel_from_event().

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

Referenced by load_module().

◆ general_options

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

Definition at line 319 of file cel.c.

Referenced by load_module().

◆ ignore_categories

const char* ignore_categories[]
static
Initial value:
= {
"manager",
"radius",
}

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

Definition at line 269 of file cel.c.

◆ ignore_option

struct aco_type ignore_option
static

Definition at line 275 of file cel.c.