Asterisk - The Open Source Telephony Project  21.4.1
Data Structures | Typedefs | Enumerations | Functions
cdr.h File Reference

Call Detail Record API. More...

#include "asterisk/channel.h"

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

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

Enumeration Type Documentation

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 };

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 };

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

Function Documentation

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

References ast_calloc.

Referenced by ast_cdr_dup().

3485 {
3486  struct ast_cdr *x;
3487 
3488  x = ast_calloc(1, sizeof(*x));
3489  return x;
3490 }
Responsible for call detail data.
Definition: cdr.h:279
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
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 2928 of file cdr.c.

References ast_debug, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.

2929 {
2930  int success = -1;
2931  struct cdr_beitem *i = NULL;
2932 
2934  AST_RWLIST_TRAVERSE(&be_list, i, list) {
2935  if (!strcasecmp(name, i->name)) {
2936  ast_debug(3, "Suspending CDR backend %s\n", i->name);
2937  i->suspended = 1;
2938  success = 0;
2939  }
2940  }
2942 
2943  return success;
2944 }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:52
Registration object for CDR backends.
Definition: cdr.c:363
#define ast_debug(level,...)
Log a DEBUG message.
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
List of registered backends.
Definition: cdr.c:372
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 2946 of file cdr.c.

References ast_debug, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.

2947 {
2948  int success = -1;
2949  struct cdr_beitem *i = NULL;
2950 
2952  AST_RWLIST_TRAVERSE(&be_list, i, list) {
2953  if (!strcasecmp(name, i->name)) {
2954  ast_debug(3, "Unsuspending CDR backend %s\n", i->name);
2955  i->suspended = 0;
2956  success = 0;
2957  }
2958  }
2960 
2961  return success;
2962 }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:52
Registration object for CDR backends.
Definition: cdr.c:363
#define ast_debug(level,...)
Log a DEBUG message.
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
List of registered backends.
Definition: cdr.c:372
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 3637 of file cdr.c.

References cdr_object::flags, cdr_object::fn_table, and cdr_object::next.

3638 {
3639  struct cdr_object *cdr;
3640  struct cdr_object *it_cdr;
3641 
3642  cdr = cdr_object_get_by_name(channel_name);
3643  if (!cdr) {
3644  return -1;
3645  }
3646 
3647  ao2_lock(cdr);
3648  for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3649  if (it_cdr->fn_table == &finalized_state_fn_table) {
3650  continue;
3651  }
3652  ast_clear_flag(&it_cdr->flags, option);
3653  }
3654  ao2_unlock(cdr);
3655 
3656  ao2_cleanup(cdr);
3657  return 0;
3658 }
struct cdr_object * next
Definition: cdr.c:777
struct ast_flags flags
Definition: cdr.c:765
struct cdr_object_fn_table * fn_table
Definition: cdr.c:757
An in-memory representation of an active CDR.
Definition: cdr.c:754
struct cdr_object_fn_table finalized_state_fn_table
The virtual table for the finalized state.
Definition: cdr.c:736
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 3492 of file cdr.c.

Referenced by ast_cdr_format_var(), and cdr_object_finalize().

3493 {
3494  switch (disposition) {
3495  case AST_CDR_NULL:
3496  return "NO ANSWER"; /* by default, for backward compatibility */
3497  case AST_CDR_NOANSWER:
3498  return "NO ANSWER";
3499  case AST_CDR_FAILED:
3500  return "FAILED";
3501  case AST_CDR_BUSY:
3502  return "BUSY";
3503  case AST_CDR_ANSWERED:
3504  return "ANSWERED";
3505  case AST_CDR_CONGESTION:
3506  return "CONGESTION";
3507  }
3508  return "UNKNOWN";
3509 }
enum ast_cdr_disposition disposition
Definition: cdr.c:759
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 3060 of file cdr.c.

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

3061 {
3062  struct ast_cdr *newcdr;
3063 
3064  if (!cdr) {
3065  return NULL;
3066  }
3067  newcdr = ast_cdr_alloc();
3068  if (!newcdr) {
3069  return NULL;
3070  }
3071 
3072  *newcdr = *cdr;
3074  copy_variables(&newcdr->varshead, &cdr->varshead);
3075  newcdr->next = NULL;
3076 
3077  return newcdr;
3078 }
struct ast_cdr * ast_cdr_alloc(void)
Allocate a CDR record.
Definition: cdr.c:3484
static int copy_variables(struct varshead *to_list, struct varshead *from_list)
Copy variables from one list to another.
Definition: cdr.c:788
struct varshead varshead
Definition: cdr.h:326
Responsible for call detail data.
Definition: cdr.h:279
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:681
void ast_cdr_engine_term ( void  )

