Asterisk - The Open Source Telephony Project GIT-master-754dea3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
Data Structures | Typedefs | Enumerations | Functions
cdr.h File Reference

Call Detail Record API. More...

#include "asterisk/channel.h"
Include dependency graph for cdr.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ast_cdr
 Responsible for call detail data. More...
 
struct  ast_cdr_config
 The global options available for CDRs. More...
 
struct  ast_cdr_config::batch_settings
 

Typedefs

typedef int(* ast_cdrbe) (struct ast_cdr *cdr)
 CDR backend callback. More...
 

Enumerations

enum  ast_cdr_batch_mode_settings { BATCH_MODE_SCHEDULER_ONLY = 1 << 0 , BATCH_MODE_SAFE_SHUTDOWN = 1 << 1 }
 CDR Batch Mode settings. More...
 
enum  ast_cdr_disposition {
  AST_CDR_NOANSWER = 0 , AST_CDR_NULL = (1 << 0) , AST_CDR_FAILED = (1 << 1) , AST_CDR_BUSY = (1 << 2) ,
  AST_CDR_ANSWERED = (1 << 3) , AST_CDR_CONGESTION = (1 << 4)
}
 CDR Flags - Disposition. More...
 
enum  ast_cdr_options {
  AST_CDR_FLAG_KEEP_VARS = (1 << 0) , AST_CDR_FLAG_DISABLE = (1 << 1) , AST_CDR_FLAG_DISABLE_ALL = (3 << 1) , AST_CDR_FLAG_PARTY_A = (1 << 3) ,
  AST_CDR_FLAG_FINALIZE = (1 << 4) , AST_CDR_FLAG_SET_ANSWER = (1 << 5) , AST_CDR_FLAG_RESET = (1 << 6) , AST_CDR_LOCK_APP = (1 << 7)
}
 CDR manipulation options. Certain function calls will manipulate the state of a CDR object based on these flags. More...
 
enum  ast_cdr_settings {
  CDR_ENABLED = 1 << 0 , CDR_BATCHMODE = 1 << 1 , CDR_UNANSWERED = 1 << 2 , CDR_CONGESTION = 1 << 3 ,
  CDR_END_BEFORE_H_EXTEN = 1 << 4 , CDR_INITIATED_SECONDS = 1 << 5 , CDR_DEBUG = 1 << 6 , CDR_CHANNEL_DEFAULT_ENABLED = 1 << 7 ,
  CDR_IGNORE_STATE_CHANGES = 1 << 8 , CDR_IGNORE_DIAL_CHANGES = 1 << 9
}
 CDR engine settings. More...
 

Functions

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

Detailed Description

Call Detail Record API.

Call Detail Record Engine.

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m
Since
12

Definition in file cdr.h.

Typedef Documentation

◆ ast_cdrbe

typedef int(* ast_cdrbe) (struct ast_cdr *cdr)

CDR backend callback.

Warning
CDR backends should NOT attempt to access the channel associated with a CDR record. This channel is not guaranteed to exist when the CDR backend is invoked.

Definition at line 465 of file cdr.h.

Enumeration Type Documentation

◆ ast_cdr_batch_mode_settings

CDR Batch Mode settings.

Enumerator
BATCH_MODE_SCHEDULER_ONLY 

Don't spawn a thread to handle the batches - do it on the scheduler

BATCH_MODE_SAFE_SHUTDOWN 

During safe shutdown, submit the batched CDRs

Definition at line 233 of file cdr.h.

233 {
234 BATCH_MODE_SCHEDULER_ONLY = 1 << 0, /*!< Don't spawn a thread to handle the batches - do it on the scheduler */
235 BATCH_MODE_SAFE_SHUTDOWN = 1 << 1, /*!< During safe shutdown, submit the batched CDRs */
236};
@ BATCH_MODE_SAFE_SHUTDOWN
Definition: cdr.h:235
@ BATCH_MODE_SCHEDULER_ONLY
Definition: cdr.h:234

◆ ast_cdr_disposition

CDR Flags - Disposition.

Enumerator
AST_CDR_NOANSWER 
AST_CDR_NULL 
AST_CDR_FAILED 
AST_CDR_BUSY 
AST_CDR_ANSWERED 
AST_CDR_CONGESTION 

Definition at line 256 of file cdr.h.

256 {
258 AST_CDR_NULL = (1 << 0),
259 AST_CDR_FAILED = (1 << 1),
260 AST_CDR_BUSY = (1 << 2),
261 AST_CDR_ANSWERED = (1 << 3),
262 AST_CDR_CONGESTION = (1 << 4),
263};
@ AST_CDR_CONGESTION
Definition: cdr.h:262
@ AST_CDR_NULL
Definition: cdr.h:258
@ AST_CDR_NOANSWER
Definition: cdr.h:257
@ AST_CDR_ANSWERED
Definition: cdr.h:261
@ AST_CDR_BUSY
Definition: cdr.h:260
@ AST_CDR_FAILED
Definition: cdr.h:259

◆ ast_cdr_options

CDR manipulation options. Certain function calls will manipulate the state of a CDR object based on these flags.

Enumerator
AST_CDR_FLAG_KEEP_VARS 

Copy variables during the operation

AST_CDR_FLAG_DISABLE 

Disable the current CDR

AST_CDR_FLAG_DISABLE_ALL 

Disable the CDR and all future CDRs

AST_CDR_FLAG_PARTY_A 

