Wed Jan 8 2020 09:49:59

Asterisk developer's documentation


cdr.c File Reference

Call Detail Record API. More...

#include "asterisk.h"
#include <signal.h>
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/cdr.h"
#include "asterisk/callerid.h"
#include "asterisk/manager.h"
#include "asterisk/causes.h"
#include "asterisk/linkedlists.h"
#include "asterisk/utils.h"
#include "asterisk/sched.h"
#include "asterisk/config.h"
#include "asterisk/cli.h"
#include "asterisk/stringfields.h"
#include "asterisk/data.h"

Go to the source code of this file.

Data Structures

struct  ast_cdr_batch
 
struct  ast_cdr_batch_item
 
struct  ast_cdr_beitem
 
struct  be_list
 

Functions

struct ast_cdrast_cdr_alloc (void)
 Allocate a CDR record. More...
 
int ast_cdr_amaflags2int (const char *flag)
 Convert a string to a detail record AMA flag. More...
 
void ast_cdr_answer (struct ast_cdr *cdr)
 Answer a call. More...
 
struct ast_cdrast_cdr_append (struct ast_cdr *cdr, struct ast_cdr *newcdr)
 
int ast_cdr_appenduserfield (struct ast_channel *chan, const char *userfield)
 Append to CDR user field for channel (stored in CDR) More...
 
void ast_cdr_busy (struct ast_cdr *cdr)
 Busy a call. More...
 
int ast_cdr_copy_vars (struct ast_cdr *to_cdr, struct ast_cdr *from_cdr)
 
int ast_cdr_data_add_structure (struct ast_data *tree, struct ast_cdr *cdr, int recur)
 
void ast_cdr_detach (struct ast_cdr *cdr)
 Detaches the detail record for posting (and freeing) either now or at a later time in bulk with other records during batch mode operation. More...
 
void ast_cdr_discard (struct ast_cdr *cdr)
 the same as a cdr_free call, only with no checks; just get rid of it More...
 
char * ast_cdr_disp2str (int disposition)
 Disposition to a string. More...
 
int ast_cdr_disposition (struct ast_cdr *cdr, int cause)
 Save the result of the call based on the AST_CAUSE_*. More...
 
struct ast_cdrast_cdr_dup (struct ast_cdr *cdr)
 Duplicate a record. More...
 
struct ast_cdrast_cdr_dup_unique (struct ast_cdr *cdr)
 Duplicate a record and increment the sequence number. More...
 
struct ast_cdrast_cdr_dup_unique_swap (struct ast_cdr *cdr)
 Duplicate a record and increment the sequence number of the old record. More...
 
void ast_cdr_end (struct ast_cdr *cdr)
 End a call. More...
 
int ast_cdr_engine_init (void)
 Load the configuration file cdr.conf and possibly start the CDR scheduling thread. More...
 
int ast_cdr_engine_reload (void)
 Reload the configuration file cdr.conf and start/stop CDR scheduling thread. More...
 
void ast_cdr_engine_term (void)
 
void ast_cdr_failed (struct ast_cdr *cdr)
 Fail a call. More...
 
char * ast_cdr_flags2str (int flag)
 
void ast_cdr_free (struct ast_cdr *cdr)
 Free a CDR record. More...
 
void ast_cdr_free_vars (struct ast_cdr *cdr, int recur)
 
void ast_cdr_getvar (struct ast_cdr *cdr, const char *name, char **ret, char *workspace, int workspacelen, int recur, int raw)
 
static const char * ast_cdr_getvar_internal (struct ast_cdr *cdr, const char *name, int recur)
 
int ast_cdr_init (struct ast_cdr *cdr, struct ast_channel *c)
 Initialize based on a channel. More...
 
int ast_cdr_isset_unanswered (void)
 
void ast_cdr_merge (struct ast_cdr *to, struct ast_cdr *from)
 Move the non-null data from the "from" cdr to the "to" cdr. More...
 
void ast_cdr_noanswer (struct ast_cdr *cdr)
 A call wasn't answered. More...
 
int ast_cdr_register (const char *name, const char *desc, ast_cdrbe be)
 Register a CDR driver. Each registered CDR driver generates a CDR. More...
 
void ast_cdr_reset (struct ast_cdr *cdr, struct ast_flags *_flags)
 Reset the detail record, optionally posting it first. More...
 
int ast_cdr_serialize_variables (struct ast_cdr *cdr, struct ast_str **buf, char delim, char sep, int recur)
 
int ast_cdr_setaccount (struct ast_channel *chan, const char *account)
 Set account code, will generate AMI event. More...
 
int ast_cdr_setamaflags (struct ast_channel *chan, const char *flag)
 Set AMA flags for channel. More...
 
void ast_cdr_setanswer (struct ast_cdr *cdr, struct timeval t)
 Set the answer time for a call. More...
 
void ast_cdr_setapp (struct ast_cdr *cdr, const char *app, const char *data)
 Set the last executed application. More...
 
int ast_cdr_setcid (struct ast_cdr *cdr, struct ast_channel *c)
 Initialize based on a channel. More...
 
void ast_cdr_setdestchan (struct ast_cdr *cdr, const char *chann)
 Set the destination channel, if there was one. More...
 
void ast_cdr_setdisposition (struct ast_cdr *cdr, long int disposition)
 Set the disposition for a call. More...
 
int ast_cdr_setpeeraccount (struct ast_channel *chan, const char *account)
 Set the peer account. More...
 
int ast_cdr_setuserfield (struct ast_channel *chan, const char *userfield)
 Set CDR user field for channel (stored in CDR) More...
 
int ast_cdr_setvar (struct ast_cdr *cdr, const char *name, const char *value, int recur)
 
void ast_cdr_specialized_reset (struct ast_cdr *cdr, struct ast_flags *_flags)
 
void ast_cdr_start (struct ast_cdr *cdr)
 Start a call. More...
 
void ast_cdr_submit_batch (int do_shutdown)
 Spawns (possibly) a new thread to submit a batch of CDRs to the backend engines. More...
 
void ast_cdr_unregister (const char *name)
 Unregister a CDR handling engine. More...
 
int ast_cdr_update (struct ast_channel *c)
 Update CDR on a channel. More...
 
static void cdr_engine_shutdown (void)
 
static void cdr_get_tv (struct timeval when, const char *fmt, char *buf, int bufsize)
 
static void cdr_merge_vars (struct ast_cdr *to, struct ast_cdr *from)
 
static int cdr_seq_inc (struct ast_cdr *cdr)
 
int check_cdr_enabled (void)
 Return TRUE if CDR subsystem is enabled. More...
 
static void check_post (struct ast_cdr *cdr)
 print a warning if cdr already posted More...
 
static void * do_batch_backend_process (void *data)
 
static void * do_cdr (void *data)
 
static void do_reload (int reload)
 