Submit any remaining CDRs and prepare for shutdown

Definition at line 4665 of file cdr.c.

References ao2_global_obj_ref, ast_debug, BATCH_MODE_SAFE_SHUTDOWN, CDR_BATCHMODE, module_config::general, RAII_VAR, ast_cdr_config::batch_settings::settings, ast_cdr_config::settings, stasis_message_create(), and stasis_message_router_publish_sync().

4666 {
4667  RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
4668 
4669  /* Since this is called explicitly during process shutdown, we might not have ever
4670  * been initialized. If so, the config object will be NULL.
4671  */
4672  if (!mod_cfg) {
4673  return;
4674  }
4675 
4676  if (cdr_sync_message_type()) {
4677  void *payload;
4678  struct stasis_message *message;
4679 
4680  if (!stasis_router) {
4681  return;
4682  }
4683 
4684  /* Make sure we have the needed items */
4685  payload = ao2_alloc(sizeof(*payload), NULL);
4686  if (!payload) {
4687  return;
4688  }
4689 
4690  ast_debug(1, "CDR Engine termination request received; waiting on messages...\n");
4691 
4692  message = stasis_message_create(cdr_sync_message_type(), payload);
4693  if (message) {
4695  }
4696  ao2_cleanup(message);
4697  ao2_cleanup(payload);
4698  }
4699 
4700  if (ast_test_flag(&mod_cfg->general->settings, CDR_BATCHMODE)) {
4701  cdr_submit_batch(ast_test_flag(&mod_cfg->general->batch_settings.settings, BATCH_MODE_SAFE_SHUTDOWN));
4702  }
4703 }
static struct stasis_message_router * stasis_router
Message router for stasis messages regarding channel state.
Definition: cdr.c:413
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
The configuration settings for this module.
Definition: cdr.c:264
#define ast_debug(level,...)
Log a DEBUG message.
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.
#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
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 3699 of file cdr.c.

References cdr_object::answer, ao2_ref, AST_CDR_FLAG_FINALIZE, AST_CDR_FLAG_KEEP_VARS, AST_CDR_FLAG_RESET, AST_CDR_FLAG_SET_ANSWER, AST_CDR_LOCK_APP, ast_debug, AST_STATE_UP, ast_string_field_set, ast_tvnow(), cdr_object_create_and_append(), cdr_object_finalize(), cdr_object_transition_state(), copy_variables(), ast_cdr::flags, cdr_object_snapshot::flags, cdr_object::flags, cdr_object::fn_table, free_variables(), cdr_object::lastevent, lock, 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.

