Asterisk - The Open Source Telephony Project  GIT-master-1f78ee9
Data Structures | Macros | Enumerations | Functions | Variables
cdr.c File Reference

Call Detail Record API. More...

#include "asterisk.h"
#include <signal.h>
#include <inttypes.h>
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/cdr.h"
#include "asterisk/callerid.h"
#include "asterisk/manager.h"
#include "asterisk/module.h"
#include "asterisk/causes.h"
#include "asterisk/linkedlists.h"
#include "asterisk/utils.h"
#include "asterisk/sched.h"
#include "asterisk/config.h"
#include "asterisk/cli.h"
#include "asterisk/stringfields.h"
#include "asterisk/config_options.h"
#include "asterisk/json.h"
#include "asterisk/parking.h"
#include "asterisk/stasis.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/stasis_bridges.h"
#include "asterisk/stasis_message_router.h"
#include "asterisk/astobj2.h"
#include "asterisk/taskprocessor.h"

Go to the source code of this file.

Data Structures

struct  be_list
 List of registered backends. More...
 
struct  bridge_leave_data
 
struct  cdr_batch
 The actual batch queue. More...
 
struct  cdr_batch_item
 Queued CDR waiting to be batched. More...
 
struct  cdr_beitem
 Registration object for CDR backends. More...
 
struct  cdr_object
 An in-memory representation of an active CDR. More...
 
struct  cdr_object_fn_table
 A virtual table used for cdr_object. More...
 
struct  cdr_object_snapshot
 A wrapper object around a snapshot. Fields that are mutable by the CDR engine are replicated here. More...
 
struct  mo_list
 List of registered modifiers. More...
 
struct  module_config
 The configuration settings for this module. More...
 
struct  party_b_userfield_update
 

Macros

#define CDR_DEBUG(fmt, ...)
 
#define cdr_set_debug_mode(mod_cfg)
 
#define DEFAULT_BATCH_SAFE_SHUTDOWN   "1"
 
#define DEFAULT_BATCH_SCHEDULER_ONLY   "0"
 
#define DEFAULT_BATCH_SIZE   "100"
 
#define DEFAULT_BATCH_TIME   "300"
 
#define DEFAULT_BATCHMODE   "0"
 
#define DEFAULT_CONGESTION   "0"
 
#define DEFAULT_ENABLED   "1"
 
#define DEFAULT_END_BEFORE_H_EXTEN   "1"
 
#define DEFAULT_INITIATED_SECONDS   "0"
 
#define DEFAULT_UNANSWERED   "0"
 
#define FORMAT_STRING   "%-25.25s %-25.25s %-15.15s %-8.8s %-8.8s %-8.8s %-8.8ld %-8.8ld\n"
 
#define FORMAT_STRING   "%-10.10s %-20.20s %-25.25s %-15.15s %-15.15s %-8.8s %-8.8s %-8.8s %-8.8ld %-8.8ld\n"
 
#define MAX_BATCH_SIZE   1000
 
#define MAX_BATCH_TIME   86400
 
#define TITLE_STRING   "%-25.25s %-25.25s %-15.15s %-8.8s %-8.8s %-8.8s %-8.8s %-8.8s\n"
 
#define TITLE_STRING   "%-10.10s %-20.20s %-25.25s %-15.15s %-15.15s %-8.8s %-8.8s %-8.8s %-8.8s %-8.8s\n"
 

Enumerations

enum  process_bridge_enter_results { BRIDGE_ENTER_ONLY_PARTY, BRIDGE_ENTER_OBTAINED_PARTY_B, BRIDGE_ENTER_NO_PARTY_B, BRIDGE_ENTER_NEED_CDR }
 Return types for process_bridge_enter functions. More...
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
static AO2_GLOBAL_OBJ_STATIC (module_configs)
 The container for the module configuration. More...
 
struct ast_cdrast_cdr_alloc (void)
 Allocate a CDR record. More...
 
int ast_cdr_backend_suspend (const char *name)
 Suspend a CDR backend temporarily. More...
 
int ast_cdr_backend_unsuspend (const char *name)
 Unsuspend a CDR backend. More...
 
int ast_cdr_clear_property (const char *channel_name, enum ast_cdr_options option)
 Clear a property on a CDR for a channel. More...
 
const char * ast_cdr_disp2str (int disposition)
 Disposition to a string. More...
 
struct ast_cdrast_cdr_dup (struct ast_cdr *cdr)
 Duplicate a public CDR. More...
 
void ast_cdr_engine_term (void)
 
int ast_cdr_fork (const char *channel_name, struct ast_flags *options)
 Fork a CDR. More...
 
void ast_cdr_format_var (struct ast_cdr *cdr, const char *name, char **ret, char *workspace, int workspacelen, int raw)
 Format a CDR variable from an already posted CDR. More...
 
void ast_cdr_free (struct ast_cdr *cdr)
 Free a CDR record. More...
 
static int ast_cdr_generic_unregister (struct be_list *generic_list, const char *name)
 
struct ast_cdr_configast_cdr_get_config (void)
 Obtain the current CDR configuration. More...
 
int ast_cdr_getvar (const char *channel_name, const char *name, char *value, size_t length)
 Retrieve a CDR variable from a channel's current CDR. More...
 
int ast_cdr_is_enabled (void)
 Return TRUE if CDR subsystem is enabled. More...
 
struct stasis_message_routerast_cdr_message_router (void)
 Return the message router for the CDR engine. More...
 
int ast_cdr_modifier_register (const char *name, const char *desc, ast_cdrbe be)
 Register a CDR modifier. More...
 
int ast_cdr_modifier_unregister (const char *name)
 Unregister a CDR modifier. More...
 
int ast_cdr_register (const char *name, const char *desc, ast_cdrbe be)
 Register a CDR handling engine. More...
 
int ast_cdr_reset (const char *channel_name, int keep_variables)
 Reset the detail record. More...
 
int ast_cdr_serialize_variables (const char *channel_name, struct ast_str **buf, char delim, char sep)
 Serializes all the data and variables for a current CDR record. More...
 
void ast_cdr_set_config (struct ast_cdr_config *config)
 Set the current CDR configuration. More...
 
int ast_cdr_set_property (const char *channel_name, enum ast_cdr_options option)
 Set a property on a CDR for a channel. More...
 
void ast_cdr_setuserfield (const char *channel_name, const char *userfield)
 Set CDR user field for channel (stored in CDR) More...
 
int ast_cdr_setvar (const char *channel_name, const char *name, const char *value)
 Set a variable on a CDR. More...
 