static char * handle_cli_status (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_submit (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static int init_batch (void)
 
static void post_cdr (struct ast_cdr *cdr)
 
static void reset_batch (void)
 
static void set_one_cid (struct ast_cdr *cdr, struct ast_channel *c)
 
static int submit_scheduled_batch (const void *data)
 
static void submit_unscheduled_batch (void)
 

Variables

char ast_default_accountcode [AST_MAX_ACCOUNT_CODE]
 
int ast_default_amaflags = AST_CDR_DOCUMENTATION
 
static struct ast_cdr_batchbatch = NULL
 
static const int BATCH_SAFE_SHUTDOWN_DEFAULT = 1
 
static const int BATCH_SCHEDULER_ONLY_DEFAULT = 0
 
static const int BATCH_SIZE_DEFAULT = 100
 
static const int BATCH_TIME_DEFAULT = 300
 
static int batchmode
 
static const int BATCHMODE_DEFAULT = 0
 
static int batchsafeshutdown
 
static int batchscheduleronly
 
static int batchsize
 
static int batchtime
 
static struct be_list be_list = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
 
static ast_mutex_t cdr_batch_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
 
static ast_cond_t cdr_pending_cond
 
static ast_mutex_t cdr_pending_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
 
static const char *const cdr_readonly_vars []
 
static int cdr_sched = -1
 
static ast_mutex_t cdr_sched_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
 
static int cdr_sequence = 0
 
static pthread_t cdr_thread = AST_PTHREADT_NULL
 
static struct ast_cli_entry cli_status = AST_CLI_DEFINE(handle_cli_status, "Display the CDR status")
 
static struct ast_cli_entry cli_submit = AST_CLI_DEFINE(handle_cli_submit, "Posts all pending batched CDR data")
 
static int enabled
 
static const int ENABLED_DEFAULT = 1
 
static struct sched_contextsched
 
static int unanswered
 
static const int UNANSWERED_DEFAULT = 0
 

Detailed Description

Call Detail Record API.

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

Definition in file cdr.c.

Function Documentation

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

References ast_calloc, ast_log(), and LOG_ERROR.

Referenced by __agent_start_monitoring(), __ast_channel_alloc_ap(), __ast_request_and_dial(), ast_bridge_call(), ast_cdr_dup(), ast_pbx_outgoing_cdr_failed(), builtin_blindtransfer(), clear_caller(), findmeexec(), and start_monitor_exec().

500 {
501  struct ast_cdr *x;
502  x = ast_calloc(1, sizeof(*x));
503  if (!x)
504  ast_log(LOG_ERROR,"Allocation Failure for a CDR!\n");
505  return x;
506 }
Responsible for call detail data.
Definition: cdr.h:82
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_calloc(a, b)
Definition: astmm.h:82
int ast_cdr_amaflags2int ( const char *  flag)

Convert a string to a detail record AMA flag.

Parameters
flagstring form of flag Converts the string form of the flag to the binary form.
Returns
the binary form of the flag

Definition at line 1105 of file cdr.c.

References AST_CDR_BILLING, AST_CDR_DOCUMENTATION, and AST_CDR_OMIT.

Referenced by ast_cdr_setamaflags(), build_device(), build_gateway(), build_peer(), build_user(), config_parse_variables(), process_dahdi(), and set_config().

1106 {
1107  if (!strcasecmp(flag, "default"))
1108  return 0;
1109  if (!strcasecmp(flag, "omit"))
1110  return AST_CDR_OMIT;
1111  if (!strcasecmp(flag, "billing"))
1112  return AST_CDR_BILLING;
1113  if (!strcasecmp(flag, "documentation"))
1114  return AST_CDR_DOCUMENTATION;
1115  return -1;
1116 }
void ast_cdr_answer ( struct ast_cdr cdr)

Answer a call.

Parameters
cdrthe cdr you wish to associate with the call Starts all CDR stuff necessary for doing CDR when answering a call
Note
NULL argument is just fine.

Definition at line 737 of file cdr.c.

References ast_cdr::answer, AST_CDR_ANSWERED, AST_CDR_FLAG_ANSLOCKED, AST_CDR_FLAG_DONT_TOUCH, AST_CDR_FLAG_LOCKED, ast_test_flag, ast_tvnow(), ast_tvzero(), check_post(), ast_cdr::disposition, and ast_cdr::next.

Referenced by __ast_request_and_dial(), ast_bridge_call(), and ast_raw_answer().

738 {
739 
740  for (; cdr; cdr = cdr->next) {
742  continue;
744  continue;
745  check_post(cdr);
746  if (cdr->disposition < AST_CDR_ANSWERED)
748  if (ast_tvzero(cdr->answer))
749  cdr->answer = ast_tvnow();
750  }
751 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_cdr * next
Definition: cdr.h:132
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:100
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
static void check_post(struct ast_cdr *cdr)
print a warning if cdr already posted
Definition: cdr.c:467
struct timeval answer
Definition: cdr.h:102
long int disposition
Definition: cdr.h:110
struct ast_cdr* ast_cdr_append ( struct ast_cdr cdr,
struct ast_cdr newcdr 
)

Definition at line 1216 of file cdr.c.

References ast_cdr::next.

Referenced by ast_cdr_fork(), ast_cdr_merge(), and try_calling().

1217 {
1218  struct ast_cdr *ret;
1219 
1220  if (cdr) {
1221  ret = cdr;
1222 
1223  while (cdr->next)
1224  cdr = cdr->next;
1225  cdr->next = newcdr;
1226  } else {
1227  ret = newcdr;
1228  }
1229 
1230  return ret;
1231 }
struct ast_cdr * next
Definition: cdr.h:132
Responsible for call detail data.
Definition: cdr.h:82
int ast_cdr_appenduserfield ( struct ast_channel chan,
const char *  userfield 
)

Append to CDR user field for channel (stored in CDR)

Note
The channel should be locked before calling.

Definition at line 1069 of file cdr.c.

References AST_CDR_FLAG_LOCKED, ast_copy_string(), ast_test_flag, ast_channel::cdr, len(), ast_cdr::next, and ast_cdr::userfield.

Referenced by ast_bridge_call().

1070 {
1071  struct ast_cdr *cdr = chan->cdr;
1072 
1073  for ( ; cdr ; cdr = cdr->next) {
1074  int len = strlen(cdr->userfield);
1075 
1077  ast_copy_string(cdr->userfield + len, userfield, sizeof(cdr->userfield) - len);
1078  }
1079 
1080  return 0;
1081 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_cdr * next
Definition: cdr.h:132
struct ast_cdr * cdr
Definition: channel.h:766
Responsible for call detail data.
Definition: cdr.h:82
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
char userfield[AST_MAX_USER_FIELD]
Definition: cdr.h:125
void ast_cdr_busy ( struct ast_cdr cdr)

Busy a call.

Parameters
cdrthe cdr you wish to associate with the call Marks the channel disposition as "BUSY" Will skip CDR's in chain with ANS_LOCK bit set. (see forkCDR() application. Returns nothing

Definition at line 753 of file cdr.c.

References AST_CDR_BUSY, AST_CDR_FLAG_LOCKED, ast_test_flag, check_post(), ast_cdr::disposition, and ast_cdr::next.

Referenced by __ast_request_and_dial(), ast_cdr_disposition(), handle_cause(), pbx_builtin_busy(), and ring_entry().

754 {
755 
756  for (; cdr; cdr = cdr->next) {
757  if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
758  check_post(cdr);
759  cdr->disposition = AST_CDR_BUSY;
760  }
761  }
762 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_cdr * next
Definition: cdr.h:132
static void check_post(struct ast_cdr *cdr)
print a warning if cdr already posted
Definition: cdr.c:467
long int disposition
Definition: cdr.h:110
int ast_cdr_copy_vars ( struct ast_cdr to_cdr,
struct ast_cdr from_cdr 
)

Definition at line 383 of file cdr.c.

References AST_LIST_INSERT_HEAD, AST_LIST_TRAVERSE, ast_strlen_zero(), ast_var_assign(), ast_var_name(), ast_var_value(), var, and ast_cdr::varshead.

Referenced by ast_bridge_call(), and ast_cdr_dup().

384 {
385  struct ast_var_t *variables, *newvariable = NULL;
386  struct varshead *headpa, *headpb;
387  const char *var, *val;
388  int x = 0;
389 
390  if (!to_cdr || !from_cdr) /* don't die if one of the pointers is null */
391  return 0;
392 
393  headpa = &from_cdr->varshead;
394  headpb = &to_cdr->varshead;
395 
396  AST_LIST_TRAVERSE(headpa,variables,entries) {
397  if (variables &&
398  (var = ast_var_name(variables)) && (val = ast_var_value(variables)) &&
399  !ast_strlen_zero(var) && !ast_strlen_zero(val) &&
400  (newvariable = ast_var_assign(var, val))) {
401  AST_LIST_INSERT_HEAD(headpb, newvariable, entries);
402  x++;
403  }
404  }
405 
406  return x;
407 }
Definition: ast_expr2.c:325
const char * ast_var_value(const struct ast_var_t *var)
Definition: chanvars.c:89
struct ast_var_t * ast_var_assign(const char *name, const char *value)
Definition: chanvars.c:41
const char * ast_var_name(const struct ast_var_t *var)
Definition: chanvars.c:69
#define var
Definition: ast_expr2f.c:606
struct varshead varshead
Definition: cdr.h:130
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:696
int ast_cdr_data_add_structure ( struct ast_data tree,
struct ast_cdr cdr,
int  recur 
)
Parameters
[in]treeWhere to insert the cdr.
[in]cdrThe cdr structure to insert in 'tree'.
[in]recurGo throw all the cdr levels.
Return values
<0on error.
0on success.

Definition at line 1674 of file cdr.c.

References ast_cdr_getvar(), ast_data_add_int(), ast_data_add_node(), ast_data_add_str(), AST_LIST_TRAVERSE, ast_strlen_zero(), ast_var_name(), ast_var_value(), cdr_readonly_vars, ast_var_t::entries, ast_cdr::next, var, and ast_cdr::varshead.

Referenced by ast_channel_data_add_structure().

1675 {
1676  struct ast_cdr *tmpcdr;
1677  struct ast_data *level;
1678  struct ast_var_t *variables;
1679  const char *var, *val;
1680  int x = 1, i;
1681  char workspace[256];
1682  char *tmp;
1683 
1684  if (!cdr) {
1685  return -1;
1686  }
1687 
1688  for (tmpcdr = cdr; tmpcdr; tmpcdr = (recur ? tmpcdr->next : NULL)) {
1689  level = ast_data_add_node(tree, "level");
1690  if (!level) {
1691  continue;
1692  }
1693 
1694  ast_data_add_int(level, "level_number", x);
1695 
1696  AST_LIST_TRAVERSE(&tmpcdr->varshead, variables, entries) {
1697  if (variables && (var = ast_var_name(variables)) &&
1698  (val = ast_var_value(variables)) && !ast_strlen_zero(var)
1699  && !ast_strlen_zero(val)) {
1700  ast_data_add_str(level, var, val);
1701  } else {
1702  break;
1703  }
1704  }
1705 
1706  for (i = 0; cdr_readonly_vars[i]; i++) {
1707  workspace[0] = 0; /* null out the workspace, because the cdr_get_tv() won't write anything if time is NULL, so you get old vals */
1708  ast_cdr_getvar(tmpcdr, cdr_readonly_vars[i], &tmp, workspace, sizeof(workspace), 0, 0);
1709  if (!tmp) {
1710  continue;
1711  }
1712  ast_data_add_str(level, cdr_readonly_vars[i], tmp);
1713  }
1714 
1715  x++;
1716  }
1717 
1718  return 0;
1719 }
The data tree to be returned by the callbacks and managed by functions local to this file...
Definition: data.c:85
Definition: ast_expr2.c:325
const char * ast_var_value(const struct ast_var_t *var)
Definition: chanvars.c:89
const char * ast_var_name(const struct ast_var_t *var)
Definition: chanvars.c:69
struct ast_cdr * next
Definition: cdr.h:132
#define var
Definition: ast_expr2f.c:606
struct varshead varshead
Definition: cdr.h:130
void ast_cdr_getvar(struct ast_cdr *cdr, const char *name, char **ret, char *workspace, int workspacelen, int recur, int raw)
Definition: cdr.c:264
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
struct ast_data * ast_data_add_node(struct ast_data *root, const char *childname)
Add a container child.
Definition: data.c:2317
static const char *const cdr_readonly_vars[]
Definition: cdr.c:336
Responsible for call detail data.
Definition: cdr.h:82
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
struct ast_var_t::@158 entries
struct ast_data * ast_data_add_str(struct ast_data *root, const char *childname, const char *string)
Add a string node type.
Definition: data.c:2401
struct ast_data * ast_data_add_int(struct ast_data *root, const char *childname, int value)
Add an integer node type.
Definition: data.c:2322
void ast_cdr_detach ( struct ast_cdr cdr)

Detaches the detail record for posting (and freeing) either now or at a later time in bulk with other records during batch mode operation.

Parameters
cdrWhich CDR to detach from the channel thread Prevents the channel thread from blocking on the CDR handling Returns nothing

Definition at line 1328 of file cdr.c.

References ast_calloc, AST_CDR_FLAG_POST_DISABLED, ast_cdr_free(), ast_debug, ast_mutex_lock, ast_mutex_unlock, ast_set_flag, batch, batchmode, batchsize, ast_cdr_batch_item::cdr, cdr_batch_lock, enabled, ast_cdr_batch::head, init_batch(), ast_cdr_batch_item::next, post_cdr(), ast_cdr_batch::size, submit_unscheduled_batch(), and ast_cdr_batch::tail.

Referenced by ast_bridge_call(), ast_cdr_reset(), ast_hangup(), and ast_pbx_outgoing_cdr_failed().

1329 {
1330  struct ast_cdr_batch_item *newtail;
1331  int curr;
1332  int submit_batch = 0;
1333 
1334  if (!cdr)
1335  return;
1336 
1337  /* maybe they disabled CDR stuff completely, so just drop it */
1338  if (!enabled) {
1339  ast_debug(1, "Dropping CDR !\n");
1341  ast_cdr_free(cdr);
1342  return;
1343  }
1344 
1345  /* post stuff immediately if we are not in batch mode, this is legacy behaviour */
1346  if (!batchmode) {
1347  post_cdr(cdr);
1348  ast_cdr_free(cdr);
1349  return;
1350  }
1351 
1352  /* otherwise, each CDR gets put into a batch list (at the end) */
1353  ast_debug(1, "CDR detaching from this thread\n");
1354 
1355  /* we'll need a new tail for every CDR */
1356  if (!(newtail = ast_calloc(1, sizeof(*newtail)))) {
1357  post_cdr(cdr);
1358  ast_cdr_free(cdr);
1359  return;
1360  }
1361 
1362  /* don't traverse a whole list (just keep track of the tail) */
1364  if (!batch)
1365  init_batch();
1366  if (!batch->head) {
1367  /* new batch is empty, so point the head at the new tail */
1368  batch->head = newtail;
1369  } else {
1370  /* already got a batch with something in it, so just append a new tail */
1371  batch->tail->next = newtail;
1372  }
1373  newtail->cdr = cdr;
1374  batch->tail = newtail;
1375  curr = batch->size++;
1376 
1377  /* if we have enough stuff to post, then do it */
1378  if (curr >= (batchsize - 1)) {
1379  submit_batch = 1;
1380  }
1382 
1383  /* Don't call submit_unscheduled_batch with the cdr_batch_lock held */
1384  if (submit_batch) {
1386  }
1387 }
static int batchsize
Definition: cdr.c:100
static struct ast_cdr_batch * batch
static int batchmode
Definition: cdr.c:94
#define ast_set_flag(p, flag)
Definition: utils.h:70
static void post_cdr(struct ast_cdr *cdr)
Definition: cdr.c:1118
#define ast_mutex_lock(a)
Definition: lock.h:155
struct ast_cdr_batch_item * head
Definition: cdr.c:78
struct ast_cdr_batch_item * tail
Definition: cdr.c:79
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
struct ast_cdr * cdr
Definition: cdr.c:72
static int init_batch(void)
Definition: cdr.c:1242
struct ast_cdr_batch_item * next
Definition: cdr.c:73
int size
Definition: cdr.c:77
static ast_mutex_t cdr_batch_lock
Definition: cdr.c:114
#define ast_calloc(a, b)
Definition: astmm.h:82
void ast_cdr_free(struct ast_cdr *cdr)
Free a CDR record.
Definition: cdr.c:475
static int enabled
Definition: cdr.c:91
static void submit_unscheduled_batch(void)
Definition: cdr.c:1312
#define ast_mutex_unlock(a)
Definition: lock.h:156
void ast_cdr_discard ( struct ast_cdr cdr)

the same as a cdr_free call, only with no checks; just get rid of it

Discard and free a CDR record.

Definition at line 488 of file cdr.c.

References ast_cdr_free_vars(), ast_free, and ast_cdr::next.

Referenced by ast_async_goto(), ast_bridge_call(), ast_cdr_merge(), ast_channel_destructor(), and ast_dummy_channel_destructor().

489 {
490  while (cdr) {
491  struct ast_cdr *next = cdr->next;
492 
493  ast_cdr_free_vars(cdr, 0);
494  ast_free(cdr);
495  cdr = next;
496  }
497 }
struct ast_cdr * next
Definition: cdr.h:132
Responsible for call detail data.
Definition: cdr.h:82
#define ast_free(a)
Definition: astmm.h:97
void ast_cdr_free_vars(struct ast_cdr *cdr, int recur)
Definition: cdr.c:454
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 959 of file cdr.c.

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

Referenced by ast_cdr_getvar(), build_csv_record(), build_radius_record(), csv_log(), execute_cb(), manager_log(), and tds_log().

960 {
961  switch (disposition) {
962  case AST_CDR_NULL:
963  return "NO ANSWER"; /* by default, for backward compatibility */
964  case AST_CDR_NOANSWER:
965  return "NO ANSWER";
966  case AST_CDR_FAILED:
967  return "FAILED";
968  case AST_CDR_BUSY:
969  return "BUSY";
970  case AST_CDR_ANSWERED:
971  return "ANSWERED";
972  }
973  return "UNKNOWN";
974 }
long int disposition
Definition: cdr.h:110
int ast_cdr_disposition ( struct ast_cdr cdr,
int  cause 
)

Save the result of the call based on the AST_CAUSE_*.

Parameters
cdrthe cdr you wish to associate with the call
causethe AST_CAUSE_* Returns nothing

Definition at line 790 of file cdr.c.

References AST_CAUSE_BUSY, AST_CAUSE_NO_ANSWER, AST_CAUSE_NORMAL, ast_cdr_busy(), ast_cdr_noanswer(), and ast_cdr::next.

Referenced by __ast_request_and_dial(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), clear_caller(), and findmeexec().

791 {
792  int res = 0;
793 
794  for (; cdr; cdr = cdr->next) {
795  switch (cause) { /* handle all the non failure, busy cases, return 0 not to set disposition,
796  return -1 to set disposition to FAILED */
797  case AST_CAUSE_BUSY:
798  ast_cdr_busy(cdr);
799  break;
800  case AST_CAUSE_NO_ANSWER:
801  ast_cdr_noanswer(cdr);
802  break;
803  case AST_CAUSE_NORMAL:
804  break;
805  default:
806  res = -1;
807  }
808  }
809  return res;
810 }
struct ast_cdr * next
Definition: cdr.h:132
#define AST_CAUSE_NO_ANSWER
Definition: causes.h:108
#define AST_CAUSE_NORMAL
Definition: causes.h:150
void ast_cdr_noanswer(struct ast_cdr *cdr)
A call wasn&#39;t answered.
Definition: cdr.c:776
#define AST_CAUSE_BUSY
Definition: causes.h:148
void ast_cdr_busy(struct ast_cdr *cdr)
Busy a call.
Definition: cdr.c:753
struct ast_cdr* ast_cdr_dup ( struct ast_cdr cdr)

Duplicate a record.

Duplicate a CDR record

Returns
Pointer to new CDR record

Definition at line 213 of file cdr.c.

References ast_cdr_alloc(), ast_cdr_copy_vars(), ast_cdr::next, and ast_cdr::varshead.

Referenced by ast_async_goto(), ast_cdr_dup_unique(), ast_cdr_dup_unique_swap(), ast_cdr_merge(), custom_log(), manager_log(), syslog_log(), and try_calling().

214 {
215  struct ast_cdr *newcdr;
216 
217  if (!cdr) /* don't die if we get a null cdr pointer */
218  return NULL;
219  newcdr = ast_cdr_alloc();
220  if (!newcdr)
221  return NULL;
222 
223  memcpy(newcdr, cdr, sizeof(*newcdr));
224  /* The varshead is unusable, volatile even, after the memcpy so we take care of that here */
225  memset(&newcdr->varshead, 0, sizeof(newcdr->varshead));
226  ast_cdr_copy_vars(newcdr, cdr);
227  newcdr->next = NULL;
228 
229  return newcdr;
230 }
struct ast_cdr * next
Definition: cdr.h:132
struct varshead varshead
Definition: cdr.h:130
Responsible for call detail data.
Definition: cdr.h:82
int ast_cdr_copy_vars(struct ast_cdr *to_cdr, struct ast_cdr *from_cdr)
Definition: cdr.c:383
struct ast_cdr * ast_cdr_alloc(void)
Allocate a CDR record.
Definition: cdr.c:499
struct ast_cdr* ast_cdr_dup_unique ( struct ast_cdr cdr)

Duplicate a record and increment the sequence number.

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

Definition at line 190 of file cdr.c.

References ast_cdr_dup(), and cdr_seq_inc().

Referenced by ast_cdr_fork().

191 {
192  struct ast_cdr *newcdr = ast_cdr_dup(cdr);
193  if (!newcdr)
194  return NULL;
195 
196  cdr_seq_inc(newcdr);
197  return newcdr;
198 }
static int cdr_seq_inc(struct ast_cdr *cdr)
Definition: cdr.c:892
struct ast_cdr * ast_cdr_dup(struct ast_cdr *cdr)
Duplicate a record.
Definition: cdr.c:213
Responsible for call detail data.
Definition: cdr.h:82
struct ast_cdr* ast_cdr_dup_unique_swap ( struct ast_cdr cdr)

Duplicate a record and increment the sequence number of the old record.

Parameters
cdrthe record to duplicate
Return values
amalloc'd ast_cdr structure,
NULLon error (malloc failure)
Note
This version increments the original CDR's sequence number rather than the duplicate's sequence number. The effect is as if the original CDR's sequence number was swapped with the duplicate's sequence number.
See Also
ast_cdr_dup()
ast_cdr_dup_unique()

Definition at line 200 of file cdr.c.

References ast_cdr_dup(), and cdr_seq_inc().

Referenced by ast_bridge_call(), and ast_cdr_reset().

201 {
202  struct ast_cdr *newcdr = ast_cdr_dup(cdr);
203  if (!newcdr)
204  return NULL;
205 
206  cdr_seq_inc(cdr);
207  return newcdr;
208 }
static int cdr_seq_inc(struct ast_cdr *cdr)
Definition: cdr.c:892
struct ast_cdr * ast_cdr_dup(struct ast_cdr *cdr)
Duplicate a record.
Definition: cdr.c:213
Responsible for call detail data.
Definition: cdr.h:82
void ast_cdr_end ( struct ast_cdr cdr)

End a call.

Parameters
cdrthe cdr you have associated the call with Registers the end of call time in the cdr structure. Returns nothing

Definition at line 933 of file cdr.c.

References ast_cdr::answer, AST_CDR_ANSWERED, AST_CDR_FAILED, AST_CDR_FLAG_DONT_TOUCH, AST_CDR_FLAG_LOCKED, ast_log(), AST_OPT_FLAG_INITIATED_SECONDS, ast_options, ast_test_flag, ast_tvnow(), ast_tvzero(), ast_cdr::billsec, ast_cdr::channel, check_post(), ast_cdr::disposition, ast_cdr::duration, ast_cdr::end, LOG_WARNING, ast_cdr::next, S_OR, and ast_cdr::start.

Referenced by __ast_pbx_run(), __ast_request_and_dial(), ast_bridge_call(), ast_cdr_fork(), ast_cdr_reset(), ast_hangup(), ast_pbx_outgoing_cdr_failed(), clear_caller(), and findmeexec().

934 {
935  for ( ; cdr ; cdr = cdr->next) {
937  continue;
938  check_post(cdr);
939  if (ast_tvzero(cdr->end))
940  cdr->end = ast_tvnow();
941  if (ast_tvzero(cdr->start)) {
942  ast_log(LOG_WARNING, "CDR on channel '%s' has not started\n", S_OR(cdr->channel, "<unknown>"));
944  } else
945  cdr->duration = cdr->end.tv_sec - cdr->start.tv_sec;
946  if (ast_tvzero(cdr->answer)) {
947  if (cdr->disposition == AST_CDR_ANSWERED) {
948  ast_log(LOG_WARNING, "CDR on channel '%s' has no answer time but is 'ANSWERED'\n", S_OR(cdr->channel, "<unknown>"));
950  }
951  } else {
952  cdr->billsec = cdr->end.tv_sec - cdr->answer.tv_sec;
954  cdr->billsec += cdr->end.tv_usec > cdr->answer.tv_usec ? 1 : 0;
955  }
956  }
957 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
long int billsec
Definition: cdr.h:108
#define LOG_WARNING
Definition: logger.h:144
struct ast_cdr * next
Definition: cdr.h:132
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:100
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
char channel[AST_MAX_EXTENSION]
Definition: cdr.h:92
static void check_post(struct ast_cdr *cdr)
print a warning if cdr already posted
Definition: cdr.c:467
struct timeval answer
Definition: cdr.h:102
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
struct timeval start
Definition: cdr.h:100
long int duration
Definition: cdr.h:106
struct ast_flags ast_options
Definition: asterisk.c:178
struct timeval end
Definition: cdr.h:104
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
long int disposition
Definition: cdr.h:110
int ast_cdr_engine_init ( void  )

Load the configuration file cdr.conf and possibly start the CDR scheduling thread.

Definition at line 1646 of file cdr.c.

References ast_cli_register(), ast_log(), ast_register_atexit(), cdr_engine_shutdown(), cli_status, do_reload(), LOG_ERROR, and sched_context_create().

Referenced by main().

1647 {
1649  if (!sched) {
1650  ast_log(LOG_ERROR, "Unable to create schedule context.\n");
1651  return -1;
1652  }
1653 
1655  do_reload(0);
1657 
1658  return 0;
1659 }
int ast_cli_register(struct ast_cli_entry *e)
Registers a command or an array of commands.
Definition: cli.c:2159
static void do_reload(int reload)
Definition: cdr.c:1497
static void cdr_engine_shutdown(void)
Definition: cdr.c:1627
Definition: sched.c:57
int ast_register_atexit(void(*func)(void))
Register a function to be executed before Asterisk exits.
Definition: asterisk.c:998
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static struct ast_cli_entry cli_status
Definition: cdr.c:1495
struct sched_context * sched_context_create(void)
New schedule context.
Definition: sched.c:246
int ast_cdr_engine_reload ( void  )

Reload the configuration file cdr.conf and start/stop CDR scheduling thread.

Definition at line 1668 of file cdr.c.

References do_reload().

1669 {
1670  do_reload(1);
1671  return 0;
1672 }
static void do_reload(int reload)
Definition: cdr.c:1497
void ast_cdr_engine_term ( void  )

Submit any remaining CDRs and prepare for shutdown

Definition at line 1663 of file cdr.c.

References ast_cdr_submit_batch(), and batchsafeshutdown.

Referenced by can_safely_quit(), and do_reload().

1664 {
1666 }
void ast_cdr_submit_batch(int shutdown)
Spawns (possibly) a new thread to submit a batch of CDRs to the backend engines.
Definition: cdr.c:1270
static int batchsafeshutdown
Definition: cdr.c:109
void ast_cdr_failed ( struct ast_cdr cdr)

Fail a call.

Parameters
cdrthe cdr you wish to associate with the call Marks the channel disposition as "FAILED" Will skip CDR's in chain with ANS_LOCK bit set. (see forkCDR() application. Returns nothing

Definition at line 764 of file cdr.c.

References AST_CDR_FAILED, AST_CDR_FLAG_LOCKED, ast_test_flag, check_post(), ast_cdr::disposition, and ast_cdr::next.

Referenced by __ast_request_and_dial(), ast_pbx_outgoing_app(), ast_pbx_outgoing_cdr_failed(), ast_pbx_outgoing_exten(), clear_caller(), findmeexec(), handle_cause(), try_calling(), and wait_for_answer().

765 {
766  for (; cdr; cdr = cdr->next) {
767  check_post(cdr);
768  if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
769  check_post(cdr);
770  if (cdr->disposition < AST_CDR_FAILED)
772  }
773  }
774 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_cdr * next
Definition: cdr.h:132
static void check_post(struct ast_cdr *cdr)
print a warning if cdr already posted
Definition: cdr.c:467
long int disposition
Definition: cdr.h:110
char* ast_cdr_flags2str ( int  flag)

Converts AMA flag to printable string

Definition at line 977 of file cdr.c.

References AST_CDR_BILLING, AST_CDR_DOCUMENTATION, and AST_CDR_OMIT.

Referenced by _sip_show_peer(), _skinny_show_line(), ast_cdr_getvar(), ast_channel_data_add_structure(), build_csv_record(), build_radius_record(), csv_log(), manager_log(), peers_data_provider_get(), sip_show_user(), tds_log(), and users_data_provider_get().

978 {
979  switch (flag) {
980  case AST_CDR_OMIT:
981  return "OMIT";
982  case AST_CDR_BILLING:
983  return "BILLING";
985  return "DOCUMENTATION";
986  }
987  return "Unknown";
988 }
void ast_cdr_free ( struct ast_cdr cdr)

Free a CDR record.

Parameters
cdrast_cdr structure to free Returns nothing

Definition at line 475 of file cdr.c.

References ast_cdr_free_vars(), ast_free, and ast_cdr::next.

Referenced by ast_cdr_detach(), and do_batch_backend_process().

476 {
477 
478  while (cdr) {
479  struct ast_cdr *next = cdr->next;
480 
481  ast_cdr_free_vars(cdr, 0);
482  ast_free(cdr);
483  cdr = next;
484  }
485 }
struct ast_cdr * next
Definition: cdr.h:132
Responsible for call detail data.
Definition: cdr.h:82
#define ast_free(a)
Definition: astmm.h:97
void ast_cdr_free_vars(struct ast_cdr *cdr, int recur)
Definition: cdr.c:454
void ast_cdr_free_vars ( struct ast_cdr cdr,
int  recur 
)

Definition at line 454 of file cdr.c.

References AST_LIST_REMOVE_HEAD, ast_var_delete(), ast_cdr::next, and ast_cdr::varshead.

Referenced by ast_cdr_discard(), ast_cdr_fork(), ast_cdr_free(), and ast_cdr_reset().

455 {
456 
457  /* clear variables */
458  for (; cdr; cdr = recur ? cdr->next : NULL) {
459  struct ast_var_t *vardata;
460  struct varshead *headp = &cdr->varshead;
461  while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries)))
462  ast_var_delete(vardata);
463  }
464 }
struct ast_cdr * next
Definition: cdr.h:132
void ast_var_delete(struct ast_var_t *var)
Definition: chanvars.c:63
struct varshead varshead
Definition: cdr.h:130
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:818
void ast_cdr_getvar ( struct ast_cdr cdr,
const char *  name,
char **  ret,
char *  workspace,
int  workspacelen,
int  recur,
int  raw 
)

CDR channel variable retrieval

Definition at line 264 of file cdr.c.

References ast_cdr::accountcode, ast_cdr::amaflags, ast_cdr::answer, ast_cdr_disp2str(), ast_cdr_flags2str(), ast_cdr_getvar_internal(), ast_copy_string(), ast_strlen_zero(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), ast_cdr::billsec, 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, ast_cdr::peeraccount, ast_cdr::sequence, ast_cdr::src, ast_cdr::start, ast_cdr::uniqueid, and ast_cdr::userfield.

Referenced by ast_cdr_data_add_structure(), ast_cdr_serialize_variables(), cdr_handler(), cdr_read(), odbc_log(), and pgsql_log().

265 {
266  const char *fmt = "%Y-%m-%d %T";
267  const char *varbuf;
268 
269  if (!cdr) /* don't die if the cdr is null */
270  return;
271 
272  *ret = NULL;
273  /* special vars (the ones from the struct ast_cdr when requested by name)
274  I'd almost say we should convert all the stringed vals to vars */
275 
276  if (!strcasecmp(name, "clid"))
277  ast_copy_string(workspace, cdr->clid, workspacelen);
278  else if (!strcasecmp(name, "src"))
279  ast_copy_string(workspace, cdr->src, workspacelen);
280  else if (!strcasecmp(name, "dst"))
281  ast_copy_string(workspace, cdr->dst, workspacelen);
282  else if (!strcasecmp(name, "dcontext"))
283  ast_copy_string(workspace, cdr->dcontext, workspacelen);
284  else if (!strcasecmp(name, "channel"))
285  ast_copy_string(workspace, cdr->channel, workspacelen);
286  else if (!strcasecmp(name, "dstchannel"))
287  ast_copy_string(workspace, cdr->dstchannel, workspacelen);
288  else if (!strcasecmp(name, "lastapp"))
289  ast_copy_string(workspace, cdr->lastapp, workspacelen);
290  else if (!strcasecmp(name, "lastdata"))
291  ast_copy_string(workspace, cdr->lastdata, workspacelen);
292  else if (!strcasecmp(name, "start"))
293  cdr_get_tv(cdr->start, raw ? NULL : fmt, workspace, workspacelen);
294  else if (!strcasecmp(name, "answer"))
295  cdr_get_tv(cdr->answer, raw ? NULL : fmt, workspace, workspacelen);
296  else if (!strcasecmp(name, "end"))
297  cdr_get_tv(cdr->end, raw ? NULL : fmt, workspace, workspacelen);
298  else if (!strcasecmp(name, "duration")) {
299  snprintf(workspace, workspacelen, "%ld", cdr->end.tv_sec != 0 ? cdr->duration : (long)ast_tvdiff_ms(ast_tvnow(), cdr->start) / 1000);
300  } else if (!strcasecmp(name, "billsec")) {
301  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);
302  } else if (!strcasecmp(name, "disposition")) {
303  if (raw) {
304  snprintf(workspace, workspacelen, "%ld", cdr->disposition);
305  } else {
306  ast_copy_string(workspace, ast_cdr_disp2str(cdr->disposition), workspacelen);
307  }
308  } else if (!strcasecmp(name, "amaflags")) {
309  if (raw) {
310  snprintf(workspace, workspacelen, "%ld", cdr->amaflags);
311  } else {
312  ast_copy_string(workspace, ast_cdr_flags2str(cdr->amaflags), workspacelen);
313  }
314  } else if (!strcasecmp(name, "accountcode"))
315  ast_copy_string(workspace, cdr->accountcode, workspacelen);
316  else if (!strcasecmp(name, "peeraccount"))
317  ast_copy_string(workspace, cdr->peeraccount, workspacelen);
318  else if (!strcasecmp(name, "uniqueid"))
319  ast_copy_string(workspace, cdr->uniqueid, workspacelen);
320  else if (!strcasecmp(name, "linkedid"))
321  ast_copy_string(workspace, cdr->linkedid, workspacelen);
322  else if (!strcasecmp(name, "userfield"))
323  ast_copy_string(workspace, cdr->userfield, workspacelen);
324  else if (!strcasecmp(name, "sequence"))
325  snprintf(workspace, workspacelen, "%d", cdr->sequence);
326  else if ((varbuf = ast_cdr_getvar_internal(cdr, name, recur)))
327  ast_copy_string(workspace, varbuf, workspacelen);
328  else
329  workspace[0] = '\0';
330 
331  if (!ast_strlen_zero(workspace))
332  *ret = workspace;
333 }
char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: cdr.h:114
char dstchannel[AST_MAX_EXTENSION]
Definition: cdr.h:94
long int billsec
Definition: cdr.h:108
char dcontext[AST_MAX_EXTENSION]
Definition: cdr.h:90
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:100
char uniqueid[150]
Definition: cdr.h:121
int sequence
Definition: cdr.h:127
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:90
char * ast_cdr_flags2str(int flags)
Definition: cdr.c:977
static const char * ast_cdr_getvar_internal(struct ast_cdr *cdr, const char *name, int recur)
Definition: cdr.c:232
char lastdata[AST_MAX_EXTENSION]
Definition: cdr.h:98
long int amaflags
Definition: cdr.h:112
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char linkedid[32]
Definition: cdr.h:123
static void cdr_get_tv(struct timeval when, const char *fmt, char *buf, int bufsize)
Definition: cdr.c:249
char dst[AST_MAX_EXTENSION]
Definition: cdr.h:88
char channel[AST_MAX_EXTENSION]
Definition: cdr.h:92
struct timeval answer
Definition: cdr.h:102
char lastapp[AST_MAX_EXTENSION]
Definition: cdr.h:96
struct timeval start
Definition: cdr.h:100
static const char name[]
long int duration
Definition: cdr.h:106
char src[AST_MAX_EXTENSION]
Definition: cdr.h:86
char peeraccount[AST_MAX_ACCOUNT_CODE]
Definition: cdr.h:116
struct timeval end
Definition: cdr.h:104
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
long int disposition
Definition: cdr.h:110
char clid[AST_MAX_EXTENSION]
Definition: cdr.h:84
char * ast_cdr_disp2str(int disposition)
Disposition to a string.
Definition: cdr.c:959
char userfield[AST_MAX_USER_FIELD]
Definition: cdr.h:125
static const char* ast_cdr_getvar_internal ( struct ast_cdr cdr,
const char *  name,
int  recur 
)
static

Definition at line 232 of file cdr.c.

References AST_LIST_TRAVERSE, ast_strlen_zero(), ast_var_name(), ast_var_value(), ast_cdr::next, and ast_cdr::varshead.

Referenced by ast_cdr_getvar().

233 {
234  if (ast_strlen_zero(name))
235  return NULL;
236 
237  for (; cdr; cdr = recur ? cdr->next : NULL) {
238  struct ast_var_t *variables;
239  struct varshead *headp = &cdr->varshead;
240  AST_LIST_TRAVERSE(headp, variables, entries) {
241  if (!strcasecmp(name, ast_var_name(variables)))
242  return ast_var_value(variables);
243  }
244  }
245 
246  return NULL;
247 }
const char * ast_var_value(const struct ast_var_t *var)
Definition: chanvars.c:89
const char * ast_var_name(const struct ast_var_t *var)
Definition: chanvars.c:69
struct ast_cdr * next
Definition: cdr.h:132
struct varshead varshead
Definition: cdr.h:130
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
static const char name[]
int ast_cdr_init ( struct ast_cdr cdr,
struct ast_channel chan 
)

Initialize based on a channel.

Parameters
cdrCall Detail Record to use for channel
chanChannel to bind CDR with Initializes a CDR and associates it with a particular channel
Note
The channel should be locked before calling.
Returns
0 by default

Definition at line 897 of file cdr.c.

References ast_channel::_state, ast_cdr::accountcode, ast_channel::accountcode, ast_cdr::amaflags, ast_channel::amaflags, AST_CDR_ANSWERED, AST_CDR_FLAG_LOCKED, AST_CDR_NOANSWER, ast_copy_string(), ast_default_amaflags, AST_STATE_UP, ast_test_flag, cdr_seq_inc(), ast_cdr::channel, ast_channel::context, ast_cdr::dcontext, ast_cdr::disposition, ast_cdr::dst, ast_channel::exten, ast_cdr::linkedid, ast_channel::linkedid, ast_channel::macrocontext, ast_channel::macroexten, ast_channel::name, ast_cdr::next, ast_cdr::peeraccount, ast_channel::peeraccount, S_OR, set_one_cid(), ast_cdr::uniqueid, and ast_channel::uniqueid.

Referenced by __ast_channel_alloc_ap(), __ast_request_and_dial(), ast_pbx_outgoing_cdr_failed(), builtin_blindtransfer(), clear_caller(), findmeexec(), and try_calling().

898 {
899  for ( ; cdr ; cdr = cdr->next) {
900  if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
901  ast_copy_string(cdr->channel, c->name, sizeof(cdr->channel));
902  set_one_cid(cdr, c);
903  cdr_seq_inc(cdr);
904 
907  ast_copy_string(cdr->accountcode, c->accountcode, sizeof(cdr->accountcode));
908  ast_copy_string(cdr->peeraccount, c->peeraccount, sizeof(cdr->peeraccount));
909  /* Destination information */
910  ast_copy_string(cdr->dst, S_OR(c->macroexten,c->exten), sizeof(cdr->dst));
911  ast_copy_string(cdr->dcontext, S_OR(c->macrocontext,c->context), sizeof(cdr->dcontext));
912  /* Unique call identifier */
913  ast_copy_string(cdr->uniqueid, c->uniqueid, sizeof(cdr->uniqueid));
914  /* Linked call identifier */
915  ast_copy_string(cdr->linkedid, c->linkedid, sizeof(cdr->linkedid));
916  }
917  }
918  return 0;
919 }
static void set_one_cid(struct ast_cdr *cdr, struct ast_channel *c)
Definition: cdr.c:859
const ast_string_field peeraccount
Definition: channel.h:787
char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: cdr.h:114
const ast_string_field uniqueid
Definition: channel.h:787
#define ast_test_flag(p, flag)
Definition: utils.h:63
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
struct ast_cdr * next
Definition: cdr.h:132
static int cdr_seq_inc(struct ast_cdr *cdr)
Definition: cdr.c:892
char dcontext[AST_MAX_EXTENSION]
Definition: cdr.h:90
char uniqueid[150]
Definition: cdr.h:121
int ast_default_amaflags
Definition: cdr.c:59
const ast_string_field linkedid
Definition: channel.h:787
long int amaflags
Definition: cdr.h:112
char linkedid[32]
Definition: cdr.h:123
char dst[AST_MAX_EXTENSION]
Definition: cdr.h:88
char channel[AST_MAX_EXTENSION]
Definition: cdr.h:92
enum ast_channel_state _state
Definition: channel.h:839
const ast_string_field name
Definition: channel.h:787
char macrocontext[AST_MAX_CONTEXT]
Definition: channel.h:870
char peeraccount[AST_MAX_ACCOUNT_CODE]
Definition: cdr.h:116
char macroexten[AST_MAX_EXTENSION]
Definition: channel.h:871
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
const ast_string_field accountcode
Definition: channel.h:787
long int disposition
Definition: cdr.h:110
int amaflags
Definition: channel.h:843
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
int ast_cdr_isset_unanswered ( void  )