3700 {
3701  RAII_VAR(struct cdr_object *, cdr, cdr_object_get_by_name(channel_name), ao2_cleanup);
3702  struct cdr_object *new_cdr;
3703  struct cdr_object *it_cdr;
3704  struct cdr_object *cdr_obj;
3705 
3706  if (!cdr) {
3707  return -1;
3708  }
3709 
3710  {
3711  SCOPED_AO2LOCK(lock, cdr);
3712  struct timeval now = ast_tvnow();
3713 
3714  cdr_obj = cdr->last;
3715  if (cdr_obj->fn_table == &finalized_state_fn_table) {
3716  /* If the last CDR in the chain is finalized, don't allow a fork -
3717  * things are already dying at this point
3718  */
3719  return -1;
3720  }
3721 
3722  /* Copy over the basic CDR information. The Party A information is
3723  * copied over automatically as part of the append
3724  */
3725  ast_debug(1, "Forking CDR for channel %s\n", cdr->party_a.snapshot->base->name);
3726  new_cdr = cdr_object_create_and_append(cdr, &now);
3727  if (!new_cdr) {
3728  return -1;
3729  }
3730  new_cdr->fn_table = cdr_obj->fn_table;
3731  ast_string_field_set(new_cdr, bridge, cdr->bridge);
3732  ast_string_field_set(new_cdr, appl, cdr->appl);
3733  ast_string_field_set(new_cdr, data, cdr->data);
3734  ast_string_field_set(new_cdr, context, cdr->context);
3735  ast_string_field_set(new_cdr, exten, cdr->exten);
3736  new_cdr->flags = cdr->flags;
3737  /* Explicitly clear the AST_CDR_LOCK_APP flag - we want
3738  * the application to be changed on the new CDR if the
3739  * dialplan demands it
3740  */
3741  ast_clear_flag(&new_cdr->flags, AST_CDR_LOCK_APP);
3742 
3743  /* If there's a Party B, copy it over as well */
3744  if (cdr_obj->party_b.snapshot) {
3745  new_cdr->party_b.snapshot = cdr_obj->party_b.snapshot;
3746  ao2_ref(new_cdr->party_b.snapshot, +1);
3747  cdr_all_relink(new_cdr);
3748  strcpy(new_cdr->party_b.userfield, cdr_obj->party_b.userfield);
3749  new_cdr->party_b.flags = cdr_obj->party_b.flags;
3750  if (ast_test_flag(options, AST_CDR_FLAG_KEEP_VARS)) {
3751  copy_variables(&new_cdr->party_b.variables, &cdr_obj->party_b.variables);
3752  }
3753  }
3754  new_cdr->start = cdr_obj->start;
3755  new_cdr->answer = cdr_obj->answer;
3756  new_cdr->lastevent = ast_tvnow();
3757 
3758  /* Modify the times based on the flags passed in */
3759  if (ast_test_flag(options, AST_CDR_FLAG_SET_ANSWER)
3760  && new_cdr->party_a.snapshot->state == AST_STATE_UP) {
3761  new_cdr->answer = ast_tvnow();
3762  }
3763  if (ast_test_flag(options, AST_CDR_FLAG_RESET)) {
3764  new_cdr->answer = ast_tvnow();
3765  new_cdr->start = ast_tvnow();
3766  }
3767 
3768  /* Create and append, by default, copies over the variables */
3769  if (!ast_test_flag(options, AST_CDR_FLAG_KEEP_VARS)) {
3770  free_variables(&new_cdr->party_a.variables);
3771  }
3772 
3773  /* Finalize any current CDRs */
3774  if (ast_test_flag(options, AST_CDR_FLAG_FINALIZE)) {
3775  for (it_cdr = cdr; it_cdr != new_cdr; it_cdr = it_cdr->next) {
3776  if (it_cdr->fn_table == &finalized_state_fn_table) {
3777  continue;
3778  }
3779  /* Force finalization on the CDR. This will bypass any checks for
3780  * end before 'h' extension.
3781  */
3782  cdr_object_finalize(it_cdr);
3784  }
3785  }
3786  }
3787 
3788  return 0;
3789 }
struct varshead variables
Definition: cdr.c:750
struct ast_channel_snapshot * snapshot
Definition: cdr.c:747
struct cdr_object * next
Definition: cdr.c:777
struct cdr_object_snapshot party_b
Definition: cdr.c:756
const ast_string_field exten
Definition: cdr.c:776
struct timeval answer
Definition: cdr.c:761
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
struct timeval start
Definition: cdr.c:760
unsigned int flags
Definition: cdr.c:749
static int copy_variables(struct varshead *to_list, struct varshead *from_list)
Copy variables from one list to another.
Definition: cdr.c:788
struct cdr_object_snapshot party_a
Definition: cdr.c:755
const ast_string_field appl
Definition: cdr.c:776
const ast_string_field context
Definition: cdr.c:776
char userfield[AST_MAX_USER_FIELD]
Definition: cdr.c:748
struct ast_flags flags
Definition: cdr.c:765
ast_mutex_t lock
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define ast_debug(level,...)
Log a DEBUG message.
static void free_variables(struct varshead *headp)
Delete all variables from a variable list.
Definition: cdr.c:819
struct cdr_object_fn_table * fn_table
Definition: cdr.c:757
An in-memory representation of an active CDR.
Definition: cdr.c:754
struct cdr_object * last
Definition: cdr.c:778
const ast_string_field data
Definition: cdr.c:776
struct timeval lastevent
Definition: cdr.c:763
#define SCOPED_AO2LOCK(varname, obj)
scoped lock specialization for ao2 mutexes.
Definition: lock.h:604
enum ast_channel_state state
struct cdr_object_fn_table finalized_state_fn_table
The virtual table for the finalized state.
Definition: cdr.c:736
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:1116
static void cdr_object_finalize(struct cdr_object *cdr)
Finalize a CDR.
Definition: cdr.c:1479
#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
const ast_string_field bridge
Definition: cdr.c:776
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:864
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
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 3112 of file cdr.c.