Set the channel as party A

AST_CDR_FLAG_FINALIZE 

Finalize the current CDRs

AST_CDR_FLAG_SET_ANSWER 

If the channel is answered, set the answer time to now

AST_CDR_FLAG_RESET 

If set, set the start and answer time to now

AST_CDR_LOCK_APP 

Prevent any further changes to the application field/data field for this CDR

Definition at line 242 of file cdr.h.

242 {
243 AST_CDR_FLAG_KEEP_VARS = (1 << 0), /*!< Copy variables during the operation */
244 AST_CDR_FLAG_DISABLE = (1 << 1), /*!< Disable the current CDR */
245 AST_CDR_FLAG_DISABLE_ALL = (3 << 1), /*!< Disable the CDR and all future CDRs */
246 AST_CDR_FLAG_PARTY_A = (1 << 3), /*!< Set the channel as party A */
247 AST_CDR_FLAG_FINALIZE = (1 << 4), /*!< Finalize the current CDRs */
248 AST_CDR_FLAG_SET_ANSWER = (1 << 5), /*!< If the channel is answered, set the answer time to now */
249 AST_CDR_FLAG_RESET = (1 << 6), /*!< If set, set the start and answer time to now */
250 AST_CDR_LOCK_APP = (1 << 7), /*!< Prevent any further changes to the application field/data field for this CDR */
251};
@ AST_CDR_FLAG_DISABLE_ALL
Definition: cdr.h:245
@ AST_CDR_LOCK_APP
Definition: cdr.h:250
@ AST_CDR_FLAG_FINALIZE
Definition: cdr.h:247
@ AST_CDR_FLAG_DISABLE
Definition: cdr.h:244
@ AST_CDR_FLAG_PARTY_A
Definition: cdr.h:246
@ AST_CDR_FLAG_KEEP_VARS
Definition: cdr.h:243
@ AST_CDR_FLAG_RESET
Definition: cdr.h:249
@ AST_CDR_FLAG_SET_ANSWER
Definition: cdr.h:248

◆ ast_cdr_settings

CDR engine settings.

Enumerator
CDR_ENABLED 

Enable CDRs

CDR_BATCHMODE 

Whether or not we should dispatch CDRs in batches

CDR_UNANSWERED 

Log unanswered CDRs

CDR_CONGESTION 

Treat congestion as if it were a failed call

CDR_END_BEFORE_H_EXTEN 

End the CDR before the 'h' extension runs

CDR_INITIATED_SECONDS 

Include microseconds into the billing time

CDR_DEBUG 

Enables extra debug statements

CDR_CHANNEL_DEFAULT_ENABLED 

Whether CDR is enabled for each channel by default

CDR_IGNORE_STATE_CHANGES 

Whether to ignore bridge and other call state change events

CDR_IGNORE_DIAL_CHANGES 

Whether to ignore dial state changes

Definition at line 219 of file cdr.h.

219 {
220 CDR_ENABLED = 1 << 0, /*!< Enable CDRs */
221 CDR_BATCHMODE = 1 << 1, /*!< Whether or not we should dispatch CDRs in batches */
222 CDR_UNANSWERED = 1 << 2, /*!< Log unanswered CDRs */
223 CDR_CONGESTION = 1 << 3, /*!< Treat congestion as if it were a failed call */
224 CDR_END_BEFORE_H_EXTEN = 1 << 4, /*!< End the CDR before the 'h' extension runs */
225 CDR_INITIATED_SECONDS = 1 << 5, /*!< Include microseconds into the billing time */
226 CDR_DEBUG = 1 << 6, /*!< Enables extra debug statements */
227 CDR_CHANNEL_DEFAULT_ENABLED = 1 << 7, /*!< Whether CDR is enabled for each channel by default */
228 CDR_IGNORE_STATE_CHANGES = 1 << 8, /*!< Whether to ignore bridge and other call state change events */
229 CDR_IGNORE_DIAL_CHANGES = 1 << 9, /*!< Whether to ignore dial state changes */
230};
@ CDR_UNANSWERED
Definition: cdr.h:222
@ CDR_IGNORE_STATE_CHANGES
Definition: cdr.h:228
@ CDR_INITIATED_SECONDS
Definition: cdr.h:225
@ CDR_ENABLED
Definition: cdr.h:220
@ CDR_CHANNEL_DEFAULT_ENABLED
Definition: cdr.h:227
@ CDR_END_BEFORE_H_EXTEN
Definition: cdr.h:224
@ CDR_IGNORE_DIAL_CHANGES
Definition: cdr.h:229
@ CDR_BATCHMODE
Definition: cdr.h:221
@ CDR_CONGESTION
Definition: cdr.h:223
@ CDR_DEBUG
Definition: cdr.h:226

Function Documentation

◆ ast_cdr_alloc()

struct ast_cdr * ast_cdr_alloc ( void  )

Allocate a CDR record.

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

Definition at line 3555 of file cdr.c.

3556{
3557 struct ast_cdr *x;
3558
3559 x = ast_calloc(1, sizeof(*x));
3560 return x;
3561}
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
Responsible for call detail data.
Definition: cdr.h:279

References ast_calloc.

Referenced by ast_cdr_dup().

◆ ast_cdr_backend_suspend()

int ast_cdr_backend_suspend ( const char *  name)

Suspend a CDR backend temporarily.

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

Definition at line 2986 of file cdr.c.