Definition at line 185 of file cdr.c.

References unanswered.

Referenced by ring_entry(), and try_calling().

186 {
187  return unanswered;
188 }
static int unanswered
Definition: cdr.c:97
void ast_cdr_merge ( struct ast_cdr to,
struct ast_cdr from 
)

Move the non-null data from the "from" cdr to the "to" cdr.

Parameters
tothe cdr to get the goodies
fromthe cdr to give the goodies

Definition at line 543 of file cdr.c.

References ast_cdr::accountcode, ast_cdr::amaflags, ast_cdr::answer, ast_cdr_append(), ast_cdr_discard(), AST_CDR_DOCUMENTATION, ast_cdr_dup(), AST_CDR_FLAG_CHILD, AST_CDR_FLAG_KEEP_VARS, AST_CDR_FLAG_LOCKED, AST_CDR_FLAG_POST_DISABLED, AST_CDR_FLAG_POSTED, AST_CDR_NOANSWER, ast_copy_string(), ast_log(), ast_set_flag, ast_strlen_zero(), ast_test_flag, ast_tv(), ast_tvcmp(), ast_tvzero(), ast_cdr::billsec, cdr_merge_vars(), 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, LOG_WARNING, ast_cdr::next, ast_cdr::peeraccount, ast_cdr::src, ast_cdr::start, and ast_cdr::userfield.