References ast_cdr::accountcode, ast_cdr::amaflags, ast_cdr_disp2str(), ast_channel_amaflags2string(), ast_copy_string(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), ast_cdr::billsec, ast_cdr::clid, ast_cdr::dcontext, ast_cdr::disposition, ast_cdr::dst, ast_cdr::dstchannel, ast_cdr::duration, ast_cdr::lastapp, ast_cdr::lastdata, ast_cdr::linkedid, ast_cdr::peeraccount, ast_cdr::sequence, ast_cdr::src, ast_cdr::uniqueid, and ast_cdr::userfield.

3113 {
3114  const char *fmt = "%Y-%m-%d %T";
3115  const char *varbuf;
3116 
3117  if (!cdr) {
3118  return;
3119  }
3120 
3121  *ret = NULL;
3122 
3123  if (!strcasecmp(name, "clid")) {
3124  ast_copy_string(workspace, cdr->clid, workspacelen);
3125  } else if (!strcasecmp(name, "src")) {
3126  ast_copy_string(workspace, cdr->src, workspacelen);
3127  } else if (!strcasecmp(name, "dst")) {
3128  ast_copy_string(workspace, cdr->dst, workspacelen);
3129  } else if (!strcasecmp(name, "dcontext")) {
3130  ast_copy_string(workspace, cdr->dcontext, workspacelen);
3131  } else if (!strcasecmp(name, "channel")) {
3132  ast_copy_string(workspace, cdr->channel, workspacelen);
3133  } else if (!strcasecmp(name, "dstchannel")) {
3134  ast_copy_string(workspace, cdr->dstchannel, workspacelen);
3135  } else if (!strcasecmp(name, "lastapp")) {
3136  ast_copy_string(workspace, cdr->lastapp, workspacelen);
3137  } else if (!strcasecmp(name, "lastdata")) {
3138  ast_copy_string(workspace, cdr->lastdata, workspacelen);
3139  } else if (!strcasecmp(name, "start")) {
3140  cdr_get_tv(cdr->start, raw ? NULL : fmt, workspace, workspacelen);
3141  } else if (!strcasecmp(name, "answer")) {
3142  cdr_get_tv(cdr->answer, raw ? NULL : fmt, workspace, workspacelen);
3143  } else if (!strcasecmp(name, "end")) {
3144  cdr_get_tv(cdr->end, raw ? NULL : fmt, workspace, workspacelen);
3145  } else if (!strcasecmp(name, "duration")) {
3146  snprintf(workspace, workspacelen, "%ld", cdr->end.tv_sec != 0 ? cdr->duration : (long)ast_tvdiff_ms(ast_tvnow(), cdr->start) / 1000);
3147  } else if (!strcasecmp(name, "billsec")) {
3148  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);
3149  } else if (!strcasecmp(name, "disposition")) {
3150  if (raw) {
3151  snprintf(workspace, workspacelen, "%ld", cdr->disposition);
3152  } else {
3153  ast_copy_string(workspace, ast_cdr_disp2str(cdr->disposition), workspacelen);
3154  }
3155  } else if (!strcasecmp(name, "amaflags")) {
3156  if (raw) {
3157  snprintf(workspace, workspacelen, "%ld", cdr->amaflags);
3158  } else {
3159  ast_copy_string(workspace, ast_channel_amaflags2string(cdr->amaflags), workspacelen);
3160  }
3161  } else if (!strcasecmp(name, "accountcode")) {
3162  ast_copy_string(workspace, cdr->accountcode, workspacelen);
3163  } else if (!strcasecmp(name, "peeraccount")) {
3164  ast_copy_string(workspace, cdr->peeraccount, workspacelen);
3165  } else if (!strcasecmp(name, "uniqueid")) {
3166  ast_copy_string(workspace, cdr->uniqueid, workspacelen);
3167  } else if (!strcasecmp(name, "linkedid")) {
3168  ast_copy_string(workspace, cdr->linkedid, workspacelen);
3169  } else if (!strcasecmp(name, "userfield")) {
3170  ast_copy_string(workspace, cdr->userfield, workspacelen);
3171  } else if (!strcasecmp(name, "sequence")) {
3172  snprintf(workspace, workspacelen, "%d", cdr->sequence);
3173  } else if ((varbuf = cdr_format_var_internal(cdr, name))) {
3174  ast_copy_string(workspace, varbuf, workspacelen);
3175  } else {
3176  workspace[0] = '\0';
3177  }
3178 
3179  if (!ast_strlen_zero(workspace)) {
3180  *ret = workspace;
3181  }
3182 }
char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: cdr.h:311
char dstchannel[AST_MAX_EXTENSION]
Definition: cdr.h:291
long int billsec
Definition: cdr.h:305
char dcontext[AST_MAX_EXTENSION]
Definition: cdr.h:287
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:117
int sequence
Definition: cdr.h:323
const char * ast_channel_amaflags2string(enum ama_flags flags)
Convert the enum representation of an AMA flag to a string representation.
Definition: channel.c:4373
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
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
char lastdata[AST_MAX_EXTENSION]
Definition: cdr.h:295
long int amaflags
Definition: cdr.h:309
char linkedid[AST_MAX_UNIQUEID]
Definition: cdr.h:319
char uniqueid[AST_MAX_UNIQUEID]
Definition: cdr.h:317
char dst[AST_MAX_EXTENSION]
Definition: cdr.h:285
char lastapp[AST_MAX_EXTENSION]
Definition: cdr.h:293
long int duration
Definition: cdr.h:303
char src[AST_MAX_EXTENSION]
Definition: cdr.h:283
char peeraccount[AST_MAX_ACCOUNT_CODE]
Definition: cdr.h:313
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
long int disposition
Definition: cdr.h:307
char clid[AST_MAX_EXTENSION]
Definition: cdr.h:281
char userfield[AST_MAX_USER_FIELD]
Definition: cdr.h:321
const char * ast_cdr_disp2str(int disposition)
Disposition to a string.
Definition: cdr.c:3492
void ast_cdr_free ( struct ast_cdr cdr)