2987{
2988 int success = -1;
2989 struct cdr_beitem *i = NULL;
2990
2992 AST_RWLIST_TRAVERSE(&be_list, i, list) {
2993 if (!strcasecmp(name, i->name)) {
2994 ast_debug(3, "Suspending CDR backend %s\n", i->name);
2995 i->suspended = 1;
2996 success = 0;
2997 }
2998 }
3000
3001 return success;
3002}
static const char name[]
Definition: format_mp3.c:68
#define ast_debug(level,...)
Log a DEBUG message.
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:52
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:494
#define NULL
Definition: resample.c:96
List of registered backends.
Definition: cdr.c:426
Registration object for CDR backends.
Definition: cdr.c:417
char name[20]
Definition: cdr.c:418

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

Referenced by load_config(), and odbc_load_module().

◆ 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 3004 of file cdr.c.

3005{
3006 int success = -1;
3007 struct cdr_beitem *i = NULL;
3008
3010 AST_RWLIST_TRAVERSE(&be_list, i, list) {
3011 if (!strcasecmp(name, i->name)) {
3012 ast_debug(3, "Unsuspending CDR backend %s\n", i->name);
3013 i->suspended = 0;
3014 success = 0;
3015 }
3016 }
3018
3019 return success;
3020}

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

Referenced by load_config(), and odbc_load_module().

◆ 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 3708 of file cdr.c.

3709{
3710 struct cdr_object *cdr;
3711 struct cdr_object *it_cdr;
3712
3713 cdr = cdr_object_get_by_name(channel_name);
3714 if (!cdr) {
3715 return -1;
3716 }
3717
3718 ao2_lock(cdr);
3719 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3720 if (it_cdr->fn_table == &finalized_state_fn_table) {
3721 continue;
3722 }
3723 ast_clear_flag(&it_cdr->flags, option);
3724 }
3725 ao2_unlock(cdr);
3726
3727 ao2_cleanup(cdr);
3728 return 0;
3729}
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_unlock(a)
Definition: astobj2.h:729
#define ao2_lock(a)
Definition: astobj2.h:717
struct cdr_object_fn_table finalized_state_fn_table
The virtual table for the finalized state.
Definition: cdr.c:790
static struct cdr_object * cdr_object_get_by_name(const char *name)
Definition: cdr.c:3445
An in-memory representation of an active CDR.
Definition: cdr.c:808
struct cdr_object_fn_table * fn_table
Definition: cdr.c:811
struct cdr_object * next
Definition: cdr.c:832
struct ast_flags flags
Definition: cdr.c:819
#define ast_clear_flag(p, flag)
Definition: utils.h:77

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

Referenced by AST_TEST_DEFINE(), and cdr_prop_write_callback().

◆ 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 3563 of file cdr.c.

3564{
3565 switch (disposition) {
3566 case AST_CDR_NULL:
3567 return "NO ANSWER"; /* by default, for backward compatibility */
3568 case AST_CDR_NOANSWER:
3569 return "NO ANSWER";
3570 case AST_CDR_FAILED:
3571 return "FAILED";
3572 case AST_CDR_BUSY:
3573 return "BUSY";
3574 case AST_CDR_ANSWERED:
3575 return "ANSWERED";
3576 case AST_CDR_CONGESTION:
3577 return "CONGESTION";
3578 }
3579 return "UNKNOWN";
3580}

References AST_CDR_ANSWERED, AST_CDR_BUSY, AST_CDR_CONGESTION, AST_CDR_FAILED, AST_CDR_NOANSWER, AST_CDR_NULL, and ast_cdr::disposition.

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

◆ ast_cdr_dup()

struct ast_cdr * ast_cdr_dup ( struct ast_cdr cdr)

Duplicate a public CDR.

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

Definition at line 3118 of file cdr.c.

3119{
3120 struct ast_cdr *newcdr;
3121
3122 if (!cdr) {
3123 return NULL;
3124 }
3125 newcdr = ast_cdr_alloc();
3126 if (!newcdr) {
3127 return NULL;
3128 }
3129
3130 *newcdr = *cdr;
3132 copy_variables(&newcdr->varshead, &cdr->varshead);
3133 newcdr->next = NULL;
3134
3135 return newcdr;
3136}
struct ast_cdr * ast_cdr_alloc(void)
Allocate a CDR record.
Definition: cdr.c:3555
static int copy_variables(struct varshead *to_list, struct varshead *from_list)
Copy variables from one list to another.
Definition: cdr.c:843
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:681
struct ast_cdr * next
Definition: cdr.h:332
struct varshead varshead
Definition: cdr.h:330

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

Referenced by custom_log(), manager_log(), and write_cdr().

◆ ast_cdr_engine_term()

void ast_cdr_engine_term ( void  )

Submit any remaining CDRs and prepare for shutdown

Definition at line 4736 of file cdr.c.