544 {
545  struct ast_cdr *zcdr;
546  struct ast_cdr *lto = NULL;
547  struct ast_cdr *lfrom = NULL;
548  int discard_from = 0;
549 
550  if (!to || !from)
551  return;
552 
553  /* don't merge into locked CDR's -- it's bad business */
555  zcdr = to; /* safety valve? */
556  while (to->next) {
557  lto = to;
558  to = to->next;
559  }
560 
562  ast_log(LOG_WARNING, "Merging into locked CDR... no choice.\n");
563  to = zcdr; /* safety-- if all there are is locked CDR's, then.... ?? */
564  lto = NULL;
565  }
566  }
567 
568  if (ast_test_flag(from, AST_CDR_FLAG_LOCKED)) {
569  struct ast_cdr *llfrom = NULL;
570  discard_from = 1;
571  if (lto) {
572  /* insert the from stuff after lto */
573  lto->next = from;
574  lfrom = from;
575  while (lfrom && lfrom->next) {
576  if (!lfrom->next->next)
577  llfrom = lfrom;
578  lfrom = lfrom->next;
579  }
580  /* rip off the last entry and put a copy of the to at the end */
581  if (llfrom) {
582  llfrom->next = to;
583  }
584  from = lfrom;
585  } else {
586  /* save copy of the current *to cdr */
587  struct ast_cdr tcdr;
588  memcpy(&tcdr, to, sizeof(tcdr));
589  /* copy in the locked from cdr */
590  memcpy(to, from, sizeof(*to));
591  lfrom = from;
592  while (lfrom && lfrom->next) {
593  if (!lfrom->next->next)
594  llfrom = lfrom;
595  lfrom = lfrom->next;
596  }
597  from->next = NULL;
598  /* rip off the last entry and put a copy of the to at the end */
599  if (llfrom == from) {
600  to = to->next = ast_cdr_dup(&tcdr);
601  } else if (llfrom) {
602  to = llfrom->next = ast_cdr_dup(&tcdr);
603  }
604  from = lfrom;
605  }
606  }
607 
608  if (!ast_tvzero(from->start)) {
609  if (!ast_tvzero(to->start)) {
610  if (ast_tvcmp(to->start, from->start) > 0 ) {
611  to->start = from->start; /* use the earliest time */
612  from->start = ast_tv(0,0); /* we actively "steal" these values */
613  }
614  /* else nothing to do */
615  } else {
616  to->start = from->start;
617  from->start = ast_tv(0,0); /* we actively "steal" these values */
618  }
619  }
620  if (!ast_tvzero(from->answer)) {
621  if (!ast_tvzero(to->answer)) {
622  if (ast_tvcmp(to->answer, from->answer) > 0 ) {
623  to->answer = from->answer; /* use the earliest time */
624  from->answer = ast_tv(0,0); /* we actively "steal" these values */
625  }
626  /* we got the earliest answer time, so we'll settle for that? */
627  } else {
628  to->answer = from->answer;
629  from->answer = ast_tv(0,0); /* we actively "steal" these values */
630  }
631  }
632  if (!ast_tvzero(from->end)) {
633  if (!ast_tvzero(to->end)) {
634  if (ast_tvcmp(to->end, from->end) < 0 ) {
635  to->end = from->end; /* use the latest time */
636  from->end = ast_tv(0,0); /* we actively "steal" these values */
637  to->duration = to->end.tv_sec - to->start.tv_sec; /* don't forget to update the duration, billsec, when we set end */
638  to->billsec = ast_tvzero(to->answer) ? 0 : to->end.tv_sec - to->answer.tv_sec;
639  }
640  /* else, nothing to do */
641  } else {
642  to->end = from->end;
643  from->end = ast_tv(0,0); /* we actively "steal" these values */
644  to->duration = to->end.tv_sec - to->start.tv_sec;
645  to->billsec = ast_tvzero(to->answer) ? 0 : to->end.tv_sec - to->answer.tv_sec;
646  }
647  }
648  if (to->disposition < from->disposition) {
649  to->disposition = from->disposition;
651  }
652  if (ast_strlen_zero(to->lastapp) && !ast_strlen_zero(from->lastapp)) {
653  ast_copy_string(to->lastapp, from->lastapp, sizeof(to->lastapp));
654  from->lastapp[0] = 0; /* theft */
655  }
656  if (ast_strlen_zero(to->lastdata) && !ast_strlen_zero(from->lastdata)) {
657  ast_copy_string(to->lastdata, from->lastdata, sizeof(to->lastdata));
658  from->lastdata[0] = 0; /* theft */
659  }
660  if (ast_strlen_zero(to->dcontext) && !ast_strlen_zero(from->dcontext)) {
661  ast_copy_string(to->dcontext, from->dcontext, sizeof(to->dcontext));
662  from->dcontext[0] = 0; /* theft */
663  }
665  ast_copy_string(to->dstchannel, from->dstchannel, sizeof(to->dstchannel));
666  from->dstchannel[0] = 0; /* theft */
667  }
668  if (!ast_strlen_zero(from->channel) && (ast_strlen_zero(to->channel) || !strncasecmp(from->channel, "Agent/", 6))) {
669  ast_copy_string(to->channel, from->channel, sizeof(to->channel));
670  from->channel[0] = 0; /* theft */
671  }
672  if (ast_strlen_zero(to->src) && !ast_strlen_zero(from->src)) {
673  ast_copy_string(to->src, from->src, sizeof(to->src));
674  from->src[0] = 0; /* theft */
675  }
676  if (ast_strlen_zero(to->clid) && !ast_strlen_zero(from->clid)) {
677  ast_copy_string(to->clid, from->clid, sizeof(to->clid));
678  from->clid[0] = 0; /* theft */
679  }
680  if (ast_strlen_zero(to->dst) && !ast_strlen_zero(from->dst)) {
681  ast_copy_string(to->dst, from->dst, sizeof(to->dst));
682  from->dst[0] = 0; /* theft */
683  }
684  if (!to->amaflags)
686  if (!from->amaflags)
687  from->amaflags = AST_CDR_DOCUMENTATION; /* make sure both amaflags are set to something (DOC is default) */
689  to->amaflags = from->amaflags;
690  }
692  ast_copy_string(to->accountcode, from->accountcode, sizeof(to->accountcode));
693  }
695  ast_copy_string(to->peeraccount, from->peeraccount, sizeof(to->peeraccount));
696  }
698  ast_copy_string(to->userfield, from->userfield, sizeof(to->userfield));
699  }
700  /* flags, varsead, ? */
701  cdr_merge_vars(from, to);
702 
713 
714  /* last, but not least, we need to merge any forked CDRs to the 'to' cdr */
715  while (from->next) {
716  /* just rip 'em off the 'from' and insert them on the 'to' */
717  zcdr = from->next;
718  from->next = zcdr->next;
719  zcdr->next = NULL;
720  /* zcdr is now ripped from the current list; */
721  ast_cdr_append(to, zcdr);
722  }
723  if (discard_from)
724  ast_cdr_discard(from);
725 }
char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: cdr.h:114
char dstchannel[AST_MAX_EXTENSION]
Definition: cdr.h:94
#define ast_test_flag(p, flag)
Definition: utils.h:63
long int billsec
Definition: cdr.h:108
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define LOG_WARNING
Definition: logger.h:144
struct ast_cdr * next
Definition: cdr.h:132
char dcontext[AST_MAX_EXTENSION]
Definition: cdr.h:90
struct ast_cdr * ast_cdr_dup(struct ast_cdr *cdr)
Duplicate a record.
Definition: cdr.c:213
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:100
char lastdata[AST_MAX_EXTENSION]
Definition: cdr.h:98
struct ast_cdr * ast_cdr_append(struct ast_cdr *cdr, struct ast_cdr *newcdr)
Definition: cdr.c:1216
long int amaflags
Definition: cdr.h:112
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char dst[AST_MAX_EXTENSION]
Definition: cdr.h:88
char channel[AST_MAX_EXTENSION]
Definition: cdr.h:92
struct timeval answer
Definition: cdr.h:102
Responsible for call detail data.
Definition: cdr.h:82
char lastapp[AST_MAX_EXTENSION]
Definition: cdr.h:96
int ast_tvcmp(struct timeval _a, struct timeval _b)
Compres two struct timeval instances returning -1, 0, 1 if the first arg is smaller, equal or greater to the second.
Definition: time.h:120
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
struct timeval start
Definition: cdr.h:100
long int duration
Definition: cdr.h:106
char src[AST_MAX_EXTENSION]
Definition: cdr.h:86
char peeraccount[AST_MAX_ACCOUNT_CODE]
Definition: cdr.h:116
void ast_cdr_discard(struct ast_cdr *cdr)
Discard and free a CDR record.
Definition: cdr.c:488
struct timeval end
Definition: cdr.h:104
static void cdr_merge_vars(struct ast_cdr *to, struct ast_cdr *from)
Definition: cdr.c:508
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition: time.h:179
long int disposition
Definition: cdr.h:110
char clid[AST_MAX_EXTENSION]
Definition: cdr.h:84
char userfield[AST_MAX_USER_FIELD]
Definition: cdr.h:125
void ast_cdr_noanswer ( struct ast_cdr cdr)

A call wasn't answered.

Parameters
cdrthe cdr you wish to associate with the call Marks the channel disposition as "NO ANSWER" Will skip CDR's in chain with ANS_LOCK bit set. (see forkCDR() application.

Definition at line 776 of file cdr.c.

References AST_CDR_FLAG_LOCKED, AST_CDR_NOANSWER, ast_test_flag, check_post(), ast_cdr::disposition, and ast_cdr::next.

Referenced by ast_cdr_disposition(), handle_cause(), and wait_for_answer().

777 {
778  while (cdr) {
779  if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
780  check_post(cdr);
782  }
783  cdr = cdr->next;
784  }
785 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_cdr * next
Definition: cdr.h:132
static void check_post(struct ast_cdr *cdr)
print a warning if cdr already posted
Definition: cdr.c:467
long int disposition
Definition: cdr.h:110
int ast_cdr_register ( const char *  name,
const char *  desc,
ast_cdrbe  be 
)

Register a CDR driver. Each registered CDR driver generates a CDR.

Register a CDR handling engine.

Return values
0on success.
-1on error

Definition at line 130 of file cdr.c.

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

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

131 {
132  struct ast_cdr_beitem *i = NULL;
133 
134  if (!name)
135  return -1;
136 
137  if (!be) {
138  ast_log(LOG_WARNING, "CDR engine '%s' lacks backend\n", name);
139  return -1;
140  }
141 
143  AST_RWLIST_TRAVERSE(&be_list, i, list) {
144  if (!strcasecmp(name, i->name)) {
145  ast_log(LOG_WARNING, "Already have a CDR backend called '%s'\n", name);
147  return -1;
148  }
149  }
150 
151  if (!(i = ast_calloc(1, sizeof(*i))))
152  return -1;
153 
154  i->be = be;
155  ast_copy_string(i->name, name, sizeof(i->name));
156  ast_copy_string(i->desc, desc, sizeof(i->desc));
157 
158  AST_RWLIST_INSERT_HEAD(&be_list, i, list);
160 
161  return 0;
162 }
ast_cdrbe be
Definition: cdr.c:65
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define LOG_WARNING
Definition: logger.h:144
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
char desc[80]
Definition: cdr.c:64
#define AST_RWLIST_INSERT_HEAD
Definition: linkedlists.h:703
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
static const char desc[]
Definition: cdr_radius.c:85
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static const char name[]
char name[20]
Definition: cdr.c:63
#define ast_calloc(a, b)
Definition: astmm.h:82
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
Definition: cdr.c:69
void ast_cdr_reset ( struct ast_cdr cdr,
struct ast_flags flags 
)

Reset the detail record, optionally posting it first.

Parameters
cdrwhich cdr to act upon
flags|AST_CDR_FLAG_POSTED whether or not to post the cdr first before resetting it |AST_CDR_FLAG_LOCKED whether or not to reset locked CDR's

Definition at line 1149 of file cdr.c.

References ast_cdr::answer, ast_cdr_detach(), ast_cdr_dup_unique_swap(), ast_cdr_end(), AST_CDR_FLAG_KEEP_VARS, AST_CDR_FLAG_LOCKED, AST_CDR_FLAG_POST_DISABLED, AST_CDR_FLAG_POST_ENABLE, AST_CDR_FLAG_POSTED, ast_cdr_free_vars(), AST_CDR_NOANSWER, ast_cdr_start(), ast_clear_flag, ast_copy_flags, AST_FLAGS_ALL, ast_set_flag, ast_test_flag, ast_cdr::billsec, ast_cdr::disposition, ast_cdr::duration, ast_cdr::end, ast_cdr::next, and ast_cdr::start.

Referenced by ast_cdr_fork(), dial_exec_full(), disa_exec(), pbx_builtin_resetcdr(), and try_calling().

1150 {
1151  struct ast_cdr *duplicate;
1152  struct ast_flags flags = { 0 };
1153 
1154  if (_flags)
1155  ast_copy_flags(&flags, _flags, AST_FLAGS_ALL);
1156 
1157  for ( ; cdr ; cdr = cdr->next) {
1158  /* Detach if post is requested */
1160  if (ast_test_flag(&flags, AST_CDR_FLAG_POSTED)) {
1161  ast_cdr_end(cdr);
1162  if ((duplicate = ast_cdr_dup_unique_swap(cdr))) {
1163  ast_cdr_detach(duplicate);
1164  }
1166  }
1167 
1168  /* enable CDR only */
1169  if (ast_test_flag(&flags, AST_CDR_FLAG_POST_ENABLE)) {
1171  continue;
1172  }
1173 
1174  /* clear variables */
1175  if (!ast_test_flag(&flags, AST_CDR_FLAG_KEEP_VARS)) {
1176  ast_cdr_free_vars(cdr, 0);
1177  }
1178 
1179  /* Reset to initial state */
1181  memset(&cdr->start, 0, sizeof(cdr->start));
1182  memset(&cdr->end, 0, sizeof(cdr->end));
1183  memset(&cdr->answer, 0, sizeof(cdr->answer));
1184  cdr->billsec = 0;
1185  cdr->duration = 0;
1186  ast_cdr_start(cdr);
1188  }
1189  }
1190 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
void ast_cdr_end(struct ast_cdr *cdr)
End a call.
Definition: cdr.c:933
long int billsec
Definition: cdr.h:108
#define ast_set_flag(p, flag)
Definition: utils.h:70
struct ast_cdr * next
Definition: cdr.h:132
unsigned int flags
Definition: utils.h:201
#define ast_copy_flags(dest, src, flagz)
Definition: utils.h:84
struct ast_cdr * ast_cdr_dup_unique_swap(struct ast_cdr *cdr)
Duplicate a record and increment the sequence number of the old record.
Definition: cdr.c:200
struct timeval answer
Definition: cdr.h:102
Responsible for call detail data.
Definition: cdr.h:82
void ast_cdr_start(struct ast_cdr *cdr)
Start a call.
Definition: cdr.c:727
void ast_cdr_detach(struct ast_cdr *cdr)
Detaches the detail record for posting (and freeing) either now or at a later time in bulk with other...
Definition: cdr.c:1328
struct timeval start
Definition: cdr.h:100
#define AST_FLAGS_ALL
Definition: utils.h:196
long int duration
Definition: cdr.h:106
Structure used to handle boolean flags.
Definition: utils.h:200
#define ast_clear_flag(p, flag)
Definition: utils.h:77
struct timeval end
Definition: cdr.h:104
long int disposition
Definition: cdr.h:110
void ast_cdr_free_vars(struct ast_cdr *cdr, int recur)
Definition: cdr.c:454
int ast_cdr_serialize_variables ( struct ast_cdr cdr,
struct ast_str **  buf,
char  delim,
char  sep,
int  recur 
)