Free a CDR record.

Parameters
cdrast_cdr structure to free

Definition at line 3473 of file cdr.c.

References free_variables(), and ast_cdr::varshead.

Referenced by ast_channel_destructor(), and ast_dummy_channel_destructor().

3474 {
3475  while (cdr) {
3476  struct ast_cdr *next = cdr->next;
3477 
3478  free_variables(&cdr->varshead);
3479  ast_free(cdr);
3480  cdr = next;
3481  }
3482 }
struct varshead varshead
Definition: cdr.h:326
static void free_variables(struct varshead *headp)
Delete all variables from a variable list.
Definition: cdr.c:819
Responsible for call detail data.
Definition: cdr.h:279
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 2888 of file cdr.c.

References ao2_bump, ao2_global_obj_ref, and module_config::general.

2889 {
2890  struct ast_cdr_config *general;
2891  struct module_config *mod_cfg;
2892 
2893  mod_cfg = ao2_global_obj_ref(module_configs);
2894  if (!mod_cfg) {
2895  return NULL;
2896  }
2897  general = ao2_bump(mod_cfg->general);
2898  ao2_cleanup(mod_cfg);
2899  return general;
2900 }
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
The configuration settings for this module.
Definition: cdr.c:264
The global options available for CDRs.
Definition: cdr.h:267
struct ast_cdr_config * general
Definition: cdr.c:265
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 3386 of file cdr.c.

References cdr_object_format_property(), cdr_object_format_var_internal(), and cdr_object::last.

3387 {
3388  struct cdr_object *cdr;
3389  struct cdr_object *cdr_obj;
3390 
3391  if (ast_strlen_zero(name)) {
3392  return 1;
3393  }
3394 
3395  cdr = cdr_object_get_by_name(channel_name);
3396  if (!cdr) {
3397  ast_log(AST_LOG_ERROR, "Unable to find CDR for channel %s\n", channel_name);
3398  return 1;
3399  }
3400 
3401  ao2_lock(cdr);
3402 
3403  cdr_obj = cdr->last;
3404  if (cdr_object_format_property(cdr_obj, name, value, length)) {
3405  /* Property failed; attempt variable */
3406  cdr_object_format_var_internal(cdr_obj, name, value, length);
3407  }
3408 
3409  ao2_unlock(cdr);
3410 
3411  ao2_cleanup(cdr);
3412  return 0;
3413 }
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:3288
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:3305
An in-memory representation of an active CDR.
Definition: cdr.c:754
struct cdr_object * last
Definition: cdr.c:778
const ast_string_field name
Definition: cdr.c:776
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 4356 of file cdr.c.

References ao2_bump, and stasis_router.