4737{
4738 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
4739
4740 /* Since this is called explicitly during process shutdown, we might not have ever
4741 * been initialized. If so, the config object will be NULL.
4742 */
4743 if (!mod_cfg) {
4744 return;
4745 }
4746
4747 if (cdr_sync_message_type()) {
4748 void *payload;
4749 struct stasis_message *message;
4750
4751 if (!stasis_router) {
4752 return;
4753 }
4754
4755 /* Make sure we have the needed items */
4756 payload = ao2_alloc(sizeof(*payload), NULL);
4757 if (!payload) {
4758 return;
4759 }
4760
4761 ast_debug(1, "CDR Engine termination request received; waiting on messages...\n");
4762
4763 message = stasis_message_create(cdr_sync_message_type(), payload);
4764 if (message) {
4766 }
4768 ao2_cleanup(payload);
4769 }
4770
4771 if (ast_test_flag(&mod_cfg->general->settings, CDR_BATCHMODE)) {
4772 cdr_submit_batch(ast_test_flag(&mod_cfg->general->batch_settings.settings, BATCH_MODE_SAFE_SHUTDOWN));
4773 }
4774}
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
static struct stasis_message_router * stasis_router
Message router for stasis messages regarding channel state.
Definition: cdr.c:467
static void cdr_submit_batch(int shutdown)
Definition: cdr.c:3899
struct stasis_message * stasis_message_create(struct stasis_message_type *type, void *data)
Create a new message.
void stasis_message_router_publish_sync(struct stasis_message_router *router, struct stasis_message *message)
Publish a message to a message router's subscription synchronously.
The configuration settings for this module.
Definition: cdr.c:318
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941

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

Referenced by can_safely_quit(), and finalize_batch_mode().

◆ 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 3770 of file cdr.c.

3771{
3772 RAII_VAR(struct cdr_object *, cdr, cdr_object_get_by_name(channel_name), ao2_cleanup);
3773 struct cdr_object *new_cdr;
3774 struct cdr_object *it_cdr;
3775 struct cdr_object *cdr_obj;
3776
3777 if (!cdr) {
3778 return -1;
3779 }
3780
3781 {
3782 SCOPED_AO2LOCK(lock, cdr);
3783 struct timeval now = ast_tvnow();
3784
3785 cdr_obj = cdr->last;
3786 if (cdr_obj->fn_table == &finalized_state_fn_table) {
3787 /* If the last CDR in the chain is finalized, don't allow a fork -
3788 * things are already dying at this point
3789 */
3790 return -1;
3791 }
3792
3793 /* Copy over the basic CDR information. The Party A information is
3794 * copied over automatically as part of the append
3795 */
3796 ast_debug(1, "Forking CDR for channel %s\n", cdr->party_a.snapshot->base->name);
3797 new_cdr = cdr_object_create_and_append(cdr, &now);
3798 if (!new_cdr) {
3799 return -1;
3800 }
3801 new_cdr->fn_table = cdr_obj->fn_table;
3802 ast_string_field_set(new_cdr, bridge, cdr->bridge);
3803 ast_string_field_set(new_cdr, appl, cdr->appl);
3804 ast_string_field_set(new_cdr, data, cdr->data);
3805 ast_string_field_set(new_cdr, context, cdr->context);
3806 ast_string_field_set(new_cdr, exten, cdr->exten);
3807 new_cdr->flags = cdr->flags;
3808 /* Explicitly clear the AST_CDR_LOCK_APP flag - we want
3809 * the application to be changed on the new CDR if the
3810 * dialplan demands it
3811 */
3813
3814 /* If there's a Party B, copy it over as well */
3815 if (cdr_obj->party_b.snapshot) {
3816 new_cdr->party_b.snapshot = cdr_obj->party_b.snapshot;
3817 ao2_ref(new_cdr->party_b.snapshot, +1);
3818 cdr_all_relink(new_cdr);
3819 strcpy(new_cdr->party_b.userfield, cdr_obj->party_b.userfield);
3820 new_cdr->party_b.flags = cdr_obj->party_b.flags;
3822 copy_variables(&new_cdr->party_b.variables, &cdr_obj->party_b.variables);
3823 }
3824 }
3825 new_cdr->start = cdr_obj->start;
3826 new_cdr->answer = cdr_obj->answer;
3827 new_cdr->lastevent = ast_tvnow();
3828
3829 /* Modify the times based on the flags passed in */
3831 && new_cdr->party_a.snapshot->state == AST_STATE_UP) {
3832 new_cdr->answer = ast_tvnow();
3833 }
3835 new_cdr->answer = ast_tvnow();
3836 new_cdr->start = ast_tvnow();
3837 }
3838
3839 /* Create and append, by default, copies over the variables */
3841 free_variables(&new_cdr->party_a.variables);
3842 }
3843
3844 /* Finalize any current CDRs */
3846 for (it_cdr = cdr; it_cdr != new_cdr; it_cdr = it_cdr->next) {
3847 if (it_cdr->fn_table == &finalized_state_fn_table) {
3848 continue;
3849 }
3850 /* Force finalization on the CDR. This will bypass any checks for
3851 * end before 'h' extension.
3852 */
3853 cdr_object_finalize(it_cdr);
3855 }
3856 }
3857 }
3858
3859 return 0;
3860}
ast_mutex_t lock
Definition: app_sla.c:337
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
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:1172
static void cdr_object_finalize(struct cdr_object *cdr)
Finalize a CDR.
Definition: cdr.c:1537
static void cdr_all_relink(struct cdr_object *cdr)
Definition: cdr.c:1045
static void free_variables(struct varshead *headp)
Delete all variables from a variable list.
Definition: cdr.c:874
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:919
@ AST_STATE_UP
Definition: channelstate.h:42
#define SCOPED_AO2LOCK(varname, obj)
scoped lock specialization for ao2 mutexes.
Definition: lock.h:608
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
enum ast_channel_state state
unsigned int flags
Definition: utils.h:200
char userfield[AST_MAX_USER_FIELD]
Definition: cdr.c:802
struct varshead variables
Definition: cdr.c:804
struct ast_channel_snapshot * snapshot
Definition: cdr.c:801
unsigned int flags
Definition: cdr.c:803
struct timeval answer
Definition: cdr.c:815
struct cdr_object_snapshot party_a
Definition: cdr.c:809
struct timeval lastevent
Definition: cdr.c:817
struct cdr_object * last
Definition: cdr.c:833
struct timeval start
Definition: cdr.c:814
struct cdr_object_snapshot party_b
Definition: cdr.c:810
static struct test_options options
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159

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(), cdr_object::bridge, cdr_all_relink(), cdr_object_create_and_append(), cdr_object_finalize(), cdr_object_get_by_name(), cdr_object_transition_state(), voicemailpwcheck::context, copy_variables(), cdr_object::data, cdr_object::exten, finalized_state_fn_table, ast_flags::flags, cdr_object_snapshot::flags, cdr_object::flags, cdr_object::fn_table, free_variables(), cdr_object::last, cdr_object::lastevent, lock, cdr_object::next, options, 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().