Definition at line 409 of file cdr.c.

References ast_cdr_getvar(), AST_LIST_TRAVERSE, ast_log(), ast_str_append(), ast_str_reset(), ast_var_name(), ast_var_value(), cdr_readonly_vars, ast_var_t::entries, LOG_ERROR, ast_cdr::next, S_OR, total, var, and ast_cdr::varshead.

Referenced by handle_showchan().

410 {
411  struct ast_var_t *variables;
412  const char *var;
413  char *tmp;
414  char workspace[256];
415  int total = 0, x = 0, i;
416 
417  ast_str_reset(*buf);
418 
419  for (; cdr; cdr = recur ? cdr->next : NULL) {
420  if (++x > 1)
421  ast_str_append(buf, 0, "\n");
422 
423  AST_LIST_TRAVERSE(&cdr->varshead, variables, entries) {
424  if (!(var = ast_var_name(variables))) {
425  continue;
426  }
427 
428  if (ast_str_append(buf, 0, "level %d: %s%c%s%c", x, var, delim, S_OR(ast_var_value(variables), ""), sep) < 0) {
429  ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
430  break;
431  }
432 
433  total++;
434  }
435 
436  for (i = 0; cdr_readonly_vars[i]; i++) {
437  workspace[0] = 0; /* null out the workspace, because the cdr_get_tv() won't write anything if time is NULL, so you get old vals */
438  ast_cdr_getvar(cdr, cdr_readonly_vars[i], &tmp, workspace, sizeof(workspace), 0, 0);
439  if (!tmp)
440  continue;
441 
442  if (ast_str_append(buf, 0, "level %d: %s%c%s%c", x, cdr_readonly_vars[i], delim, tmp, sep) < 0) {
443  ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
444  break;
445  } else
446  total++;
447  }
448  }
449 
450  return total;
451 }
const char * ast_var_value(const struct ast_var_t *var)
Definition: chanvars.c:89
const char * ast_var_name(const struct ast_var_t *var)
Definition: chanvars.c:69
struct ast_cdr * next
Definition: cdr.h:132
#define var
Definition: ast_expr2f.c:606
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:900
struct varshead varshead
Definition: cdr.h:130
void ast_cdr_getvar(struct ast_cdr *cdr, const char *name, char **ret, char *workspace, int workspacelen, int recur, int raw)
Definition: cdr.c:264
static const char *const cdr_readonly_vars[]
Definition: cdr.c:336
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
struct ast_var_t::@158 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:436
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
static int total
Definition: res_adsi.c:967
int ast_cdr_setaccount ( struct ast_channel chan,
const char *  account 
)

Set account code, will generate AMI event.

Note
The channel should be locked before calling.

Definition at line 990 of file cdr.c.

References ast_cdr::accountcode, accountcode, ast_channel::accountcode, AST_CDR_FLAG_LOCKED, ast_copy_string(), ast_manager_event, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_channel::cdr, EVENT_FLAG_CALL, ast_channel::name, ast_cdr::next, and ast_channel::uniqueid.

Referenced by __ast_request_and_dial(), ast_bridge_call(), ast_call_forward(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), auth_exec(), and cdr_write().

991 {
992  struct ast_cdr *cdr = chan->cdr;
993  const char *old_acct = "";
994 
995  if (!ast_strlen_zero(chan->accountcode)) {
996  old_acct = ast_strdupa(chan->accountcode);
997  }
998 
999  ast_string_field_set(chan, accountcode, account);
1000  for ( ; cdr ; cdr = cdr->next) {
1001  if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
1002  ast_copy_string(cdr->accountcode, chan->accountcode, sizeof(cdr->accountcode));
1003  }
1004  }
1005 
1006  ast_manager_event(chan, EVENT_FLAG_CALL, "NewAccountCode",
1007  "Channel: %s\r\n"
1008  "Uniqueid: %s\r\n"
1009  "AccountCode: %s\r\n"
1010  "OldAccountCode: %s\r\n",
1011  chan->name, chan->uniqueid, chan->accountcode, old_acct);
1012 
1013  return 0;
1014 }
static char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: chan_iax2.c:383
char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: cdr.h:114
const ast_string_field uniqueid
Definition: channel.h:787
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_cdr * next
Definition: cdr.h:132
#define EVENT_FLAG_CALL
Definition: manager.h:72
struct ast_cdr * cdr
Definition: channel.h:766
#define ast_manager_event(chan, category, event, contents,...)
Definition: manager.h:221
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
Responsible for call detail data.
Definition: cdr.h:82
const ast_string_field name
Definition: channel.h:787
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
const ast_string_field accountcode
Definition: channel.h:787
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:344
int ast_cdr_setamaflags ( struct ast_channel chan,
const char *  amaflags 
)

Set AMA flags for channel.

Note
The channel should be locked before calling.

Definition at line 1042 of file cdr.c.

References ast_cdr::amaflags, ast_cdr_amaflags2int(), AST_CDR_FLAG_LOCKED, ast_test_flag, ast_channel::cdr, and ast_cdr::next.

Referenced by cdr_write(), and pbx_builtin_setamaflags().

1043 {
1044  struct ast_cdr *cdr;
1045  int newflag = ast_cdr_amaflags2int(flag);
1046  if (newflag) {
1047  for (cdr = chan->cdr; cdr; cdr = cdr->next) {
1048  if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
1049  cdr->amaflags = newflag;
1050  }
1051  }
1052  }
1053 
1054  return 0;
1055 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_cdr * next
Definition: cdr.h:132
struct ast_cdr * cdr
Definition: channel.h:766
long int amaflags
Definition: cdr.h:112
Responsible for call detail data.
Definition: cdr.h:82
int ast_cdr_amaflags2int(const char *flag)
Convert a string to a detail record AMA flag.
Definition: cdr.c:1105
void ast_cdr_setanswer ( struct ast_cdr cdr,
struct timeval  t 
)

Set the answer time for a call.

Parameters
cdrthe cdr you wish to associate with the call
tthe answer time Starts all CDR stuff necessary for doing CDR when answering a call NULL argument is just fine.

Definition at line 834 of file cdr.c.

References ast_cdr::answer, AST_CDR_FLAG_ANSLOCKED, AST_CDR_FLAG_DONT_TOUCH, AST_CDR_FLAG_LOCKED, ast_test_flag, check_post(), and ast_cdr::next.

Referenced by ast_bridge_call(), and dial_exec_full().

835 {
836 
837  for (; cdr; cdr = cdr->next) {
839  continue;
841  continue;
842  check_post(cdr);
843  cdr->answer = t;
844  }
845 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_cdr * next
Definition: cdr.h:132
static void check_post(struct ast_cdr *cdr)
print a warning if cdr already posted
Definition: cdr.c:467
struct timeval answer
Definition: cdr.h:102
void ast_cdr_setapp ( struct ast_cdr cdr,
const char *  app,
const char *  data 
)

Set the last executed application.

Parameters
cdrwhich cdr to act upon
appthe name of the app you wish to change it to
datathe data you want in the data field of app you set it to Changes the value of the last executed app Returns nothing

Definition at line 822 of file cdr.c.

References AST_CDR_FLAG_LOCKED, ast_copy_string(), ast_test_flag, check_post(), ast_cdr::lastapp, ast_cdr::lastdata, ast_cdr::next, and S_OR.

Referenced by __ast_request_and_dial(), agi_handle_command(), clear_caller(), findmeexec(), and pbx_exec().

823 {
824 
825  for (; cdr; cdr = cdr->next) {
826  if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
827  check_post(cdr);
828  ast_copy_string(cdr->lastapp, S_OR(app, ""), sizeof(cdr->lastapp));
829  ast_copy_string(cdr->lastdata, S_OR(data, ""), sizeof(cdr->lastdata));
830  }
831  }
832 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_cdr * next
Definition: cdr.h:132
char lastdata[AST_MAX_EXTENSION]
Definition: cdr.h:98
static const char app[]
Definition: app_adsiprog.c:49
static void check_post(struct ast_cdr *cdr)
print a warning if cdr already posted
Definition: cdr.c:467
char lastapp[AST_MAX_EXTENSION]
Definition: cdr.h:96
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
int ast_cdr_setcid ( struct ast_cdr cdr,
struct ast_channel chan 
)

Initialize based on a channel.

Parameters
cdrCall Detail Record to use for channel
chanChannel to bind CDR with Initializes a CDR and associates it with a particular channel
Note
The channel should be locked before calling.
Returns
0 by default

Definition at line 883 of file cdr.c.

References AST_CDR_FLAG_LOCKED, ast_test_flag, ast_cdr::next, and set_one_cid().

Referenced by ast_bridge_call(), ast_channel_set_caller_event(), ast_set_callerid(), and callerid_write().

884 {
885  for (; cdr; cdr = cdr->next) {
887  set_one_cid(cdr, c);
888  }
889  return 0;
890 }
static void set_one_cid(struct ast_cdr *cdr, struct ast_channel *c)
Definition: cdr.c:859
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_cdr * next
Definition: cdr.h:132
void ast_cdr_setdestchan ( struct ast_cdr cdr,
const char *  chan 
)

Set the destination channel, if there was one.

Parameters
cdrWhich cdr it's applied to
chanChannel to which dest will be Sets the destination channel the CDR is applied to Returns nothing

Definition at line 812 of file cdr.c.

References AST_CDR_FLAG_LOCKED, ast_copy_string(), ast_test_flag, check_post(), ast_cdr::dstchannel, and ast_cdr::next.

Referenced by dial_exec_full(), parked_call_exec(), ring_entry(), and try_calling().

813 {
814  for (; cdr; cdr = cdr->next) {
815  if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
816  check_post(cdr);
817  ast_copy_string(cdr->dstchannel, chann, sizeof(cdr->dstchannel));
818  }
819  }
820 }
char dstchannel[AST_MAX_EXTENSION]
Definition: cdr.h:94
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_cdr * next
Definition: cdr.h:132
static void check_post(struct ast_cdr *cdr)
print a warning if cdr already posted
Definition: cdr.c:467
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
void ast_cdr_setdisposition ( struct ast_cdr cdr,
long int  disposition 
)

Set the disposition for a call.

Parameters
cdrthe cdr you wish to associate with the call
dispositionthe new disposition Set the disposition on a call. NULL argument is just fine.

Definition at line 847 of file cdr.c.

References AST_CDR_FLAG_LOCKED, ast_test_flag, check_post(), ast_cdr::disposition, and ast_cdr::next.

Referenced by ast_bridge_call().

848 {
849 
850  for (; cdr; cdr = cdr->next) {
852  continue;
853  check_post(cdr);
854  cdr->disposition = disposition;
855  }
856 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_cdr * next
Definition: cdr.h:132
static void check_post(struct ast_cdr *cdr)
print a warning if cdr already posted
Definition: cdr.c:467
long int disposition
Definition: cdr.h:110
int ast_cdr_setpeeraccount ( struct ast_channel chan,
const char *  account 
)

Set the peer account.

Note
The channel should be locked before calling.

Definition at line 1016 of file cdr.c.

References AST_CDR_FLAG_LOCKED, ast_copy_string(), ast_manager_event, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_channel::cdr, EVENT_FLAG_CALL, ast_channel::name, ast_cdr::next, ast_cdr::peeraccount, ast_channel::peeraccount, and ast_channel::uniqueid.

Referenced by cdr_write().

1017 {
1018  struct ast_cdr *cdr = chan->cdr;
1019  const char *old_acct = "";
1020 
1021  if (!ast_strlen_zero(chan->peeraccount)) {
1022  old_acct = ast_strdupa(chan->peeraccount);
1023  }
1024 
1025  ast_string_field_set(chan, peeraccount, account);
1026  for ( ; cdr ; cdr = cdr->next) {
1027  if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
1028  ast_copy_string(cdr->peeraccount, chan->peeraccount, sizeof(cdr->peeraccount));
1029  }
1030  }
1031 
1032  ast_manager_event(chan, EVENT_FLAG_CALL, "NewPeerAccount",
1033  "Channel: %s\r\n"
1034  "Uniqueid: %s\r\n"
1035  "PeerAccount: %s\r\n"
1036  "OldPeerAccount: %s\r\n",
1037  chan->name, chan->uniqueid, chan->peeraccount, old_acct);
1038 
1039  return 0;
1040 }
const ast_string_field peeraccount
Definition: channel.h:787
const ast_string_field uniqueid
Definition: channel.h:787
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_cdr * next
Definition: cdr.h:132
#define EVENT_FLAG_CALL
Definition: manager.h:72
struct ast_cdr * cdr
Definition: channel.h:766
#define ast_manager_event(chan, category, event, contents,...)
Definition: manager.h:221
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
Responsible for call detail data.
Definition: cdr.h:82
const ast_string_field name
Definition: channel.h:787
char peeraccount[AST_MAX_ACCOUNT_CODE]
Definition: cdr.h:116
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:344
int ast_cdr_setuserfield ( struct ast_channel chan,
const char *  userfield 
)

Set CDR user field for channel (stored in CDR)

Note
The channel should be locked before calling.

Definition at line 1057 of file cdr.c.

References AST_CDR_FLAG_LOCKED, ast_copy_string(), ast_test_flag, ast_channel::cdr, ast_cdr::next, and ast_cdr::userfield.

Referenced by __agent_start_monitoring(), ast_bridge_call(), cdr_write(), handle_request_info(), and start_monitor_exec().

1058 {
1059  struct ast_cdr *cdr = chan->cdr;
1060 
1061  for ( ; cdr ; cdr = cdr->next) {
1063  ast_copy_string(cdr->userfield, userfield, sizeof(cdr->userfield));
1064  }
1065 
1066  return 0;
1067 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_cdr * next
Definition: cdr.h:132
struct ast_cdr * cdr
Definition: channel.h:766
Responsible for call detail data.
Definition: cdr.h:82
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
char userfield[AST_MAX_USER_FIELD]
Definition: cdr.h:125
int ast_cdr_setvar ( struct ast_cdr cdr,
const char *  name,
const char *  value,
int  recur 
)

Set a CDR channel variable

Note
You can't set the CDR variables that belong to the actual CDR record, like "billsec".

Definition at line 343 of file cdr.c.

References AST_CDR_FLAG_DONT_TOUCH, AST_CDR_FLAG_LOCKED, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), ast_test_flag, ast_var_assign(), ast_var_delete(), ast_var_name(), cdr_readonly_vars, LOG_ERROR, ast_cdr::next, and ast_cdr::varshead.

Referenced by ast_cdr_fork(), cdr_write(), and set_one_cid().