4357 {
4358  if (!stasis_router) {
4359  return NULL;
4360  }
4361 
4363  return stasis_router;
4364 }
static struct stasis_message_router * stasis_router
Message router for stasis messages regarding channel state.
Definition: cdr.c:413
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
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 3010 of file cdr.c.

3011 {
3012  return cdr_generic_register((struct be_list *)&mo_list, name, desc, be);
3013 }
List of registered modifiers.
Definition: cdr.c:375
const ast_string_field name
Definition: cdr.c:776
List of registered backends.
Definition: cdr.c:372
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 3055 of file cdr.c.

3056 {
3057  return ast_cdr_generic_unregister((struct be_list *)&mo_list, name);
3058 }
List of registered modifiers.
Definition: cdr.c:375
const ast_string_field name
Definition: cdr.c:776
List of registered backends.
Definition: cdr.c:372
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 3005 of file cdr.c.

3006 {
3007  return cdr_generic_register(&be_list, name, desc, be);
3008 }
const ast_string_field name
Definition: cdr.c:776
List of registered backends.
Definition: cdr.c:372
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 3660 of file cdr.c.

References cdr_object::answer, AST_LIST_REMOVE_HEAD, ast_tvnow(), cdr_object_check_party_a_answer(), 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 dial_exec_full().

3661 {
3662  struct cdr_object *cdr;
3663  struct ast_var_t *vardata;
3664  struct cdr_object *it_cdr;
3665 
3666  cdr = cdr_object_get_by_name(channel_name);
3667  if (!cdr) {
3668  return -1;
3669  }
3670 
3671  ao2_lock(cdr);
3672  for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3673  /* clear variables */
3674  if (!keep_variables) {
3675  while ((vardata = AST_LIST_REMOVE_HEAD(&it_cdr->party_a.variables, entries))) {
3676  ast_var_delete(vardata);
3677  }
3678  if (cdr->party_b.snapshot) {
3679  while ((vardata = AST_LIST_REMOVE_HEAD(&it_cdr->party_b.variables, entries))) {
3680  ast_var_delete(vardata);
3681  }
3682  }
3683  }
3684 
3685  /* Reset to initial state */
3686  memset(&it_cdr->start, 0, sizeof(it_cdr->start));
3687  memset(&it_cdr->end, 0, sizeof(it_cdr->end));
3688  memset(&it_cdr->answer, 0, sizeof(it_cdr->answer));
3689  it_cdr->start = ast_tvnow();
3690  it_cdr->lastevent = it_cdr->start;
3692  }
3693  ao2_unlock(cdr);
3694 
3695  ao2_cleanup(cdr);
3696  return 0;
3697 }
struct varshead variables
Definition: cdr.c:750
struct ast_channel_snapshot * snapshot
Definition: cdr.c:747
struct cdr_object * next
Definition: cdr.c:777
struct cdr_object_snapshot party_b
Definition: cdr.c:756
struct timeval answer
Definition: cdr.c:761
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
struct timeval start
Definition: cdr.c:760
struct cdr_object_snapshot party_a
Definition: cdr.c:755
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833
An in-memory representation of an active CDR.
Definition: cdr.c:754
struct timeval lastevent
Definition: cdr.c:763
struct timeval end
Definition: cdr.c:762
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:1533
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 3415 of file cdr.c.

References AST_LIST_TRAVERSE, ast_str_append(), ast_str_reset(), CDR_ENABLED, cdr_object_format_property(), cdr_object::next, cdr_object::party_a, S_OR, and cdr_object_snapshot::variables.

Referenced by handle_showchan().