◆ 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 extracted, provide epoch seconds. Otherwise format as a date/time stamp

Definition at line 3170 of file cdr.c.

3171{
3172 const char *fmt = "%Y-%m-%d %T";
3173 const char *varbuf;
3174
3175 if (!cdr) {
3176 return;
3177 }
3178
3179 *ret = NULL;
3180
3181 if (!strcasecmp(name, "clid")) {
3182 ast_copy_string(workspace, cdr->clid, workspacelen);
3183 } else if (!strcasecmp(name, "src")) {
3184 ast_copy_string(workspace, cdr->src, workspacelen);
3185 } else if (!strcasecmp(name, "dst")) {
3186 ast_copy_string(workspace, cdr->dst, workspacelen);
3187 } else if (!strcasecmp(name, "dcontext")) {
3188 ast_copy_string(workspace, cdr->dcontext, workspacelen);
3189 } else if (!strcasecmp(name, "channel")) {
3190 ast_copy_string(workspace, cdr->channel, workspacelen);
3191 } else if (!strcasecmp(name, "dstchannel")) {
3192 ast_copy_string(workspace, cdr->dstchannel, workspacelen);
3193 } else if (!strcasecmp(name, "lastapp")) {
3194 ast_copy_string(workspace, cdr->lastapp, workspacelen);
3195 } else if (!strcasecmp(name, "lastdata")) {
3196 ast_copy_string(workspace, cdr->lastdata, workspacelen);
3197 } else if (!strcasecmp(name, "start")) {
3198 cdr_get_tv(cdr->start, raw ? NULL : fmt, workspace, workspacelen);
3199 } else if (!strcasecmp(name, "answer")) {
3200 cdr_get_tv(cdr->answer, raw ? NULL : fmt, workspace, workspacelen);
3201 } else if (!strcasecmp(name, "end")) {
3202 cdr_get_tv(cdr->end, raw ? NULL : fmt, workspace, workspacelen);
3203 } else if (!strcasecmp(name, "duration")) {
3204 snprintf(workspace, workspacelen, "%ld", cdr->end.tv_sec != 0 ? cdr->duration : (long)ast_tvdiff_ms(ast_tvnow(), cdr->start) / 1000);
3205 } else if (!strcasecmp(name, "billsec")) {
3206 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);
3207 } else if (!strcasecmp(name, "disposition")) {
3208 if (raw) {
3209 snprintf(workspace, workspacelen, "%ld", cdr->disposition);
3210 } else {
3211 ast_copy_string(workspace, ast_cdr_disp2str(cdr->disposition), workspacelen);
3212 }
3213 } else if (!strcasecmp(name, "amaflags")) {
3214 if (raw) {
3215 snprintf(workspace, workspacelen, "%ld", cdr->amaflags);
3216 } else {
3217 ast_copy_string(workspace, ast_channel_amaflags2string(cdr->amaflags), workspacelen);
3218 }
3219 } else if (!strcasecmp(name, "accountcode")) {
3220 ast_copy_string(workspace, cdr->accountcode, workspacelen);
3221 } else if (!strcasecmp(name, "peeraccount")) {
3222 ast_copy_string(workspace, cdr->peeraccount, workspacelen);
3223 } else if (!strcasecmp(name, "uniqueid")) {
3224 ast_copy_string(workspace, cdr->uniqueid, workspacelen);
3225 } else if (!strcasecmp(name, "linkedid")) {
3226 ast_copy_string(workspace, cdr->linkedid, workspacelen);
3227 } else if (!strcasecmp(name, "tenantid")) {
3228 ast_copy_string(workspace, cdr->tenantid, workspacelen);
3229 } else if (!strcasecmp(name, "peertenantid")) {
3230 ast_copy_string(workspace, cdr->peertenantid, workspacelen);
3231 } else if (!strcasecmp(name, "userfield")) {
3232 ast_copy_string(workspace, cdr->userfield, workspacelen);
3233 } else if (!strcasecmp(name, "sequence")) {
3234 snprintf(workspace, workspacelen, "%d", cdr->sequence);
3235 } else if ((varbuf = cdr_format_var_internal(cdr, name))) {
3236 ast_copy_string(workspace, varbuf, workspacelen);
3237 } else {
3238 workspace[0] = '\0';
3239 }
3240
3241 if (!ast_strlen_zero(workspace)) {
3242 *ret = workspace;
3243 }
3244}
static void cdr_get_tv(struct timeval when, const char *fmt, char *buf, int bufsize)
Definition: cdr.c:3155
static const char * cdr_format_var_internal(struct ast_cdr *cdr, const char *name)
Definition: cdr.c:3138
const char * ast_cdr_disp2str(int disposition)
Disposition to a string.
Definition: cdr.c:3563
const char * ast_channel_amaflags2string(enum ama_flags flags)
Convert the enum representation of an AMA flag to a string representation.
Definition: channel.c:4390
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
char dstchannel[AST_MAX_EXTENSION]
Definition: cdr.h:291
long int disposition
Definition: cdr.h:307
char lastdata[AST_MAX_EXTENSION]
Definition: cdr.h:295
char linkedid[AST_MAX_UNIQUEID]
Definition: cdr.h:319
char userfield[AST_MAX_USER_FIELD]
Definition: cdr.h:325
char peertenantid[AST_MAX_TENANT_ID]
Definition: cdr.h:323
long int billsec
Definition: cdr.h:305
struct timeval answer
Definition: cdr.h:299
char channel[AST_MAX_EXTENSION]
Definition: cdr.h:289
char peeraccount[AST_MAX_ACCOUNT_CODE]
Definition: cdr.h:313
long int duration
Definition: cdr.h:303
long int amaflags
Definition: cdr.h:309
char src[AST_MAX_EXTENSION]
Definition: cdr.h:283
char dst[AST_MAX_EXTENSION]
Definition: cdr.h:285
char clid[AST_MAX_EXTENSION]
Definition: cdr.h:281
char uniqueid[AST_MAX_UNIQUEID]
Definition: cdr.h:317
char tenantid[AST_MAX_TENANT_ID]
Definition: cdr.h:321
int sequence
Definition: cdr.h:327
struct timeval start
Definition: cdr.h:297
char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: cdr.h:311
char lastapp[AST_MAX_EXTENSION]
Definition: cdr.h:293
char dcontext[AST_MAX_EXTENSION]
Definition: cdr.h:287
struct timeval end
Definition: cdr.h:301
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:117
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:107

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, name, NULL, ast_cdr::peeraccount, ast_cdr::peertenantid, ast_cdr::sequence, ast_cdr::src, ast_cdr::start, ast_cdr::tenantid, ast_cdr::uniqueid, and ast_cdr::userfield.

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