344 {
345  struct ast_var_t *newvariable;
346  struct varshead *headp;
347  int x;
348 
349  for (x = 0; cdr_readonly_vars[x]; x++) {
350  if (!strcasecmp(name, cdr_readonly_vars[x])) {
351  ast_log(LOG_ERROR, "Attempt to set the '%s' read-only variable!.\n", name);
352  return -1;
353  }
354  }
355 
356  if (!cdr) {
357  ast_log(LOG_ERROR, "Attempt to set a variable on a nonexistent CDR record.\n");
358  return -1;
359  }
360 
361  for (; cdr; cdr = recur ? cdr->next : NULL) {
363  continue;
364  headp = &cdr->varshead;
365  AST_LIST_TRAVERSE_SAFE_BEGIN(headp, newvariable, entries) {
366  if (!strcasecmp(ast_var_name(newvariable), name)) {
367  /* there is already such a variable, delete it */
368  AST_LIST_REMOVE_CURRENT(entries);
369  ast_var_delete(newvariable);
370  break;
371  }
372  }
374 
375  if (value && (newvariable = ast_var_assign(name, value))) {
376  AST_LIST_INSERT_HEAD(headp, newvariable, entries);
377  }
378  }
379 
380  return 0;
381 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_var_t * ast_var_assign(const char *name, const char *value)
Definition: chanvars.c:41
const char * ast_var_name(const struct ast_var_t *var)
Definition: chanvars.c:69
struct ast_cdr * next
Definition: cdr.h:132
int value
Definition: syslog.c:39
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:600
void ast_var_delete(struct ast_var_t *var)
Definition: chanvars.c:63
struct varshead varshead
Definition: cdr.h:130
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:554
static const char *const cdr_readonly_vars[]
Definition: cdr.c:336
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:696
static const char name[]
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
void ast_cdr_specialized_reset ( struct ast_cdr cdr,
struct ast_flags flags 
)

Reset the detail record times, flags

Parameters
cdrwhich cdr to act upon
flags|AST_CDR_FLAG_POSTED whether or not to post the cdr first before resetting it |AST_CDR_FLAG_LOCKED whether or not to reset locked CDR's

Definition at line 1192 of file cdr.c.

References ast_cdr::answer, AST_CDR_FLAG_POST_DISABLED, AST_CDR_NULL, ast_cdr_start(), ast_clear_flag, ast_copy_flags, AST_FLAGS_ALL, ast_set_flag, ast_test_flag, ast_cdr::billsec, ast_cdr::disposition, ast_cdr::duration, ast_cdr::end, and ast_cdr::start.

Referenced by ast_bridge_call().

1193 {
1194  struct ast_flags flags = { 0 };
1195 
1196  if (_flags)
1197  ast_copy_flags(&flags, _flags, AST_FLAGS_ALL);
1198 
1199  /* Reset to initial state */
1200  if (ast_test_flag(cdr, AST_CDR_FLAG_POST_DISABLED)) { /* But do NOT lose the NoCDR() setting */
1203  } else {
1205  }
1206 
1207  memset(&cdr->start, 0, sizeof(cdr->start));
1208  memset(&cdr->end, 0, sizeof(cdr->end));
1209  memset(&cdr->answer, 0, sizeof(cdr->answer));
1210  cdr->billsec = 0;
1211  cdr->duration = 0;
1212  ast_cdr_start(cdr);
1213  cdr->disposition = AST_CDR_NULL;
1214 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
long int billsec
Definition: cdr.h:108
#define ast_set_flag(p, flag)
Definition: utils.h:70
unsigned int flags
Definition: utils.h:201
#define ast_copy_flags(dest, src, flagz)
Definition: utils.h:84
struct timeval answer
Definition: cdr.h:102
void ast_cdr_start(struct ast_cdr *cdr)
Start a call.
Definition: cdr.c:727
struct timeval start
Definition: cdr.h:100
#define AST_FLAGS_ALL
Definition: utils.h:196
long int duration
Definition: cdr.h:106
Structure used to handle boolean flags.
Definition: utils.h:200
#define ast_clear_flag(p, flag)
Definition: utils.h:77
struct timeval end
Definition: cdr.h:104
long int disposition
Definition: cdr.h:110
void ast_cdr_start ( struct ast_cdr cdr)

Start a call.

Parameters
cdrthe cdr you wish to associate with the call Starts all CDR stuff necessary for monitoring a call Returns nothing

Definition at line 727 of file cdr.c.

References AST_CDR_FLAG_LOCKED, ast_test_flag, ast_tvnow(), check_post(), ast_cdr::next, and ast_cdr::start.

Referenced by __ast_channel_alloc_ap(), __ast_request_and_dial(), ast_bridge_call(), ast_cdr_reset(), ast_cdr_specialized_reset(), ast_pbx_outgoing_cdr_failed(), builtin_blindtransfer(), clear_caller(), and findmeexec().

728 {
729  for (; cdr; cdr = cdr->next) {
730  if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
731  check_post(cdr);
732  cdr->start = ast_tvnow();
733  }
734  }
735 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_cdr * next
Definition: cdr.h:132
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
static void check_post(struct ast_cdr *cdr)
print a warning if cdr already posted
Definition: cdr.c:467
struct timeval start
Definition: cdr.h:100
void ast_cdr_submit_batch ( int  shutdown)

Spawns (possibly) a new thread to submit a batch of CDRs to the backend engines.

Parameters
shutdownWhether or not we are shutting down Blocks the asterisk shutdown procedures until the CDR data is submitted. Returns nothing

Definition at line 1270 of file cdr.c.

References ast_debug, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_pthread_create_detached_background, AST_PTHREADT_NULL, batch, batchscheduleronly, cdr_batch_lock, do_batch_backend_process(), ast_cdr_batch::head, LOG_WARNING, and reset_batch().

Referenced by ast_cdr_engine_term(), and submit_scheduled_batch().

1271 {
1272  struct ast_cdr_batch_item *oldbatchitems = NULL;
1273  pthread_t batch_post_thread = AST_PTHREADT_NULL;
1274 
1275  /* if there's no batch, or no CDRs in the batch, then there's nothing to do */
1276  if (!batch || !batch->head)
1277  return;
1278 
1279  /* move the old CDRs aside, and prepare a new CDR batch */
1281  oldbatchitems = batch->head;
1282  reset_batch();
1284 
1285  /* if configured, spawn a new thread to post these CDRs,
1286  also try to save as much as possible if we are shutting down safely */
1287  if (batchscheduleronly || do_shutdown) {
1288  ast_debug(1, "CDR single-threaded batch processing begins now\n");
1289  do_batch_backend_process(oldbatchitems);
1290  } else {
1291  if (ast_pthread_create_detached_background(&batch_post_thread, NULL, do_batch_backend_process, oldbatchitems)) {
1292  ast_log(LOG_WARNING, "CDR processing thread could not detach, now trying in this thread\n");
1293  do_batch_backend_process(oldbatchitems);
1294  } else {
1295  ast_debug(1, "CDR multi-threaded batch processing begins now\n");
1296  }
1297  }
1298 }
static void reset_batch(void)
Definition: cdr.c:1234
static void * do_batch_backend_process(void *data)
Definition: cdr.c:1253
static struct ast_cdr_batch * batch
#define LOG_WARNING
Definition: logger.h:144
static int batchscheduleronly
Definition: cdr.c:106
#define ast_mutex_lock(a)
Definition: lock.h:155
struct ast_cdr_batch_item * head
Definition: cdr.c:78
#define ast_pthread_create_detached_background(a, b, c, d)
Definition: utils.h:431
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define AST_PTHREADT_NULL
Definition: lock.h:65
static ast_mutex_t cdr_batch_lock
Definition: cdr.c:114
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_mutex_unlock(a)
Definition: lock.h:156
void ast_cdr_unregister ( const char *  name)

Unregister a CDR handling engine.

unregister a CDR driver

Definition at line 165 of file cdr.c.

References ast_free, AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, and ast_cdr_beitem::name.

Referenced by load_config(), odbc_load_module(), reload(), tds_unload_module(), and unload_module().

166 {
167  struct ast_cdr_beitem *i = NULL;
168 
171  if (!strcasecmp(name, i->name)) {
173  break;
174  }
175  }
178 
179  if (i) {
180  ast_verb(2, "Unregistered '%s' CDR backend\n", name);
181  ast_free(i);
182  }
183 }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define ast_verb(level,...)
Definition: logger.h:243
#define AST_RWLIST_REMOVE_CURRENT
Definition: linkedlists.h:565
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:542
static const char name[]
#define ast_free(a)
Definition: astmm.h:97
char name[20]
Definition: cdr.c:63
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:602
Definition: cdr.c:69
int ast_cdr_update ( struct ast_channel chan)

Update CDR on a channel.

Note
The channel should be locked before calling.

Definition at line 1083 of file cdr.c.

References ast_cdr::accountcode, ast_channel::accountcode, AST_CDR_FLAG_LOCKED, ast_copy_string(), ast_test_flag, ast_channel::cdr, ast_channel::context, ast_cdr::dcontext, ast_cdr::dst, ast_channel::exten, ast_cdr::linkedid, ast_channel::linkedid, ast_channel::macrocontext, ast_channel::macroexten, ast_cdr::next, ast_cdr::peeraccount, ast_channel::peeraccount, S_OR, and set_one_cid().

Referenced by __ast_pbx_run(), __ast_request_and_dial(), ast_bridge_call(), cb_events(), clear_caller(), findmeexec(), and local_call().

1084 {
1085  struct ast_cdr *cdr = c->cdr;
1086 
1087  for ( ; cdr ; cdr = cdr->next) {
1088  if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
1089  set_one_cid(cdr, c);
1090 
1091  /* Copy account code et-al */
1092  ast_copy_string(cdr->accountcode, c->accountcode, sizeof(cdr->accountcode));
1093  ast_copy_string(cdr->peeraccount, c->peeraccount, sizeof(cdr->peeraccount));
1094  ast_copy_string(cdr->linkedid, c->linkedid, sizeof(cdr->linkedid));
1095 
1096  /* Destination information */ /* XXX privilege macro* ? */
1097  ast_copy_string(cdr->dst, S_OR(c->macroexten, c->exten), sizeof(cdr->dst));
1098  ast_copy_string(cdr->dcontext, S_OR(c->macrocontext, c->context), sizeof(cdr->dcontext));
1099  }
1100  }
1101 
1102  return 0;
1103 }
static void set_one_cid(struct ast_cdr *cdr, struct ast_channel *c)
Definition: cdr.c:859
const ast_string_field peeraccount
Definition: channel.h:787
char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: cdr.h:114
#define ast_test_flag(p, flag)
Definition: utils.h:63
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
struct ast_cdr * next
Definition: cdr.h:132
char dcontext[AST_MAX_EXTENSION]
Definition: cdr.h:90
struct ast_cdr * cdr
Definition: channel.h:766
const ast_string_field linkedid
Definition: channel.h:787
char linkedid[32]
Definition: cdr.h:123
char dst[AST_MAX_EXTENSION]
Definition: cdr.h:88
Responsible for call detail data.
Definition: cdr.h:82
char macrocontext[AST_MAX_CONTEXT]
Definition: channel.h:870
char peeraccount[AST_MAX_ACCOUNT_CODE]
Definition: cdr.h:116
char macroexten[AST_MAX_EXTENSION]
Definition: channel.h:871
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
const ast_string_field accountcode
Definition: channel.h:787
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
static void cdr_engine_shutdown ( void  )
static

Definition at line 1627 of file cdr.c.

References ast_cli_unregister(), ast_cond_destroy, ast_free, AST_PTHREADT_NULL, batch, cdr_pending_cond, cdr_thread, cli_status, cli_submit, and sched_context_destroy().

Referenced by ast_cdr_engine_init().

1628 {
1629  if (cdr_thread != AST_PTHREADT_NULL) {
1630  /* wake up the thread so it will exit */
1631  pthread_cancel(cdr_thread);
1632  pthread_kill(cdr_thread, SIGURG);
1633  pthread_join(cdr_thread, NULL);
1636  }
1638 
1641  sched = NULL;
1642  ast_free(batch);
1643  batch = NULL;
1644 }
static struct ast_cdr_batch * batch
int ast_cli_unregister(struct ast_cli_entry *e)
Unregisters a command or an array of commands.
Definition: cli.c:2153
Definition: sched.c:57
#define AST_PTHREADT_NULL
Definition: lock.h:65
void sched_context_destroy(struct sched_context *c)
destroys a schedule context Destroys (free&#39;s) the given sched_context structure
Definition: sched.c:267
static ast_cond_t cdr_pending_cond
Definition: cdr.c:118
#define ast_cond_destroy(cond)
Definition: lock.h:168
#define ast_free(a)
Definition: astmm.h:97
static struct ast_cli_entry cli_status
Definition: cdr.c:1495
static struct ast_cli_entry cli_submit
Definition: cdr.c:1494
static pthread_t cdr_thread
Definition: cdr.c:89
static void cdr_get_tv ( struct timeval  when,
const char *  fmt,
char *  buf,
int  bufsize 
)
static

Definition at line 249 of file cdr.c.

References ast_localtime(), and ast_strftime().

Referenced by ast_cdr_getvar().

250 {
251  if (fmt == NULL) { /* raw mode */
252  snprintf(buf, bufsize, "%ld.%06ld", (long)when.tv_sec, (long)when.tv_usec);
253  } else {
254  if (when.tv_sec) {
255  struct ast_tm tm;
256 
257  ast_localtime(&when, &tm, NULL);
258  ast_strftime(buf, bufsize, fmt, &tm);
259  }
260  }
261 }
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1570
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Definition: localtime.c:2351
static void cdr_merge_vars ( struct ast_cdr to,
struct ast_cdr from 
)
static

Definition at line 508 of file cdr.c.

References AST_LIST_MOVE_CURRENT, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), ast_var_name(), ast_var_value(), LOG_NOTICE, and ast_cdr::varshead.

Referenced by ast_cdr_merge().

509 {
510  struct ast_var_t *variablesfrom,*variablesto;
511  struct varshead *headpfrom = &to->varshead;
512  struct varshead *headpto = &from->varshead;
513  AST_LIST_TRAVERSE_SAFE_BEGIN(headpfrom, variablesfrom, entries) {
514  /* for every var in from, stick it in to */
515  const char *fromvarname, *fromvarval;
516  const char *tovarname = NULL, *tovarval = NULL;
517  fromvarname = ast_var_name(variablesfrom);
518  fromvarval = ast_var_value(variablesfrom);
519  tovarname = 0;
520 
521  /* now, quick see if that var is in the 'to' cdr already */
522  AST_LIST_TRAVERSE(headpto, variablesto, entries) {
523 
524  /* now, quick see if that var is in the 'to' cdr already */
525  if ( strcasecmp(fromvarname, ast_var_name(variablesto)) == 0 ) {
526  tovarname = ast_var_name(variablesto);
527  tovarval = ast_var_value(variablesto);
528  break;
529  }
530  }
531  if (tovarname && strcasecmp(fromvarval,tovarval) != 0) { /* this message here to see how irritating the userbase finds it */
532  ast_log(LOG_NOTICE, "Merging CDR's: variable %s value %s dropped in favor of value %s\n", tovarname, fromvarval, tovarval);
533  continue;
534  } else if (tovarname && strcasecmp(fromvarval,tovarval) == 0) /* if they are the same, the job is done */
535  continue;
536 
537  /* rip this var out of the from cdr, and stick it in the to cdr */
538  AST_LIST_MOVE_CURRENT(headpto, entries);
539  }
541 }
const char * ast_var_value(const struct ast_var_t *var)
Definition: chanvars.c:89
const char * ast_var_name(const struct ast_var_t *var)
Definition: chanvars.c:69
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:600
struct varshead varshead
Definition: cdr.h:130
#define AST_LIST_MOVE_CURRENT(newhead, field)
Definition: linkedlists.h:567
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
static int cdr_seq_inc ( struct ast_cdr cdr)
static

Definition at line 892 of file cdr.c.

References ast_atomic_fetchadd_int(), cdr_sequence, and ast_cdr::sequence.

Referenced by ast_cdr_dup_unique(), ast_cdr_dup_unique_swap(), and ast_cdr_init().

893 {
894  return (cdr->sequence = ast_atomic_fetchadd_int(&cdr_sequence, +1));
895 }
int sequence
Definition: cdr.h:127
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return * the previous value of *p. This can be used to handle reference co...
Definition: lock.h:603
static int cdr_sequence
Definition: cdr.c:83
int check_cdr_enabled ( void  )

Return TRUE if CDR subsystem is enabled.

Definition at line 120 of file cdr.c.

References enabled.

Referenced by action_coresettings(), and handle_show_settings().

121 {
122  return enabled;
123 }
static int enabled
Definition: cdr.c:91
static void check_post ( struct ast_cdr cdr)
static

print a warning if cdr already posted

