Asterisk - The Open Source Telephony Project  18.5.0
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 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 458 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 230 of file cdr.h.

230  {
231  BATCH_MODE_SCHEDULER_ONLY = 1 << 0, /*!< Don't spawn a thread to handle the batches - do it on the scheduler */
232  BATCH_MODE_SAFE_SHUTDOWN = 1 << 1, /*!< During safe shutdown, submit the batched CDRs */
233 };

◆ 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 253 of file cdr.h.

253  {
254  AST_CDR_NOANSWER = 0,
255  AST_CDR_NULL = (1 << 0),
256  AST_CDR_FAILED = (1 << 1),
257  AST_CDR_BUSY = (1 << 2),
258  AST_CDR_ANSWERED = (1 << 3),
259  AST_CDR_CONGESTION = (1 << 4),
260 };

◆ 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 239 of file cdr.h.

239  {
240  AST_CDR_FLAG_KEEP_VARS = (1 << 0), /*!< Copy variables during the operation */
241  AST_CDR_FLAG_DISABLE = (1 << 1), /*!< Disable the current CDR */
242  AST_CDR_FLAG_DISABLE_ALL = (3 << 1), /*!< Disable the CDR and all future CDRs */
243  AST_CDR_FLAG_PARTY_A = (1 << 3), /*!< Set the channel as party A */
244  AST_CDR_FLAG_FINALIZE = (1 << 4), /*!< Finalize the current CDRs */
245  AST_CDR_FLAG_SET_ANSWER = (1 << 5), /*!< If the channel is answered, set the answer time to now */
246  AST_CDR_FLAG_RESET = (1 << 6), /*!< If set, set the start and answer time to now */
247  AST_CDR_LOCK_APP = (1 << 7), /*!< Prevent any further changes to the application field/data field for this CDR */
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

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 };
Definition: cdr.h:226

Function Documentation

◆ 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:452
#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:452
#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:452
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
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:452
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:911
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:4418
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
#define ast_strlen_zero(foo)
Definition: strings.h:52
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
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_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_strlen_zero(foo)
Definition: strings.h:52
#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
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:695
#define ao2_unlock(a)
Definition: astobj2.h:730
struct cdr_object_snapshot party_a
Definition: cdr.c:713
#define ast_strlen_zero(foo)
Definition: strings.h:52
#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 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
struct ast_var_t::@249 entries
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