◆ ast_cdr_free()

void ast_cdr_free ( struct ast_cdr cdr)

Free a CDR record.

Parameters
cdrast_cdr structure to free

Definition at line 3544 of file cdr.c.

3545{
3546 while (cdr) {
3547 struct ast_cdr *next = cdr->next;
3548
3549 free_variables(&cdr->varshead);
3550 ast_free(cdr);
3551 cdr = next;
3552 }
3553}
#define ast_free(a)
Definition: astmm.h:180

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

◆ 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
Returns
The current CDR configuration

Definition at line 2946 of file cdr.c.

2947{
2948 struct ast_cdr_config *general;
2949 struct module_config *mod_cfg;
2950
2951 mod_cfg = ao2_global_obj_ref(module_configs);
2952 if (!mod_cfg) {
2953 return NULL;
2954 }
2955 general = ao2_bump(mod_cfg->general);
2956 ao2_cleanup(mod_cfg);
2957 return general;
2958}
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
The global options available for CDRs.
Definition: cdr.h:267
struct ast_cdr_config * general
Definition: cdr.c:319

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

Referenced by test_cdr_init_cb().

◆ 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 3457 of file cdr.c.

3458{
3459 struct cdr_object *cdr;
3460 struct cdr_object *cdr_obj;
3461
3462 if (ast_strlen_zero(name)) {
3463 return 1;
3464 }
3465
3466 cdr = cdr_object_get_by_name(channel_name);
3467 if (!cdr) {
3468 ast_log(AST_LOG_ERROR, "Unable to find CDR for channel %s\n", channel_name);
3469 return 1;
3470 }
3471
3472 ao2_lock(cdr);
3473
3474 cdr_obj = cdr->last;
3475 if (cdr_object_format_property(cdr_obj, name, value, length)) {
3476 /* Property failed; attempt variable */
3477 cdr_object_format_var_internal(cdr_obj, name, value, length);
3478 }
3479
3480 ao2_unlock(cdr);
3481
3482 ao2_cleanup(cdr);
3483 return 0;
3484}
#define ast_log
Definition: astobj2.c:42
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:3368
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:3351
#define AST_LOG_ERROR
int value
Definition: syslog.c:37

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(), cdr_object::last, name, and value.

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

◆ ast_cdr_is_enabled()

int ast_cdr_is_enabled ( void  )

Return TRUE if CDR subsystem is enabled.

Definition at line 2981 of file cdr.c.

2982{
2984}
static int is_cdr_flag_set(unsigned int cdr_flag)
Definition: cdr.c:1222

References CDR_ENABLED, and is_cdr_flag_set().

Referenced by action_coresettings(), and handle_show_settings().

◆ 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
Returns
the stasis_message_router otherwise

Definition at line 4427 of file cdr.c.

4428{
4429 if (!stasis_router) {
4430 return NULL;
4431 }
4432
4434 return stasis_router;
4435}

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

◆ 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 3068 of file cdr.c.