3416 {
3417  struct cdr_object *cdr;
3418  struct cdr_object *it_cdr;
3419  struct ast_var_t *variable;
3420  const char *var;
3421  char workspace[256];
3422  int total = 0, x = 0, i;
3423 
3424  cdr = cdr_object_get_by_name(channel_name);
3425  if (!cdr) {
3426  if (is_cdr_flag_set(CDR_ENABLED)) {
3427  ast_log(AST_LOG_ERROR, "Unable to find CDR for channel %s\n", channel_name);
3428  }
3429  return 0;
3430  }
3431 
3432  ast_str_reset(*buf);
3433 
3434  ao2_lock(cdr);
3435  for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3436  if (++x > 1) {
3437  ast_str_append(buf, 0, "\n");
3438  }
3439 
3440  AST_LIST_TRAVERSE(&it_cdr->party_a.variables, variable, entries) {
3441  if (!(var = ast_var_name(variable))) {
3442  continue;
3443  }
3444 
3445  if (ast_str_append(buf, 0, "level %d: %s%c%s%c", x, var, delim, S_OR(ast_var_value(variable), ""), sep) < 0) {
3446  ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
3447  break;
3448  }
3449 
3450  total++;
3451  }
3452 
3453  for (i = 0; cdr_readonly_vars[i]; i++) {
3454  if (cdr_object_format_property(it_cdr, cdr_readonly_vars[i], workspace, sizeof(workspace))) {
3455  /* Unhandled read-only CDR variable. */
3456  ast_assert(0);
3457  continue;
3458  }
3459 
3460  if (!ast_strlen_zero(workspace)
3461  && ast_str_append(buf, 0, "level %d: %s%c%s%c", x, cdr_readonly_vars[i], delim, workspace, sep) < 0) {
3462  ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
3463  break;
3464  }
3465  total++;
3466  }
3467  }
3468  ao2_unlock(cdr);
3469  ao2_cleanup(cdr);
3470  return total;
3471 }
struct varshead variables
Definition: cdr.c:750
struct cdr_object * next
Definition: cdr.c:777
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
struct cdr_object_snapshot party_a
Definition: cdr.c:755
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:3305
An in-memory representation of an active CDR.
Definition: cdr.c:754
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
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
#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_cdr_set_config ( struct ast_cdr_config config)

Set the current CDR configuration.

Since
12
Parameters
configThe new CDR configuration

Definition at line 2902 of file cdr.c.

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

2903 {
2904  struct module_config *mod_cfg;
2905 
2906  if (!config) {
2907  return;
2908  }
2909 
2910  mod_cfg = ao2_global_obj_ref(module_configs);
2911  if (!mod_cfg) {
2912  return;
2913  }
2914 
2915  ao2_replace(mod_cfg->general, config);
2916 
2917  cdr_set_debug_mode(mod_cfg);
2919 
2920  ao2_cleanup(mod_cfg);
2921 }
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
The configuration settings for this module.
Definition: cdr.c:264
#define ao2_replace(dst, src)
Replace one object reference with another cleaning up the original.
Definition: astobj2.h:501
struct ast_cdr_config * general
Definition: cdr.c:265
static int cdr_toggle_runtime_options(void)
Checks if CDRs are enabled and enables/disables the necessary options.
Definition: cdr.c:4552
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 3610 of file cdr.c.

References cdr_object::flags, cdr_object::fn_table, cdr_object::next, and cdr_object::party_a.

3611 {
3612  struct cdr_object *cdr;
3613  struct cdr_object *it_cdr;
3614 
3615  cdr = cdr_object_get_by_name(channel_name);
3616  if (!cdr) {
3617  return -1;
3618  }
3619 
3620  ao2_lock(cdr);
3621  for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3622  if (it_cdr->fn_table == &finalized_state_fn_table) {
3623  continue;
3624  }
3625  /* Note: in general, set the flags on both the CDR record as well as the
3626  * Party A. Sometimes all we have is the Party A to look at.
3627  */
3628  ast_set_flag(&it_cdr->flags, option);
3629  ast_set_flag(&it_cdr->party_a, option);
3630  }
3631  ao2_unlock(cdr);
3632 
3633  ao2_cleanup(cdr);
3634  return 0;
3635 }
struct cdr_object * next
Definition: cdr.c:777
struct cdr_object_snapshot party_a
Definition: cdr.c:755
struct ast_flags flags
Definition: cdr.c:765
struct cdr_object_fn_table * fn_table
Definition: cdr.c:757
An in-memory representation of an active CDR.
Definition: cdr.c:754
struct cdr_object_fn_table finalized_state_fn_table
The virtual table for the finalized state.
Definition: cdr.c:736
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 3539 of file cdr.c.

References ast_copy_string(), cdr_object_update_party_b_userfield_cb(), cdr_object::fn_table, cdr_object::next, OBJ_MULTIPLE, OBJ_NODATA, OBJ_SEARCH_KEY, cdr_object::party_a, and cdr_object_snapshot::userfield.