Definition at line 467 of file cdr.c.

References AST_CDR_FLAG_POSTED, ast_log(), ast_test_flag, ast_cdr::channel, LOG_NOTICE, and S_OR.

Referenced by ast_cdr_answer(), ast_cdr_busy(), ast_cdr_end(), ast_cdr_failed(), ast_cdr_noanswer(), ast_cdr_setanswer(), ast_cdr_setapp(), ast_cdr_setdestchan(), ast_cdr_setdisposition(), ast_cdr_start(), and post_cdr().

468 {
469  if (!cdr)
470  return;
472  ast_log(LOG_NOTICE, "CDR on channel '%s' already posted\n", S_OR(cdr->channel, "<unknown>"));
473 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
char channel[AST_MAX_EXTENSION]
Definition: cdr.h:92
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
static void* do_batch_backend_process ( void *  data)
static

Definition at line 1253 of file cdr.c.

References ast_cdr_free(), ast_free, ast_cdr_batch_item::cdr, ast_cdr_batch_item::next, and post_cdr().

Referenced by ast_cdr_submit_batch().

1254 {
1255  struct ast_cdr_batch_item *processeditem;
1256  struct ast_cdr_batch_item *batchitem = data;
1257 
1258  /* Push each CDR into storage mechanism(s) and free all the memory */
1259  while (batchitem) {
1260  post_cdr(batchitem->cdr);
1261  ast_cdr_free(batchitem->cdr);
1262  processeditem = batchitem;
1263  batchitem = batchitem->next;
1264  ast_free(processeditem);
1265  }
1266 
1267  return NULL;
1268 }
static void post_cdr(struct ast_cdr *cdr)
Definition: cdr.c:1118
struct ast_cdr * cdr
Definition: cdr.c:72
struct ast_cdr_batch_item * next
Definition: cdr.c:73
#define ast_free(a)
Definition: astmm.h:97
void ast_cdr_free(struct ast_cdr *cdr)
Free a CDR record.
Definition: cdr.c:475
static void* do_cdr ( void *  data)
static

Definition at line 1389 of file cdr.c.

References ast_cond_timedwait, ast_debug, ast_mutex_lock, ast_mutex_unlock, ast_samp2tv(), ast_sched_runq(), ast_sched_wait(), ast_tvadd(), ast_tvnow(), cdr_pending_cond, and cdr_pending_lock.

Referenced by do_reload().

1390 {
1391  struct timespec timeout;
1392  int schedms;
1393  int numevents = 0;
1394 
1395  for (;;) {
1396  struct timeval now;
1397  schedms = ast_sched_wait(sched);
1398  /* this shouldn't happen, but provide a 1 second default just in case */
1399  if (schedms <= 0)
1400  schedms = 1000;
1401  now = ast_tvadd(ast_tvnow(), ast_samp2tv(schedms, 1000));
1402  timeout.tv_sec = now.tv_sec;
1403  timeout.tv_nsec = now.tv_usec * 1000;
1404  /* prevent stuff from clobbering cdr_pending_cond, then wait on signals sent to it until the timeout expires */
1407  numevents = ast_sched_runq(sched);
1409  ast_debug(2, "Processed %d scheduled CDR batches from the run queue\n", numevents);
1410  }
1411 
1412  return NULL;
1413 }
Definition: sched.c:57
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
#define ast_mutex_lock(a)
Definition: lock.h:155
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static ast_mutex_t cdr_pending_lock
Definition: cdr.c:117
struct timeval ast_samp2tv(unsigned int _nsamp, unsigned int _rate)
Returns a timeval corresponding to the duration of n samples at rate r. Useful to convert samples to ...
Definition: time.h:191
static ast_cond_t cdr_pending_cond
Definition: cdr.c:118
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: utils.c:1587
int ast_sched_runq(struct sched_context *con)
Runs the queue.
Definition: sched.c:600
int ast_sched_wait(struct sched_context *con) attribute_warn_unused_result
Determines number of seconds until the next outstanding event to take place Determine the number of s...
Definition: sched.c:334
#define ast_cond_timedwait(cond, mutex, time)
Definition: lock.h:172
#define ast_mutex_unlock(a)
Definition: lock.h:156
static void do_reload ( int  reload)
static

Definition at line 1497 of file cdr.c.

References ast_cdr_engine_term(), ast_cli_register(), ast_cli_unregister(), ast_cond_destroy, ast_cond_init, ast_config_destroy(), ast_config_load2(), ast_log(), ast_mutex_lock, ast_mutex_unlock, AST_OPT_FLAG_END_CDR_BEFORE_H_EXTEN, AST_OPT_FLAG_INITIATED_SECONDS, ast_options, ast_pthread_create_background, AST_PTHREADT_NULL, ast_register_atexit(), ast_sched_add(), AST_SCHED_DEL, ast_set2_flag, ast_true(), ast_unregister_atexit(), ast_variable_retrieve(), BATCH_SAFE_SHUTDOWN_DEFAULT, BATCH_SCHEDULER_ONLY_DEFAULT, BATCH_SIZE_DEFAULT, BATCH_TIME_DEFAULT, batchmode, BATCHMODE_DEFAULT, batchsafeshutdown, batchscheduleronly, batchsize, batchtime, cdr_batch_lock, cdr_pending_cond, cdr_sched, cdr_sched_lock, cdr_thread, cli_submit, config, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, CONFIG_STATUS_FILEUNCHANGED, do_cdr(), enabled, ENABLED_DEFAULT, EVENT_FLAG_SYSTEM, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event, submit_scheduled_batch(), unanswered, and UNANSWERED_DEFAULT.

Referenced by ast_cdr_engine_init(), and ast_cdr_engine_reload().

1498 {
1499  struct ast_config *config;
1500  const char *enabled_value;
1501  const char *unanswered_value;
1502  const char *batched_value;
1503  const char *scheduleronly_value;
1504  const char *batchsafeshutdown_value;
1505  const char *size_value;
1506  const char *time_value;
1507  const char *end_before_h_value;
1508  const char *initiatedseconds_value;
1509  int cfg_size;
1510  int cfg_time;
1511  int was_enabled;
1512  int was_batchmode;
1513  struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
1514 
1515  if ((config = ast_config_load2("cdr.conf", "cdr", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) {
1516  return;
1517  }
1518 
1520 
1521  was_enabled = enabled;
1522  was_batchmode = batchmode;
1523 
1531 
1532  if (config == CONFIG_STATUS_FILEMISSING || config == CONFIG_STATUS_FILEINVALID) {
1534  return;
1535  }
1536 
1537  /* don't run the next scheduled CDR posting while reloading */
1541 
1542  if (config) {
1543  if ((enabled_value = ast_variable_retrieve(config, "general", "enable"))) {
1544  enabled = ast_true(enabled_value);
1545  }
1546  if ((unanswered_value = ast_variable_retrieve(config, "general", "unanswered"))) {
1547  unanswered = ast_true(unanswered_value);
1548  }
1549  if ((batched_value = ast_variable_retrieve(config, "general", "batch"))) {
1550  batchmode = ast_true(batched_value);
1551  }
1552  if ((scheduleronly_value = ast_variable_retrieve(config, "general", "scheduleronly"))) {
1553  batchscheduleronly = ast_true(scheduleronly_value);
1554  }
1555  if ((batchsafeshutdown_value = ast_variable_retrieve(config, "general", "safeshutdown"))) {
1556  batchsafeshutdown = ast_true(batchsafeshutdown_value);
1557  }
1558  if ((size_value = ast_variable_retrieve(config, "general", "size"))) {
1559  if (sscanf(size_value, "%30d", &cfg_size) < 1)
1560  ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", size_value);
1561  else if (cfg_size < 0)
1562  ast_log(LOG_WARNING, "Invalid maximum batch size '%d' specified, using default\n", cfg_size);
1563  else
1564  batchsize = cfg_size;
1565  }
1566  if ((time_value = ast_variable_retrieve(config, "general", "time"))) {
1567  if (sscanf(time_value, "%30d", &cfg_time) < 1)
1568  ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", time_value);
1569  else if (cfg_time < 0)
1570  ast_log(LOG_WARNING, "Invalid maximum batch time '%d' specified, using default\n", cfg_time);
1571  else
1572  batchtime = cfg_time;
1573  }
1574  if ((end_before_h_value = ast_variable_retrieve(config, "general", "endbeforehexten")))
1576  if ((initiatedseconds_value = ast_variable_retrieve(config, "general", "initiatedseconds")))
1578  }
1579 
1580  if (enabled && !batchmode) {
1581  ast_log(LOG_NOTICE, "CDR simple logging enabled.\n");
1582  } else if (enabled && batchmode) {
1586  ast_log(LOG_NOTICE, "CDR batch mode logging enabled, first of either size %d or time %d seconds.\n", batchsize, batchtime);
1587  } else {
1588  ast_log(LOG_NOTICE, "CDR logging disabled, data will be lost.\n");
1589  }
1590 
1591  /* if this reload enabled the CDR batch mode, create the background thread
1592  if it does not exist */
1593  if (enabled && batchmode && (!was_enabled || !was_batchmode) && (cdr_thread == AST_PTHREADT_NULL)) {
1595  if (ast_pthread_create_background(&cdr_thread, NULL, do_cdr, NULL) < 0) {
1596  ast_log(LOG_ERROR, "Unable to start CDR thread.\n");
1600  } else {
1603  }
1604  /* if this reload disabled the CDR and/or batch mode and there is a background thread,
1605  kill it */
1606  } else if (((!enabled && was_enabled) || (!batchmode && was_batchmode)) && (cdr_thread != AST_PTHREADT_NULL)) {
1607  /* wake up the thread so it will exit */
1608  pthread_cancel(cdr_thread);
1609  pthread_kill(cdr_thread, SIGURG);
1610  pthread_join(cdr_thread, NULL);
1615  /* if leaving batch mode, then post the CDRs in the batch,
1616  and don't reschedule, since we are stopping CDR logging */
1617  if (!batchmode && was_batchmode) {
1619  }
1620  }
1621 
1623  ast_config_destroy(config);
1624  manager_event(EVENT_FLAG_SYSTEM, "Reload", "Module: CDR\r\nMessage: CDR subsystem reload requested\r\n");
1625 }
static int batchsize
Definition: cdr.c:100
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
Definition: config.c:625
static const char config[]
Definition: cdr_csv.c:57
static const int UNANSWERED_DEFAULT
Definition: cdr.c:98
int ast_cli_register(struct ast_cli_entry *e)
Registers a command or an array of commands.
Definition: cli.c:2159
static void * do_cdr(void *data)
Definition: cdr.c:1389
#define ast_set2_flag(p, value, flag)
Definition: utils.h:94
static int batchmode
Definition: cdr.c:94
int ast_sched_add(struct sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event Schedule an event to take place at some point in the future. callback will be called with data as the argument, when milliseconds into the future (approximately) If callback returns 0, no further events will be re-scheduled.
Definition: sched.c:446
int ast_cli_unregister(struct ast_cli_entry *e)
Unregisters a command or an array of commands.
Definition: cli.c:2153
#define LOG_WARNING
Definition: logger.h:144
static int batchsafeshutdown
Definition: cdr.c:109
static int batchscheduleronly
Definition: cdr.c:106
static ast_mutex_t cdr_sched_lock
Definition: cdr.c:112
Definition: sched.c:57
#define ast_cond_init(cond, attr)
Definition: lock.h:167
static int submit_scheduled_batch(const void *data)
Definition: cdr.c:1300
static const int BATCH_TIME_DEFAULT
Definition: cdr.c:104
#define ast_mutex_lock(a)
Definition: lock.h:155
static const int ENABLED_DEFAULT
Definition: cdr.c:92
static const int BATCH_SCHEDULER_ONLY_DEFAULT
Definition: cdr.c:107
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
Definition: config.c:2499
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
#define ast_pthread_create_background(a, b, c, d)
Definition: utils.h:426
#define CONFIG_STATUS_FILEMISSING
Definition: config.h:50
#define EVENT_FLAG_SYSTEM
Definition: manager.h:71
#define AST_SCHED_DEL(sched, id)
a loop construct to ensure that the scheduled task get deleted. The idea is that if we loop attemptin...
Definition: sched.h:51
void ast_unregister_atexit(void(*func)(void))
Unregister a function registered with ast_register_atexit().
Definition: asterisk.c:1008
#define AST_PTHREADT_NULL
Definition: lock.h:65
int ast_register_atexit(void(*func)(void))
Register a function to be executed before Asterisk exits.
Definition: asterisk.c:998
static const int BATCH_SAFE_SHUTDOWN_DEFAULT
Definition: cdr.c:110
static int reload(void)
Definition: app_amd.c:497
void ast_cdr_engine_term(void)
Definition: cdr.c:1663
#define LOG_ERROR
Definition: logger.h:155
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is &quot;true&quot;. This function checks to see whether a string passed to it is an indication of an &quot;true&quot; value. It checks to see if the string is &quot;yes&quot;, &quot;true&quot;, &quot;y&quot;, &quot;t&quot;, &quot;on&quot; or &quot;1&quot;.
Definition: utils.c:1533
static int batchtime
Definition: cdr.c:103
static ast_cond_t cdr_pending_cond
Definition: cdr.c:118
static ast_mutex_t cdr_batch_lock
Definition: cdr.c:114
static const int BATCH_SIZE_DEFAULT
Definition: cdr.c:101
static int cdr_sched
Definition: cdr.c:88
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_cond_destroy(cond)
Definition: lock.h:168
#define LOG_NOTICE
Definition: logger.h:133
Structure used to handle boolean flags.
Definition: utils.h:200
static int unanswered
Definition: cdr.c:97
static const int BATCHMODE_DEFAULT
Definition: cdr.c:95
struct ast_flags ast_options
Definition: asterisk.c:178
#define CONFIG_STATUS_FILEINVALID
Definition: config.h:52
static int enabled
Definition: cdr.c:91
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
Definition: manager.h:219
static struct ast_cli_entry cli_submit
Definition: cdr.c:1494
static pthread_t cdr_thread
Definition: cdr.c:89
#define CONFIG_STATUS_FILEUNCHANGED
Definition: config.h:51
#define ast_mutex_unlock(a)
Definition: lock.h:156
static char* handle_cli_status ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1415 of file cdr.c.

References ast_cli_args::argc, ast_cli(), AST_RWLIST_EMPTY, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_sched_when(), batch, batchmode, batchsafeshutdown, batchscheduleronly, batchsize, batchtime, cdr_sched, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, enabled, ESS, ast_cli_args::fd, ast_cdr_beitem::name, ast_cdr_batch::size, unanswered, and ast_cli_entry::usage.

1416 {
1417  struct ast_cdr_beitem *beitem=NULL;
1418  int cnt=0;
1419  long nextbatchtime=0;
1420 
1421  switch (cmd) {
1422  case CLI_INIT:
1423  e->command = "cdr show status";
1424  e->usage =
1425  "Usage: cdr show status\n"
1426  " Displays the Call Detail Record engine system status.\n";
1427  return NULL;
1428  case CLI_GENERATE:
1429  return NULL;
1430  }
1431 
1432  if (a->argc > 3)
1433  return CLI_SHOWUSAGE;
1434 
1435  ast_cli(a->fd, "\n");
1436  ast_cli(a->fd, "Call Detail Record (CDR) settings\n");
1437  ast_cli(a->fd, "----------------------------------\n");
1438  ast_cli(a->fd, " Logging: %s\n", enabled ? "Enabled" : "Disabled");
1439  ast_cli(a->fd, " Mode: %s\n", batchmode ? "Batch" : "Simple");
1440  if (enabled) {
1441  ast_cli(a->fd, " Log unanswered calls: %s\n\n", unanswered ? "Yes" : "No");
1442  if (batchmode) {
1443  ast_cli(a->fd, "* Batch Mode Settings\n");
1444  ast_cli(a->fd, " -------------------\n");
1445  if (batch)
1446  cnt = batch->size;
1447  if (cdr_sched > -1)
1448  nextbatchtime = ast_sched_when(sched, cdr_sched);
1449  ast_cli(a->fd, " Safe shutdown: %s\n", batchsafeshutdown ? "Enabled" : "Disabled");
1450  ast_cli(a->fd, " Threading model: %s\n", batchscheduleronly ? "Scheduler only" : "Scheduler plus separate threads");
1451  ast_cli(a->fd, " Current batch size: %d record%s\n", cnt, ESS(cnt));
1452  ast_cli(a->fd, " Maximum batch size: %d record%s\n", batchsize, ESS(batchsize));
1453  ast_cli(a->fd, " Maximum batch time: %d second%s\n", batchtime, ESS(batchtime));
1454  ast_cli(a->fd, " Next batch processing time: %ld second%s\n\n", nextbatchtime, ESS(nextbatchtime));
1455  }
1456  ast_cli(a->fd, "* Registered Backends\n");
1457  ast_cli(a->fd, " -------------------\n");
1459  if (AST_RWLIST_EMPTY(&be_list)) {
1460  ast_cli(a->fd, " (none)\n");
1461  } else {
1462  AST_RWLIST_TRAVERSE(&be_list, beitem, list) {
1463  ast_cli(a->fd, " %s\n", beitem->name);
1464  }
1465  }
1467  ast_cli(a->fd, "\n");
1468  }
1469 
1470  return CLI_SUCCESS;
1471 }
static int batchsize
Definition: cdr.c:100
static struct ast_cdr_batch * batch
static int batchmode
Definition: cdr.c:94
const int argc
Definition: cli.h:154
static int batchsafeshutdown
Definition: cdr.c:109
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
static int batchscheduleronly
Definition: cdr.c:106
Definition: sched.c:57
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
const int fd
Definition: cli.h:153
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
#define AST_RWLIST_EMPTY
Definition: linkedlists.h:451
int size
Definition: cdr.c:77
#define CLI_SHOWUSAGE
Definition: cli.h:44
long ast_sched_when(struct sched_context *con, int id)
Returns the number of seconds before an event takes place.
Definition: sched.c:664
static int batchtime
Definition: cdr.c:103
static int cdr_sched
Definition: cdr.c:88
#define ESS(x)
Definition: cli.h:58
char * command
Definition: cli.h:180
static int unanswered
Definition: cdr.c:97
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
char name[20]
Definition: cdr.c:63
static int enabled
Definition: cdr.c:91
Definition: cdr.c:69
static char* handle_cli_submit ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1473 of file cdr.c.

References ast_cli_args::argc, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, submit_unscheduled_batch(), and ast_cli_entry::usage.

1474 {
1475  switch (cmd) {
1476  case CLI_INIT:
1477  e->command = "cdr submit";
1478  e->usage =
1479  "Usage: cdr submit\n"
1480  " Posts all pending batched CDR data to the configured CDR backend engine modules.\n";
1481  return NULL;
1482  case CLI_GENERATE:
1483  return NULL;
1484  }
1485  if (a->argc > 2)
1486  return CLI_SHOWUSAGE;
1487 
1489  ast_cli(a->fd, "Submitted CDRs to backend engines for processing. This may take a while.\n");
1490 
1491  return CLI_SUCCESS;
1492 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const int fd
Definition: cli.h:153
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static void submit_unscheduled_batch(void)
Definition: cdr.c:1312
static int init_batch ( void  )
static
Note
Don't call without cdr_batch_lock

Definition at line 1242 of file cdr.c.

References ast_malloc, batch, and reset_batch().

Referenced by ast_cdr_detach().

1243 {
1244  /* This is the single meta-batch used to keep track of all CDRs during the entire life of the program */
1245  if (!(batch = ast_malloc(sizeof(*batch))))
1246  return -1;
1247 
1248  reset_batch();
1249 
1250  return 0;
1251 }
static void reset_batch(void)
Definition: cdr.c:1234
static struct ast_cdr_batch * batch
#define ast_malloc(a)
Definition: astmm.h:91
static void post_cdr ( struct ast_cdr cdr)
static

Definition at line 1118 of file cdr.c.

References AST_CDR_ANSWERED, AST_CDR_FLAG_DIALED, AST_CDR_FLAG_ORIGINATED, AST_CDR_FLAG_POST_DISABLED, AST_CDR_FLAG_POSTED, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_set_flag, ast_strlen_zero(), ast_test_flag, ast_cdr_beitem::be, ast_cdr::channel, check_post(), ast_cdr::disposition, ast_cdr::dstchannel, ast_cdr::next, and unanswered.

Referenced by ast_cdr_detach(), and do_batch_backend_process().

1119 {
1120  struct ast_cdr_beitem *i;
1121 
1122  for ( ; cdr ; cdr = cdr->next) {
1124  /* For people, who don't want to see unanswered single-channel events */
1126  continue;
1127  }
1128 
1129  /* don't post CDRs that are for dialed channels unless those
1130  * channels were originated from asterisk (pbx_spool, manager,
1131  * cli) */
1134  continue;
1135  }
1136 
1137  check_post(cdr);
1140  continue;
1142  AST_RWLIST_TRAVERSE(&be_list, i, list) {
1143  i->be(cdr);
1144  }
1146  }
1147 }
char dstchannel[AST_MAX_EXTENSION]
Definition: cdr.h:94
#define ast_test_flag(p, flag)
Definition: utils.h:63
ast_cdrbe be
Definition: cdr.c:65
#define ast_set_flag(p, flag)
Definition: utils.h:70
struct ast_cdr * next
Definition: cdr.h:132
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
char channel[AST_MAX_EXTENSION]
Definition: cdr.h:92
static void check_post(struct ast_cdr *cdr)
print a warning if cdr already posted
Definition: cdr.c:467
static int unanswered
Definition: cdr.c:97
long int disposition
Definition: cdr.h:110
Definition: cdr.c:69
static void reset_batch ( void  )
static
Note
Don't call without cdr_batch_lock

Definition at line 1234 of file cdr.c.

References batch, ast_cdr_batch::head, ast_cdr_batch::size, and ast_cdr_batch::tail.

Referenced by ast_cdr_submit_batch(), and init_batch().

1235 {
1236  batch->size = 0;
1237  batch->head = NULL;
1238  batch->tail = NULL;
1239 }
static struct ast_cdr_batch * batch
struct ast_cdr_batch_item * head
Definition: cdr.c:78
struct ast_cdr_batch_item * tail
Definition: cdr.c:79
int size
Definition: cdr.c:77
static void set_one_cid ( struct ast_cdr cdr,
struct ast_channel c 
)
static

Definition at line 859 of file cdr.c.

References ast_party_caller::ani, ast_callerid_merge(), ast_cdr_setvar(), ast_copy_string(), ast_channel::caller, ast_cdr::clid, ast_channel::dialed, ast_party_caller::id, ast_party_id::name, ast_party_id::number, ast_party_dialed::number, S_COR, S_OR, ast_cdr::src, ast_party_name::str, ast_party_number::str, ast_party_subaddress::str, ast_party_dialed::str, ast_party_id::subaddress, ast_party_dialed::subaddress, ast_party_name::valid, ast_party_number::valid, and ast_party_subaddress::valid.

Referenced by ast_cdr_init(), ast_cdr_setcid(), and ast_cdr_update().

860 {
861  const char *num;
862 
863  if (!cdr) {
864  return;
865  }
866 
867  /* Grab source from ANI or normal Caller*ID */
868  num = S_COR(c->caller.ani.number.valid, c->caller.ani.number.str,
869  S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL));
870  ast_callerid_merge(cdr->clid, sizeof(cdr->clid),
871  S_COR(c->caller.id.name.valid, c->caller.id.name.str, NULL), num, "");
872  ast_copy_string(cdr->src, S_OR(num, ""), sizeof(cdr->src));
873  ast_cdr_setvar(cdr, "dnid", S_OR(c->dialed.number.str, ""), 0);
874 
875  if (c->caller.id.subaddress.valid) {
876  ast_cdr_setvar(cdr, "callingsubaddr", S_OR(c->caller.id.subaddress.str, ""), 0);
877  }
878  if (c->dialed.subaddress.valid) {
879  ast_cdr_setvar(cdr, "calledsubaddr", S_OR(c->dialed.subaddress.str, ""), 0);
880  }
881 }
int ast_cdr_setvar(struct ast_cdr *cdr, const char *name, const char *value, int recur)
Definition: cdr.c:343
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
char * str
Subscriber phone number (Malloced)
Definition: channel.h:336
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
struct ast_party_name name
Subscriber name.
Definition: channel.h:290
char * str
Subscriber name (Malloced)
Definition: channel.h:214
unsigned char valid
TRUE if the subaddress information is valid/present.
Definition: channel.h:278
char * str
Malloced subaddress string.
Definition: channel.h:263
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
char * ast_callerid_merge(char *buf, int bufsiz, const char *name, const char *num, const char *unknown)
Definition: callerid.c:1074
struct ast_party_id ani
Automatic Number Identification (ANI)
Definition: channel.h:377
struct ast_party_dialed::@155 number
Dialed/Called number.
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:83
struct ast_party_dialed dialed
Dialed/Called information.
Definition: channel.h:797
struct ast_party_subaddress subaddress
Subscriber subaddress.
Definition: channel.h:294
struct ast_party_subaddress subaddress
Dialed/Called subaddress.
Definition: channel.h:341
char src[AST_MAX_EXTENSION]
Definition: cdr.h:86
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:229
char clid[AST_MAX_EXTENSION]
Definition: cdr.h:84
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
static int submit_scheduled_batch ( const void *  data)
static

Definition at line 1300 of file cdr.c.

References ast_cdr_submit_batch(), ast_mutex_lock, ast_mutex_unlock, ast_sched_add(), batchtime, cdr_sched, and cdr_sched_lock.

Referenced by do_reload(), and submit_unscheduled_batch().

1301 {
1303  /* manually reschedule from this point in time */
1307  /* returning zero so the scheduler does not automatically reschedule */
1308  return 0;
1309 }
void ast_cdr_submit_batch(int shutdown)
Spawns (possibly) a new thread to submit a batch of CDRs to the backend engines.
Definition: cdr.c:1270
int ast_sched_add(struct sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event Schedule an event to take place at some point in the future. callback will be called with data as the argument, when milliseconds into the future (approximately) If callback returns 0, no further events will be re-scheduled.
Definition: sched.c:446
static ast_mutex_t cdr_sched_lock
Definition: cdr.c:112
Definition: sched.c:57
static int submit_scheduled_batch(const void *data)
Definition: cdr.c:1300
#define ast_mutex_lock(a)
Definition: lock.h:155
static int batchtime
Definition: cdr.c:103
static int cdr_sched
Definition: cdr.c:88
#define ast_mutex_unlock(a)
Definition: lock.h:156
static void submit_unscheduled_batch ( void  )
static

Do not hold the batch lock while calling this function

Definition at line 1312 of file cdr.c.

References ast_cond_signal, ast_mutex_lock, ast_mutex_unlock, ast_sched_add(), AST_SCHED_DEL, cdr_pending_cond, cdr_pending_lock, cdr_sched, cdr_sched_lock, and submit_scheduled_batch().

Referenced by ast_cdr_detach(), and handle_cli_submit().

1313 {
1314  /* Prevent two deletes from happening at the same time */
1316  /* this is okay since we are not being called from within the scheduler */
1318  /* schedule the submission to occur ASAP (1 ms) */
1321 
1322  /* signal the do_cdr thread to wakeup early and do some work (that lazy thread ;) */
1326 }
int ast_sched_add(struct sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event Schedule an event to take place at some point in the future. callback will be called with data as the argument, when milliseconds into the future (approximately) If callback returns 0, no further events will be re-scheduled.
Definition: sched.c:446
static ast_mutex_t cdr_sched_lock
Definition: cdr.c:112
Definition: sched.c:57
static int submit_scheduled_batch(const void *data)
Definition: cdr.c:1300
#define ast_mutex_lock(a)
Definition: lock.h:155
#define ast_cond_signal(cond)
Definition: lock.h:169
#define AST_SCHED_DEL(sched, id)
a loop construct to ensure that the scheduled task get deleted. The idea is that if we loop attemptin...
Definition: sched.h:51
static ast_mutex_t cdr_pending_lock
Definition: cdr.c:117
static ast_cond_t cdr_pending_cond
Definition: cdr.c:118
static int cdr_sched
Definition: cdr.c:88
#define ast_mutex_unlock(a)
Definition: lock.h:156

Variable Documentation

char ast_default_accountcode[AST_MAX_ACCOUNT_CODE]

Definition at line 60 of file cdr.c.

Referenced by __ast_channel_alloc_ap().

int ast_default_amaflags = AST_CDR_DOCUMENTATION

Default AMA flag for billing records (CDR's)

Definition at line 59 of file cdr.c.

Referenced by __ast_channel_alloc_ap(), ast_bridge_call(), and ast_cdr_init().

const int BATCH_SAFE_SHUTDOWN_DEFAULT = 1
static

Definition at line 110 of file cdr.c.

Referenced by do_reload().

const int BATCH_SCHEDULER_ONLY_DEFAULT = 0
static

Definition at line 107 of file cdr.c.

Referenced by do_reload().

const int BATCH_SIZE_DEFAULT = 100
static

Definition at line 101 of file cdr.c.

Referenced by do_reload().

const int BATCH_TIME_DEFAULT = 300
static

Definition at line 104 of file cdr.c.

Referenced by do_reload().

int batchmode
static

Definition at line 94 of file cdr.c.

Referenced by ast_cdr_detach(), do_reload(), and handle_cli_status().

const int BATCHMODE_DEFAULT = 0
static

Definition at line 95 of file cdr.c.

Referenced by do_reload().

int batchsafeshutdown
static

Definition at line 109 of file cdr.c.

Referenced by ast_cdr_engine_term(), do_reload(), and handle_cli_status().

int batchscheduleronly
static

Definition at line 106 of file cdr.c.

Referenced by ast_cdr_submit_batch(), do_reload(), and handle_cli_status().

int batchsize
static

Definition at line 100 of file cdr.c.

Referenced by ast_cdr_detach(), do_reload(), and handle_cli_status().

int batchtime
static

Definition at line 103 of file cdr.c.

Referenced by do_reload(), handle_cli_status(), and submit_scheduled_batch().

struct be_list be_list = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
static
ast_mutex_t cdr_batch_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
static

Definition at line 114 of file cdr.c.

Referenced by ast_cdr_detach(), ast_cdr_submit_batch(), and do_reload().

ast_cond_t cdr_pending_cond
static

Definition at line 118 of file cdr.c.

Referenced by cdr_engine_shutdown(), do_cdr(), do_reload(), and submit_unscheduled_batch().

ast_mutex_t cdr_pending_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
static

Definition at line 117 of file cdr.c.

Referenced by do_cdr(), and submit_unscheduled_batch().

const char* const cdr_readonly_vars[]
static
Initial value:
= { "clid", "src", "dst", "dcontext", "channel", "dstchannel",
"lastapp", "lastdata", "start", "answer", "end", "duration",
"billsec", "disposition", "amaflags", "accountcode", "uniqueid", "linkedid",
"userfield", "sequence", NULL }

Definition at line 336 of file cdr.c.

Referenced by ast_cdr_data_add_structure(), ast_cdr_serialize_variables(), and ast_cdr_setvar().

int cdr_sched = -1
static
ast_mutex_t cdr_sched_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
static

Definition at line 112 of file cdr.c.

Referenced by do_reload(), submit_scheduled_batch(), and submit_unscheduled_batch().

int cdr_sequence = 0
static

Definition at line 83 of file cdr.c.

Referenced by cdr_seq_inc().

pthread_t cdr_thread = AST_PTHREADT_NULL
static

Definition at line 89 of file cdr.c.

Referenced by cdr_engine_shutdown(), and do_reload().

struct ast_cli_entry cli_status = AST_CLI_DEFINE(handle_cli_status, "Display the CDR status")
static

Definition at line 1495 of file cdr.c.

Referenced by ast_cdr_engine_init(), and cdr_engine_shutdown().

struct ast_cli_entry cli_submit = AST_CLI_DEFINE(handle_cli_submit, "Posts all pending batched CDR data")
static

Definition at line 1494 of file cdr.c.

Referenced by cdr_engine_shutdown(), and do_reload().

int enabled
static
const int ENABLED_DEFAULT = 1
static

Definition at line 92 of file cdr.c.

Referenced by do_reload().

struct sched_context* sched
static

Definition at line 87 of file cdr.c.

int unanswered
static

Definition at line 97 of file cdr.c.

Referenced by ast_cdr_isset_unanswered(), do_reload(), handle_cli_status(), and post_cdr().

const int UNANSWERED_DEFAULT = 0
static

Definition at line 98 of file cdr.c.

Referenced by do_reload().