3069{
3070 return cdr_generic_register((struct be_list *)&mo_list, name, desc, be);
3071}
static int cdr_generic_register(struct be_list *generic_list, const char *name, const char *desc, ast_cdrbe be)
Definition: cdr.c:3022
static const char desc[]
Definition: cdr_radius.c:84
char * be
Definition: eagi_proxy.c:73
List of registered modifiers.
Definition: cdr.c:429

References be, cdr_generic_register(), desc, and name.

◆ 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 3113 of file cdr.c.

3114{
3115 return ast_cdr_generic_unregister((struct be_list *)&mo_list, name);
3116}
static int ast_cdr_generic_unregister(struct be_list *generic_list, const char *name)
Definition: cdr.c:3073

References ast_cdr_generic_unregister(), and name.

◆ 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 3063 of file cdr.c.

3064{
3066}

References be, cdr_generic_register(), desc, and name.

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

◆ 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 3731 of file cdr.c.

3732{
3733 struct cdr_object *cdr;
3734 struct ast_var_t *vardata;
3735 struct cdr_object *it_cdr;
3736
3737 cdr = cdr_object_get_by_name(channel_name);
3738 if (!cdr) {
3739 return -1;
3740 }
3741
3742 ao2_lock(cdr);
3743 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3744 /* clear variables */
3745 if (!keep_variables) {
3746 while ((vardata = AST_LIST_REMOVE_HEAD(&it_cdr->party_a.variables, entries))) {
3747 ast_var_delete(vardata);
3748 }
3749 if (cdr->party_b.snapshot) {
3750 while ((vardata = AST_LIST_REMOVE_HEAD(&it_cdr->party_b.variables, entries))) {
3751 ast_var_delete(vardata);
3752 }
3753 }
3754 }
3755
3756 /* Reset to initial state */
3757 memset(&it_cdr->start, 0, sizeof(it_cdr->start));
3758 memset(&it_cdr->end, 0, sizeof(it_cdr->end));
3759 memset(&it_cdr->answer, 0, sizeof(it_cdr->answer));
3760 it_cdr->start = ast_tvnow();
3761 it_cdr->lastevent = it_cdr->start;
3763 }
3764 ao2_unlock(cdr);
3765
3766 ao2_cleanup(cdr);
3767 return 0;
3768}
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:1591
void ast_var_delete(struct ast_var_t *var)
Definition: extconf.c:2471
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833
struct timeval end
Definition: cdr.c:816

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

◆ 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
Returns
the total number of serialized variables

Definition at line 3486 of file cdr.c.

3487{
3488 struct cdr_object *cdr;
3489 struct cdr_object *it_cdr;
3490 struct ast_var_t *variable;
3491 const char *var;
3492 char workspace[256];
3493 int total = 0, x = 0, i;
3494
3495 cdr = cdr_object_get_by_name(channel_name);
3496 if (!cdr) {
3498 ast_log(AST_LOG_ERROR, "Unable to find CDR for channel %s\n", channel_name);
3499 }
3500 return 0;
3501 }
3502
3504
3505 ao2_lock(cdr);
3506 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3507 if (++x > 1) {
3508 ast_str_append(buf, 0, "\n");
3509 }
3510
3511 AST_LIST_TRAVERSE(&it_cdr->party_a.variables, variable, entries) {
3512 if (!(var = ast_var_name(variable))) {
3513 continue;
3514 }
3515
3516 if (ast_str_append(buf, 0, "level %d: %s%c%s%c", x, var, delim, S_OR(ast_var_value(variable), ""), sep) < 0) {
3517 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
3518 break;
3519 }
3520
3521 total++;
3522 }
3523
3524 for (i = 0; cdr_readonly_vars[i]; i++) {
3525 if (cdr_object_format_property(it_cdr, cdr_readonly_vars[i], workspace, sizeof(workspace))) {
3526 /* Unhandled read-only CDR variable. */
3527 ast_assert(0);
3528 continue;
3529 }
3530
3531 if (!ast_strlen_zero(workspace)
3532 && ast_str_append(buf, 0, "level %d: %s%c%s%c", x, cdr_readonly_vars[i], delim, workspace, sep) < 0) {
3533 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
3534 break;
3535 }
3536 total++;
3537 }
3538 }
3539 ao2_unlock(cdr);
3540 ao2_cleanup(cdr);
3541 return total;
3542}
#define var
Definition: ast_expr2f.c:605
static const char *const cdr_readonly_vars[]
Definition: cdr.c:3278
const char * ast_var_name(const struct ast_var_t *var)
Definition: chanvars.c:60
const char * ast_var_value(const struct ast_var_t *var)
Definition: chanvars.c:80
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_ERROR
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
static int total
Definition: res_adsi.c:970
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1139
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:693
struct ast_var_t::@213 entries
#define ast_assert(a)
Definition: utils.h:739

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(), buf, CDR_ENABLED, cdr_object_format_property(), cdr_object_get_by_name(), cdr_readonly_vars, 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().

◆ 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 2960 of file cdr.c.

2961{
2962 struct module_config *mod_cfg;
2963
2964 if (!config) {
2965 return;
2966 }
2967
2968 mod_cfg = ao2_global_obj_ref(module_configs);
2969 if (!mod_cfg) {
2970 return;
2971 }
2972
2973 ao2_replace(mod_cfg->general, config);
2974
2975 cdr_set_debug_mode(mod_cfg);
2977
2978 ao2_cleanup(mod_cfg);
2979}
#define ao2_replace(dst, src)
Replace one object reference with another cleaning up the original.
Definition: astobj2.h:501
#define cdr_set_debug_mode(mod_cfg)
Definition: cdr.c:298
static int cdr_toggle_runtime_options(void)
Checks if CDRs are enabled and enables/disables the necessary options.
Definition: cdr.c:4623
static const char config[]
Definition: chan_ooh323.c:111

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