3540 {
3541  struct cdr_object *cdr;
3542  struct party_b_userfield_update party_b_info = {
3543  .channel_name = channel_name,
3544  .userfield = userfield,
3545  };
3546  struct cdr_object *it_cdr;
3547 
3548  /* Handle Party A */
3549  cdr = cdr_object_get_by_name(channel_name);
3550  if (cdr) {
3551  ao2_lock(cdr);
3552  for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3553  if (it_cdr->fn_table == &finalized_state_fn_table && it_cdr->next != NULL) {
3554  continue;
3555  }
3556  ast_copy_string(it_cdr->party_a.userfield, userfield,
3557  sizeof(it_cdr->party_a.userfield));
3558  }
3559  ao2_unlock(cdr);
3560  }
3561 
3562  /* Handle Party B */
3563  ao2_callback_data(active_cdrs_all, OBJ_NODATA | OBJ_MULTIPLE | OBJ_SEARCH_KEY,
3564  cdr_object_update_party_b_userfield_cb, (char *) party_b_info.channel_name,
3565  &party_b_info);
3566 
3567  ao2_cleanup(cdr);
3568 }
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:3517
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1101
struct cdr_object * next
Definition: cdr.c:777
struct cdr_object_snapshot party_a
Definition: cdr.c:755
char userfield[AST_MAX_USER_FIELD]
Definition: cdr.c:748
struct cdr_object_fn_table * fn_table
Definition: cdr.c:757
An in-memory representation of an active CDR.
Definition: cdr.c:754
struct cdr_object_fn_table finalized_state_fn_table
The virtual table for the finalized state.
Definition: cdr.c:736
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
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:410
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 3240 of file cdr.c.

References ao2_callback, ao2_iterator_destroy(), ast_strdupa, ast_channel_snapshot::base, cdr_object::fn_table, ast_channel_snapshot_base::name, cdr_object::next, OBJ_MULTIPLE, cdr_object::party_a, cdr_object::party_b, cdr_object_snapshot::snapshot, and cdr_object_snapshot::variables.

3241 {
3242  struct cdr_object *cdr;
3243  struct cdr_object *it_cdr;
3244  struct ao2_iterator *it_cdrs;
3245  char *arg = ast_strdupa(channel_name);
3246  int x;
3247 
3248  for (x = 0; cdr_readonly_vars[x]; x++) {
3249  if (!strcasecmp(name, cdr_readonly_vars[x])) {
3250  ast_log(LOG_ERROR, "Attempt to set the '%s' read-only variable!\n", name);
3251  return -1;
3252  }
3253  }
3254 
3255  it_cdrs = ao2_callback(active_cdrs_master, OBJ_MULTIPLE, cdr_object_select_all_by_name_cb, arg);
3256  if (!it_cdrs) {
3257  ast_log(AST_LOG_ERROR, "Unable to find CDR for channel %s\n", channel_name);
3258  return -1;
3259  }
3260 
3261  for (; (cdr = ao2_iterator_next(it_cdrs)); ao2_unlock(cdr), ao2_cleanup(cdr)) {
3262  ao2_lock(cdr);
3263  for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3264  struct varshead *headp = NULL;
3265 
3266  if (it_cdr->fn_table == &finalized_state_fn_table && it_cdr->next != NULL) {
3267  continue;
3268  }
3269  if (!strcasecmp(channel_name, it_cdr->party_a.snapshot->base->name)) {
3270  headp = &it_cdr->party_a.variables;
3271  } else if (it_cdr->party_b.snapshot
3272  && !strcasecmp(channel_name, it_cdr->party_b.snapshot->base->name)) {
3273  headp = &it_cdr->party_b.variables;
3274  }
3275  if (headp) {
3276  set_variable(headp, name, value);
3277  }
3278  }
3279  }
3280  ao2_iterator_destroy(it_cdrs);
3281 
3282  return 0;
3283 }
struct ast_channel_snapshot_base * base
struct varshead variables
Definition: cdr.c:750
struct ast_channel_snapshot * snapshot
Definition: cdr.c:747
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container, as described below.
Definition: astobj2.h:1693
struct cdr_object * next
Definition: cdr.c:777
struct cdr_object_snapshot party_b
Definition: cdr.c:756
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
struct cdr_object_snapshot party_a
Definition: cdr.c:755
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
struct cdr_object_fn_table * fn_table
Definition: cdr.c:757
An in-memory representation of an active CDR.
Definition: cdr.c:754
static struct ao2_container * active_cdrs_master
A container of the active master CDRs indexed by Party A channel uniqueid.
Definition: cdr.c:407
struct cdr_object_fn_table finalized_state_fn_table
The virtual table for the finalized state.
Definition: cdr.c:736
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
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 3050 of file cdr.c.

3051 {
3052  return ast_cdr_generic_unregister(&be_list, name);
3053 }
List of registered backends.
Definition: cdr.c:372