int ast_cdr_unregister (const char *name)
 Unregister a CDR handling engine. More...
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static enum process_bridge_enter_results base_process_bridge_enter (struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
 
static int base_process_bridge_leave (struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
 
static int base_process_dial_end (struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer, const char *dial_status)
 
static int base_process_parked_channel (struct cdr_object *cdr, struct ast_parked_call_payload *parking_info)
 
static int base_process_party_a (struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
 
static void bridge_candidate_add_to_cdr (struct cdr_object *cdr, struct cdr_object_snapshot *party_b)
 
static void bridge_candidate_process (struct cdr_object *cdr, struct cdr_object *base_cand_cdr)
 Process a single bridge_candidate. More...
 
static int bridge_state_process_bridge_leave (struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
 
static void bridge_state_process_party_b (struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
 
static int cdr_all_cmp_fn (void *obj, void *arg, int flags)
 
static int cdr_all_hash_fn (const void *obj, const int flags)
 
static void cdr_all_print_fn (void *v_obj, void *where, ao2_prnt_fn *prnt)
 
static void cdr_all_relink (struct cdr_object *cdr)
 
static void cdr_all_unlink (struct cdr_object *cdr)
 
static void cdr_detach (struct ast_cdr *cdr)
 
static void cdr_enable_batch_mode (struct ast_cdr_config *config)
 
static void cdr_engine_shutdown (void)
 
static const char * cdr_format_var_internal (struct ast_cdr *cdr, const char *name)
 
static int cdr_generic_register (struct be_list *generic_list, const char *name, const char *desc, ast_cdrbe be)
 
static void cdr_get_tv (struct timeval when, const char *fmt, char *buf, int bufsize)
 
static int cdr_master_cmp_fn (void *obj, void *arg, int flags)
 
static int cdr_master_hash_fn (const void *obj, const int flags)
 
static void cdr_master_print_fn (void *v_obj, void *where, ao2_prnt_fn *prnt)
 
static struct cdr_objectcdr_object_alloc (struct ast_channel_snapshot *chan, const struct timeval *event_time)
 cdr_object constructor More...
 
static void cdr_object_check_party_a_answer (struct cdr_object *cdr)
 Check to see if a CDR needs to be answered based on its Party A. Note that this is safe to call as much as you want - we won't answer twice. More...
 
static void cdr_object_check_party_a_hangup (struct cdr_object *cdr)
 Check to see if a CDR needs to move to the finalized state because its Party A hungup. More...
 
static struct cdr_objectcdr_object_create_and_append (struct cdr_object *cdr, const struct timeval *event_time)
 Create a new cdr_object and append it to an existing chain. More...
 
static struct ast_cdrcdr_object_create_public_records (struct cdr_object *cdr)
 Create a chain of ast_cdr objects from a chain of cdr_object suitable for consumption by the registered CDR backends. More...
 
static void cdr_object_dispatch (struct cdr_object *cdr)
 Dispatch a CDR. More...
 
static int cdr_object_dispatch_all_cb (void *obj, void *arg, int flags)
 This dispatches all cdr_objects. It should only be used during shutdown, so that we get billing records for everything that we can. More...
 
static void cdr_object_dtor (void *obj)
 cdr_object Destructor More...
 
static void cdr_object_finalize (struct cdr_object *cdr)
 Finalize a CDR. More...
 
static int cdr_object_finalize_party_b (void *obj, void *arg, void *data, int flags)
 
static int cdr_object_format_property (struct cdr_object *cdr_obj, const char *name, char *value, size_t length)
 Format one of the standard properties on a cdr_object. More...
 
static void cdr_object_format_var_internal (struct cdr_object *cdr, const char *name, char *value, size_t length)
 Format a variable on a cdr_object. More...
 
static long cdr_object_get_billsec (struct cdr_object *cdr)
 Compute the billsec for a cdr_object. More...
 
static struct cdr_objectcdr_object_get_by_name (const char *name)
 
static int cdr_object_get_by_name_cb (void *obj, void *arg, int flags)
 
static long cdr_object_get_duration (struct cdr_object *cdr)
 
static int cdr_object_party_b_left_bridge_cb (void *obj, void *arg, void *data, int flags)
 Callback used to notify CDRs of a Party B leaving the bridge. More...
 
static struct cdr_object_snapshotcdr_object_pick_party_a (struct cdr_object_snapshot *left, struct cdr_object_snapshot *right)
 Given two CDR snapshots, figure out who should be Party A for the resulting CDR. More...
 
static int cdr_object_select_all_by_name_cb (void *obj, void *arg, int flags)
 
static void cdr_object_set_disposition (struct cdr_object *cdr, int hangupcause)
 Set the disposition on a cdr_object based on a hangupcause code. More...
 
static void cdr_object_snapshot_copy (struct cdr_object_snapshot *dst, struct cdr_object_snapshot *src)
 Copy a snapshot and its details. More...
 
static void cdr_object_swap_snapshot (struct cdr_object_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot)
 Swap an old cdr_object_snapshot's ast_channel_snapshot for a new ast_channel_snapshot. More...
 
static void cdr_object_transition_state (struct cdr_object *cdr, struct cdr_object_fn_table *fn_table)
 Transition a cdr_object to a new state. More...
 
static void cdr_object_transition_state_init (struct cdr_object *cdr, struct cdr_object_fn_table *fn_table, int do_init)
 Transition a cdr_object to a new state with initiation flag. More...
 
static void cdr_object_update_cid (struct cdr_object_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot)
 
static int cdr_object_update_party_b (void *obj, void *arg, void *data, int flags)
 
static int cdr_object_update_party_b_userfield_cb (void *obj, void *arg, void *data, int flags)
 Callback used to update the userfield on Party B on all CDRs. More...
 
static void cdr_submit_batch (int shutdown)
 
static int cdr_toggle_runtime_options (void)
 Checks if CDRs are enabled and enables/disables the necessary options. More...
 
static int check_new_cdr_needed (struct ast_channel_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot)
 Determine if we need to add a new CDR based on snapshots. More...
 
static char * cli_complete_show (struct ast_cli_args *a)
 Complete user input for 'cdr show'. More...
 
static void cli_show_channel (struct ast_cli_args *a)
 
static void cli_show_channels (struct ast_cli_args *a)
 
 CONFIG_INFO_CORE ("cdr", cfg_info, module_configs, module_config_alloc,.files=ACO_FILES(&module_file_conf),.post_apply_config=module_config_post_apply,)
 
static int copy_variables (struct varshead *to_list, struct varshead *from_list)
 Copy variables from one list to another. More...
 
static int create_subscriptions (void)
 Create the Stasis subcriptions for CDRs. More...
 
static void destroy_subscriptions (void)
 Destroy the active Stasis subscriptions. More...
 
static enum process_bridge_enter_results dial_state_process_bridge_enter (struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
 
static int dial_state_process_dial_begin (struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer)
 
static int dial_state_process_dial_end (struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer, const char *dial_status)
 
static void dial_state_process_party_b (struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
 
static int dial_status_end (const char *dialstatus)
 
static enum ast_cdr_disposition dial_status_to_disposition (const char *dial_status)
 
static enum process_bridge_enter_results dialed_pending_state_process_bridge_enter (struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
 
static int dialed_pending_state_process_dial_begin (struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer)
 
static int dialed_pending_state_process_parking_bridge_enter (struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
 
static int dialed_pending_state_process_party_a (struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
 
static void * do_batch_backend_process (void *data)
 
static void * do_cdr (void *data)
 
static int filter_bridge_messages (struct ast_bridge_snapshot *bridge)
 Filter bridge messages based on bridge technology. More...
 
static int filter_channel_snapshot (struct ast_channel_snapshot *snapshot)
 
static int filter_channel_snapshot_message (struct ast_channel_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot)
 
static void finalize_batch_mode (void)
 
static void finalized_state_init_function (struct cdr_object *cdr)
 
static int finalized_state_process_party_a (struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
 
static void free_variables (struct varshead *headp)
 Delete all variables from a variable list. More...
 
static void handle_bridge_enter_message (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void handle_bridge_leave_message (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 Handler for when a channel leaves a bridge. More...
 
static void handle_bridge_pairings (struct cdr_object *cdr, struct ast_bridge_snapshot *bridge)
 Handle creating bridge pairings for the cdr_object that just entered a bridge. More...
 
static void handle_cdr_sync_message (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 Handler for a synchronization message. More...
 
static void handle_channel_snapshot_update_message (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 Handler for channel snapshot update messages. More...
 
static char * handle_cli_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_show (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_status (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_submit (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static void handle_dial_message (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 Handler for Stasis-Core dial messages. More...
 
static void handle_parked_call_message (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 Handler for when a channel is parked. More...
 
static void handle_parking_bridge_enter_message (struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel, const struct timeval *event_time)
 Handle entering into a parking bridge. More...
 
static void handle_standard_bridge_enter_message (struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel, const struct timeval *event_time)
 Handle a bridge enter message for a 'normal' bridge. More...
 
static int init_batch (void)
 
static int is_cdr_flag_set (unsigned int cdr_flag)
 
static int load_module (void)
 
static void * module_config_alloc (void)
 Create a new module config object. More...
 
static void module_config_destructor (void *obj)
 Dispose of a module config object. More...
 
static void module_config_post_apply (void)
 
static int parked_state_process_bridge_leave (struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
 
static void post_cdr (struct ast_cdr *cdr)
 
static int process_config (int reload)
 
static int reload_module (void)
 
static void reset_batch (void)
 
static void set_variable (struct varshead *headp, const char *name, const char *value)
 
static int single_state_bridge_enter_comparison (struct cdr_object *cdr, struct cdr_object *cand_cdr)
 Handle a comparison between our cdr_object and a cdr_object already in the bridge while in the Single state. The goal of this is to find a Party B for our CDR. More...
 
static void single_state_init_function (struct cdr_object *cdr)
 
static enum process_bridge_enter_results single_state_process_bridge_enter (struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
 
static int single_state_process_dial_begin (struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer)
 
static int single_state_process_parking_bridge_enter (struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
 
static void single_state_process_party_b (struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
 
static int snapshot_cep_changed (struct ast_channel_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot)
 Return whether or not a channel has changed its state in the dialplan, subject to endbeforehexten logic. More...
 
static int snapshot_is_dialed (struct ast_channel_snapshot *snapshot)
 Return whether or not a ast_channel_snapshot is for a channel that was created as the result of a dial operation. More...
 
static void start_batch_mode (void)
 
 STASIS_MESSAGE_TYPE_DEFN_LOCAL (cdr_sync_message_type)
 A message type used to synchronize with the CDR topic. More...
 
static int submit_scheduled_batch (const void *data)
 
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 = "CDR 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 struct ao2_containeractive_cdrs_all
 A container of all active CDRs with a Party B indexed by Party B channel name. More...
 
static struct ao2_containeractive_cdrs_master
 A container of the active master CDRs indexed by Party A channel uniqueid. More...
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct cdr_batchbatch = NULL
 
static struct be_list be_list = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
 
struct cdr_object_fn_table bridge_state_fn_table
 The virtual table for the Bridged state. More...
 
static struct stasis_forwardbridge_subscription
 Our subscription for bridges. More...
 
static ast_mutex_t cdr_batch_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 Lock protecting modifications to the batch queue. More...
 
static int cdr_debug_enabled
 
static ast_cond_t cdr_pending_cond
 
static ast_mutex_t cdr_pending_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 These are used to wake up the CDR thread when there's work to do. More...
 
static const char *const cdr_readonly_vars []
 
static int cdr_sched = -1
 
static ast_mutex_t cdr_sched_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 
static pthread_t cdr_thread = AST_PTHREADT_NULL
 
static struct stasis_topiccdr_topic
 The parent topic for all topics we want to aggregate for CDRs. More...
 
static struct stasis_forwardchannel_subscription
 Our subscription for channels. More...
 
static struct ast_cli_entry cli_commands []
 
struct cdr_object_fn_table dial_state_fn_table
 The virtual table for the Dial state. More...
 
struct cdr_object_fn_table dialed_pending_state_fn_table
 The virtual table for the Dialed Pending state. More...
 
struct cdr_object_fn_table finalized_state_fn_table
 The virtual table for the finalized state. More...
 
static struct aco_type general_option
 The type definition for general options. More...
 
static struct aco_typegeneral_options [] = ACO_TYPES(&general_option)
 
static int global_cdr_sequence = 0
 The global sequence counter used for CDRs. More...
 
static const char * ignore_categories []
 
static struct aco_type ignore_option
 
static struct mo_list mo_list = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
 
static struct aco_file module_file_conf
 The file definition. More...
 
struct cdr_object_fn_table parked_state_fn_table
 The virtual table for the Parked state. More...
 
static struct stasis_forwardparking_subscription
 Our subscription for parking. More...
 
static struct ast_sched_contextsched
 Scheduler items. More...
 
struct cdr_object_fn_table single_state_fn_table
 The virtual table for the Single state. More...
 
static struct stasis_message_routerstasis_router
 Message router for stasis messages regarding channel state. More...
 

Detailed Description

Call Detail Record API.

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m
Note
Includes code and algorithms from the Zapata library.
We do a lot of checking here in the CDR code to try to be sure we don't ever let a CDR slip through our fingers somehow. If someone allocates a CDR, it must be completely handled normally or a WARNING shall be logged, so that we can best keep track of any escape condition where the CDR isn't properly generated and posted.

Definition in file cdr.c.

Macro Definition Documentation

◆ CDR_DEBUG

#define CDR_DEBUG (   fmt,
  ... 
)

◆ cdr_set_debug_mode

#define cdr_set_debug_mode (   mod_cfg)
Value:
do { \
cdr_debug_enabled = ast_test_flag(&(mod_cfg)->general->settings, CDR_DEBUG); \
} while (0)
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define CDR_DEBUG(fmt,...)
Definition: cdr.c:210

Definition at line 203 of file cdr.c.

Referenced by ast_cdr_set_config(), handle_cli_debug(), module_config_post_apply(), and process_config().

◆ DEFAULT_BATCH_SAFE_SHUTDOWN

#define DEFAULT_BATCH_SAFE_SHUTDOWN   "1"

Definition at line 201 of file cdr.c.

Referenced by process_config().

◆ DEFAULT_BATCH_SCHEDULER_ONLY

#define DEFAULT_BATCH_SCHEDULER_ONLY   "0"

Definition at line 200 of file cdr.c.

Referenced by process_config().

◆ DEFAULT_BATCH_SIZE

#define DEFAULT_BATCH_SIZE   "100"

Definition at line 196 of file cdr.c.

Referenced by process_config().

◆ DEFAULT_BATCH_TIME

#define DEFAULT_BATCH_TIME   "300"

Definition at line 198 of file cdr.c.

Referenced by process_config().

◆ DEFAULT_BATCHMODE

#define DEFAULT_BATCHMODE   "0"

Definition at line 190 of file cdr.c.

Referenced by process_config().

◆ DEFAULT_CONGESTION

#define DEFAULT_CONGESTION   "0"

Definition at line 192 of file cdr.c.

◆ DEFAULT_ENABLED

#define DEFAULT_ENABLED   "1"

Definition at line 189 of file cdr.c.

Referenced by process_config().

◆ DEFAULT_END_BEFORE_H_EXTEN

#define DEFAULT_END_BEFORE_H_EXTEN   "1"

Definition at line 193 of file cdr.c.

Referenced by process_config().

◆ DEFAULT_INITIATED_SECONDS

#define DEFAULT_INITIATED_SECONDS   "0"

Definition at line 194 of file cdr.c.

Referenced by process_config().

◆ DEFAULT_UNANSWERED

#define DEFAULT_UNANSWERED   "0"

Definition at line 191 of file cdr.c.

Referenced by process_config().

◆ FORMAT_STRING [1/2]

#define FORMAT_STRING   "%-25.25s %-25.25s %-15.15s %-8.8s %-8.8s %-8.8s %-8.8ld %-8.8ld\n"

◆ FORMAT_STRING [2/2]

#define FORMAT_STRING   "%-10.10s %-20.20s %-25.25s %-15.15s %-15.15s %-8.8s %-8.8s %-8.8s %-8.8ld %-8.8ld\n"

◆ MAX_BATCH_SIZE

#define MAX_BATCH_SIZE   1000

Definition at line 197 of file cdr.c.

Referenced by process_config().

◆ MAX_BATCH_TIME

#define MAX_BATCH_TIME   86400

Definition at line 199 of file cdr.c.

Referenced by process_config().

◆ TITLE_STRING [1/2]

#define TITLE_STRING   "%-25.25s %-25.25s %-15.15s %-8.8s %-8.8s %-8.8s %-8.8s %-8.8s\n"

◆ TITLE_STRING [2/2]

#define TITLE_STRING   "%-10.10s %-20.20s %-25.25s %-15.15s %-15.15s %-8.8s %-8.8s %-8.8s %-8.8s %-8.8s\n"

Enumeration Type Documentation

◆ process_bridge_enter_results

Return types for process_bridge_enter functions.

Enumerator
BRIDGE_ENTER_ONLY_PARTY 

The CDR was the only party in the bridge.

BRIDGE_ENTER_OBTAINED_PARTY_B 

The CDR was able to obtain a Party B from some other party already in the bridge

BRIDGE_ENTER_NO_PARTY_B 

The CDR was not able to obtain a Party B

BRIDGE_ENTER_NEED_CDR 

This CDR can't handle a bridge enter message and a new CDR needs to be created

Definition at line 391 of file cdr.c.

391  {
392  /*!
393  * The CDR was the only party in the bridge.
394  */
396  /*!
397  * The CDR was able to obtain a Party B from some other party already in the bridge
398  */
400  /*!
401  * The CDR was not able to obtain a Party B
402  */
404  /*!
405  * This CDR can't handle a bridge enter message and a new CDR needs to be created
406  */
408 };

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 4651 of file cdr.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 4651 of file cdr.c.

◆ AO2_GLOBAL_OBJ_STATIC()

static AO2_GLOBAL_OBJ_STATIC ( module_configs  )
static

The container for the module configuration.

◆ ast_cdr_alloc()

struct ast_cdr* ast_cdr_alloc ( void  )

Allocate a CDR record.

Return values
amalloc'd ast_cdr structure
NULLon error (malloc failure)

Definition at line 3422 of file cdr.c.

References ast_calloc.

Referenced by ast_cdr_dup().

3423 {
3424  struct ast_cdr *x;
3425 
3426  x = ast_calloc(1, sizeof(*x));
3427  return x;
3428 }
Responsible for call detail data.
Definition: cdr.h:276
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204

◆ ast_cdr_backend_suspend()

int ast_cdr_backend_suspend ( const char *  name)

Suspend a CDR backend temporarily.

Return values
0The backend is suspdended
-1The backend could not be suspended

Definition at line 2866 of file cdr.c.

References ast_debug, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, cdr_beitem::name, and NULL.

Referenced by load_config(), my_unload_module(), and odbc_load_module().

2867 {
2868  int success = -1;
2869  struct cdr_beitem *i = NULL;
2870 
2872  AST_RWLIST_TRAVERSE(&be_list, i, list) {
2873  if (!strcasecmp(name, i->name)) {
2874  ast_debug(3, "Suspending CDR backend %s\n", i->name);
2875  i->suspended = 1;
2876  success = 0;
2877  }
2878  }
2880 
2881  return success;
2882 }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define NULL
Definition: resample.c:96
Registration object for CDR backends.
Definition: cdr.c:321
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
char name[20]
Definition: cdr.c:322
static const char name[]
Definition: cdr_mysql.c:74
List of registered backends.
Definition: cdr.c:330

◆ ast_cdr_backend_unsuspend()

int ast_cdr_backend_unsuspend ( const char *  name)

Unsuspend a CDR backend.

Return values
0The backend was unsuspended
-1The back could not be unsuspended

Definition at line 2884 of file cdr.c.

References ast_debug, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, cdr_beitem::name, and NULL.

Referenced by load_config(), my_load_module(), and odbc_load_module().

2885 {
2886  int success = -1;
2887  struct cdr_beitem *i = NULL;
2888 
2890  AST_RWLIST_TRAVERSE(&be_list, i, list) {
2891  if (!strcasecmp(name, i->name)) {
2892  ast_debug(3, "Unsuspending CDR backend %s\n", i->name);
2893  i->suspended = 0;
2894  success = 0;
2895  }
2896  }
2898 
2899  return success;
2900 }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define NULL
Definition: resample.c:96
Registration object for CDR backends.
Definition: cdr.c:321
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
char name[20]
Definition: cdr.c:322
static const char name[]
Definition: cdr_mysql.c:74
List of registered backends.
Definition: cdr.c:330

◆ ast_cdr_clear_property()

int ast_cdr_clear_property ( const char *  channel_name,
enum ast_cdr_options  option 
)

Clear a property on a CDR for a channel.

Since
12 Clears a flag previously set by ast_cdr_set_property
Parameters
channel_nameThe CDR's channel
optionOption to clear from the CDR
Return values
0on success
1on error

Definition at line 3575 of file cdr.c.

References ao2_cleanup, ao2_lock, ao2_unlock, ast_clear_flag, cdr_object_get_by_name(), cdr_object::flags, cdr_object::fn_table, and cdr_object::next.

Referenced by appcdr_callback(), AST_TEST_DEFINE(), and cdr_prop_write_callback().

3576 {
3577  struct cdr_object *cdr;
3578  struct cdr_object *it_cdr;
3579 
3580  cdr = cdr_object_get_by_name(channel_name);
3581  if (!cdr) {
3582  return -1;
3583  }
3584 
3585  ao2_lock(cdr);
3586  for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3587  if (it_cdr->fn_table == &finalized_state_fn_table) {
3588  continue;
3589  }
3590  ast_clear_flag(&it_cdr->flags, option);
3591  }
3592  ao2_unlock(cdr);
3593 
3594  ao2_cleanup(cdr);
3595  return 0;
3596 }
struct cdr_object * next
Definition: cdr.c:735
#define ao2_unlock(a)
Definition: astobj2.h:730
struct ast_flags flags
Definition: cdr.c:723
#define ao2_lock(a)
Definition: astobj2.h:718
static struct cdr_object * cdr_object_get_by_name(const char *name)
Definition: cdr.c:3312
struct cdr_object_fn_table * fn_table
Definition: cdr.c:715
An in-memory representation of an active CDR.
Definition: cdr.c:712
#define ast_clear_flag(p, flag)
Definition: utils.h:77
struct cdr_object_fn_table finalized_state_fn_table
The virtual table for the finalized state.
Definition: cdr.c:694
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ ast_cdr_disp2str()

const char* ast_cdr_disp2str ( int  disposition)

Disposition to a string.

Parameters
dispositioninput binary form Converts the binary form of a disposition to string form.
Returns
a pointer to the string form

Definition at line 3430 of file cdr.c.

References AST_CDR_ANSWERED, AST_CDR_BUSY, AST_CDR_CONGESTION, AST_CDR_FAILED, AST_CDR_NOANSWER, and AST_CDR_NULL.

Referenced by ast_cdr_format_var(), beanstalk_put(), build_csv_record(), build_radius_record(), cdr_object_finalize(), cdr_read_callback(), execute_cb(), manager_log(), and tds_log().

3431 {
3432  switch (disposition) {
3433  case AST_CDR_NULL:
3434  return "NO ANSWER"; /* by default, for backward compatibility */
3435  case AST_CDR_NOANSWER:
3436  return "NO ANSWER";
3437  case AST_CDR_FAILED:
3438  return "FAILED";
3439  case AST_CDR_BUSY:
3440  return "BUSY";
3441  case AST_CDR_ANSWERED:
3442  return "ANSWERED";
3443  case AST_CDR_CONGESTION:
3444  return "CONGESTION";
3445  }
3446  return "UNKNOWN";
3447 }
enum ast_cdr_disposition disposition
Definition: cdr.c:717

◆ ast_cdr_dup()

struct ast_cdr* ast_cdr_dup ( struct ast_cdr cdr)

Duplicate a public CDR.

Parameters
cdrthe record to duplicate
Return values
amalloc'd ast_cdr structure,
NULLon error (malloc failure)

Definition at line 2998 of file cdr.c.

References ast_cdr_alloc(), AST_LIST_HEAD_INIT_NOLOCK, copy_variables(), ast_cdr::next, NULL, and ast_cdr::varshead.

Referenced by custom_log(), load_values_config(), manager_log(), and syslog_log().

2999 {
3000  struct ast_cdr *newcdr;
3001 
3002  if (!cdr) {
3003  return NULL;
3004  }
3005  newcdr = ast_cdr_alloc();
3006  if (!newcdr) {
3007  return NULL;
3008  }
3009 
3010  *newcdr = *cdr;
3012  copy_variables(&newcdr->varshead, &cdr->varshead);
3013  newcdr->next = NULL;
3014 
3015  return newcdr;
3016 }
struct ast_cdr * next
Definition: cdr.h:325
struct ast_cdr * ast_cdr_alloc(void)
Allocate a CDR record.
Definition: cdr.c:3422
static int copy_variables(struct varshead *to_list, struct varshead *from_list)
Copy variables from one list to another.
Definition: cdr.c:746
#define NULL
Definition: resample.c:96
struct varshead varshead
Definition: cdr.h:323
Responsible for call detail data.
Definition: cdr.h:276
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:680

◆ ast_cdr_engine_term()

void ast_cdr_engine_term ( void  )

Submit any remaining CDRs and prepare for shutdown

Definition at line 4577 of file cdr.c.

References ao2_alloc, ao2_cleanup, ao2_global_obj_ref, ast_debug, ast_test_flag, BATCH_MODE_SAFE_SHUTDOWN, CDR_BATCHMODE, cdr_submit_batch(), NULL, RAII_VAR, stasis_message_create(), and stasis_message_router_publish_sync().

Referenced by can_safely_quit(), and finalize_batch_mode().

4578 {
4579  RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
4580 
4581  /* Since this is called explicitly during process shutdown, we might not have ever
4582  * been initialized. If so, the config object will be NULL.
4583  */
4584  if (!mod_cfg) {
4585  return;
4586  }
4587 
4588  if (cdr_sync_message_type()) {
4589  void *payload;
4590  struct stasis_message *message;
4591 
4592  if (!stasis_router) {
4593  return;
4594  }
4595 
4596  /* Make sure we have the needed items */
4597  payload = ao2_alloc(sizeof(*payload), NULL);
4598  if (!payload) {
4599  return;
4600  }
4601 
4602  ast_debug(1, "CDR Engine termination request received; waiting on messages...\n");
4603 
4604  message = stasis_message_create(cdr_sync_message_type(), payload);
4605  if (message) {
4607  }
4608  ao2_cleanup(message);
4609  ao2_cleanup(payload);
4610  }
4611 
4612  if (ast_test_flag(&mod_cfg->general->settings, CDR_BATCHMODE)) {
4613  cdr_submit_batch(ast_test_flag(&mod_cfg->general->batch_settings.settings, BATCH_MODE_SAFE_SHUTDOWN));
4614  }
4615 }
static struct stasis_message_router * stasis_router
Message router for stasis messages regarding channel state.
Definition: cdr.c:371
#define ast_test_flag(p, flag)
Definition: utils.h:63
void stasis_message_router_publish_sync(struct stasis_message_router *router, struct stasis_message *message)
Publish a message to a message router&#39;s subscription synchronously.
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
static void cdr_submit_batch(int shutdown)
Definition: cdr.c:3766
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#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:851
The configuration settings for this module.
Definition: cdr.c:222
struct stasis_message * stasis_message_create(struct stasis_message_type *type, void *data)
Create a new message.
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ ast_cdr_fork()

int ast_cdr_fork ( const char *  channel_name,
struct ast_flags options 
)

Fork a CDR.

Since
12
Parameters
channel_nameThe name of the channel whose CDR should be forked
optionsOptions to control how the fork occurs.
Return values
0on success
-1on failure

Definition at line 3637 of file cdr.c.

References cdr_object::answer, ao2_cleanup, ao2_ref, cdr_object::appl, AST_CDR_FLAG_FINALIZE, AST_CDR_FLAG_KEEP_VARS, AST_CDR_FLAG_RESET, AST_CDR_FLAG_SET_ANSWER, AST_CDR_LOCK_APP, ast_clear_flag, ast_debug, AST_STATE_UP, ast_string_field_set, ast_test_flag, ast_tvnow(), ast_channel_snapshot::base, cdr_object::bridge, cdr_all_relink(), cdr_object_create_and_append(), cdr_object_finalize(), cdr_object_get_by_name(), cdr_object_transition_state(), context, cdr_object::context, copy_variables(), cdr_object::data, exten, cdr_object::exten, cdr_object_snapshot::flags, cdr_object::flags, cdr_object::fn_table, free_variables(), cdr_object::last, cdr_object::lastevent, lock, ast_channel_snapshot_base::name, cdr_object::next, cdr_object::party_a, cdr_object::party_b, RAII_VAR, SCOPED_AO2LOCK, cdr_object_snapshot::snapshot, cdr_object::start, ast_channel_snapshot::state, cdr_object_snapshot::userfield, and cdr_object_snapshot::variables.

Referenced by AST_TEST_DEFINE(), and forkcdr_callback().

3638 {
3639  RAII_VAR(struct cdr_object *, cdr, cdr_object_get_by_name(channel_name), ao2_cleanup);
3640  struct cdr_object *new_cdr;
3641  struct cdr_object *it_cdr;
3642  struct cdr_object *cdr_obj;
3643 
3644  if (!cdr) {
3645  return -1;
3646  }
3647 
3648  {
3649  SCOPED_AO2LOCK(lock, cdr);
3650  struct timeval now = ast_tvnow();
3651 
3652  cdr_obj = cdr->last;
3653  if (cdr_obj->fn_table == &finalized_state_fn_table) {
3654  /* If the last CDR in the chain is finalized, don't allow a fork -
3655  * things are already dying at this point
3656  */
3657  return -1;
3658  }
3659 
3660  /* Copy over the basic CDR information. The Party A information is
3661  * copied over automatically as part of the append
3662  */
3663  ast_debug(1, "Forking CDR for channel %s\n", cdr->party_a.snapshot->base->name);
3664  new_cdr = cdr_object_create_and_append(cdr, &now);
3665  if (!new_cdr) {
3666  return -1;
3667  }
3668  new_cdr->fn_table = cdr_obj->fn_table;
3669  ast_string_field_set(new_cdr, bridge, cdr->bridge);
3670  ast_string_field_set(new_cdr, appl, cdr->appl);
3671  ast_string_field_set(new_cdr, data, cdr->data);
3672  ast_string_field_set(new_cdr, context, cdr->context);
3673  ast_string_field_set(new_cdr, exten, cdr->exten);
3674  new_cdr->flags = cdr->flags;
3675  /* Explicitly clear the AST_CDR_LOCK_APP flag - we want
3676  * the application to be changed on the new CDR if the
3677  * dialplan demands it
3678  */
3680 
3681  /* If there's a Party B, copy it over as well */
3682  if (cdr_obj->party_b.snapshot) {
3683  new_cdr->party_b.snapshot = cdr_obj->party_b.snapshot;
3684  ao2_ref(new_cdr->party_b.snapshot, +1);
3685  cdr_all_relink(new_cdr);
3686  strcpy(new_cdr->party_b.userfield, cdr_obj->party_b.userfield);
3687  new_cdr->party_b.flags = cdr_obj->party_b.flags;
3688  if (ast_test_flag(options, AST_CDR_FLAG_KEEP_VARS)) {
3689  copy_variables(&new_cdr->party_b.variables, &cdr_obj->party_b.variables);
3690  }
3691  }
3692  new_cdr->start = cdr_obj->start;
3693  new_cdr->answer = cdr_obj->answer;
3694  new_cdr->lastevent = ast_tvnow();
3695 
3696  /* Modify the times based on the flags passed in */
3698  && new_cdr->party_a.snapshot->state == AST_STATE_UP) {
3699  new_cdr->answer = ast_tvnow();
3700  }
3701  if (ast_test_flag(options, AST_CDR_FLAG_RESET)) {
3702  new_cdr->answer = ast_tvnow();
3703  new_cdr->start = ast_tvnow();
3704  }
3705 
3706  /* Create and append, by default, copies over the variables */
3707  if (!ast_test_flag(options, AST_CDR_FLAG_KEEP_VARS)) {
3708  free_variables(&new_cdr->party_a.variables);
3709  }
3710 
3711  /* Finalize any current CDRs */
3712  if (ast_test_flag(options, AST_CDR_FLAG_FINALIZE)) {
3713  for (it_cdr = cdr; it_cdr != new_cdr; it_cdr = it_cdr->next) {
3714  if (it_cdr->fn_table == &finalized_state_fn_table) {
3715  continue;
3716  }
3717  /* Force finalization on the CDR. This will bypass any checks for
3718  * end before 'h' extension.
3719  */
3720  cdr_object_finalize(it_cdr);
3722  }
3723  }
3724  }
3725 
3726  return 0;
3727 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
struct varshead variables
Definition: cdr.c:708
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_channel_snapshot * snapshot
Definition: cdr.c:705
unsigned int flags
Definition: utils.h:200
struct cdr_object * next
Definition: cdr.c:735
struct cdr_object_snapshot party_b
Definition: cdr.c:714
struct timeval answer
Definition: cdr.c:719
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
struct timeval start
Definition: cdr.c:718
unsigned int flags
Definition: cdr.c:707
static int copy_variables(struct varshead *to_list, struct varshead *from_list)
Copy variables from one list to another.
Definition: cdr.c:746
struct cdr_object_snapshot party_a
Definition: cdr.c:713
const ast_string_field appl
Definition: cdr.c:734
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
char userfield[AST_MAX_USER_FIELD]
Definition: cdr.c:706
struct ast_flags flags
Definition: cdr.c:723
#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:851
ast_mutex_t lock
Definition: app_meetme.c:1091
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static struct cdr_object * cdr_object_get_by_name(const char *name)
Definition: cdr.c:3312
static void free_variables(struct varshead *headp)
Delete all variables from a variable list.
Definition: cdr.c:777
struct cdr_object_fn_table * fn_table
Definition: cdr.c:715
An in-memory representation of an active CDR.
Definition: cdr.c:712
struct cdr_object * last
Definition: cdr.c:736
const ast_string_field data
Definition: cdr.c:734
struct timeval lastevent
Definition: cdr.c:721
#define SCOPED_AO2LOCK(varname, obj)
scoped lock specialization for ao2 mutexes.
Definition: lock.h:602
enum ast_channel_state state
#define ast_clear_flag(p, flag)
Definition: utils.h:77
struct cdr_object_fn_table finalized_state_fn_table
The virtual table for the finalized state.
Definition: cdr.c:694
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
static struct cdr_object * cdr_object_create_and_append(struct cdr_object *cdr, const struct timeval *event_time)
Create a new cdr_object and append it to an existing chain.
Definition: cdr.c:1075
static void cdr_object_finalize(struct cdr_object *cdr)
Finalize a CDR.
Definition: cdr.c:1440
const ast_string_field bridge
Definition: cdr.c:734
static void cdr_all_relink(struct cdr_object *cdr)
Definition: cdr.c:949
static void cdr_object_transition_state(struct cdr_object *cdr, struct cdr_object_fn_table *fn_table)
Transition a cdr_object to a new state.
Definition: cdr.c:821
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ ast_cdr_format_var()

void ast_cdr_format_var ( struct ast_cdr cdr,
const char *  name,
char **  ret,
char *  workspace,
int  workspacelen,
int  raw 
)

Format a CDR variable from an already posted CDR.

Since
12
Parameters
cdrThe dispatched CDR to process
nameThe name of the variable
retPointer to the formatted buffer
workspaceA pointer to the buffer to use to format the variable
workspacelenThe size of workspace
rawIf non-zero and a date/time is extraced, provide epoch seconds. Otherwise format as a date/time stamp

Definition at line 3050 of file cdr.c.

References ast_cdr::accountcode, ast_cdr::amaflags, ast_cdr::answer, ast_cdr_disp2str(), ast_channel_amaflags2string(), ast_copy_string(), ast_strlen_zero, ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), ast_cdr::billsec, cdr_format_var_internal(), cdr_get_tv(), ast_cdr::channel, ast_cdr::clid, ast_cdr::dcontext, ast_cdr::disposition, ast_cdr::dst, ast_cdr::dstchannel, ast_cdr::duration, ast_cdr::end, ast_cdr::lastapp, ast_cdr::lastdata, ast_cdr::linkedid, NULL, ast_cdr::peeraccount, ast_cdr::sequence, ast_cdr::src, ast_cdr::start, ast_cdr::uniqueid, and ast_cdr::userfield.

Referenced by cdr_handler(), cdr_read_callback(), cdr_retrieve_time(), mysql_log(), odbc_log(), and pgsql_log().

3051 {
3052  const char *fmt = "%Y-%m-%d %T";
3053  const char *varbuf;
3054 
3055  if (!cdr) {
3056  return;
3057  }
3058 
3059  *ret = NULL;
3060 
3061  if (!strcasecmp(name, "clid")) {
3062  ast_copy_string(workspace, cdr->clid, workspacelen);
3063  } else if (!strcasecmp(name, "src")) {
3064  ast_copy_string(workspace, cdr->src, workspacelen);
3065  } else if (!strcasecmp(name, "dst")) {
3066  ast_copy_string(workspace, cdr->dst, workspacelen);
3067  } else if (!strcasecmp(name, "dcontext")) {
3068  ast_copy_string(workspace, cdr->dcontext, workspacelen);
3069  } else if (!strcasecmp(name, "channel")) {
3070  ast_copy_string(workspace, cdr->channel, workspacelen);
3071  } else if (!strcasecmp(name, "dstchannel")) {
3072  ast_copy_string(workspace, cdr->dstchannel, workspacelen);
3073  } else if (!strcasecmp(name, "lastapp")) {
3074  ast_copy_string(workspace, cdr->lastapp, workspacelen);
3075  } else if (!strcasecmp(name, "lastdata")) {
3076  ast_copy_string(workspace, cdr->lastdata, workspacelen);
3077  } else if (!strcasecmp(name, "start")) {
3078  cdr_get_tv(cdr->start, raw ? NULL : fmt, workspace, workspacelen);
3079  } else if (!strcasecmp(name, "answer")) {
3080  cdr_get_tv(cdr->answer, raw ? NULL : fmt, workspace, workspacelen);
3081  } else if (!strcasecmp(name, "end")) {
3082  cdr_get_tv(cdr->end, raw ? NULL : fmt, workspace, workspacelen);
3083  } else if (!strcasecmp(name, "duration")) {
3084  snprintf(workspace, workspacelen, "%ld", cdr->end.tv_sec != 0 ? cdr->duration : (long)ast_tvdiff_ms(ast_tvnow(), cdr->start) / 1000);
3085  } else if (!strcasecmp(name, "billsec")) {
3086  snprintf(workspace, workspacelen, "%ld", (cdr->billsec || !ast_tvzero(cdr->end) || ast_tvzero(cdr->answer)) ? cdr->billsec : (long)ast_tvdiff_ms(ast_tvnow(), cdr->answer) / 1000);
3087  } else if (!strcasecmp(name, "disposition")) {
3088  if (raw) {
3089  snprintf(workspace, workspacelen, "%ld", cdr->disposition);
3090  } else {
3091  ast_copy_string(workspace, ast_cdr_disp2str(cdr->disposition), workspacelen);
3092  }
3093  } else if (!strcasecmp(name, "amaflags")) {
3094  if (raw) {
3095  snprintf(workspace, workspacelen, "%ld", cdr->amaflags);
3096  } else {
3097  ast_copy_string(workspace, ast_channel_amaflags2string(cdr->amaflags), workspacelen);
3098  }
3099  } else if (!strcasecmp(name, "accountcode")) {
3100  ast_copy_string(workspace, cdr->accountcode, workspacelen);
3101  } else if (!strcasecmp(name, "peeraccount")) {
3102  ast_copy_string(workspace, cdr->peeraccount, workspacelen);
3103  } else if (!strcasecmp(name, "uniqueid")) {
3104  ast_copy_string(workspace, cdr->uniqueid, workspacelen);
3105  } else if (!strcasecmp(name, "linkedid")) {
3106  ast_copy_string(workspace, cdr->linkedid, workspacelen);
3107  } else if (!strcasecmp(name, "userfield")) {
3108  ast_copy_string(workspace, cdr->userfield, workspacelen);
3109  } else if (!strcasecmp(name, "sequence")) {
3110  snprintf(workspace, workspacelen, "%d", cdr->sequence);
3111  } else if ((varbuf = cdr_format_var_internal(cdr, name))) {
3112  ast_copy_string(workspace, varbuf, workspacelen);
3113  } else {
3114  workspace[0] = '\0';
3115  }
3116 
3117  if (!ast_strlen_zero(workspace)) {
3118  *ret = workspace;
3119  }
3120 }
char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: cdr.h:308
char dstchannel[AST_MAX_EXTENSION]
Definition: cdr.h:288
long int billsec
Definition: cdr.h:302
char dcontext[AST_MAX_EXTENSION]
Definition: cdr.h:284
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:108
int sequence
Definition: cdr.h:320
const char * ast_channel_amaflags2string(enum ama_flags flags)
Convert the enum representation of an AMA flag to a string representation.
Definition: channel.c:4367
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98
#define NULL
Definition: resample.c:96
char lastdata[AST_MAX_EXTENSION]
Definition: cdr.h:292
long int amaflags
Definition: cdr.h:306
char linkedid[AST_MAX_UNIQUEID]
Definition: cdr.h:316
char uniqueid[AST_MAX_UNIQUEID]
Definition: cdr.h:314
static void cdr_get_tv(struct timeval when, const char *fmt, char *buf, int bufsize)
Definition: cdr.c:3035
char dst[AST_MAX_EXTENSION]
Definition: cdr.h:282
char channel[AST_MAX_EXTENSION]
Definition: cdr.h:286
static const char * cdr_format_var_internal(struct ast_cdr *cdr, const char *name)
Definition: cdr.c:3018
struct timeval answer
Definition: cdr.h:296
char lastapp[AST_MAX_EXTENSION]
Definition: cdr.h:290
#define ast_strlen_zero(a)
Definition: muted.c:73
struct timeval start
Definition: cdr.h:294
static const char name[]
Definition: cdr_mysql.c:74
long int duration
Definition: cdr.h:300
char src[AST_MAX_EXTENSION]
Definition: cdr.h:280
char peeraccount[AST_MAX_ACCOUNT_CODE]
Definition: cdr.h:310
struct timeval end
Definition: cdr.h:298
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
long int disposition
Definition: cdr.h:304
char clid[AST_MAX_EXTENSION]
Definition: cdr.h:278
char userfield[AST_MAX_USER_FIELD]
Definition: cdr.h:318
const char * ast_cdr_disp2str(int disposition)
Disposition to a string.
Definition: cdr.c:3430

◆ ast_cdr_free()

void ast_cdr_free ( struct ast_cdr cdr)

Free a CDR record.

Parameters
cdrast_cdr structure to free Returns nothing

Definition at line 3411 of file cdr.c.

References ast_free, free_variables(), ast_cdr::next, and ast_cdr::varshead.

Referenced by ast_channel_destructor(), ast_dummy_channel_destructor(), cdr_detach(), clear_mock_cdr_backend(), and do_batch_backend_process().

3412 {
3413  while (cdr) {
3414  struct ast_cdr *next = cdr->next;
3415 
3416  free_variables(&cdr->varshead);
3417  ast_free(cdr);
3418  cdr = next;
3419  }
3420 }
struct ast_cdr * next
Definition: cdr.h:325
struct varshead varshead
Definition: cdr.h:323
static void free_variables(struct varshead *headp)
Delete all variables from a variable list.
Definition: cdr.c:777
Responsible for call detail data.
Definition: cdr.h:276
#define ast_free(a)
Definition: astmm.h:182

◆ ast_cdr_generic_unregister()

static int ast_cdr_generic_unregister ( struct be_list generic_list,
const char *  name 
)
static

Definition at line 2953 of file cdr.c.

References ao2_container_count(), ast_free, ast_log, AST_LOG_WARNING, AST_RWLIST_REMOVE, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, match(), cdr_beitem::name, and NULL.

Referenced by ast_cdr_modifier_unregister(), and ast_cdr_unregister().

2954 {
2955  struct cdr_beitem *match = NULL;
2956  int active_count;
2957 
2958  AST_RWLIST_WRLOCK(generic_list);
2959  AST_RWLIST_TRAVERSE(generic_list, match, list) {
2960  if (!strcasecmp(name, match->name)) {
2961  break;
2962  }
2963  }
2964 
2965  if (!match) {
2966  AST_RWLIST_UNLOCK(generic_list);
2967  return 0;
2968  }
2969 
2970  active_count = ao2_container_count(active_cdrs_master);
2971 
2972  if (!match->suspended && active_count != 0) {
2973  AST_RWLIST_UNLOCK(generic_list);
2974  ast_log(AST_LOG_WARNING, "Unable to unregister CDR backend %s; %d CDRs are still active\n",
2975  name, active_count);
2976  return -1;
2977  }
2978 
2979  AST_RWLIST_REMOVE(generic_list, match, list);
2980  AST_RWLIST_UNLOCK(generic_list);
2981 
2982  ast_verb(2, "Unregistered '%s' CDR backend\n", name);
2983  ast_free(match);
2984 
2985  return 0;
2986 }
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define AST_LOG_WARNING
Definition: logger.h:279
static int match(struct ast_sockaddr *addr, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
Definition: chan_iax2.c:2315
#define NULL
Definition: resample.c:96
#define ast_verb(level,...)
Definition: logger.h:455
Registration object for CDR backends.
Definition: cdr.c:321
#define ast_log
Definition: astobj2.c:42
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
char name[20]
Definition: cdr.c:322
static struct ao2_container * active_cdrs_master
A container of the active master CDRs indexed by Party A channel uniqueid.
Definition: cdr.c:365
static const char name[]
Definition: cdr_mysql.c:74
#define ast_free(a)
Definition: astmm.h:182
#define AST_RWLIST_REMOVE
Definition: linkedlists.h:884

◆ ast_cdr_get_config()

struct ast_cdr_config* ast_cdr_get_config ( void  )

Obtain the current CDR 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 CDR configuration

Definition at line 2826 of file cdr.c.

References ao2_bump, ao2_cleanup, ao2_global_obj_ref, module_config::general, and NULL.

Referenced by test_cdr_init_cb().

2827 {
2828  struct ast_cdr_config *general;
2829  struct module_config *mod_cfg;
2830 
2831  mod_cfg = ao2_global_obj_ref(module_configs);
2832  if (!mod_cfg) {
2833  return NULL;
2834  }
2835  general = ao2_bump(mod_cfg->general);
2836  ao2_cleanup(mod_cfg);
2837  return general;
2838 }
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define NULL
Definition: resample.c:96
#define ao2_bump(obj)
Definition: astobj2.h:491
The configuration settings for this module.
Definition: cdr.c:222
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
The global options available for CDRs.
Definition: cdr.h:264
struct ast_cdr_config * general
Definition: cdr.c:223

◆ ast_cdr_getvar()

int ast_cdr_getvar ( const char *  channel_name,
const char *  name,
char *  value,
size_t  length 
)

Retrieve a CDR variable from a channel's current CDR.

Since
12
Parameters
channel_nameThe name of the party A channel that the CDR is associated with
nameThe name of the variable to retrieve
valueBuffer to hold the value
lengthThe size of the buffer
Return values
0on success
non-zeroon failure

Definition at line 3324 of file cdr.c.

References ao2_cleanup, ao2_lock, ao2_unlock, ast_log, AST_LOG_ERROR, ast_strlen_zero, cdr_object_format_property(), cdr_object_format_var_internal(), cdr_object_get_by_name(), and cdr_object::last.

Referenced by AST_TEST_DEFINE(), cdr_read_callback(), and cdr_retrieve_time().

3325 {
3326  struct cdr_object *cdr;
3327  struct cdr_object *cdr_obj;
3328 
3329  if (ast_strlen_zero(name)) {
3330  return 1;
3331  }
3332 
3333  cdr = cdr_object_get_by_name(channel_name);
3334  if (!cdr) {
3335  ast_log(AST_LOG_ERROR, "Unable to find CDR for channel %s\n", channel_name);
3336  return 1;
3337  }
3338 
3339  ao2_lock(cdr);
3340 
3341  cdr_obj = cdr->last;
3342  if (cdr_object_format_property(cdr_obj, name, value, length)) {
3343  /* Property failed; attempt variable */
3344  cdr_object_format_var_internal(cdr_obj, name, value, length);
3345  }
3346 
3347  ao2_unlock(cdr);
3348 
3349  ao2_cleanup(cdr);
3350  return 0;
3351 }
static void cdr_object_format_var_internal(struct cdr_object *cdr, const char *name, char *value, size_t length)
Format a variable on a cdr_object.
Definition: cdr.c:3226
#define ao2_unlock(a)
Definition: astobj2.h:730
int value
Definition: syslog.c:37
#define ast_log
Definition: astobj2.c:42
#define AST_LOG_ERROR
Definition: logger.h:290
static int cdr_object_format_property(struct cdr_object *cdr_obj, const char *name, char *value, size_t length)
Format one of the standard properties on a cdr_object.
Definition: cdr.c:3243
#define ao2_lock(a)
Definition: astobj2.h:718
static struct cdr_object * cdr_object_get_by_name(const char *name)
Definition: cdr.c:3312
An in-memory representation of an active CDR.
Definition: cdr.c:712
struct cdr_object * last
Definition: cdr.c:736
#define ast_strlen_zero(a)
Definition: muted.c:73
static const char name[]
Definition: cdr_mysql.c:74
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ ast_cdr_is_enabled()

int ast_cdr_is_enabled ( void  )

Return TRUE if CDR subsystem is enabled.

Definition at line 2861 of file cdr.c.

References CDR_ENABLED, and is_cdr_flag_set().

Referenced by action_coresettings(), and handle_show_settings().

2862 {
2863  return is_cdr_flag_set(CDR_ENABLED);
2864 }
static int is_cdr_flag_set(unsigned int cdr_flag)
Definition: cdr.c:1127

◆ ast_cdr_message_router()

struct stasis_message_router* ast_cdr_message_router ( void  )

Return the message router for the CDR engine.

This returns the stasis_message_router that the CDR engine uses for dispatching Stasis Message Bus API messages. The reference on the message router is bumped and must be released by the caller of this function.

Return values
NULLif the CDR engine is disabled or unavailable
thestasis_message_router otherwise

Definition at line 4291 of file cdr.c.

References ao2_bump, NULL, and stasis_router.

Referenced by cdr_prop_write(), cdr_read(), cdr_write(), forkcdr_exec(), load_module(), publish_app_cdr_message(), and unload_module().

4292 {
4293  if (!stasis_router) {
4294  return NULL;
4295  }
4296 
4298  return stasis_router;
4299 }
static struct stasis_message_router * stasis_router
Message router for stasis messages regarding channel state.
Definition: cdr.c:371
#define NULL
Definition: resample.c:96
#define ao2_bump(obj)
Definition: astobj2.h:491

◆ ast_cdr_modifier_register()

int ast_cdr_modifier_register ( const char *  name,
const char *  desc,
ast_cdrbe  be 
)

Register a CDR modifier.

Parameters
namename associated with the particular CDR modifier
descdescription of the CDR modifier
befunction pointer to a CDR modifier

Used to register a Call Detail Record modifier.

This gives modules a chance to modify CDR fields before they are dispatched to registered backends (odbc, syslog, etc).

Note
The modified CDR will be passed to all registered backends for logging. For instance, if cdr_manager changes the CDR data, cdr_adaptive_odbc will also get the modified CDR.
Return values
0on success.
-1on error

Definition at line 2948 of file cdr.c.

References cdr_generic_register().

2949 {
2950  return cdr_generic_register((struct be_list *)&mo_list, name, desc, be);
2951 }
static const char desc[]
Definition: cdr_mysql.c:73
char * be
Definition: eagi_proxy.c:73
static int cdr_generic_register(struct be_list *generic_list, const char *name, const char *desc, ast_cdrbe be)
Definition: cdr.c:2902
List of registered modifiers.
Definition: cdr.c:333
static const char name[]
Definition: cdr_mysql.c:74
List of registered backends.
Definition: cdr.c:330

◆ ast_cdr_modifier_unregister()

int ast_cdr_modifier_unregister ( const char *  name)

Unregister a CDR modifier.

Parameters
namename of CDR modifier to unregister Unregisters a CDR modifier by its name
Return values
0The modifier unregistered successfully
-1The modifier could not be unregistered at this time

Definition at line 2993 of file cdr.c.

References ast_cdr_generic_unregister().

2994 {
2995  return ast_cdr_generic_unregister((struct be_list *)&mo_list, name);
2996 }
static int ast_cdr_generic_unregister(struct be_list *generic_list, const char *name)
Definition: cdr.c:2953
List of registered modifiers.
Definition: cdr.c:333
static const char name[]
Definition: cdr_mysql.c:74
List of registered backends.
Definition: cdr.c:330

◆ ast_cdr_register()

int ast_cdr_register ( const char *  name,
const char *  desc,
ast_cdrbe  be 
)

Register a CDR handling engine.

Parameters
namename associated with the particular CDR handler
descdescription of the CDR handler
befunction pointer to a CDR handler Used to register a Call Detail Record handler.
Return values
0on success.
-1on error

Definition at line 2943 of file cdr.c.

References cdr_generic_register().

Referenced by load_module(), load_values_config(), my_load_module(), odbc_load_module(), and unload_module().

2944 {
2945  return cdr_generic_register(&be_list, name, desc, be);
2946 }
static const char desc[]
Definition: cdr_mysql.c:73
char * be
Definition: eagi_proxy.c:73
static int cdr_generic_register(struct be_list *generic_list, const char *name, const char *desc, ast_cdrbe be)
Definition: cdr.c:2902
static const char name[]
Definition: cdr_mysql.c:74
List of registered backends.
Definition: cdr.c:330

◆ ast_cdr_reset()

int ast_cdr_reset ( const char *  channel_name,
int  keep_variables 
)

Reset the detail record.

Parameters
channel_nameThe channel that the CDR is associated with
keep_variablesKeep the variables during the reset. If zero, variables are discarded during the reset.
Return values
0on success
-1on failure

Definition at line 3598 of file cdr.c.

References cdr_object::answer, ao2_cleanup, ao2_lock, ao2_unlock, AST_LIST_REMOVE_HEAD, ast_tvnow(), ast_var_delete(), cdr_object_check_party_a_answer(), cdr_object_get_by_name(), cdr_object::end, cdr_object::lastevent, cdr_object::next, cdr_object::party_a, cdr_object::party_b, cdr_object_snapshot::snapshot, cdr_object::start, and cdr_object_snapshot::variables.

Referenced by appcdr_callback(), and dial_exec_full().

3599 {
3600  struct cdr_object *cdr;
3601  struct ast_var_t *vardata;
3602  struct cdr_object *it_cdr;
3603 
3604  cdr = cdr_object_get_by_name(channel_name);
3605  if (!cdr) {
3606  return -1;
3607  }
3608 
3609  ao2_lock(cdr);
3610  for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3611  /* clear variables */
3612  if (!keep_variables) {
3613  while ((vardata = AST_LIST_REMOVE_HEAD(&it_cdr->party_a.variables, entries))) {
3614  ast_var_delete(vardata);
3615  }
3616  if (cdr->party_b.snapshot) {
3617  while ((vardata = AST_LIST_REMOVE_HEAD(&it_cdr->party_b.variables, entries))) {
3618  ast_var_delete(vardata);
3619  }
3620  }
3621  }
3622 
3623  /* Reset to initial state */
3624  memset(&it_cdr->start, 0, sizeof(it_cdr->start));
3625  memset(&it_cdr->end, 0, sizeof(it_cdr->end));
3626  memset(&it_cdr->answer, 0, sizeof(it_cdr->answer));
3627  it_cdr->start = ast_tvnow();
3628  it_cdr->lastevent = it_cdr->start;
3630  }
3631  ao2_unlock(cdr);
3632 
3633  ao2_cleanup(cdr);
3634  return 0;
3635 }
struct varshead variables
Definition: cdr.c:708
struct ast_channel_snapshot * snapshot
Definition: cdr.c:705
struct cdr_object * next
Definition: cdr.c:735
struct cdr_object_snapshot party_b
Definition: cdr.c:714
struct timeval answer
Definition: cdr.c:719
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define ao2_unlock(a)
Definition: astobj2.h:730
struct timeval start
Definition: cdr.c:718
struct cdr_object_snapshot party_a
Definition: cdr.c:713
#define ao2_lock(a)
Definition: astobj2.h:718
static struct cdr_object * cdr_object_get_by_name(const char *name)
Definition: cdr.c:3312
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
An in-memory representation of an active CDR.
Definition: cdr.c:712
void ast_var_delete(struct ast_var_t *var)
Definition: extconf.c:2473
struct timeval lastevent
Definition: cdr.c:721
struct timeval end
Definition: cdr.c:720
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static void cdr_object_check_party_a_answer(struct cdr_object *cdr)
Check to see if a CDR needs to be answered based on its Party A. Note that this is safe to call as mu...
Definition: cdr.c:1494

◆ ast_cdr_serialize_variables()

int ast_cdr_serialize_variables ( const char *  channel_name,
struct ast_str **  buf,
char  delim,
char  sep 
)

Serializes all the data and variables for a current CDR record.

Parameters
channel_nameThe channel to get the CDR for
bufA buffer to use for formatting the data
delimA delimeter to use to separate variable keys/values
sepA separator to use between nestings
Return values
thetotal number of serialized variables

Definition at line 3353 of file cdr.c.

References ao2_cleanup, ao2_lock, ao2_unlock, ast_assert, AST_LIST_TRAVERSE, ast_log, AST_LOG_ERROR, ast_str_append(), ast_str_reset(), ast_strlen_zero, ast_var_name(), ast_var_value(), CDR_ENABLED, cdr_object_format_property(), cdr_object_get_by_name(), ast_var_t::entries, is_cdr_flag_set(), LOG_ERROR, cdr_object::next, cdr_object::party_a, S_OR, total, var, and cdr_object_snapshot::variables.

Referenced by handle_showchan().

3354 {
3355  struct cdr_object *cdr;
3356  struct cdr_object *it_cdr;
3357  struct ast_var_t *variable;
3358  const char *var;
3359  char workspace[256];
3360  int total = 0, x = 0, i;
3361 
3362  cdr = cdr_object_get_by_name(channel_name);
3363  if (!cdr) {
3365  ast_log(AST_LOG_ERROR, "Unable to find CDR for channel %s\n", channel_name);
3366  }
3367  return 0;
3368  }
3369 
3370  ast_str_reset(*buf);
3371 
3372  ao2_lock(cdr);
3373  for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3374  if (++x > 1) {
3375  ast_str_append(buf, 0, "\n");
3376  }
3377 
3378  AST_LIST_TRAVERSE(&it_cdr->party_a.variables, variable, entries) {
3379  if (!(var = ast_var_name(variable))) {
3380  continue;
3381  }
3382 
3383  if (ast_str_append(buf, 0, "level %d: %s%c%s%c", x, var, delim, S_OR(ast_var_value(variable), ""), sep) < 0) {
3384  ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
3385  break;
3386  }
3387 
3388  total++;
3389  }
3390 
3391  for (i = 0; cdr_readonly_vars[i]; i++) {
3392  if (cdr_object_format_property(it_cdr, cdr_readonly_vars[i], workspace, sizeof(workspace))) {
3393  /* Unhandled read-only CDR variable. */
3394  ast_assert(0);
3395  continue;
3396  }
3397 
3398  if (!ast_strlen_zero(workspace)
3399  && ast_str_append(buf, 0, "level %d: %s%c%s%c", x, cdr_readonly_vars[i], delim, workspace, sep) < 0) {
3400  ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
3401  break;
3402  }
3403  total++;
3404  }
3405  }
3406  ao2_unlock(cdr);
3407  ao2_cleanup(cdr);
3408  return total;
3409 }
struct varshead variables
Definition: cdr.c:708
const char * ast_var_value(const struct ast_var_t *var)
Definition: chanvars.c:80
static int is_cdr_flag_set(unsigned int cdr_flag)
Definition: cdr.c:1127
const char * ast_var_name(const struct ast_var_t *var)
Definition: chanvars.c:60
struct cdr_object * next
Definition: cdr.c:735
#define var
Definition: ast_expr2f.c:614
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
#define ast_assert(a)
Definition: utils.h:650
#define ao2_unlock(a)
Definition: astobj2.h:730
struct cdr_object_snapshot party_a
Definition: cdr.c:713
#define ast_log
Definition: astobj2.c:42
#define AST_LOG_ERROR
Definition: logger.h:290
static int cdr_object_format_property(struct cdr_object *cdr_obj, const char *name, char *value, size_t length)
Format one of the standard properties on a cdr_object.
Definition: cdr.c:3243
struct ast_var_t::@243 entries
#define ao2_lock(a)
Definition: astobj2.h:718
static const char *const cdr_readonly_vars[]
Definition: cdr.c:3154
static struct cdr_object * cdr_object_get_by_name(const char *name)
Definition: cdr.c:3312
An in-memory representation of an active CDR.
Definition: cdr.c:712
#define LOG_ERROR
Definition: logger.h:285
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_strlen_zero(a)
Definition: muted.c:73
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:653
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
static int total
Definition: res_adsi.c:968

◆ ast_cdr_set_config()

void ast_cdr_set_config ( struct ast_cdr_config config)

Set the current CDR configuration.

Since
12
Parameters
configThe new CDR configuration

Definition at line 2840 of file cdr.c.

References ao2_cleanup, ao2_global_obj_ref, ao2_replace, cdr_set_debug_mode, cdr_toggle_runtime_options(), and module_config::general.

Referenced by test_cdr_cleanup_cb().

2841 {
2842  struct module_config *mod_cfg;
2843 
2844  if (!config) {
2845  return;
2846  }
2847 
2848  mod_cfg = ao2_global_obj_ref(module_configs);
2849  if (!mod_cfg) {
2850  return;
2851  }
2852 
2853  ao2_replace(mod_cfg->general, config);
2854 
2855  cdr_set_debug_mode(mod_cfg);
2857 
2858  ao2_cleanup(mod_cfg);
2859 }
#define cdr_set_debug_mode(mod_cfg)
Definition: cdr.c:203
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
The configuration settings for this module.
Definition: cdr.c:222
#define ao2_replace(dst, src)
Definition: astobj2.h:517
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ast_cdr_config * general
Definition: cdr.c:223
static int cdr_toggle_runtime_options(void)
Checks if CDRs are enabled and enables/disables the necessary options.
Definition: cdr.c:4488

◆ ast_cdr_set_property()

int ast_cdr_set_property ( const char *  channel_name,
enum ast_cdr_options  option 
)

Set a property on a CDR for a channel.

Since
12 This function sets specific administrative properties on a CDR for a channel. This includes properties like preventing a CDR from being dispatched, to setting the channel as the preferred Party A in future CDRs. See enum ast_cdr_options for more information.
Parameters
channel_nameThe CDR's channel
optionOption to apply to the CDR
Return values
0on success
1on error

Definition at line 3548 of file cdr.c.

References ao2_cleanup, ao2_lock, ao2_unlock, ast_set_flag, cdr_object_get_by_name(), cdr_object::flags, cdr_object::fn_table, cdr_object::next, and cdr_object::party_a.

Referenced by appcdr_callback(), AST_TEST_DEFINE(), and cdr_prop_write_callback().

3549 {
3550  struct cdr_object *cdr;
3551  struct cdr_object *it_cdr;
3552 
3553  cdr = cdr_object_get_by_name(channel_name);
3554  if (!cdr) {
3555  return -1;
3556  }
3557 
3558  ao2_lock(cdr);
3559  for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3560  if (it_cdr->fn_table == &finalized_state_fn_table) {
3561  continue;
3562  }
3563  /* Note: in general, set the flags on both the CDR record as well as the
3564  * Party A. Sometimes all we have is the Party A to look at.
3565  */
3566  ast_set_flag(&it_cdr->flags, option);
3567  ast_set_flag(&it_cdr->party_a, option);
3568  }
3569  ao2_unlock(cdr);
3570 
3571  ao2_cleanup(cdr);
3572  return 0;
3573 }
#define ast_set_flag(p, flag)
Definition: utils.h:70
struct cdr_object * next
Definition: cdr.c:735
#define ao2_unlock(a)
Definition: astobj2.h:730
struct cdr_object_snapshot party_a
Definition: cdr.c:713
struct ast_flags flags
Definition: cdr.c:723
#define ao2_lock(a)
Definition: astobj2.h:718
static struct cdr_object * cdr_object_get_by_name(const char *name)
Definition: cdr.c:3312
struct cdr_object_fn_table * fn_table
Definition: cdr.c:715
An in-memory representation of an active CDR.
Definition: cdr.c:712
struct cdr_object_fn_table finalized_state_fn_table
The virtual table for the finalized state.
Definition: cdr.c:694
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ ast_cdr_setuserfield()

void ast_cdr_setuserfield ( const char *  channel_name,
const char *  userfield 
)

Set CDR user field for channel (stored in CDR)

Parameters
channel_nameThe name of the channel that owns the CDR
userfieldThe user field to set

Definition at line 3477 of file cdr.c.

References ao2_callback_data, ao2_cleanup, ao2_lock, ao2_unlock, ast_copy_string(), cdr_object_get_by_name(), cdr_object_update_party_b_userfield_cb(), party_b_userfield_update::channel_name, cdr_object::fn_table, cdr_object::next, NULL, OBJ_MULTIPLE, OBJ_NODATA, OBJ_SEARCH_KEY, cdr_object::party_a, cdr_object_snapshot::userfield, and party_b_userfield_update::userfield.

Referenced by AST_TEST_DEFINE(), cdr_write_callback(), handle_request_info(), and start_monitor_exec().

3478 {
3479  struct cdr_object *cdr;
3480  struct party_b_userfield_update party_b_info = {
3482  .userfield = userfield,
3483  };
3484  struct cdr_object *it_cdr;
3485 
3486  /* Handle Party A */
3487  cdr = cdr_object_get_by_name(channel_name);
3488  if (cdr) {
3489  ao2_lock(cdr);
3490  for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3491  if (it_cdr->fn_table == &finalized_state_fn_table && it_cdr->next != NULL) {
3492  continue;
3493  }
3494  ast_copy_string(it_cdr->party_a.userfield, userfield,
3495  sizeof(it_cdr->party_a.userfield));
3496  }
3497  ao2_unlock(cdr);
3498  }
3499 
3500  /* Handle Party B */
3503  &party_b_info);
3504 
3505  ao2_cleanup(cdr);
3506 }
static int cdr_object_update_party_b_userfield_cb(void *obj, void *arg, void *data, int flags)
Callback used to update the userfield on Party B on all CDRs.
Definition: cdr.c:3455
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
struct cdr_object * next
Definition: cdr.c:735
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
struct cdr_object_snapshot party_a
Definition: cdr.c:713
const char * userfield
Definition: cdr.c:3451
char userfield[AST_MAX_USER_FIELD]
Definition: cdr.c:706
#define ao2_lock(a)
Definition: astobj2.h:718
static struct cdr_object * cdr_object_get_by_name(const char *name)
Definition: cdr.c:3312
struct cdr_object_fn_table * fn_table
Definition: cdr.c:715
const char * channel_name
Definition: cdr.c:3450
An in-memory representation of an active CDR.
Definition: cdr.c:712
#define ao2_callback_data(container, flags, cb_fn, arg, data)
Definition: astobj2.h:1743
struct cdr_object_fn_table finalized_state_fn_table
The virtual table for the finalized state.
Definition: cdr.c:694
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
static struct ao2_container * active_cdrs_all
A container of all active CDRs with a Party B indexed by Party B channel name.
Definition: cdr.c:368

◆ ast_cdr_setvar()

int ast_cdr_setvar ( const char *  channel_name,
const char *  name,
const char *  value 
)

Set a variable on a CDR.

Since
12
Parameters
channel_nameThe channel to set the variable on
nameThe name of the variable to set
valueThe value of the variable to set
Return values
0on success
non-zeroon failure

Definition at line 3178 of file cdr.c.

References ao2_callback, ao2_cleanup, ao2_iterator_destroy(), ao2_iterator_next, ao2_lock, ao2_unlock, ast_log, AST_LOG_ERROR, ast_strdupa, ast_channel_snapshot::base, cdr_object_select_all_by_name_cb(), cdr_object::fn_table, LOG_ERROR, ast_channel_snapshot_base::name, cdr_object::next, NULL, OBJ_MULTIPLE, cdr_object::party_a, cdr_object::party_b, set_variable(), cdr_object_snapshot::snapshot, and cdr_object_snapshot::variables.

Referenced by AST_TEST_DEFINE(), and cdr_write_callback().

3179 {
3180  struct cdr_object *cdr;
3181  struct cdr_object *it_cdr;
3182  struct ao2_iterator *it_cdrs;
3183  char *arg = ast_strdupa(channel_name);
3184  int x;
3185 
3186  for (x = 0; cdr_readonly_vars[x]; x++) {
3187  if (!strcasecmp(name, cdr_readonly_vars[x])) {
3188  ast_log(LOG_ERROR, "Attempt to set the '%s' read-only variable!\n", name);
3189  return -1;
3190  }
3191  }
3192 
3194  if (!it_cdrs) {
3195  ast_log(AST_LOG_ERROR, "Unable to find CDR for channel %s\n", channel_name);
3196  return -1;
3197  }
3198 
3199  for (; (cdr = ao2_iterator_next(it_cdrs)); ao2_unlock(cdr), ao2_cleanup(cdr)) {
3200  ao2_lock(cdr);
3201  for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3202  struct varshead *headp = NULL;
3203 
3204  if (it_cdr->fn_table == &finalized_state_fn_table && it_cdr->next != NULL) {
3205  continue;
3206  }
3207  if (!strcasecmp(channel_name, it_cdr->party_a.snapshot->base->name)) {
3208  headp = &it_cdr->party_a.variables;
3209  } else if (it_cdr->party_b.snapshot
3210  && !strcasecmp(channel_name, it_cdr->party_b.snapshot->base->name)) {
3211  headp = &it_cdr->party_b.variables;
3212  }
3213  if (headp) {
3214  set_variable(headp, name, value);
3215  }
3216  }
3217  }
3218  ao2_iterator_destroy(it_cdrs);
3219 
3220  return 0;
3221 }
struct ast_channel_snapshot_base * base
struct varshead variables
Definition: cdr.c:708
struct ast_channel_snapshot * snapshot
Definition: cdr.c:705
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
struct cdr_object * next
Definition: cdr.c:735
struct cdr_object_snapshot party_b
Definition: cdr.c:714
static void set_variable(struct varshead *headp, const char *name, const char *value)
Definition: cdr.c:1262
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
static int cdr_object_select_all_by_name_cb(void *obj, void *arg, int flags)
Definition: cdr.c:3126
int value
Definition: syslog.c:37
struct cdr_object_snapshot party_a
Definition: cdr.c:713
#define ast_log
Definition: astobj2.c:42
#define AST_LOG_ERROR
Definition: logger.h:290
#define ao2_lock(a)
Definition: astobj2.h:718
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static const char *const cdr_readonly_vars[]
Definition: cdr.c:3154
struct cdr_object_fn_table * fn_table
Definition: cdr.c:715
An in-memory representation of an active CDR.
Definition: cdr.c:712
#define LOG_ERROR
Definition: logger.h:285
static struct ao2_container * active_cdrs_master
A container of the active master CDRs indexed by Party A channel uniqueid.
Definition: cdr.c:365
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
static const char name[]
Definition: cdr_mysql.c:74
struct cdr_object_fn_table finalized_state_fn_table
The virtual table for the finalized state.
Definition: cdr.c:694
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
const ast_string_field name

◆ ast_cdr_unregister()

int ast_cdr_unregister ( const char *  name)

Unregister a CDR handling engine.

Parameters
namename of CDR handler to unregister Unregisters a CDR by it's name
Return values
0The backend unregistered successfully
-1The backend could not be unregistered at this time

Definition at line 2988 of file cdr.c.

References ast_cdr_generic_unregister().

Referenced by load_module(), load_values_config(), my_unload_module(), reload(), tds_unload_module(), and unload_module().

2989 {
2991 }
static int ast_cdr_generic_unregister(struct be_list *generic_list, const char *name)
Definition: cdr.c:2953
static const char name[]
Definition: cdr_mysql.c:74
List of registered backends.
Definition: cdr.c:330

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 4651 of file cdr.c.

◆ base_process_bridge_enter()

static enum process_bridge_enter_results base_process_bridge_enter ( struct cdr_object cdr,
struct ast_bridge_snapshot bridge,
struct ast_channel_snapshot channel 
)
static

Definition at line 1611 of file cdr.c.

References BRIDGE_ENTER_NEED_CDR.

1612 {
1613  /* Base process bridge enter simply indicates that we can't handle it */
1614  return BRIDGE_ENTER_NEED_CDR;
1615 }

◆ base_process_bridge_leave()

static int base_process_bridge_leave ( struct cdr_object cdr,
struct ast_bridge_snapshot bridge,
struct ast_channel_snapshot channel 
)
static

Definition at line 1601 of file cdr.c.

1602 {
1603  return 0;
1604 }

◆ base_process_dial_end()

static int base_process_dial_end ( struct cdr_object cdr,
struct ast_channel_snapshot caller,
struct ast_channel_snapshot peer,
const char *  dial_status 
)
static

Definition at line 1606 of file cdr.c.

1607 {
1608  return 0;
1609 }

◆ base_process_parked_channel()

static int base_process_parked_channel ( struct cdr_object cdr,
struct ast_parked_call_payload parking_info 
)
static

Definition at line 1617 of file cdr.c.

References ast_assert, AST_CDR_LOCK_APP, ast_set_flag, ast_string_field_set, ast_channel_snapshot::base, cdr_object::flags, cdr_object::fn_table, ast_channel_snapshot_base::name, ast_parked_call_payload::parkee, ast_parked_call_payload::parkinglot, ast_parked_call_payload::parkingspace, cdr_object::party_a, cdr_object_fn_table::process_party_a, and cdr_object_snapshot::snapshot.

1618 {
1619  char park_info[128];
1620 
1621  ast_assert(!strcasecmp(parking_info->parkee->base->name, cdr->party_a.snapshot->base->name));
1622 
1623  /* Update Party A information regardless */
1624  cdr->fn_table->process_party_a(cdr, parking_info->parkee);
1625 
1626  /* Fake out where we're parked */
1627  ast_string_field_set(cdr, appl, "Park");
1628  snprintf(park_info, sizeof(park_info), "%s:%u", parking_info->parkinglot, parking_info->parkingspace);
1629  ast_string_field_set(cdr, data, park_info);
1630 
1631  /* Prevent any further changes to the App/Data fields for this record */
1633 
1634  return 0;
1635 }
struct ast_channel_snapshot_base * base
struct ast_channel_snapshot * snapshot
Definition: cdr.c:705
#define ast_set_flag(p, flag)
Definition: utils.h:70
int(*const process_party_a)(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
Process a Party A update for the cdr_object.
Definition: cdr.c:437
#define ast_assert(a)
Definition: utils.h:650
struct cdr_object_snapshot party_a
Definition: cdr.c:713
struct ast_flags flags
Definition: cdr.c:723
struct ast_channel_snapshot * parkee
Definition: parking.h:60
struct cdr_object_fn_table * fn_table
Definition: cdr.c:715
unsigned int parkingspace
Definition: parking.h:65
const ast_string_field parkinglot
Definition: parking.h:69
const ast_string_field name
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ base_process_party_a()

static int base_process_party_a ( struct cdr_object cdr,
struct ast_channel_snapshot snapshot 
)
static

Definition at line 1540 of file cdr.c.

References ast_channel_snapshot_dialplan::appl, cdr_object::appl, ast_assert, AST_CDR_LOCK_APP, AST_FLAG_SUBROUTINE_EXEC, ast_set_flag, AST_SOFTHANGUP_HANGUP_EXEC, ast_string_field_set, ast_strlen_zero, ast_test_flag, ast_channel_snapshot::base, CDR_END_BEFORE_H_EXTEN, cdr_object_check_party_a_answer(), cdr_object_check_party_a_hangup(), cdr_object_finalize(), cdr_object_swap_snapshot(), ast_channel_snapshot_dialplan::context, context, cdr_object::context, ast_channel_snapshot_dialplan::data, cdr_object::data, ast_channel_snapshot::dialplan, ast_channel_snapshot_dialplan::exten, exten, cdr_object::exten, ast_channel_snapshot::flags, cdr_object::flags, is_cdr_flag_set(), ast_channel_snapshot_peer::linkedid, ast_cdr::linkedid, cdr_object::linkedid, ast_channel_snapshot_base::name, cdr_object::party_a, ast_channel_snapshot::peer, cdr_object_snapshot::snapshot, and ast_channel_snapshot::softhangup_flags.

Referenced by dialed_pending_state_process_party_a(), and single_state_process_dial_begin().

1541 {
1542  ast_assert(strcasecmp(snapshot->base->name, cdr->party_a.snapshot->base->name) == 0);
1543 
1544  /* Finalize the CDR if we're in hangup logic and we're set to do so */
1547  cdr_object_finalize(cdr);
1548  return 0;
1549  }
1550 
1551  /*
1552  * Only record the context and extension if we aren't in a subroutine, or if
1553  * we are executing hangup logic.
1554  */
1555  if (!ast_test_flag(&snapshot->flags, AST_FLAG_SUBROUTINE_EXEC)
1557  if (strcmp(cdr->context, snapshot->dialplan->context)) {
1558  ast_string_field_set(cdr, context, snapshot->dialplan->context);
1559  }
1560  if (strcmp(cdr->exten, snapshot->dialplan->exten)) {
1561  ast_string_field_set(cdr, exten, snapshot->dialplan->exten);
1562  }
1563  }
1564 
1565  cdr_object_swap_snapshot(&cdr->party_a, snapshot);
1566 
1567  /* When Party A is originated to an application and the application exits, the stack
1568  * will attempt to clear the application and restore the dummy originate application
1569  * of "AppDialX". Prevent that, and any other application changes we might not want
1570  * here.
1571  */
1572  if (!ast_test_flag(&cdr->flags, AST_CDR_LOCK_APP)
1573  && !ast_strlen_zero(snapshot->dialplan->appl)
1574  && (strncasecmp(snapshot->dialplan->appl, "appdial", 7) || ast_strlen_zero(cdr->appl))) {
1575  if (strcmp(cdr->appl, snapshot->dialplan->appl)) {
1576  ast_string_field_set(cdr, appl, snapshot->dialplan->appl);
1577  }
1578  if (strcmp(cdr->data, snapshot->dialplan->data)) {
1579  ast_string_field_set(cdr, data, snapshot->dialplan->data);
1580  }
1581 
1582  /* Dial (app_dial) is a special case. Because pre-dial handlers, which
1583  * execute before the dial begins, will alter the application/data to
1584  * something people typically don't want to see, if we see a channel enter
1585  * into Dial here, we set the appl/data accordingly and lock it.
1586  */
1587  if (!strcmp(snapshot->dialplan->appl, "Dial")) {
1589  }
1590  }
1591 
1592  if (strcmp(cdr->linkedid, snapshot->peer->linkedid)) {
1593  ast_string_field_set(cdr, linkedid, snapshot->peer->linkedid);
1594  }
1597 
1598  return 0;
1599 }
const ast_string_field data
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
struct ast_channel_snapshot_base * base
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_channel_snapshot * snapshot
Definition: cdr.c:705
static int is_cdr_flag_set(unsigned int cdr_flag)
Definition: cdr.c:1127
#define ast_set_flag(p, flag)
Definition: utils.h:70
const ast_string_field exten
Definition: cdr.c:734
#define ast_assert(a)
Definition: utils.h:650
struct ast_channel_snapshot_dialplan * dialplan
struct cdr_object_snapshot party_a
Definition: cdr.c:713
const ast_string_field appl
Definition: cdr.c:734
const ast_string_field context
Definition: cdr.c:734
const ast_string_field context
struct ast_flags flags
Definition: cdr.c:723
const ast_string_field appl
const ast_string_field linkedid
Definition: cdr.c:734
const ast_string_field exten
struct ast_flags softhangup_flags
const ast_string_field data
Definition: cdr.c:734
static void cdr_object_check_party_a_hangup(struct cdr_object *cdr)
Check to see if a CDR needs to move to the finalized state because its Party A hungup.
Definition: cdr.c:1477
#define ast_strlen_zero(a)
Definition: muted.c:73
struct ast_flags flags
static void cdr_object_check_party_a_answer(struct cdr_object *cdr)
Check to see if a CDR needs to be answered based on its Party A. Note that this is safe to call as mu...
Definition: cdr.c:1494
static void cdr_object_swap_snapshot(struct cdr_object_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot)
Swap an old cdr_object_snapshot&#39;s ast_channel_snapshot for a new ast_channel_snapshot.
Definition: cdr.c:1531
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
struct ast_channel_snapshot_peer * peer
static void cdr_object_finalize(struct cdr_object *cdr)
Finalize a CDR.
Definition: cdr.c:1440
const ast_string_field name
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ bridge_candidate_add_to_cdr()

static void bridge_candidate_add_to_cdr ( struct cdr_object cdr,
struct cdr_object_snapshot party_b 
)
static

Definition at line 2472 of file cdr.c.

References ast_string_field_set, ast_channel_snapshot::base, cdr_object::bridge, cdr_all_relink(), CDR_DEBUG, cdr_object_check_party_a_answer(), cdr_object_create_and_append(), cdr_object_snapshot_copy(), cdr_object_transition_state(), cdr_object::lastevent, ast_channel_snapshot_base::name, cdr_object::party_a, cdr_object::party_b, and cdr_object_snapshot::snapshot.

Referenced by bridge_candidate_process().

2474 {
2475  struct cdr_object *new_cdr;
2476 
2477  new_cdr = cdr_object_create_and_append(cdr, &cdr->lastevent);
2478  if (!new_cdr) {
2479  return;
2480  }
2481  cdr_object_snapshot_copy(&new_cdr->party_b, party_b);
2482  cdr_all_relink(new_cdr);
2484  ast_string_field_set(new_cdr, bridge, cdr->bridge);
2486  CDR_DEBUG("%p - Party A %s has new Party B %s\n",
2487  new_cdr, new_cdr->party_a.snapshot->base->name,
2488  party_b->snapshot->base->name);
2489 }
struct ast_channel_snapshot_base * base
struct ast_channel_snapshot * snapshot
Definition: cdr.c:705
struct cdr_object_snapshot party_b
Definition: cdr.c:714
struct cdr_object_snapshot party_a
Definition: cdr.c:713
#define CDR_DEBUG(fmt,...)
Definition: cdr.c:210
An in-memory representation of an active CDR.
Definition: cdr.c:712
struct timeval lastevent
Definition: cdr.c:721
static void cdr_object_snapshot_copy(struct cdr_object_snapshot *dst, struct cdr_object_snapshot *src)
Copy a snapshot and its details.
Definition: cdr.c:791
static void cdr_object_check_party_a_answer(struct cdr_object *cdr)
Check to see if a CDR needs to be answered based on its Party A. Note that this is safe to call as mu...
Definition: cdr.c:1494
struct cdr_object_fn_table bridge_state_fn_table
The virtual table for the Bridged state.
Definition: cdr.c:659
static struct cdr_object * cdr_object_create_and_append(struct cdr_object *cdr, const struct timeval *event_time)
Create a new cdr_object and append it to an existing chain.
Definition: cdr.c:1075
const ast_string_field bridge
Definition: cdr.c:734
const ast_string_field name
static void cdr_all_relink(struct cdr_object *cdr)
Definition: cdr.c:949
static void cdr_object_transition_state(struct cdr_object *cdr, struct cdr_object_fn_table *fn_table)
Transition a cdr_object to a new state.
Definition: cdr.c:821
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ bridge_candidate_process()

static void bridge_candidate_process ( struct cdr_object cdr,
struct cdr_object base_cand_cdr 
)
static

Process a single bridge_candidate.

When a CDR enters a bridge, it needs to make pairings with everyone else that it is not currently paired with. This function determines, for the CDR for the channel that entered the bridge and the CDR for every other channel currently in the bridge, who is Party A and makes new CDRs.

Parameters
cdrThe cdr_obj being processed
cand_cdrThe cdr_object that is a candidate

Definition at line 2503 of file cdr.c.

References ao2_lock, ao2_unlock, ast_channel_snapshot::base, cdr_object::bridge, bridge_candidate_add_to_cdr(), cdr_all_relink(), CDR_DEBUG, cdr_object_pick_party_a(), cdr_object_snapshot_copy(), cdr_object::end, ast_channel_snapshot_base::name, cdr_object::next, cdr_object::party_a, cdr_object::party_b, and cdr_object_snapshot::snapshot.

Referenced by handle_bridge_pairings().

2504 {
2505  struct cdr_object_snapshot *party_a;
2506  struct cdr_object *cand_cdr;
2507 
2508  ao2_lock(base_cand_cdr);
2509 
2510  for (cand_cdr = base_cand_cdr; cand_cdr; cand_cdr = cand_cdr->next) {
2511  /* Skip any records that are not in this bridge */
2512  if (strcmp(cand_cdr->bridge, cdr->bridge)) {
2513  continue;
2514  }
2515 
2516  /* If the candidate is us or someone we've taken on, pass on by */
2517  if (!strcasecmp(cdr->party_a.snapshot->base->name, cand_cdr->party_a.snapshot->base->name)
2518  || (cdr->party_b.snapshot
2519  && !strcasecmp(cdr->party_b.snapshot->base->name, cand_cdr->party_a.snapshot->base->name))) {
2520  break;
2521  }
2522 
2523  party_a = cdr_object_pick_party_a(&cdr->party_a, &cand_cdr->party_a);
2524  /* We're party A - make a new CDR, append it to us, and set the candidate as
2525  * Party B */
2526  if (!strcasecmp(party_a->snapshot->base->name, cdr->party_a.snapshot->base->name)) {
2527  bridge_candidate_add_to_cdr(cdr, &cand_cdr->party_a);
2528  break;
2529  }
2530 
2531  /* We're Party B. Check if we can add ourselves immediately or if we need
2532  * a new CDR for them (they already have a Party B) */
2533  if (cand_cdr->party_b.snapshot
2534  && strcasecmp(cand_cdr->party_b.snapshot->base->name, cdr->party_a.snapshot->base->name)) {
2535  bridge_candidate_add_to_cdr(cand_cdr, &cdr->party_a);
2536  } else {
2537  CDR_DEBUG("%p - Party A %s has new Party B %s\n",
2538  cand_cdr, cand_cdr->party_a.snapshot->base->name,
2539  cdr->party_a.snapshot->base->name);
2540  cdr_object_snapshot_copy(&cand_cdr->party_b, &cdr->party_a);
2541  cdr_all_relink(cand_cdr);
2542  /* It's possible that this joined at one point and was never chosen
2543  * as party A. Clear their end time, as it would be set in such a
2544  * case.
2545  */
2546  memset(&cand_cdr->end, 0, sizeof(cand_cdr->end));
2547  }
2548 
2549  break;
2550  }
2551 
2552  ao2_unlock(base_cand_cdr);
2553 }
struct ast_channel_snapshot_base * base
struct ast_channel_snapshot * snapshot
Definition: cdr.c:705
struct cdr_object * next
Definition: cdr.c:735
struct cdr_object_snapshot party_b
Definition: cdr.c:714
A wrapper object around a snapshot. Fields that are mutable by the CDR engine are replicated here...
Definition: cdr.c:704
#define ao2_unlock(a)
Definition: astobj2.h:730
struct cdr_object_snapshot party_a
Definition: cdr.c:713
#define CDR_DEBUG(fmt,...)
Definition: cdr.c:210
static void bridge_candidate_add_to_cdr(struct cdr_object *cdr, struct cdr_object_snapshot *party_b)
Definition: cdr.c:2472
#define ao2_lock(a)
Definition: astobj2.h:718
static struct cdr_object_snapshot * cdr_object_pick_party_a(struct cdr_object_snapshot *left, struct cdr_object_snapshot *right)
Given two CDR snapshots, figure out who should be Party A for the resulting CDR.
Definition: cdr.c:1192
An in-memory representation of an active CDR.
Definition: cdr.c:712
struct timeval end
Definition: cdr.c:720
static void cdr_object_snapshot_copy(struct cdr_object_snapshot *dst, struct cdr_object_snapshot *src)
Copy a snapshot and its details.
Definition: cdr.c:791
const ast_string_field bridge
Definition: cdr.c:734
const ast_string_field name
static void cdr_all_relink(struct cdr_object *cdr)
Definition: cdr.c:949

◆ bridge_state_process_bridge_leave()

static int bridge_state_process_bridge_leave ( struct cdr_object cdr,
struct ast_bridge_snapshot bridge,
struct ast_channel_snapshot channel 
)
static

Definition at line 2015 of file cdr.c.

References ast_channel_snapshot::base, cdr_object::bridge, cdr_object_transition_state(), ast_channel_snapshot_base::name, cdr_object::party_a, cdr_object::party_b, cdr_object_snapshot::snapshot, and ast_bridge_snapshot::uniqueid.

2016 {
2017  if (strcmp(cdr->bridge, bridge->uniqueid)) {
2018  return 1;
2019  }
2020  if (strcasecmp(cdr->party_a.snapshot->base->name, channel->base->name)
2021  && cdr->party_b.snapshot
2022  && strcasecmp(cdr->party_b.snapshot->base->name, channel->base->name)) {
2023  return 1;
2024  }
2026 
2027  return 0;
2028 }
struct ast_channel_snapshot_base * base
struct ast_channel_snapshot * snapshot
Definition: cdr.c:705
struct cdr_object_snapshot party_b
Definition: cdr.c:714
struct cdr_object_snapshot party_a
Definition: cdr.c:713
const ast_string_field uniqueid
Definition: bridge.h:332
struct cdr_object_fn_table finalized_state_fn_table
The virtual table for the finalized state.
Definition: cdr.c:694
const ast_string_field bridge
Definition: cdr.c:734
const ast_string_field name
static void cdr_object_transition_state(struct cdr_object *cdr, struct cdr_object_fn_table *fn_table)
Transition a cdr_object to a new state.
Definition: cdr.c:821

◆ bridge_state_process_party_b()

static void bridge_state_process_party_b ( struct cdr_object cdr,
struct ast_channel_snapshot snapshot 
)
static

Definition at line 2002 of file cdr.c.

References ast_assert, AST_FLAG_DEAD, ast_test_flag, ast_channel_snapshot::base, cdr_object_swap_snapshot(), cdr_object_transition_state(), ast_channel_snapshot::flags, ast_channel_snapshot_base::name, cdr_object::party_b, and cdr_object_snapshot::snapshot.

2003 {
2005  && !strcasecmp(cdr->party_b.snapshot->base->name, snapshot->base->name));
2006 
2007  cdr_object_swap_snapshot(&cdr->party_b, snapshot);
2008 
2009  /* If party B hangs up, finalize this CDR */
2012  }
2013 }
struct ast_channel_snapshot_base * base
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_channel_snapshot * snapshot
Definition: cdr.c:705
struct cdr_object_snapshot party_b
Definition: cdr.c:714
#define ast_assert(a)
Definition: utils.h:650
struct cdr_object_fn_table finalized_state_fn_table
The virtual table for the finalized state.
Definition: cdr.c:694
struct ast_flags flags
static void cdr_object_swap_snapshot(struct cdr_object_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot)
Swap an old cdr_object_snapshot&#39;s ast_channel_snapshot for a new ast_channel_snapshot.
Definition: cdr.c:1531
const ast_string_field name
static void cdr_object_transition_state(struct cdr_object *cdr, struct cdr_object_fn_table *fn_table)
Transition a cdr_object to a new state.
Definition: cdr.c:821

◆ cdr_all_cmp_fn()

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

Definition at line 912 of file cdr.c.

References ast_assert, CMP_MATCH, OBJ_SEARCH_KEY, OBJ_SEARCH_MASK, OBJ_SEARCH_OBJECT, OBJ_SEARCH_PARTIAL_KEY, and cdr_object::party_b_name.

Referenced by load_module().

913 {
914  struct cdr_object *left = obj;
915  struct cdr_object *right = arg;
916  const char *right_key = arg;
917  int cmp;
918 
919  switch (flags & OBJ_SEARCH_MASK) {
920  case OBJ_SEARCH_OBJECT:
921  right_key = right->party_b_name;
922  /* Fall through */
923  case OBJ_SEARCH_KEY:
924  cmp = strcasecmp(left->party_b_name, right_key);
925  break;
927  /*
928  * We could also use a partial key struct containing a length
929  * so strlen() does not get called for every comparison instead.
930  */
931  cmp = strncasecmp(left->party_b_name, right_key, strlen(right_key));
932  break;
933  default:
934  /* Sort can only work on something with a full or partial key. */
935  ast_assert(0);
936  cmp = 0;
937  break;
938  }
939  return cmp ? 0 : CMP_MATCH;
940 }
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
#define ast_assert(a)
Definition: utils.h:650
The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
Definition: astobj2.h:1120
struct ast_flags flags
Definition: cdr.c:723
An in-memory representation of an active CDR.
Definition: cdr.c:712
const ast_string_field party_b_name
Definition: cdr.c:734
The arg parameter is an object of the same type.
Definition: astobj2.h:1091
Search option field mask.
Definition: astobj2.h:1076

◆ cdr_all_hash_fn()

static int cdr_all_hash_fn ( const void *  obj,
const int  flags 
)
static

Definition at line 888 of file cdr.c.

References ast_assert, ast_str_case_hash(), OBJ_SEARCH_KEY, OBJ_SEARCH_MASK, OBJ_SEARCH_OBJECT, and cdr_object::party_b_name.

Referenced by load_module().

889 {
890  const struct cdr_object *cdr;
891  const char *key;
892 
893  switch (flags & OBJ_SEARCH_MASK) {
894  case OBJ_SEARCH_KEY:
895  key = obj;
896  break;
897  case OBJ_SEARCH_OBJECT:
898  cdr = obj;
899  key = cdr->party_b_name;
900  break;
901  default:
902  ast_assert(0);
903  return 0;
904  }
905  return ast_str_case_hash(key);
906 }
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
#define ast_assert(a)
Definition: utils.h:650
struct ast_flags flags
Definition: cdr.c:723
An in-memory representation of an active CDR.
Definition: cdr.c:712
const ast_string_field party_b_name
Definition: cdr.c:734
The arg parameter is an object of the same type.
Definition: astobj2.h:1091
Search option field mask.
Definition: astobj2.h:1076
static force_inline int attribute_pure ast_str_case_hash(const char *str)
Compute a hash value on a case-insensitive string.
Definition: strings.h:1250

◆ cdr_all_print_fn()

static void cdr_all_print_fn ( void *  v_obj,
void *  where,
ao2_prnt_fn prnt 
)
static

Definition at line 4472 of file cdr.c.

References ast_channel_snapshot::base, cdr_object::bridge, ast_channel_snapshot_base::name, cdr_object::party_a, cdr_object::party_b, and cdr_object_snapshot::snapshot.

Referenced by load_module().

4473 {
4474  struct cdr_object *cdr = v_obj;
4475 
4476  if (!cdr) {
4477  return;
4478  }
4479  prnt(where, "Party A: %s; Party B: %s; Bridge %s",
4480  cdr->party_a.snapshot->base->name,
4481  cdr->party_b.snapshot ? cdr->party_b.snapshot->base->name : "<unknown>",
4482  cdr->bridge);
4483 }
struct ast_channel_snapshot_base * base
struct ast_channel_snapshot * snapshot
Definition: cdr.c:705
struct cdr_object_snapshot party_b
Definition: cdr.c:714
struct cdr_object_snapshot party_a
Definition: cdr.c:713
An in-memory representation of an active CDR.
Definition: cdr.c:712
const ast_string_field bridge
Definition: cdr.c:734
const ast_string_field name

◆ cdr_all_relink()

static void cdr_all_relink ( struct cdr_object cdr)
static

Definition at line 949 of file cdr.c.

References ao2_link_flags, ao2_lock, ao2_unlink_flags, ao2_unlock, ast_string_field_set, ast_channel_snapshot::base, ast_channel_snapshot_base::name, OBJ_NOLOCK, cdr_object::party_b, cdr_object::party_b_name, and cdr_object_snapshot::snapshot.

Referenced by ast_cdr_fork(), bridge_candidate_add_to_cdr(), bridge_candidate_process(), single_state_bridge_enter_comparison(), and single_state_process_dial_begin().

950 {
952  if (cdr->party_b.snapshot) {
953  if (strcasecmp(cdr->party_b_name, cdr->party_b.snapshot->base->name)) {
957  }
958  } else {
961  }
963 }
struct ast_channel_snapshot_base * base
struct ast_channel_snapshot * snapshot
Definition: cdr.c:705
struct cdr_object_snapshot party_b
Definition: cdr.c:714
Assume that the ao2_container is already locked.
Definition: astobj2.h:1067
#define ao2_link_flags(container, obj, flags)
Definition: astobj2.h:1572
#define ao2_unlock(a)
Definition: astobj2.h:730
#define ao2_lock(a)
Definition: astobj2.h:718
const ast_string_field party_b_name
Definition: cdr.c:734
static struct ao2_container * active_cdrs_all
A container of all active CDRs with a Party B indexed by Party B channel name.
Definition: cdr.c:368
#define ao2_unlink_flags(container, obj, flags)
Definition: astobj2.h:1622
const ast_string_field name
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ cdr_all_unlink()

static void cdr_all_unlink ( struct cdr_object cdr)
static

Definition at line 972 of file cdr.c.

References ao2_lock, ao2_ref, ao2_unlink_flags, ao2_unlock, ast_assert, ast_string_field_set, cdr_object::is_root, cdr_object::next, OBJ_NOLOCK, and cdr_object::party_b_name.

Referenced by cdr_object_dispatch_all_cb(), and handle_channel_snapshot_update_message().

973 {
974  struct cdr_object *cur;
975  struct cdr_object *next;
976 
977  ast_assert(cdr->is_root);
978 
979  /* Hold a ref to the root CDR to ensure the list members don't go away on us. */
980  ao2_ref(cdr, +1);
982  for (cur = cdr; cur; cur = next) {
983  next = cur->next;
985  /*
986  * It is safe to still use cur after unlinking because the
987  * root CDR holds a ref to all the CDRs in the list and we
988  * have a ref to the root CDR.
989  */
991  }
993  ao2_ref(cdr, -1);
994 }
struct cdr_object * next
Definition: cdr.c:735
Assume that the ao2_container is already locked.
Definition: astobj2.h:1067
#define ast_assert(a)
Definition: utils.h:650
#define ao2_unlock(a)
Definition: astobj2.h:730
int is_root
Definition: cdr.c:737
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
An in-memory representation of an active CDR.
Definition: cdr.c:712
const ast_string_field party_b_name
Definition: cdr.c:734
static struct ao2_container * active_cdrs_all
A container of all active CDRs with a Party B indexed by Party B channel name.
Definition: cdr.c:368
#define ao2_unlink_flags(container, obj, flags)
Definition: astobj2.h:1622
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ cdr_detach()

static void cdr_detach ( struct ast_cdr cdr)
static

Definition at line 3841 of file cdr.c.

References ao2_cleanup, ao2_global_obj_ref, ast_calloc, ast_cdr_free(), ast_debug, ast_mutex_lock, ast_mutex_unlock, ast_test_flag, batch, cdr_batch_item::cdr, cdr_batch_lock, CDR_BATCHMODE, CDR_ENABLED, cdr_batch::head, init_batch(), cdr_batch_item::next, post_cdr(), RAII_VAR, cdr_batch::size, start_batch_mode(), and cdr_batch::tail.

Referenced by cdr_object_dispatch().

3842 {
3843  struct cdr_batch_item *newtail;
3844  int curr;
3845  RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
3846  int submit_batch = 0;
3847 
3848  if (!cdr) {
3849  return;
3850  }
3851 
3852  /* maybe they disabled CDR stuff completely, so just drop it */
3853  if (!mod_cfg || !ast_test_flag(&mod_cfg->general->settings, CDR_ENABLED)) {
3854  ast_debug(1, "Dropping CDR !\n");
3855  ast_cdr_free(cdr);
3856  return;
3857  }
3858 
3859  /* post stuff immediately if we are not in batch mode, this is legacy behaviour */
3860  if (!ast_test_flag(&mod_cfg->general->settings, CDR_BATCHMODE)) {
3861  post_cdr(cdr);
3862  ast_cdr_free(cdr);
3863  return;
3864  }
3865 
3866  /* otherwise, each CDR gets put into a batch list (at the end) */
3867  ast_debug(1, "CDR detaching from this thread\n");
3868 
3869  /* we'll need a new tail for every CDR */
3870  if (!(newtail = ast_calloc(1, sizeof(*newtail)))) {
3871  post_cdr(cdr);
3872  ast_cdr_free(cdr);
3873  return;
3874  }
3875 
3876  /* don't traverse a whole list (just keep track of the tail) */
3878  if (!batch)
3879  init_batch();
3880  if (!batch->head) {
3881  /* new batch is empty, so point the head at the new tail */
3882  batch->head = newtail;
3883  } else {
3884  /* already got a batch with something in it, so just append a new tail */
3885  batch->tail->next = newtail;
3886  }
3887  newtail->cdr = cdr;
3888  batch->tail = newtail;
3889  curr = batch->size++;
3890 
3891  /* if we have enough stuff to post, then do it */
3892  if (curr >= (mod_cfg->general->batch_settings.size - 1)) {
3893  submit_batch = 1;
3894  }
3896 
3897  /* Don't submit a batch with cdr_batch_lock held */
3898  if (submit_batch) {
3899  start_batch_mode();
3900  }
3901 }
struct cdr_batch_item * tail
Definition: cdr.c:345
#define ast_test_flag(p, flag)
Definition: utils.h:63
static void post_cdr(struct ast_cdr *cdr)
Definition: cdr.c:3508
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define ast_mutex_lock(a)
Definition: lock.h:187
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
struct ast_cdr * cdr
Definition: cdr.c:337
void ast_cdr_free(struct ast_cdr *cdr)
Free a CDR record.
Definition: cdr.c:3411
#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:851
struct cdr_batch_item * next
Definition: cdr.c:338
static int init_batch(void)
Definition: cdr.c:3738
The configuration settings for this module.
Definition: cdr.c:222
static struct cdr_batch * batch
Queued CDR waiting to be batched.
Definition: cdr.c:336
static ast_mutex_t cdr_batch_lock
Lock protecting modifications to the batch queue.
Definition: cdr.c:358
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
static void start_batch_mode(void)
Definition: cdr.c:3825
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct cdr_batch_item * head
Definition: cdr.c:344
int size
Definition: cdr.c:343
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ cdr_enable_batch_mode()

static void cdr_enable_batch_mode ( struct ast_cdr_config config)
static

Definition at line 4416 of file cdr.c.

References ast_cond_init, ast_log, ast_pthread_create_background, AST_PTHREADT_NULL, ast_cdr_config::batch_settings, cdr_pending_cond, cdr_thread, do_cdr(), LOG_ERROR, LOG_NOTICE, NULL, ast_cdr_config::batch_settings::size, start_batch_mode(), and ast_cdr_config::batch_settings::time.

Referenced by cdr_toggle_runtime_options().

4417 {
4418  /* Only create the thread level portions once */
4419  if (cdr_thread == AST_PTHREADT_NULL) {
4422  ast_log(LOG_ERROR, "Unable to start CDR thread.\n");
4423  return;
4424  }
4425  }
4426 
4427  /* Start the batching process */
4428  start_batch_mode();
4429 
4430  ast_log(LOG_NOTICE, "CDR batch mode logging enabled, first of either size %u or time %u seconds.\n",
4431  config->batch_settings.size, config->batch_settings.time);
4432 }
static void * do_cdr(void *data)
Definition: cdr.c:3903
#define ast_cond_init(cond, attr)
Definition: lock.h:199
#define NULL
Definition: resample.c:96
#define ast_pthread_create_background(a, b, c, d)
Definition: utils.h:507
#define ast_log
Definition: astobj2.c:42
#define AST_PTHREADT_NULL
Definition: lock.h:66
struct ast_cdr_config::batch_settings batch_settings
#define LOG_ERROR
Definition: logger.h:285
static ast_cond_t cdr_pending_cond
Definition: cdr.c:362
#define LOG_NOTICE
Definition: logger.h:263
static void start_batch_mode(void)
Definition: cdr.c:3825
static pthread_t cdr_thread
Definition: cdr.c:355

◆ cdr_engine_shutdown()

static void cdr_engine_shutdown ( void  )
static

Definition at line 4385 of file cdr.c.

References aco_info_destroy(), ao2_callback, ao2_cleanup, ao2_container_unregister(), ao2_global_obj_release, ARRAY_LEN, ast_cli_unregister_multiple(), ast_free, ast_sched_context_destroy(), batch, cdr_object_dispatch_all_cb(), finalize_batch_mode(), NULL, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, stasis_message_router_unsubscribe_and_join(), and STASIS_MESSAGE_TYPE_CLEANUP.

Referenced by load_module().

4386 {
4388  stasis_router = NULL;
4389 
4391  cdr_topic = NULL;
4392 
4393  STASIS_MESSAGE_TYPE_CLEANUP(cdr_sync_message_type);
4394 
4400  sched = NULL;
4401  ast_free(batch);
4402  batch = NULL;
4403 
4404  aco_info_destroy(&cfg_info);
4405  ao2_global_obj_release(module_configs);
4406 
4407  ao2_container_unregister("cdrs_master");
4410 
4411  ao2_container_unregister("cdrs_all");
4414 }
static struct stasis_message_router * stasis_router
Message router for stasis messages regarding channel state.
Definition: cdr.c:371
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
void stasis_message_router_unsubscribe_and_join(struct stasis_message_router *router)
Unsubscribe the router from the upstream topic, blocking until the final message has been processed...
#define STASIS_MESSAGE_TYPE_CLEANUP(name)
Boiler-plate messaging macro for cleaning up message types.
Definition: stasis.h:1523
Definition: sched.c:76
static struct stasis_topic * cdr_topic
The parent topic for all topics we want to aggregate for CDRs.
Definition: cdr.c:383
#define NULL
Definition: resample.c:96
static int cdr_object_dispatch_all_cb(void *obj, void *arg, int flags)
This dispatches all cdr_objects. It should only be used during shutdown, so that we get billing recor...
Definition: cdr.c:4260
void ao2_container_unregister(const char *name)
Unregister a container for CLI stats and integrity check.
static struct ast_cli_entry cli_commands[]
Definition: cdr.c:4249
static struct cdr_batch * batch
void aco_info_destroy(struct aco_info *info)
Destroy an initialized aco_info struct.
#define ao2_global_obj_release(holder)
Definition: astobj2.h:865
static struct ao2_container * active_cdrs_master
A container of the active master CDRs indexed by Party A channel uniqueid.
Definition: cdr.c:365
#define ast_free(a)
Definition: astmm.h:182
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static struct ao2_container * active_cdrs_all
A container of all active CDRs with a Party B indexed by Party B channel name.
Definition: cdr.c:368
void ast_sched_context_destroy(struct ast_sched_context *c)
destroys a schedule context
Definition: sched.c:269
static void finalize_batch_mode(void)
Definition: cdr.c:4277

◆ cdr_format_var_internal()

static const char* cdr_format_var_internal ( struct ast_cdr cdr,
const char *  name 
)
static

Definition at line 3018 of file cdr.c.

References AST_LIST_TRAVERSE, ast_strlen_zero, ast_var_name(), ast_var_value(), ast_var_t::entries, NULL, and ast_cdr::varshead.

Referenced by ast_cdr_format_var().

3019 {
3020  struct ast_var_t *variables;
3021 
3022  if (ast_strlen_zero(name)) {
3023  return NULL;
3024  }
3025 
3026  AST_LIST_TRAVERSE(&cdr->varshead, variables, entries) {
3027  if (!strcasecmp(name, ast_var_name(variables))) {
3028  return ast_var_value(variables);
3029  }
3030  }
3031 
3032  return NULL;
3033 }
const char * ast_var_value(const struct ast_var_t *var)
Definition: chanvars.c:80
const char * ast_var_name(const struct ast_var_t *var)
Definition: chanvars.c:60
#define NULL
Definition: resample.c:96
struct varshead varshead
Definition: cdr.h:323
struct ast_var_t::@243 entries
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_strlen_zero(a)
Definition: muted.c:73
static const char name[]
Definition: cdr_mysql.c:74

◆ cdr_generic_register()

static int cdr_generic_register ( struct be_list generic_list,
const char *  name,
const char *  desc,
ast_cdrbe  be 
)
static

Definition at line 2902 of file cdr.c.

References ast_calloc, ast_copy_string(), ast_free, ast_log, AST_RWLIST_INSERT_HEAD, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, be, cdr_beitem::be, cdr_beitem::desc, LOG_WARNING, and cdr_beitem::name.

Referenced by ast_cdr_modifier_register(), and ast_cdr_register().

2903 {
2904  struct cdr_beitem *i;
2905  struct cdr_beitem *cur;
2906 
2907  if (!name) {
2908  return -1;
2909  }
2910 
2911  if (!be) {
2912  ast_log(LOG_WARNING, "CDR engine '%s' lacks backend\n", name);
2913 
2914  return -1;
2915  }
2916 
2917  i = ast_calloc(1, sizeof(*i));
2918  if (!i) {
2919  return -1;
2920  }
2921 
2922  i->be = be;
2923  ast_copy_string(i->name, name, sizeof(i->name));
2924  ast_copy_string(i->desc, desc, sizeof(i->desc));
2925 
2926  AST_RWLIST_WRLOCK(generic_list);
2927  AST_RWLIST_TRAVERSE(generic_list, cur, list) {
2928  if (!strcasecmp(name, cur->name)) {
2929  ast_log(LOG_WARNING, "Already have a CDR backend called '%s'\n", name);
2930  AST_RWLIST_UNLOCK(generic_list);
2931  ast_free(i);
2932 
2933  return -1;
2934  }
2935  }
2936 
2937  AST_RWLIST_INSERT_HEAD(generic_list, i, list);
2938  AST_RWLIST_UNLOCK(generic_list);
2939 
2940  return 0;
2941 }
char desc[80]
Definition: cdr.c:323
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define LOG_WARNING
Definition: logger.h:274
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
static const char desc[]
Definition: cdr_mysql.c:73
char * be
Definition: eagi_proxy.c:73
Registration object for CDR backends.
Definition: cdr.c:321
#define AST_RWLIST_INSERT_HEAD
Definition: linkedlists.h:717
#define ast_log
Definition: astobj2.c:42
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
char name[20]
Definition: cdr.c:322
static const char name[]
Definition: cdr_mysql.c:74
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
ast_cdrbe be
Definition: cdr.c:324

◆ cdr_get_tv()

static void cdr_get_tv ( struct timeval  when,
const char *  fmt,
char *  buf,
int  bufsize 
)
static

Definition at line 3035 of file cdr.c.

References ast_localtime(), ast_strftime(), and NULL.

Referenced by ast_cdr_format_var(), cdr_object_format_property(), cli_show_channel(), and cli_show_channels().

3036 {
3037  if (fmt == NULL) { /* raw mode */
3038  snprintf(buf, bufsize, "%ld.%06ld", (long)when.tv_sec, (long)when.tv_usec);
3039  } else {
3040  buf[0] = '\0';/* Ensure the buffer is initialized. */
3041  if (when.tv_sec) {
3042  struct ast_tm tm;
3043 
3044  ast_localtime(&when, &tm, NULL);
3045  ast_strftime(buf, bufsize, fmt, &tm);
3046  }
3047  }
3048 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
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
#define NULL
Definition: resample.c:96
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

◆ cdr_master_cmp_fn()

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

Definition at line 854 of file cdr.c.

References ast_assert, CMP_MATCH, OBJ_SEARCH_KEY, OBJ_SEARCH_MASK, OBJ_SEARCH_OBJECT, OBJ_SEARCH_PARTIAL_KEY, and cdr_object::uniqueid.

Referenced by load_module().

855 {
856  struct cdr_object *left = obj;
857  struct cdr_object *right = arg;
858  const char *right_key = arg;
859  int cmp;
860 
861  switch (flags & OBJ_SEARCH_MASK) {
862  case OBJ_SEARCH_OBJECT:
863  right_key = right->uniqueid;
864  /* Fall through */
865  case OBJ_SEARCH_KEY:
866  cmp = strcmp(left->uniqueid, right_key);
867  break;
869  /*
870  * We could also use a partial key struct containing a length
871  * so strlen() does not get called for every comparison instead.
872  */
873  cmp = strncmp(left->uniqueid, right_key, strlen(right_key));
874  break;
875  default:
876  /* Sort can only work on something with a full or partial key. */
877  ast_assert(0);
878  cmp = 0;
879  break;
880  }
881  return cmp ? 0 : CMP_MATCH;
882 }
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
#define ast_assert(a)
Definition: utils.h:650
The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
Definition: astobj2.h:1120
struct ast_flags flags
Definition: cdr.c:723
An in-memory representation of an active CDR.
Definition: cdr.c:712
The arg parameter is an object of the same type.
Definition: astobj2.h:1091
Search option field mask.
Definition: astobj2.h:1076
const ast_string_field uniqueid
Definition: cdr.c:734

◆ cdr_master_hash_fn()

static int cdr_master_hash_fn ( const void *  obj,
const int  flags 
)
static

Definition at line 830 of file cdr.c.

References ast_assert, ast_str_case_hash(), OBJ_SEARCH_KEY, OBJ_SEARCH_MASK, OBJ_SEARCH_OBJECT, and cdr_object::uniqueid.

Referenced by load_module().

831 {
832  const struct cdr_object *cdr;
833  const char *key;
834 
835  switch (flags & OBJ_SEARCH_MASK) {
836  case OBJ_SEARCH_KEY:
837  key = obj;
838  break;
839  case OBJ_SEARCH_OBJECT:
840  cdr = obj;
841  key = cdr->uniqueid;
842  break;
843  default:
844  ast_assert(0);
845  return 0;
846  }
847  return ast_str_case_hash(key);
848 }
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
#define ast_assert(a)
Definition: utils.h:650
struct ast_flags flags
Definition: cdr.c:723
An in-memory representation of an active CDR.
Definition: cdr.c:712
The arg parameter is an object of the same type.
Definition: astobj2.h:1091
Search option field mask.
Definition: astobj2.h:1076
const ast_string_field uniqueid
Definition: cdr.c:734
static force_inline int attribute_pure ast_str_case_hash(const char *str)
Compute a hash value on a case-insensitive string.
Definition: strings.h:1250

◆ cdr_master_print_fn()

static void cdr_master_print_fn ( void *  v_obj,
void *  where,
ao2_prnt_fn prnt 
)
static

Definition at line 4445 of file cdr.c.

References ast_channel_snapshot::base, cdr_object::bridge, ast_channel_snapshot_base::name, cdr_object::next, cdr_object::party_a, cdr_object::party_b, and cdr_object_snapshot::snapshot.

Referenced by load_module().

4446 {
4447  struct cdr_object *cdr = v_obj;
4448  struct cdr_object *it_cdr;
4449 
4450  if (!cdr) {
4451  return;
4452  }
4453  for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
4454  prnt(where, "Party A: %s; Party B: %s; Bridge %s\n",
4455  it_cdr->party_a.snapshot->base->name,
4456  it_cdr->party_b.snapshot ? it_cdr->party_b.snapshot->base->name : "<unknown>",
4457  it_cdr->bridge);
4458  }
4459 }
struct ast_channel_snapshot_base * base
struct ast_channel_snapshot * snapshot
Definition: cdr.c:705
struct cdr_object * next
Definition: cdr.c:735
struct cdr_object_snapshot party_b
Definition: cdr.c:714
struct cdr_object_snapshot party_a
Definition: cdr.c:713
An in-memory representation of an active CDR.
Definition: cdr.c:712
const ast_string_field bridge
Definition: cdr.c:734
const ast_string_field name

◆ cdr_object_alloc()

static struct cdr_object* cdr_object_alloc ( struct ast_channel_snapshot chan,
const struct timeval *  event_time 
)
static

cdr_object constructor

Parameters
chanThe ast_channel_snapshot that is the CDR's Party A

This implicitly sets the state of the newly created CDR to the Single state (single_state_fn_table)

Definition at line 1039 of file cdr.c.

References ao2_alloc, ao2_cleanup, ao2_t_ref, ast_assert, ast_atomic_fetchadd_int(), AST_CDR_NULL, ast_string_field_init, ast_string_field_set, ast_channel_snapshot::base, CDR_DEBUG, cdr_object_dtor(), cdr_object_transition_state(), cdr_object::disposition, global_cdr_sequence, cdr_object::last, cdr_object::lastevent, ast_channel_snapshot_peer::linkedid, cdr_object::linkedid, name, ast_channel_snapshot_base::name, NULL, cdr_object::party_a, ast_channel_snapshot::peer, cdr_object::sequence, cdr_object_snapshot::snapshot, ast_channel_snapshot_base::uniqueid, and cdr_object::uniqueid.

Referenced by cdr_object_create_and_append(), and handle_channel_snapshot_update_message().

1040 {
1041  struct cdr_object *cdr;
1042 
1043  ast_assert(chan != NULL);
1044 
1045  cdr = ao2_alloc(sizeof(*cdr), cdr_object_dtor);
1046  if (!cdr) {
1047  return NULL;
1048  }
1049  cdr->last = cdr;
1050  if (ast_string_field_init(cdr, 64)) {
1051  ao2_cleanup(cdr);
1052  return NULL;
1053  }
1055  ast_string_field_set(cdr, name, chan->base->name);
1057  cdr->disposition = AST_CDR_NULL;
1059  cdr->lastevent = *event_time;
1060 
1061  cdr->party_a.snapshot = chan;
1062  ao2_t_ref(cdr->party_a.snapshot, +1, "bump snapshot during CDR creation");
1063 
1064  CDR_DEBUG("%p - Created CDR for channel %s\n", cdr, chan->base->name);
1065 
1067 
1068  return cdr;
1069 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
struct ast_channel_snapshot_base * base
struct ast_channel_snapshot * snapshot
Definition: cdr.c:705
static void cdr_object_dtor(void *obj)
cdr_object Destructor
Definition: cdr.c:999
const ast_string_field uniqueid
unsigned int sequence
Definition: cdr.c:722
#define ast_assert(a)
Definition: utils.h:650
#define NULL
Definition: resample.c:96
struct cdr_object_snapshot party_a
Definition: cdr.c:713
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:755
static int global_cdr_sequence
The global sequence counter used for CDRs.
Definition: cdr.c:349
#define CDR_DEBUG(fmt,...)
Definition: cdr.c:210
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:353
const ast_string_field linkedid
Definition: cdr.c:734
enum ast_cdr_disposition disposition
Definition: cdr.c:717
An in-memory representation of an active CDR.
Definition: cdr.c:712
struct cdr_object * last
Definition: cdr.c:736
struct cdr_object_fn_table single_state_fn_table
The virtual table for the Single state.
Definition: cdr.c:573
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
struct timeval lastevent
Definition: cdr.c:721
static const char name[]
Definition: cdr_mysql.c:74
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
const ast_string_field uniqueid
Definition: cdr.c:734
struct ast_channel_snapshot_peer * peer
const ast_string_field name
static void cdr_object_transition_state(struct cdr_object *cdr, struct cdr_object_fn_table *fn_table)
Transition a cdr_object to a new state.
Definition: cdr.c:821
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ cdr_object_check_party_a_answer()

static void cdr_object_check_party_a_answer ( struct cdr_object cdr)
static

Check to see if a CDR needs to be answered based on its Party A. Note that this is safe to call as much as you want - we won't answer twice.

Definition at line 1494 of file cdr.c.

References cdr_object::answer, AST_STATE_UP, ast_tvzero(), CDR_DEBUG, cdr_object::lastevent, cdr_object::party_a, cdr_object_snapshot::snapshot, and ast_channel_snapshot::state.

Referenced by ast_cdr_reset(), base_process_party_a(), bridge_candidate_add_to_cdr(), and single_state_init_function().

1495 {
1496  if (cdr->party_a.snapshot->state == AST_STATE_UP && ast_tvzero(cdr->answer)) {
1497  cdr->answer = cdr->lastevent;
1498  /* tv_usec is suseconds_t, which could be int or long */
1499  CDR_DEBUG("%p - Set answered time to %ld.%06ld\n", cdr,
1500  (long)cdr->answer.tv_sec,
1501  (long)cdr->answer.tv_usec);
1502  }
1503 }
struct ast_channel_snapshot * snapshot
Definition: cdr.c:705
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:108
struct timeval answer
Definition: cdr.c:719
struct cdr_object_snapshot party_a
Definition: cdr.c:713
#define CDR_DEBUG(fmt,...)
Definition: cdr.c:210
struct timeval lastevent
Definition: cdr.c:721
enum ast_channel_state state

◆ cdr_object_check_party_a_hangup()

static void cdr_object_check_party_a_hangup ( struct cdr_object cdr)
static

Check to see if a CDR needs to move to the finalized state because its Party A hungup.

Definition at line 1477 of file cdr.c.

References AST_FLAG_DEAD, AST_SOFTHANGUP_HANGUP_EXEC, ast_test_flag, CDR_END_BEFORE_H_EXTEN, cdr_object_finalize(), cdr_object_transition_state(), ast_channel_snapshot::flags, cdr_object::fn_table, is_cdr_flag_set(), cdr_object::party_a, cdr_object_snapshot::snapshot, and ast_channel_snapshot::softhangup_flags.

Referenced by base_process_party_a().

1478 {
1481  cdr_object_finalize(cdr);
1482  }
1483 
1485  && cdr->fn_table != &finalized_state_fn_table) {
1487  }
1488 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_channel_snapshot * snapshot
Definition: cdr.c:705
static int is_cdr_flag_set(unsigned int cdr_flag)
Definition: cdr.c:1127
struct cdr_object_snapshot party_a
Definition: cdr.c:713
struct cdr_object_fn_table * fn_table
Definition: cdr.c:715
struct ast_flags softhangup_flags
struct cdr_object_fn_table finalized_state_fn_table
The virtual table for the finalized state.
Definition: cdr.c:694
struct ast_flags flags
static void cdr_object_finalize(struct cdr_object *cdr)
Finalize a CDR.
Definition: cdr.c:1440
static void cdr_object_transition_state(struct cdr_object *cdr, struct cdr_object_fn_table *fn_table)
Transition a cdr_object to a new state.
Definition: cdr.c:821

◆ cdr_object_create_and_append()

static struct cdr_object* cdr_object_create_and_append ( struct cdr_object cdr,
const struct timeval *  event_time 
)
static

Create a new cdr_object and append it to an existing chain.

Parameters
cdrThe cdr_object to append to

Definition at line 1075 of file cdr.c.

References cdr_object::appl, AST_CDR_FLAG_DISABLE_ALL, AST_CDR_NULL, ast_set_flag, ast_string_field_set, ast_test_flag, cdr_object_alloc(), cdr_object_snapshot_copy(), context, cdr_object::context, cdr_object::data, cdr_object::disposition, exten, cdr_object::exten, cdr_object::flags, cdr_object::last, cdr_object::linkedid, cdr_object::next, NULL, cdr_object::party_a, and cdr_object_snapshot::snapshot.

Referenced by ast_cdr_fork(), bridge_candidate_add_to_cdr(), handle_channel_snapshot_update_message(), handle_dial_message(), handle_parked_call_message(), handle_parking_bridge_enter_message(), and handle_standard_bridge_enter_message().

1076 {
1077  struct cdr_object *new_cdr;
1078  struct cdr_object *it_cdr;
1079  struct cdr_object *cdr_last;
1080 
1081  cdr_last = cdr->last;
1082  new_cdr = cdr_object_alloc(cdr_last->party_a.snapshot, event_time);
1083  if (!new_cdr) {
1084  return NULL;
1085  }
1086  new_cdr->disposition = AST_CDR_NULL;
1087 
1088  /* Copy over the linkedid, as it may have changed */
1089  ast_string_field_set(new_cdr, linkedid, cdr_last->linkedid);
1090  ast_string_field_set(new_cdr, appl, cdr_last->appl);
1091  ast_string_field_set(new_cdr, data, cdr_last->data);
1092  ast_string_field_set(new_cdr, context, cdr_last->context);
1093  ast_string_field_set(new_cdr, exten, cdr_last->exten);
1094 
1095  /*
1096  * If the current CDR says to disable all future ones,
1097  * keep the disable chain going
1098  */
1099  if (ast_test_flag(&cdr_last->flags, AST_CDR_FLAG_DISABLE_ALL)) {
1101  }
1102 
1103  /* Copy over other Party A information */
1104  cdr_object_snapshot_copy(&new_cdr->party_a, &cdr_last->party_a);
1105 
1106  /* Append the CDR to the end of the list */
1107  for (it_cdr = cdr; it_cdr->next; it_cdr = it_cdr->next) {
1108  it_cdr->last = new_cdr;
1109  }
1110  it_cdr->last = new_cdr;
1111  it_cdr->next = new_cdr;
1112 
1113  return new_cdr;
1114 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_channel_snapshot * snapshot
Definition: cdr.c:705
#define ast_set_flag(p, flag)
Definition: utils.h:70
struct cdr_object * next
Definition: cdr.c:735
const ast_string_field exten
Definition: cdr.c:734
static struct cdr_object * cdr_object_alloc(struct ast_channel_snapshot *chan, const struct timeval *event_time)
cdr_object constructor
Definition: cdr.c:1039
#define NULL
Definition: resample.c:96
struct cdr_object_snapshot party_a
Definition: cdr.c:713
const ast_string_field appl
Definition: cdr.c:734
const ast_string_field context
Definition: cdr.c:734
struct ast_flags flags
Definition: cdr.c:723
const ast_string_field linkedid
Definition: cdr.c:734
enum ast_cdr_disposition disposition
Definition: cdr.c:717
An in-memory representation of an active CDR.
Definition: cdr.c:712
struct cdr_object * last
Definition: cdr.c:736
const ast_string_field data
Definition: cdr.c:734
static void cdr_object_snapshot_copy(struct cdr_object_snapshot *dst, struct cdr_object_snapshot *src)
Copy a snapshot and its details.
Definition: cdr.c:791
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ cdr_object_create_public_records()

static struct ast_cdr* cdr_object_create_public_records ( struct cdr_object cdr)
static

Create a chain of ast_cdr objects from a chain of cdr_object suitable for consumption by the registered CDR backends.

Parameters
cdrThe cdr_object to convert to a public record
Return values
Achain of ast_cdr objects on success
NULLon failure

Definition at line 1287 of file cdr.c.

References ast_channel_snapshot_base::accountcode, ast_cdr::accountcode, ast_channel_snapshot::amaflags, ast_cdr::amaflags, ast_cdr::answer, cdr_object::answer, cdr_object::appl, ast_assert, ast_callerid_merge(), ast_calloc, ast_copy_flags, ast_copy_string(), ast_debug, AST_FLAGS_ALL, ast_free, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_strlen_zero, ast_var_assign, ast_var_name(), ast_var_value(), ast_channel_snapshot::base, ast_cdr::billsec, ast_channel_snapshot::caller, cdr_object_get_billsec(), cdr_object_get_duration(), ast_cdr::channel, ast_cdr::clid, cdr_object::context, copy_variables(), cdr_object::data, ast_cdr::dcontext, ast_cdr::disposition, cdr_object::disposition, ast_cdr::dst, ast_cdr::dstchannel, ast_cdr::duration, ast_cdr::end, cdr_object::end, ast_var_t::entries, cdr_object::exten, cdr_object::flags, ast_cdr::lastapp, ast_cdr::lastdata, ast_cdr::linkedid, cdr_object::linkedid, ast_channel_snapshot_caller::name, ast_channel_snapshot_base::name, ast_cdr::next, cdr_object::next, NULL, ast_channel_snapshot_caller::number, cdr_object::party_a, cdr_object::party_b, ast_cdr::peeraccount, ast_cdr::sequence, cdr_object::sequence, cdr_object_snapshot::snapshot, snapshot_is_dialed(), ast_cdr::src, ast_cdr::start, cdr_object::start, ast_channel_snapshot_base::uniqueid, ast_cdr::uniqueid, ast_cdr::userfield, cdr_object_snapshot::userfield, cdr_object_snapshot::variables, and ast_cdr::varshead.

Referenced by cdr_object_dispatch().

1288 {
1289  struct ast_cdr *pub_cdr = NULL, *cdr_prev = NULL;
1290  struct cdr_object *it_cdr;
1291  struct ast_var_t *it_var, *it_copy_var;
1292  struct ast_channel_snapshot *party_a;
1293  struct ast_channel_snapshot *party_b;
1294 
1295  for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
1296  struct ast_cdr *cdr_copy;
1297 
1298  /* Don't create records for CDRs where the party A was a dialed channel */
1299  if (snapshot_is_dialed(it_cdr->party_a.snapshot) && !it_cdr->party_b.snapshot) {
1300  ast_debug(1, "CDR for %s is dialed and has no Party B; discarding\n",
1301  it_cdr->party_a.snapshot->base->name);
1302  continue;
1303  }
1304 
1305  cdr_copy = ast_calloc(1, sizeof(*cdr_copy));
1306  if (!cdr_copy) {
1307  ast_free(pub_cdr);
1308  return NULL;
1309  }
1310 
1311  party_a = it_cdr->party_a.snapshot;
1312  party_b = it_cdr->party_b.snapshot;
1313 
1314  /* Party A */
1315  ast_assert(party_a != NULL);
1316  ast_copy_string(cdr_copy->accountcode, party_a->base->accountcode, sizeof(cdr_copy->accountcode));
1317  cdr_copy->amaflags = party_a->amaflags;
1318  ast_copy_string(cdr_copy->channel, party_a->base->name, sizeof(cdr_copy->channel));
1319  ast_callerid_merge(cdr_copy->clid, sizeof(cdr_copy->clid), party_a->caller->name, party_a->caller->number, "");
1320  ast_copy_string(cdr_copy->src, party_a->caller->number, sizeof(cdr_copy->src));
1321  ast_copy_string(cdr_copy->uniqueid, party_a->base->uniqueid, sizeof(cdr_copy->uniqueid));
1322  ast_copy_string(cdr_copy->lastapp, it_cdr->appl, sizeof(cdr_copy->lastapp));
1323  ast_copy_string(cdr_copy->lastdata, it_cdr->data, sizeof(cdr_copy->lastdata));
1324  ast_copy_string(cdr_copy->dst, it_cdr->exten, sizeof(cdr_copy->dst));
1325  ast_copy_string(cdr_copy->dcontext, it_cdr->context, sizeof(cdr_copy->dcontext));
1326 
1327  /* Party B */
1328  if (party_b) {
1329  ast_copy_string(cdr_copy->dstchannel, party_b->base->name, sizeof(cdr_copy->dstchannel));
1330  ast_copy_string(cdr_copy->peeraccount, party_b->base->accountcode, sizeof(cdr_copy->peeraccount));
1331  if (!ast_strlen_zero(it_cdr->party_b.userfield)) {
1332  snprintf(cdr_copy->userfield, sizeof(cdr_copy->userfield), "%s;%s", it_cdr->party_a.userfield, it_cdr->party_b.userfield);
1333  }
1334  }
1335  if (ast_strlen_zero(cdr_copy->userfield) && !ast_strlen_zero(it_cdr->party_a.userfield)) {
1336  ast_copy_string(cdr_copy->userfield, it_cdr->party_a.userfield, sizeof(cdr_copy->userfield));
1337  }
1338 
1339  /* Timestamps/durations */
1340  cdr_copy->start = it_cdr->start;
1341  cdr_copy->answer = it_cdr->answer;
1342  cdr_copy->end = it_cdr->end;
1343  cdr_copy->billsec = cdr_object_get_billsec(it_cdr);
1344  cdr_copy->duration = cdr_object_get_duration(it_cdr);
1345 
1346  /* Flags and IDs */
1347  ast_copy_flags(cdr_copy, &it_cdr->flags, AST_FLAGS_ALL);
1348  ast_copy_string(cdr_copy->linkedid, it_cdr->linkedid, sizeof(cdr_copy->linkedid));
1349  cdr_copy->disposition = it_cdr->disposition;
1350  cdr_copy->sequence = it_cdr->sequence;
1351 
1352  /* Variables */
1353  copy_variables(&cdr_copy->varshead, &it_cdr->party_a.variables);
1354  AST_LIST_TRAVERSE(&it_cdr->party_b.variables, it_var, entries) {
1355  int found = 0;
1356  struct ast_var_t *newvariable;
1357  AST_LIST_TRAVERSE(&cdr_copy->varshead, it_copy_var, entries) {
1358  if (!strcasecmp(ast_var_name(it_var), ast_var_name(it_copy_var))) {
1359  found = 1;
1360  break;
1361  }
1362  }
1363  if (!found && (newvariable = ast_var_assign(ast_var_name(it_var), ast_var_value(it_var)))) {
1364  AST_LIST_INSERT_TAIL(&cdr_copy->varshead, newvariable, entries);
1365  }
1366  }
1367 
1368  if (!pub_cdr) {
1369  pub_cdr = cdr_copy;
1370  cdr_prev = pub_cdr;
1371  } else {
1372  cdr_prev->next = cdr_copy;
1373  cdr_prev = cdr_copy;
1374  }
1375  }
1376 
1377  return pub_cdr;
1378 }
static long cdr_object_get_billsec(struct cdr_object *cdr)
Compute the billsec for a cdr_object.
Definition: cdr.c:1235
char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: cdr.h:308
struct ast_channel_snapshot_base * base
struct varshead variables
Definition: cdr.c:708
char dstchannel[AST_MAX_EXTENSION]
Definition: cdr.h:288
const ast_string_field name
struct ast_channel_snapshot * snapshot
Definition: cdr.c:705
const char * ast_var_value(const struct ast_var_t *var)
Definition: chanvars.c:80
const char * ast_var_name(const struct ast_var_t *var)
Definition: chanvars.c:60
long int billsec
Definition: cdr.h:302
struct ast_cdr * next
Definition: cdr.h:325
char dcontext[AST_MAX_EXTENSION]
Definition: cdr.h:284
struct cdr_object * next
Definition: cdr.c:735
struct cdr_object_snapshot party_b
Definition: cdr.c:714
Structure representing a snapshot of channel state.
int sequence
Definition: cdr.h:320
const ast_string_field accountcode
const ast_string_field exten
Definition: cdr.c:734
struct timeval answer
Definition: cdr.c:719
const ast_string_field uniqueid
unsigned int sequence
Definition: cdr.c:722
#define ast_assert(a)
Definition: utils.h:650
#define ast_copy_flags(dest, src, flagz)
Definition: utils.h:84
struct timeval start
Definition: cdr.c:718
static int copy_variables(struct varshead *to_list, struct varshead *from_list)
Copy variables from one list to another.
Definition: cdr.c:746
#define NULL
Definition: resample.c:96
static long cdr_object_get_duration(struct cdr_object *cdr)
Definition: cdr.c:1227
struct cdr_object_snapshot party_a
Definition: cdr.c:713
const ast_string_field appl
Definition: cdr.c:734
struct varshead varshead
Definition: cdr.h:323
const ast_string_field context
Definition: cdr.c:734
char lastdata[AST_MAX_EXTENSION]
Definition: cdr.h:292
long int amaflags
Definition: cdr.h:306
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
char userfield[AST_MAX_USER_FIELD]
Definition: cdr.c:706
struct ast_flags flags
Definition: cdr.c:723
char * ast_callerid_merge(char *buf, int bufsiz, const char *name, const char *num, const char *unknown)
Definition: callerid.c:1073
struct ast_var_t::@243 entries
char linkedid[AST_MAX_UNIQUEID]
Definition: cdr.h:316
const ast_string_field linkedid
Definition: cdr.c:734
char uniqueid[AST_MAX_UNIQUEID]
Definition: cdr.h:314
char dst[AST_MAX_EXTENSION]
Definition: cdr.h:282
char channel[AST_MAX_EXTENSION]
Definition: cdr.h:286
enum ast_cdr_disposition disposition
Definition: cdr.c:717
struct ast_channel_snapshot_caller * caller
An in-memory representation of an active CDR.
Definition: cdr.c:712
struct timeval answer
Definition: cdr.h:296
Responsible for call detail data.
Definition: cdr.h:276
char lastapp[AST_MAX_EXTENSION]
Definition: cdr.h:290
const ast_string_field data
Definition: cdr.c:734
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
static int snapshot_is_dialed(struct ast_channel_snapshot *snapshot)
Return whether or not a ast_channel_snapshot is for a channel that was created as the result of a dia...
Definition: cdr.c:1179
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_strlen_zero(a)
Definition: muted.c:73
struct timeval end
Definition: cdr.c:720
struct timeval start
Definition: cdr.h:294
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
#define AST_FLAGS_ALL
Definition: utils.h:196
#define ast_var_assign(name, value)
Definition: chanvars.h:40
long int duration
Definition: cdr.h:300
char src[AST_MAX_EXTENSION]
Definition: cdr.h:280
char peeraccount[AST_MAX_ACCOUNT_CODE]
Definition: cdr.h:310
struct timeval end
Definition: cdr.h:298
const ast_string_field number
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
long int disposition
Definition: cdr.h:304
char clid[AST_MAX_EXTENSION]
Definition: cdr.h:278
const ast_string_field name
char userfield[AST_MAX_USER_FIELD]
Definition: cdr.h:318

◆ cdr_object_dispatch()

static void cdr_object_dispatch ( struct cdr_object cdr)
static

Dispatch a CDR.

Parameters
cdrThe cdr_object to dispatch

This will create a ast_cdr object and publish it to the various backends

Definition at line 1386 of file cdr.c.

References ast_channel_snapshot::base, CDR_DEBUG, cdr_detach(), cdr_object_create_public_records(), ast_channel_snapshot_base::name, cdr_object::party_a, cdr_object::party_b, and cdr_object_snapshot::snapshot.

Referenced by cdr_object_dispatch_all_cb(), and handle_channel_snapshot_update_message().

1387 {
1388  struct ast_cdr *pub_cdr;
1389 
1390  CDR_DEBUG("%p - Dispatching CDR for Party A %s, Party B %s\n", cdr,
1391  cdr->party_a.snapshot->base->name,
1392  cdr->party_b.snapshot ? cdr->party_b.snapshot->base->name : "<none>");
1393  pub_cdr = cdr_object_create_public_records(cdr);
1394  cdr_detach(pub_cdr);
1395 }
struct ast_channel_snapshot_base * base
struct ast_channel_snapshot * snapshot
Definition: cdr.c:705
struct cdr_object_snapshot party_b
Definition: cdr.c:714
struct cdr_object_snapshot party_a
Definition: cdr.c:713
#define CDR_DEBUG(fmt,...)
Definition: cdr.c:210
static void cdr_detach(struct ast_cdr *cdr)
Definition: cdr.c:3841
Responsible for call detail data.
Definition: cdr.h:276
static struct ast_cdr * cdr_object_create_public_records(struct cdr_object *cdr)
Create a chain of ast_cdr objects from a chain of cdr_object suitable for consumption by the register...
Definition: cdr.c:1287
const ast_string_field name

◆ cdr_object_dispatch_all_cb()

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

This dispatches all cdr_objects. It should only be used during shutdown, so that we get billing records for everything that we can.

Definition at line 4260 of file cdr.c.

References ao2_lock, ao2_unlock, cdr_all_unlink(), cdr_object_dispatch(), cdr_object_transition_state(), CMP_MATCH, and cdr_object::next.

Referenced by cdr_engine_shutdown().

4261 {
4262  struct cdr_object *cdr = obj;
4263  struct cdr_object *it_cdr;
4264 
4265  ao2_lock(cdr);
4266  for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
4268  }
4269  cdr_object_dispatch(cdr);
4270  ao2_unlock(cdr);
4271 
4272  cdr_all_unlink(cdr);
4273 
4274  return CMP_MATCH;
4275 }
static void cdr_all_unlink(struct cdr_object *cdr)
Definition: cdr.c:972
struct cdr_object * next
Definition: cdr.c:735
#define ao2_unlock(a)
Definition: astobj2.h:730
static void cdr_object_dispatch(struct cdr_object *cdr)
Dispatch a CDR.
Definition: cdr.c:1386
#define ao2_lock(a)
Definition: astobj2.h:718
An in-memory representation of an active CDR.
Definition: cdr.c:712
struct cdr_object_fn_table finalized_state_fn_table
The virtual table for the finalized state.
Definition: cdr.c:694
static void cdr_object_transition_state(struct cdr_object *cdr, struct cdr_object_fn_table *fn_table)
Transition a cdr_object to a new state.
Definition: cdr.c:821

◆ cdr_object_dtor()

static void cdr_object_dtor ( void *  obj)
static

cdr_object Destructor

Definition at line 999 of file cdr.c.

References ao2_cleanup, AST_LIST_REMOVE_HEAD, ast_string_field_free_memory, ast_var_delete(), ast_var_t::entries, cdr_object::is_root, cdr_object::next, cdr_object::party_a, cdr_object::party_b, cdr_object_snapshot::snapshot, and cdr_object_snapshot::variables.

Referenced by cdr_object_alloc().

1000 {
1001  struct cdr_object *cdr = obj;
1002  struct ast_var_t *it_var;
1003 
1006  while ((it_var = AST_LIST_REMOVE_HEAD(&cdr->party_a.variables, entries))) {
1007  ast_var_delete(it_var);
1008  }
1009  while ((it_var = AST_LIST_REMOVE_HEAD(&cdr->party_b.variables, entries))) {
1010  ast_var_delete(it_var);
1011  }
1013 
1014  /* CDR destruction used to work by calling ao2_cleanup(next) and
1015  * allowing the chain to destroy itself neatly. Unfortunately, for
1016  * really long chains, this can result in a stack overflow. So now
1017  * when the root CDR is destroyed, it is responsible for unreffing
1018  * all CDRs in the chain
1019  */
1020  if (cdr->is_root) {
1021  struct cdr_object *curr = cdr->next;
1022  struct cdr_object *next;
1023 
1024  while (curr) {
1025  next = curr->next;
1026  ao2_cleanup(curr);
1027  curr = next;
1028  }
1029  }
1030 }
struct varshead variables
Definition: cdr.c:708
struct ast_channel_snapshot * snapshot
Definition: cdr.c:705
struct cdr_object * next
Definition: cdr.c:735
struct cdr_object_snapshot party_b
Definition: cdr.c:714
struct cdr_object_snapshot party_a
Definition: cdr.c:713
int is_root
Definition: cdr.c:737
struct ast_var_t::@243 entries
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
An in-memory representation of an active CDR.
Definition: cdr.c:712
void ast_var_delete(struct ast_var_t *var)
Definition: extconf.c:2473
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:368

◆ cdr_object_finalize()

static void cdr_object_finalize ( struct cdr_object cdr)
static

Finalize a CDR.

This function is safe to call multiple times. Note that you can call this explicitly before going to the finalized state if there's a chance the CDR will be re-activated, in which case the cdr_object's end time should be cleared. This function is implicitly called when a CDR transitions to the finalized state and right before it is dispatched

Parameters
cdr_objectThe CDR to finalize

Definition at line 1440 of file cdr.c.

References cdr_object::answer, AST_CDR_ANSWERED, ast_cdr_disp2str(), AST_CDR_FAILED, AST_CDR_NULL, ast_debug, ast_tvdiff_ms(), ast_tvzero(), ast_channel_snapshot::base, ast_channel_snapshot_hangup::cause, cdr_object_set_disposition(), cdr_object::disposition, cdr_object::end, ast_channel_snapshot::hangup, cdr_object::lastevent, ast_channel_snapshot_base::name, cdr_object::party_a, cdr_object::party_b, cdr_object_snapshot::snapshot, and cdr_object::start.

Referenced by ast_cdr_fork(), base_process_party_a(), cdr_object_check_party_a_hangup(), cdr_object_finalize_party_b(), cdr_object_party_b_left_bridge_cb(), dial_state_process_bridge_enter(), finalized_state_init_function(), handle_channel_snapshot_update_message(), handle_standard_bridge_enter_message(), and single_state_bridge_enter_comparison().

1441 {
1442  if (!ast_tvzero(cdr->end)) {
1443  return;
1444  }
1445  cdr->end = cdr->lastevent;
1446 
1447  if (cdr->disposition == AST_CDR_NULL) {
1448  if (!ast_tvzero(cdr->answer)) {
1450  } else if (cdr->party_a.snapshot->hangup->cause) {
1452  } else if (cdr->party_b.snapshot && cdr->party_b.snapshot->hangup->cause) {
1454  } else {
1455  cdr->disposition = AST_CDR_FAILED;
1456  }
1457  }
1458 
1459  /* tv_usec is suseconds_t, which could be int or long */
1460  ast_debug(1, "Finalized CDR for %s - start %ld.%06ld answer %ld.%06ld end %ld.%06ld dur %.3f bill %.3f dispo %s\n",
1461  cdr->party_a.snapshot->base->name,
1462  (long)cdr->start.tv_sec,
1463  (long)cdr->start.tv_usec,
1464  (long)cdr->answer.tv_sec,
1465  (long)cdr->answer.tv_usec,
1466  (long)cdr->end.tv_sec,
1467  (long)cdr->end.tv_usec,
1468  (double)ast_tvdiff_ms(cdr->end, cdr->start) / 1000.0,
1469  (double)ast_tvdiff_ms(cdr->end, cdr->answer) / 1000.0,
1471 }
struct ast_channel_snapshot_base * base
struct ast_channel_snapshot * snapshot
Definition: cdr.c:705
struct cdr_object_snapshot party_b
Definition: cdr.c:714
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:108
struct timeval answer
Definition: cdr.c:719
static void cdr_object_set_disposition(struct cdr_object *cdr, int hangupcause)
Set the disposition on a cdr_object based on a hangupcause code.
Definition: cdr.c:1402
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98
struct timeval start
Definition: cdr.c:718
struct cdr_object_snapshot party_a
Definition: cdr.c:713
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
struct ast_channel_snapshot_hangup * hangup
enum ast_cdr_disposition disposition
Definition: cdr.c:717
struct timeval lastevent
Definition: cdr.c:721
struct timeval end
Definition: cdr.c:720
const ast_string_field name
const char * ast_cdr_disp2str(int disposition)
Disposition to a string.
Definition: cdr.c:3430

◆ cdr_object_finalize_party_b()

static int cdr_object_finalize_party_b ( void *  obj,
void *  arg,
void *  data,
int  flags 
)
static

Definition at line 2196 of file cdr.c.

References ast_assert, ast_channel_snapshot::base, cdr_object_finalize(), ast_channel_snapshot_base::name, cdr_object::party_b, cdr_object::party_b_name, and cdr_object_snapshot::snapshot.

Referenced by handle_channel_snapshot_update_message().

2197 {
2198  struct cdr_object *cdr = obj;
2199 
2200  if (!strcasecmp(cdr->party_b_name, arg)) {
2201 #ifdef AST_DEVMODE
2202  struct ast_channel_snapshot *party_b = data;
2203 
2204  /*
2205  * For sanity's sake we also assert the party_b snapshot
2206  * is consistent with the key.
2207  */
2209  && !strcasecmp(cdr->party_b.snapshot->base->name, party_b->base->name));
2210 #endif
2211 
2212  /* Don't transition to the finalized state - let the Party A do
2213  * that when its ready
2214  */
2215  cdr_object_finalize(cdr);
2216  }
2217  return 0;
2218 }
struct ast_channel_snapshot_base * base
struct ast_channel_snapshot * snapshot
Definition: cdr.c:705
struct cdr_object_snapshot party_b
Definition: cdr.c:714
Structure representing a snapshot of channel state.
#define ast_assert(a)
Definition: utils.h:650
An in-memory representation of an active CDR.
Definition: cdr.c:712
const ast_string_field party_b_name
Definition: cdr.c:734
static void cdr_object_finalize(struct cdr_object *cdr)
Finalize a CDR.
Definition: cdr.c:1440
const ast_string_field name

◆ cdr_object_format_property()

static int cdr_object_format_property ( struct cdr_object cdr_obj,
const char *  name,
char *  value,
size_t  length 
)
static

Format one of the standard properties on a cdr_object.

Definition at line 3243 of file cdr.c.

References ast_channel_snapshot_base::accountcode, ast_channel_snapshot::amaflags, cdr_object::answer, ast_channel_snapshot_dialplan::appl, ast_callerid_merge(), ast_copy_string(), ast_channel_snapshot::base, ast_channel_snapshot::caller, cdr_get_tv(), cdr_object_get_billsec(), cdr_object_get_duration(), ast_channel_snapshot_dialplan::context, ast_channel_snapshot_dialplan::data, ast_channel_snapshot::dialplan, cdr_object::disposition, cdr_object::end, ast_channel_snapshot_dialplan::exten, cdr_object::linkedid, ast_channel_snapshot_caller::name, ast_channel_snapshot_base::name, NULL, ast_channel_snapshot_caller::number, cdr_object::party_a, cdr_object::party_b, cdr_object::sequence, cdr_object_snapshot::snapshot, cdr_object::start, ast_channel_snapshot_base::uniqueid, and cdr_object_snapshot::userfield.

Referenced by ast_cdr_getvar(), and ast_cdr_serialize_variables().

3244 {
3245  struct ast_channel_snapshot *party_a = cdr_obj->party_a.snapshot;
3246  struct ast_channel_snapshot *party_b = cdr_obj->party_b.snapshot;
3247 
3248  if (!strcasecmp(name, "clid")) {
3249  ast_callerid_merge(value, length, party_a->caller->name, party_a->caller->number, "");
3250  } else if (!strcasecmp(name, "src")) {
3251  ast_copy_string(value, party_a->caller->number, length);
3252  } else if (!strcasecmp(name, "dst")) {
3253  ast_copy_string(value, party_a->dialplan->exten, length);
3254  } else if (!strcasecmp(name, "dcontext")) {
3255  ast_copy_string(value, party_a->dialplan->context, length);
3256  } else if (!strcasecmp(name, "channel")) {
3257  ast_copy_string(value, party_a->base->name, length);
3258  } else if (!strcasecmp(name, "dstchannel")) {
3259  if (party_b) {
3260  ast_copy_string(value, party_b->base->name, length);
3261  } else {
3262  ast_copy_string(value, "", length);
3263  }
3264  } else if (!strcasecmp(name, "lastapp")) {
3265  ast_copy_string(value, party_a->dialplan->appl, length);
3266  } else if (!strcasecmp(name, "lastdata")) {
3267  ast_copy_string(value, party_a->dialplan->data, length);
3268  } else if (!strcasecmp(name, "start")) {
3269  cdr_get_tv(cdr_obj->start, NULL, value, length);
3270  } else if (!strcasecmp(name, "answer")) {
3271  cdr_get_tv(cdr_obj->answer, NULL, value, length);
3272  } else if (!strcasecmp(name, "end")) {
3273  cdr_get_tv(cdr_obj->end, NULL, value, length);
3274  } else if (!strcasecmp(name, "duration")) {
3275  snprintf(value, length, "%ld", cdr_object_get_duration(cdr_obj));
3276  } else if (!strcasecmp(name, "billsec")) {
3277  snprintf(value, length, "%ld", cdr_object_get_billsec(cdr_obj));
3278  } else if (!strcasecmp(name, "disposition")) {
3279  snprintf(value, length, "%u", cdr_obj->disposition);
3280  } else if (!strcasecmp(name, "amaflags")) {
3281  snprintf(value, length, "%d", party_a->amaflags);
3282  } else if (!strcasecmp(name, "accountcode")) {
3283  ast_copy_string(value, party_a->base->accountcode, length);
3284  } else if (!strcasecmp(name, "peeraccount")) {
3285  if (party_b) {
3286  ast_copy_string(value, party_b->base->accountcode, length);
3287  } else {
3288  ast_copy_string(value, "", length);
3289  }
3290  } else if (!strcasecmp(name, "uniqueid")) {
3291  ast_copy_string(value, party_a->base->uniqueid, length);
3292  } else if (!strcasecmp(name, "linkedid")) {
3293  ast_copy_string(value, cdr_obj->linkedid, length);
3294  } else if (!strcasecmp(name, "userfield")) {
3295  ast_copy_string(value, cdr_obj->party_a.userfield, length);
3296  } else if (!strcasecmp(name, "sequence")) {
3297  snprintf(value, length, "%u", cdr_obj->sequence);
3298  } else {
3299  return 1;
3300  }
3301 
3302  return 0;
3303 }
const ast_string_field data
static long cdr_object_get_billsec(struct cdr_object *cdr)
Compute the billsec for a cdr_object.
Definition: cdr.c:1235
struct ast_channel_snapshot_base * base
const ast_string_field name
struct ast_channel_snapshot * snapshot
Definition: cdr.c:705
struct cdr_object_snapshot party_b
Definition: cdr.c:714
Structure representing a snapshot of channel state.
const ast_string_field accountcode
struct timeval answer
Definition: cdr.c:719
const ast_string_field uniqueid
unsigned int sequence
Definition: cdr.c:722
struct timeval start
Definition: cdr.c:718
#define NULL
Definition: resample.c:96
static long cdr_object_get_duration(struct cdr_object *cdr)
Definition: cdr.c:1227
int value
Definition: syslog.c:37
struct ast_channel_snapshot_dialplan * dialplan
struct cdr_object_snapshot party_a
Definition: cdr.c:713
const ast_string_field context
char userfield[AST_MAX_USER_FIELD]
Definition: cdr.c:706
char * ast_callerid_merge(char *buf, int bufsiz, const char *name, const char *num, const char *unknown)
Definition: callerid.c:1073
const ast_string_field appl
const ast_string_field linkedid
Definition: cdr.c:734
const ast_string_field exten
static void cdr_get_tv(struct timeval when, const char *fmt, char *buf, int bufsize)
Definition: cdr.c:3035
enum ast_cdr_disposition disposition
Definition: cdr.c:717
struct ast_channel_snapshot_caller * caller
struct timeval end
Definition: cdr.c:720
static const char name[]
Definition: cdr_mysql.c:74
const ast_string_field number
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
const ast_string_field name

◆ cdr_object_format_var_internal()

static void cdr_object_format_var_internal ( struct cdr_object cdr,
const char *  name,
char *  value,
size_t  length 
)
static

Format a variable on a cdr_object.

Definition at line 3226 of file cdr.c.

References ast_copy_string(), AST_LIST_TRAVERSE, ast_var_name(), ast_var_value(), ast_var_t::entries, cdr_object::party_a, and cdr_object_snapshot::variables.

Referenced by ast_cdr_getvar().

3227 {
3228  struct ast_var_t *variable;
3229 
3230  AST_LIST_TRAVERSE(&cdr->party_a.variables, variable, entries) {
3231  if (!strcasecmp(name, ast_var_name(variable))) {
3232  ast_copy_string(value, ast_var_value(variable), length);
3233  return;
3234  }
3235  }
3236 
3237  *value = '\0';
3238 }
struct varshead variables
Definition: cdr.c:708
const char * ast_var_value(const struct ast_var_t *var)
Definition: chanvars.c:80
const char * ast_var_name(const struct ast_var_t *var)
Definition: chanvars.c:60
int value
Definition: syslog.c:37
struct cdr_object_snapshot party_a
Definition: cdr.c:713
struct ast_var_t::@243 entries
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
static const char name[]
Definition: cdr_mysql.c:74
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401

◆ cdr_object_get_billsec()

static long cdr_object_get_billsec ( struct cdr_object cdr)
static

Compute the billsec for a cdr_object.

Definition at line 1235 of file cdr.c.

References cdr_object::answer, ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), CDR_INITIATED_SECONDS, cdr_object::end, and is_cdr_flag_set().

Referenced by cdr_object_create_public_records(), and cdr_object_format_property().

1236 {
1237  long int ms;
1238 
1239  if (ast_tvzero(cdr->answer)) {
1240  return 0;
1241  }
1242 
1243  ms = ast_tvdiff_ms(ast_tvzero(cdr->end) ? ast_tvnow() : cdr->end, cdr->answer);
1244  if (ms % 1000 >= 500
1246  ms = (ms / 1000) + 1;
1247  } else {
1248  ms = ms / 1000;
1249  }
1250 
1251  return ms;
1252 }
static int is_cdr_flag_set(unsigned int cdr_flag)
Definition: cdr.c:1127
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:108
struct timeval answer
Definition: cdr.c:719
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98
struct timeval end
Definition: cdr.c:720

◆ cdr_object_get_by_name()

static struct cdr_object* cdr_object_get_by_name ( const char *  name)
static

Definition at line 3312 of file cdr.c.

References ao2_callback, ast_strdupa, ast_strlen_zero, cdr_object_get_by_name_cb(), and NULL.

Referenced by ast_cdr_clear_property(), ast_cdr_fork(), ast_cdr_getvar(), ast_cdr_reset(), ast_cdr_serialize_variables(), ast_cdr_set_property(), ast_cdr_setuserfield(), and cli_show_channel().

3313 {
3314  char *param;
3315 
3316  if (ast_strlen_zero(name)) {
3317  return NULL;
3318  }
3319 
3320  param = ast_strdupa(name);
3322 }
static int cdr_object_get_by_name_cb(void *obj, void *arg, int flags)
Definition: cdr.c:3142
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
#define NULL
Definition: resample.c:96
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static struct ao2_container * active_cdrs_master
A container of the active master CDRs indexed by Party A channel uniqueid.
Definition: cdr.c:365
#define ast_strlen_zero(a)
Definition: muted.c:73
static const char name[]
Definition: cdr_mysql.c:74

◆ cdr_object_get_by_name_cb()

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

Definition at line 3142 of file cdr.c.

References ast_channel_snapshot::base, CMP_MATCH, name, ast_channel_snapshot_base::name, cdr_object::party_a, and cdr_object_snapshot::snapshot.

Referenced by cdr_object_get_by_name().

3143 {
3144  struct cdr_object *cdr = obj;
3145  const char *name = arg;
3146 
3147  if (!strcasecmp(cdr->party_a.snapshot->base->name, name)) {
3148  return CMP_MATCH;
3149  }
3150  return 0;
3151 }
struct ast_channel_snapshot_base * base
struct ast_channel_snapshot * snapshot
Definition: cdr.c:705
struct cdr_object_snapshot party_a
Definition: cdr.c:713
An in-memory representation of an active CDR.
Definition: cdr.c:712
static const char name[]
Definition: cdr_mysql.c:74
const ast_string_field name

◆ cdr_object_get_duration()

static long cdr_object_get_duration ( struct cdr_object cdr)
static

Compute the duration for a cdr_object

Definition at line 1227 of file cdr.c.

References ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), cdr_object::end, and cdr_object::start.

Referenced by cdr_object_create_public_records(), and cdr_object_format_property().

1228 {
1229  return (long)(ast_tvdiff_ms(ast_tvzero(cdr->end) ? ast_tvnow() : cdr->end, cdr->start) / 1000);
1230 }
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:108
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98
struct timeval start
Definition: cdr.c:718
struct timeval end
Definition: cdr.c:720

◆ cdr_object_party_b_left_bridge_cb()

static int cdr_object_party_b_left_bridge_cb ( void *  obj,
void *  arg,
void *  data,
int  flags 
)
static

Callback used to notify CDRs of a Party B leaving the bridge.

Definition at line 2361 of file cdr.c.

References ast_assert, ast_channel_snapshot::base, cdr_object::bridge, bridge_leave_data::bridge, cdr_object_finalize(), bridge_leave_data::channel, cdr_object::fn_table, cdr_object::lastevent, bridge_leave_data::lastevent, ast_channel_snapshot_base::name, cdr_object::party_b, cdr_object::party_b_name, cdr_object_snapshot::snapshot, and ast_bridge_snapshot::uniqueid.

Referenced by handle_bridge_leave_message().

2362 {
2363  struct cdr_object *cdr = obj;
2364  struct bridge_leave_data *leave_data = data;
2365 
2366  if (cdr->fn_table == &bridge_state_fn_table
2367  && !strcmp(cdr->bridge, leave_data->bridge->uniqueid)
2368  && !strcasecmp(cdr->party_b_name, arg)) {
2369  /*
2370  * For sanity's sake we also assert the party_b snapshot
2371  * is consistent with the key.
2372  */
2374  && !strcasecmp(cdr->party_b.snapshot->base->name, leave_data->channel->base->name));
2375 
2376  /* It is our Party B, in our bridge. Set the last event and let the handler
2377  * transition our CDR appropriately when we leave the bridge.
2378  */
2379  cdr->lastevent = *leave_data->lastevent;
2380  cdr_object_finalize(cdr);
2381  }
2382  return 0;
2383 }
struct ast_bridge_snapshot * bridge
Definition: cdr.c:2355
struct ast_channel_snapshot_base * base
struct ast_channel_snapshot * snapshot
Definition: cdr.c:705
struct cdr_object_snapshot party_b
Definition: cdr.c:714
#define ast_assert(a)
Definition: utils.h:650
struct ast_channel_snapshot * channel
Definition: cdr.c:2356
struct cdr_object_fn_table * fn_table
Definition: cdr.c:715
An in-memory representation of an active CDR.
Definition: cdr.c:712
const ast_string_field party_b_name
Definition: cdr.c:734
struct timeval lastevent
Definition: cdr.c:721
const ast_string_field uniqueid
Definition: bridge.h:332
const struct timeval * lastevent
Definition: cdr.c:2357
struct cdr_object_fn_table bridge_state_fn_table
The virtual table for the Bridged state.
Definition: cdr.c:659
static void cdr_object_finalize(struct cdr_object *cdr)
Finalize a CDR.
Definition: cdr.c:1440
const ast_string_field bridge
Definition: cdr.c:734
const ast_string_field name

◆ cdr_object_pick_party_a()

static struct cdr_object_snapshot* cdr_object_pick_party_a ( struct cdr_object_snapshot left,
struct cdr_object_snapshot right 
)
static

Given two CDR snapshots, figure out who should be Party A for the resulting CDR.

Parameters
leftOne of the snapshots
rightThe other snapshot
Return values
Thesnapshot that won

Definition at line 1192 of file cdr.c.

References AST_CDR_FLAG_PARTY_A, ast_test_flag, ast_channel_snapshot::base, ast_channel_snapshot_base::creationtime, cdr_object_snapshot::snapshot, and snapshot_is_dialed().

Referenced by bridge_candidate_process(), and single_state_bridge_enter_comparison().

1193 {
1194  /* Check whether or not the party is dialed. A dialed party is never the
1195  * Party A with a party that was not dialed.
1196  */
1197  if (!snapshot_is_dialed(left->snapshot) && snapshot_is_dialed(right->snapshot)) {
1198  return left;
1199  } else if (snapshot_is_dialed(left->snapshot) && !snapshot_is_dialed(right->snapshot)) {
1200  return right;
1201  }
1202 
1203  /* Try the Party A flag */
1205  return left;
1206  } else if (!ast_test_flag(right, AST_CDR_FLAG_PARTY_A) && ast_test_flag(right, AST_CDR_FLAG_PARTY_A)) {
1207  return right;
1208  }
1209 
1210  /* Neither party is dialed and neither has the Party A flag - defer to
1211  * creation time */
1212  if (left->snapshot->base->creationtime.tv_sec < right->snapshot->base->creationtime.tv_sec) {
1213  return left;
1214  } else if (left->snapshot->base->creationtime.tv_sec > right->snapshot->base->creationtime.tv_sec) {
1215  return right;
1216  } else if (left->snapshot->base->creationtime.tv_usec > right->snapshot->base->creationtime.tv_usec) {
1217  return right;
1218  } else {
1219  /* Okay, fine, take the left one */