Referenced by test_cdr_cleanup_cb().

◆ 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 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 3681 of file cdr.c.

3682{
3683 struct cdr_object *cdr;
3684 struct cdr_object *it_cdr;
3685
3686 cdr = cdr_object_get_by_name(channel_name);
3687 if (!cdr) {
3688 return -1;
3689 }
3690
3691 ao2_lock(cdr);
3692 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3693 if (it_cdr->fn_table == &finalized_state_fn_table) {
3694 continue;
3695 }
3696 /* Note: in general, set the flags on both the CDR record as well as the
3697 * Party A. Sometimes all we have is the Party A to look at.
3698 */
3699 ast_set_flag(&it_cdr->flags, option);
3700 ast_set_flag(&it_cdr->party_a, option);
3701 }
3702 ao2_unlock(cdr);
3703
3704 ao2_cleanup(cdr);
3705 return 0;
3706}
#define ast_set_flag(p, flag)
Definition: utils.h:70

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

Referenced by AST_TEST_DEFINE(), and cdr_prop_write_callback().

◆ 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 3610 of file cdr.c.

3611{
3612 struct cdr_object *cdr;
3613 struct party_b_userfield_update party_b_info = {
3615 .userfield = userfield,
3616 };
3617 struct cdr_object *it_cdr;
3618
3619 /* Handle Party A */
3620 cdr = cdr_object_get_by_name(channel_name);
3621 if (cdr) {
3622 ao2_lock(cdr);
3623 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3624 if (it_cdr->fn_table == &finalized_state_fn_table && it_cdr->next != NULL) {
3625 continue;
3626 }
3627 ast_copy_string(it_cdr->party_a.userfield, userfield,
3628 sizeof(it_cdr->party_a.userfield));
3629 }
3630 ao2_unlock(cdr);
3631 }
3632
3633 /* Handle Party B */
3636 &party_b_info);
3637
3638 ao2_cleanup(cdr);
3639}
#define ao2_callback_data(container, flags, cb_fn, arg, data)
Definition: astobj2.h:1723
@ OBJ_NODATA
Definition: astobj2.h:1044
@ OBJ_MULTIPLE
Definition: astobj2.h:1049
@ OBJ_SEARCH_KEY
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1101
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:3588
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:464
const char * userfield
Definition: cdr.c:3584
const char * channel_name
Definition: cdr.c:3583

References active_cdrs_all, 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, finalized_state_fn_table, 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(), and cdr_write_callback().

◆ 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 3303 of file cdr.c.

3304{
3305 struct cdr_object *cdr;
3306 struct cdr_object *it_cdr;
3307 struct ao2_iterator *it_cdrs;
3308 char *arg = ast_strdupa(channel_name);
3309 int x;
3310
3311 for (x = 0; cdr_readonly_vars[x]; x++) {
3312 if (!strcasecmp(name, cdr_readonly_vars[x])) {
3313 ast_log(LOG_ERROR, "Attempt to set the '%s' read-only variable!\n", name);
3314 return -1;
3315 }
3316 }
3317
3319 if (!it_cdrs) {
3320 ast_log(AST_LOG_ERROR, "Unable to find CDR for channel %s\n", channel_name);
3321 return -1;
3322 }
3323
3324 for (; (cdr = ao2_iterator_next(it_cdrs)); ao2_unlock(cdr), ao2_cleanup(cdr)) {
3325 ao2_lock(cdr);
3326 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3327 struct varshead *headp = NULL;
3328
3329 if (it_cdr->fn_table == &finalized_state_fn_table && it_cdr->next != NULL) {
3330 continue;
3331 }
3332 if (!strcasecmp(channel_name, it_cdr->party_a.snapshot->base->name)) {
3333 headp = &it_cdr->party_a.variables;
3334 } else if (it_cdr->party_b.snapshot
3335 && !strcasecmp(channel_name, it_cdr->party_b.snapshot->base->name)) {
3336 headp = &it_cdr->party_b.variables;
3337 }
3338 if (headp) {
3339 set_variable(headp, name, value);
3340 }
3341 }
3342 }
3343 ao2_iterator_destroy(it_cdrs);
3344
3345 return 0;
3346}
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
Definition: astobj2.h:1693
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
static int cdr_object_select_all_by_name_cb(void *obj, void *arg, int flags)
Definition: cdr.c:3250
static void set_variable(struct varshead *headp, const char *name, const char *value)
Definition: cdr.c:1357
static struct ao2_container * active_cdrs_master
A container of the active master CDRs indexed by Party A channel uniqueid.
Definition: cdr.c:461
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
const ast_string_field name
struct ast_channel_snapshot_base * base

References active_cdrs_master, 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_readonly_vars, finalized_state_fn_table, cdr_object::fn_table, LOG_ERROR, name, 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, value, and cdr_object_snapshot::variables.

Referenced by AST_TEST_DEFINE(), and cdr_write_callback().

◆ 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 3108 of file cdr.c.

3109{
3111}

References ast_cdr_generic_unregister(), and name.

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