Wed Aug 18 22:34:05 2010

Asterisk developer's documentation


cdr.h File Reference

Call Detail Record API. More...

#include <sys/time.h>
#include "asterisk/channel.h"
#include "asterisk/utils.h"

Go to the source code of this file.

Data Structures

struct  ast_cdr
 Responsible for call detail data. More...

CDR Flags - Disposition

#define AST_CDR_ANSWERED   (1 << 3)
#define AST_CDR_BUSY   (1 << 2)
#define AST_CDR_FAILED   (1 << 1)
#define AST_CDR_NOANSWER   0
#define AST_CDR_NULL   (1 << 0)

CDR AMA Flags

#define AST_CDR_BILLING   (2)
#define AST_CDR_DOCUMENTATION   (3)
#define AST_CDR_OMIT   (1)

CDR Flags

#define AST_CDR_FLAG_ANSLOCKED   (1 << 8)
#define AST_CDR_FLAG_BRIDGED   (1 << 5)
#define AST_CDR_FLAG_CHILD   (1 << 3)
#define AST_CDR_FLAG_DIALED   (1 << 11)
#define AST_CDR_FLAG_DONT_TOUCH   (1 << 9)
#define AST_CDR_FLAG_ENABLE   (1 << 7)
#define AST_CDR_FLAG_KEEP_VARS   (1 << 0)
#define AST_CDR_FLAG_LOCKED   (1 << 2)
#define AST_CDR_FLAG_MAIN   (1 << 6)
#define AST_CDR_FLAG_ORIGINATED   (1 << 12)
#define AST_CDR_FLAG_POST_DISABLED   (1 << 4)
#define AST_CDR_FLAG_POST_ENABLE   (1 << 10)
#define AST_CDR_FLAG_POSTED   (1 << 1)

Defines

#define AST_MAX_ACCOUNT_CODE   20
#define AST_MAX_USER_FIELD   256

Typedefs

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

Functions

ast_cdrast_cdr_alloc (void)
 Allocate a CDR record.
int ast_cdr_amaflags2int (const char *flag)
 Convert a string to a detail record AMA flag.
void ast_cdr_answer (struct ast_cdr *cdr)
 Answer a call.
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).
void ast_cdr_busy (struct ast_cdr *cdr)
 Busy a call.
int ast_cdr_copy_vars (struct ast_cdr *to_cdr, struct ast_cdr *from_cdr)
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.
void ast_cdr_discard (struct ast_cdr *cdr)
 Discard and free a CDR record.
char * ast_cdr_disp2str (int disposition)
 Disposition to a string.
int ast_cdr_disposition (struct ast_cdr *cdr, int cause)
 Save the result of the call based on the AST_CAUSE_*.
ast_cdrast_cdr_dup (struct ast_cdr *cdr)
 Duplicate a record.
void ast_cdr_end (struct ast_cdr *cdr)
 End a call.
int ast_cdr_engine_init (void)
 Load the configuration file cdr.conf and possibly start the CDR scheduling thread.
int ast_cdr_engine_reload (void)
 Reload the configuration file cdr.conf and start/stop CDR scheduling thread.
void ast_cdr_engine_term (void)
void ast_cdr_failed (struct ast_cdr *cdr)
 Fail a call.
char * ast_cdr_flags2str (int flags)
void ast_cdr_free (struct ast_cdr *cdr)
 Free a CDR record.
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)
int ast_cdr_init (struct ast_cdr *cdr, struct ast_channel *chan)
 Initialize based on a channel.
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.
void ast_cdr_noanswer (struct ast_cdr *cdr)
 A call wasn't answered.
int ast_cdr_register (const char *name, const char *desc, ast_cdrbe be)
 Register a CDR handling engine.
void ast_cdr_reset (struct ast_cdr *cdr, struct ast_flags *flags)
 Reset the detail record, optionally posting it first.
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.
int ast_cdr_setamaflags (struct ast_channel *chan, const char *amaflags)
 Set AMA flags for channel.
void ast_cdr_setanswer (struct ast_cdr *cdr, struct timeval t)
 Set the answer time for a call.
void ast_cdr_setapp (struct ast_cdr *cdr, char *app, char *data)
 Set the last executed application.
int ast_cdr_setcid (struct ast_cdr *cdr, struct ast_channel *chan)
 Initialize based on a channel.
void ast_cdr_setdestchan (struct ast_cdr *cdr, const char *chan)
 Set the destination channel, if there was one.
void ast_cdr_setdisposition (struct ast_cdr *cdr, long int disposition)
 Set the disposition for a call.
int ast_cdr_setuserfield (struct ast_channel *chan, const char *userfield)
 Set CDR user field for channel (stored in CDR).
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.
void ast_cdr_submit_batch (int shutdown)
 Spawns (possibly) a new thread to submit a batch of CDRs to the backend engines.
void ast_cdr_unregister (const char *name)
 Unregister a CDR handling engine.
int ast_cdr_update (struct ast_channel *chan)
int check_cdr_enabled (void)
 Return TRUE if CDR subsystem is enabled.

Variables

char ast_default_accountcode [AST_MAX_ACCOUNT_CODE]
int ast_default_amaflags


Detailed Description

Call Detail Record API.

Definition in file cdr.h.


Define Documentation

#define AST_CDR_ANSWERED   (1 << 3)

Definition at line 51 of file cdr.h.

Referenced by ast_bridge_call(), ast_cdr_answer(), ast_cdr_disp2str(), ast_cdr_end(), ast_cdr_init(), post_cdr(), and wait_for_answer().

#define AST_CDR_BILLING   (2)

Definition at line 57 of file cdr.h.

Referenced by ast_cdr_amaflags2int(), and ast_cdr_flags2str().

#define AST_CDR_BUSY   (1 << 2)

Definition at line 50 of file cdr.h.

Referenced by ast_cdr_busy(), and ast_cdr_disp2str().

#define AST_CDR_DOCUMENTATION   (3)

Definition at line 58 of file cdr.h.

Referenced by ast_cdr_amaflags2int(), ast_cdr_flags2str(), and ast_cdr_merge().

#define AST_CDR_FAILED   (1 << 1)

Definition at line 49 of file cdr.h.

Referenced by ast_cdr_disp2str(), ast_cdr_end(), and ast_cdr_failed().

#define AST_CDR_FLAG_ANSLOCKED   (1 << 8)

Definition at line 38 of file cdr.h.

Referenced by ast_cdr_answer(), ast_cdr_fork(), and ast_cdr_setanswer().

#define AST_CDR_FLAG_BRIDGED   (1 << 5)

Definition at line 35 of file cdr.h.

Referenced by ast_bridge_call(), and ast_hangup().

#define AST_CDR_FLAG_CHILD   (1 << 3)

Definition at line 33 of file cdr.h.

Referenced by ast_cdr_fork(), and ast_cdr_merge().

#define AST_CDR_FLAG_DIALED   (1 << 11)

Definition at line 41 of file cdr.h.

Referenced by ast_bridge_call(), ast_call(), ast_hangup(), and post_cdr().

#define AST_CDR_FLAG_DONT_TOUCH   (1 << 9)

Definition at line 39 of file cdr.h.

Referenced by ast_cdr_answer(), ast_cdr_end(), ast_cdr_fork(), ast_cdr_setanswer(), and ast_cdr_setvar().

#define AST_CDR_FLAG_ENABLE   (1 << 7)

Definition at line 37 of file cdr.h.

#define AST_CDR_FLAG_KEEP_VARS   (1 << 0)

Definition at line 30 of file cdr.h.

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

#define AST_CDR_FLAG_LOCKED   (1 << 2)

Definition at line 32 of file cdr.h.

Referenced by ast_cdr_answer(), ast_cdr_appenduserfield(), ast_cdr_busy(), ast_cdr_end(), ast_cdr_failed(), ast_cdr_fork(), ast_cdr_init(), ast_cdr_merge(), ast_cdr_noanswer(), ast_cdr_reset(), ast_cdr_setaccount(), ast_cdr_setamaflags(), ast_cdr_setanswer(), ast_cdr_setapp(), ast_cdr_setcid(), ast_cdr_setdestchan(), ast_cdr_setdisposition(), ast_cdr_setuserfield(), ast_cdr_setvar(), ast_cdr_start(), ast_cdr_update(), cdr_read(), and pick_unlocked_cdr().

#define AST_CDR_FLAG_MAIN   (1 << 6)

Definition at line 36 of file cdr.h.

Referenced by ast_bridge_call().

#define AST_CDR_FLAG_ORIGINATED   (1 << 12)

Definition at line 42 of file cdr.h.

Referenced by __ast_request_and_dial(), ast_call_forward(), and post_cdr().

#define AST_CDR_FLAG_POST_DISABLED   (1 << 4)

Definition at line 34 of file cdr.h.

Referenced by ast_bridge_call(), ast_cdr_detach(), ast_cdr_merge(), ast_cdr_reset(), ast_cdr_specialized_reset(), ast_hangup(), connect_link(), nocdr_exec(), post_cdr(), rpt(), rpt_call(), rpt_exec(), rpt_tele_thread(), and try_calling().

#define AST_CDR_FLAG_POST_ENABLE   (1 << 10)

Definition at line 40 of file cdr.h.

Referenced by ast_cdr_reset().

#define AST_CDR_FLAG_POSTED   (1 << 1)

Definition at line 31 of file cdr.h.

Referenced by ast_cdr_merge(), ast_cdr_reset(), check_post(), and post_cdr().

#define AST_CDR_NOANSWER   0

Definition at line 47 of file cdr.h.

Referenced by ast_cdr_disp2str(), ast_cdr_init(), ast_cdr_merge(), ast_cdr_noanswer(), and ast_cdr_reset().

#define AST_CDR_NULL   (1 << 0)

Definition at line 48 of file cdr.h.

Referenced by ast_bridge_call(), ast_cdr_disp2str(), ast_cdr_specialized_reset(), and ast_hangup().

#define AST_CDR_OMIT   (1)

Definition at line 56 of file cdr.h.

Referenced by ast_cdr_amaflags2int(), and ast_cdr_flags2str().

#define AST_MAX_ACCOUNT_CODE   20

Definition at line 62 of file cdr.h.

#define AST_MAX_USER_FIELD   256

Definition at line 61 of file cdr.h.

Referenced by tds_log().


Typedef Documentation

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

CDR backend callback.

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

Definition at line 129 of file cdr.h.


Function Documentation

struct ast_cdr* ast_cdr_alloc ( void   ) 

Allocate a CDR record.

Return values:
a malloc'd ast_cdr structure
NULL on error (malloc failure)

Definition at line 453 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(), builtin_blindtransfer(), clear_caller(), findmeexec(), and start_monitor_exec().

00454 {
00455    struct ast_cdr *x;
00456    x = ast_calloc(1, sizeof(*x));
00457    if (!x)
00458       ast_log(LOG_ERROR,"Allocation Failure for a CDR!\n");
00459    return x;
00460 }

int ast_cdr_amaflags2int ( const char *  flag  ) 

Convert a string to a detail record AMA flag.

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

Definition at line 1011 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(), and set_config().

01012 {
01013    if (!strcasecmp(flag, "default"))
01014       return 0;
01015    if (!strcasecmp(flag, "omit"))
01016       return AST_CDR_OMIT;
01017    if (!strcasecmp(flag, "billing"))
01018       return AST_CDR_BILLING;
01019    if (!strcasecmp(flag, "documentation"))
01020       return AST_CDR_DOCUMENTATION;
01021    return -1;
01022 }

void ast_cdr_answer ( struct ast_cdr cdr  ) 

Answer a call.

Parameters:
cdr the 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 688 of file cdr.c.

References 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(), and ast_cdr::next.

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

00689 {
00690 
00691    for (; cdr; cdr = cdr->next) {
00692       if (ast_test_flag(cdr, AST_CDR_FLAG_ANSLOCKED)) 
00693          continue;
00694       if (ast_test_flag(cdr, AST_CDR_FLAG_DONT_TOUCH) && ast_test_flag(cdr, AST_CDR_FLAG_LOCKED))
00695          continue;
00696       check_post(cdr);
00697       if (cdr->disposition < AST_CDR_ANSWERED)
00698          cdr->disposition = AST_CDR_ANSWERED;
00699       if (ast_tvzero(cdr->answer))
00700          cdr->answer = ast_tvnow();
00701    }
00702 }

struct ast_cdr* ast_cdr_append ( struct ast_cdr cdr,
struct ast_cdr newcdr 
)

Definition at line 1124 of file cdr.c.

References ast_cdr::next.

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

01125 {
01126    struct ast_cdr *ret;
01127 
01128    if (cdr) {
01129       ret = cdr;
01130 
01131       while (cdr->next)
01132          cdr = cdr->next;
01133       cdr->next = newcdr;
01134    } else {
01135       ret = newcdr;
01136    }
01137 
01138    return ret;
01139 }

int ast_cdr_appenduserfield ( struct ast_channel chan,
const char *  userfield 
)

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

Definition at line 977 of file cdr.c.

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

00978 {
00979    struct ast_cdr *cdr = chan->cdr;
00980 
00981    for ( ; cdr ; cdr = cdr->next) {
00982       int len = strlen(cdr->userfield);
00983 
00984       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED))
00985          ast_copy_string(cdr->userfield + len, userfield, sizeof(cdr->userfield) - len);
00986    }
00987 
00988    return 0;
00989 }

void ast_cdr_busy ( struct ast_cdr cdr  ) 

Busy a call.

Parameters:
cdr the 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 704 of file cdr.c.

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

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

00705 {
00706 
00707    for (; cdr; cdr = cdr->next) {
00708       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
00709          check_post(cdr);
00710          cdr->disposition = AST_CDR_BUSY;
00711       }
00712    }
00713 }

int ast_cdr_copy_vars ( struct ast_cdr to_cdr,
struct ast_cdr from_cdr 
)

Definition at line 336 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_cdr_dup().

00337 {
00338    struct ast_var_t *variables, *newvariable = NULL;
00339    struct varshead *headpa, *headpb;
00340    const char *var, *val;
00341    int x = 0;
00342 
00343    if (!to_cdr || !from_cdr) /* don't die if one of the pointers is null */
00344       return 0;
00345 
00346    headpa = &from_cdr->varshead;
00347    headpb = &to_cdr->varshead;
00348 
00349    AST_LIST_TRAVERSE(headpa,variables,entries) {
00350       if (variables &&
00351           (var = ast_var_name(variables)) && (val = ast_var_value(variables)) &&
00352           !ast_strlen_zero(var) && !ast_strlen_zero(val)) {
00353          newvariable = ast_var_assign(var, val);
00354          AST_LIST_INSERT_HEAD(headpb, newvariable, entries);
00355          x++;
00356       }
00357    }
00358 
00359    return x;
00360 }

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:
cdr Which CDR to detach from the channel thread Prevents the channel thread from blocking on the CDR handling Returns nothing

Definition at line 1229 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().

01230 {
01231    struct ast_cdr_batch_item *newtail;
01232    int curr;
01233 
01234    if (!cdr)
01235       return;
01236 
01237    /* maybe they disabled CDR stuff completely, so just drop it */
01238    if (!enabled) {
01239       ast_debug(1, "Dropping CDR !\n");
01240       ast_set_flag(cdr, AST_CDR_FLAG_POST_DISABLED);
01241       ast_cdr_free(cdr);
01242       return;
01243    }
01244 
01245    /* post stuff immediately if we are not in batch mode, this is legacy behaviour */
01246    if (!batchmode) {
01247       post_cdr(cdr);
01248       ast_cdr_free(cdr);
01249       return;
01250    }
01251 
01252    /* otherwise, each CDR gets put into a batch list (at the end) */
01253    ast_debug(1, "CDR detaching from this thread\n");
01254 
01255    /* we'll need a new tail for every CDR */
01256    if (!(newtail = ast_calloc(1, sizeof(*newtail)))) {
01257       post_cdr(cdr);
01258       ast_cdr_free(cdr);
01259       return;
01260    }
01261 
01262    /* don't traverse a whole list (just keep track of the tail) */
01263    ast_mutex_lock(&cdr_batch_lock);
01264    if (!batch)
01265       init_batch();
01266    if (!batch->head) {
01267       /* new batch is empty, so point the head at the new tail */
01268       batch->head = newtail;
01269    } else {
01270       /* already got a batch with something in it, so just append a new tail */
01271       batch->tail->next = newtail;
01272    }
01273    newtail->cdr = cdr;
01274    batch->tail = newtail;
01275    curr = batch->size++;
01276    ast_mutex_unlock(&cdr_batch_lock);
01277 
01278    /* if we have enough stuff to post, then do it */
01279    if (curr >= (batchsize - 1))
01280       submit_unscheduled_batch();
01281 }

void ast_cdr_discard ( struct ast_cdr cdr  ) 

Discard and free a CDR record.

Parameters:
cdr ast_cdr structure to free Returns nothing -- same as free, but no checks or complaints

Definition at line 442 of file cdr.c.

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

Referenced by ast_async_goto(), ast_bridge_call(), ast_cdr_merge(), and ast_channel_free().

00443 {
00444    while (cdr) {
00445       struct ast_cdr *next = cdr->next;
00446 
00447       ast_cdr_free_vars(cdr, 0);
00448       ast_free(cdr);
00449       cdr = next;
00450    }
00451 }

char* ast_cdr_disp2str ( int  disposition  ) 

Disposition to a string.

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

Definition at line 900 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().

00901 {
00902    switch (disposition) {
00903    case AST_CDR_NULL:
00904       return "NO ANSWER"; /* by default, for backward compatibility */
00905    case AST_CDR_NOANSWER:
00906       return "NO ANSWER";
00907    case AST_CDR_FAILED:
00908       return "FAILED";     
00909    case AST_CDR_BUSY:
00910       return "BUSY";    
00911    case AST_CDR_ANSWERED:
00912       return "ANSWERED";
00913    }
00914    return "UNKNOWN";
00915 }

int ast_cdr_disposition ( struct ast_cdr cdr,
int  cause 
)

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

Parameters:
cdr the cdr you wish to associate with the call
cause the AST_CAUSE_* Returns nothing

Definition at line 744 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().

00745 {
00746    int res = 0;
00747 
00748    for (; cdr; cdr = cdr->next) {
00749       switch (cause) {  /* handle all the non failure, busy cases, return 0 not to set disposition,
00750                      return -1 to set disposition to FAILED */
00751       case AST_CAUSE_BUSY:
00752          ast_cdr_busy(cdr);
00753          break;
00754       case AST_CAUSE_NO_ANSWER:
00755          ast_cdr_noanswer(cdr);
00756          break;
00757       case AST_CAUSE_NORMAL:
00758          break;
00759       default:
00760          res = -1;
00761       }
00762    }
00763    return res;
00764 }

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

References ast_cdr_alloc(), and ast_cdr_copy_vars().

Referenced by ast_async_goto(), ast_bridge_call(), ast_cdr_fork(), ast_cdr_merge(), and ast_cdr_reset().

00169 {
00170    struct ast_cdr *newcdr;
00171    
00172    if (!cdr) /* don't die if we get a null cdr pointer */
00173       return NULL;
00174    newcdr = ast_cdr_alloc();
00175    if (!newcdr)
00176       return NULL;
00177 
00178    memcpy(newcdr, cdr, sizeof(*newcdr));
00179    /* The varshead is unusable, volatile even, after the memcpy so we take care of that here */
00180    memset(&newcdr->varshead, 0, sizeof(newcdr->varshead));
00181    ast_cdr_copy_vars(newcdr, cdr);
00182    newcdr->next = NULL;
00183 
00184    return newcdr;
00185 }

void ast_cdr_end ( struct ast_cdr cdr  ) 

End a call.

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

Definition at line 877 of file cdr.c.

References AST_CDR_ANSWERED, AST_CDR_FAILED, AST_CDR_FLAG_DONT_TOUCH, AST_CDR_FLAG_LOCKED, ast_log(), ast_test_flag, ast_tvnow(), ast_tvzero(), check_post(), LOG_WARNING, ast_cdr::next, and S_OR.

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

00878 {
00879    for ( ; cdr ; cdr = cdr->next) {
00880       if (ast_test_flag(cdr, AST_CDR_FLAG_DONT_TOUCH) && ast_test_flag(cdr, AST_CDR_FLAG_LOCKED))
00881          continue;
00882       check_post(cdr);
00883       if (ast_tvzero(cdr->end))
00884          cdr->end = ast_tvnow();
00885       if (ast_tvzero(cdr->start)) {
00886          ast_log(LOG_WARNING, "CDR on channel '%s' has not started\n", S_OR(cdr->channel, "<unknown>"));
00887          cdr->disposition = AST_CDR_FAILED;
00888       } else
00889          cdr->duration = cdr->end.tv_sec - cdr->start.tv_sec;
00890       if (ast_tvzero(cdr->answer)) {
00891          if (cdr->disposition == AST_CDR_ANSWERED) {
00892             ast_log(LOG_WARNING, "CDR on channel '%s' has no answer time but is 'ANSWERED'\n", S_OR(cdr->channel, "<unknown>"));
00893             cdr->disposition = AST_CDR_FAILED;
00894          }
00895       } else
00896          cdr->billsec = cdr->end.tv_sec - cdr->answer.tv_sec;
00897    }
00898 }

int ast_cdr_engine_init ( void   ) 

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

Definition at line 1520 of file cdr.c.

References ast_cli_register(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), cdr_batch_lock, cli_status, do_reload(), init_batch(), LOG_ERROR, and sched_context_create().

Referenced by main().

01521 {
01522    int res;
01523 
01524    sched = sched_context_create();
01525    if (!sched) {
01526       ast_log(LOG_ERROR, "Unable to create schedule context.\n");
01527       return -1;
01528    }
01529 
01530    ast_cli_register(&cli_status);
01531 
01532    res = do_reload(0);
01533    if (res) {
01534       ast_mutex_lock(&cdr_batch_lock);
01535       res = init_batch();
01536       ast_mutex_unlock(&cdr_batch_lock);
01537    }
01538 
01539    return res;
01540 }

int ast_cdr_engine_reload ( void   ) 

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

Definition at line 1549 of file cdr.c.

References do_reload().

01550 {
01551    return do_reload(1);
01552 }

void ast_cdr_engine_term ( void   ) 

Submit any remaining CDRs and prepare for shutdown

Definition at line 1544 of file cdr.c.

References ast_cdr_submit_batch(), and batchsafeshutdown.

Referenced by do_reload(), and quit_handler().

01545 {
01546    ast_cdr_submit_batch(batchsafeshutdown);
01547 }

void ast_cdr_failed ( struct ast_cdr cdr  ) 

Fail a call.

Parameters:
cdr the 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 715 of file cdr.c.

References AST_CDR_FAILED, AST_CDR_FLAG_LOCKED, ast_test_flag, check_post(), 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(), and handle_cause().

00716 {
00717    for (; cdr; cdr = cdr->next) {
00718       check_post(cdr);
00719       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
00720          check_post(cdr);
00721          if (cdr->disposition < AST_CDR_FAILED)
00722             cdr->disposition = AST_CDR_FAILED;
00723       }
00724    }
00725 }

char* ast_cdr_flags2str ( int  flag  ) 

Converts AMA flag to printable string

Definition at line 918 of file cdr.c.

References AST_CDR_BILLING, AST_CDR_DOCUMENTATION, and AST_CDR_OMIT.

Referenced by _sip_show_peer(), ast_cdr_getvar(), build_csv_record(), build_radius_record(), csv_log(), handle_skinny_show_line(), manager_log(), sip_show_user(), and tds_log().

00919 {
00920    switch (flag) {
00921    case AST_CDR_OMIT:
00922       return "OMIT";
00923    case AST_CDR_BILLING:
00924       return "BILLING";
00925    case AST_CDR_DOCUMENTATION:
00926       return "DOCUMENTATION";
00927    }
00928    return "Unknown";
00929 }

void ast_cdr_free ( struct ast_cdr cdr  ) 

Free a CDR record.

Parameters:
cdr ast_cdr structure to free Returns nothing

Definition at line 429 of file cdr.c.

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

Referenced by ast_cdr_detach(), and do_batch_backend_process().

00430 {
00431 
00432    while (cdr) {
00433       struct ast_cdr *next = cdr->next;
00434 
00435       ast_cdr_free_vars(cdr, 0);
00436       ast_free(cdr);
00437       cdr = next;
00438    }
00439 }

void ast_cdr_free_vars ( struct ast_cdr cdr,
int  recur 
)

Definition at line 408 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().

00409 {
00410 
00411    /* clear variables */
00412    for (; cdr; cdr = recur ? cdr->next : NULL) {
00413       struct ast_var_t *vardata;
00414       struct varshead *headp = &cdr->varshead;
00415       while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries)))
00416          ast_var_delete(vardata);
00417    }
00418 }

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 219 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_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::src, ast_cdr::start, ast_cdr::uniqueid, and ast_cdr::userfield.

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

00220 {
00221    const char *fmt = "%Y-%m-%d %T";
00222    const char *varbuf;
00223 
00224    if (!cdr)  /* don't die if the cdr is null */
00225       return;
00226 
00227    *ret = NULL;
00228    /* special vars (the ones from the struct ast_cdr when requested by name) 
00229       I'd almost say we should convert all the stringed vals to vars */
00230 
00231    if (!strcasecmp(name, "clid"))
00232       ast_copy_string(workspace, cdr->clid, workspacelen);
00233    else if (!strcasecmp(name, "src"))
00234       ast_copy_string(workspace, cdr->src, workspacelen);
00235    else if (!strcasecmp(name, "dst"))
00236       ast_copy_string(workspace, cdr->dst, workspacelen);
00237    else if (!strcasecmp(name, "dcontext"))
00238       ast_copy_string(workspace, cdr->dcontext, workspacelen);
00239    else if (!strcasecmp(name, "channel"))
00240       ast_copy_string(workspace, cdr->channel, workspacelen);
00241    else if (!strcasecmp(name, "dstchannel"))
00242       ast_copy_string(workspace, cdr->dstchannel, workspacelen);
00243    else if (!strcasecmp(name, "lastapp"))
00244       ast_copy_string(workspace, cdr->lastapp, workspacelen);
00245    else if (!strcasecmp(name, "lastdata"))
00246       ast_copy_string(workspace, cdr->lastdata, workspacelen);
00247    else if (!strcasecmp(name, "start"))
00248       cdr_get_tv(cdr->start, raw ? NULL : fmt, workspace, workspacelen);
00249    else if (!strcasecmp(name, "answer"))
00250       cdr_get_tv(cdr->answer, raw ? NULL : fmt, workspace, workspacelen);
00251    else if (!strcasecmp(name, "end"))
00252       cdr_get_tv(cdr->end, raw ? NULL : fmt, workspace, workspacelen);
00253    else if (!strcasecmp(name, "duration"))
00254       snprintf(workspace, workspacelen, "%ld", cdr->duration ? cdr->duration : (long)ast_tvdiff_ms(ast_tvnow(), cdr->start) / 1000);
00255    else if (!strcasecmp(name, "billsec"))
00256       snprintf(workspace, workspacelen, "%ld", cdr->billsec || cdr->answer.tv_sec == 0 ? cdr->billsec : (long)ast_tvdiff_ms(ast_tvnow(), cdr->answer) / 1000);
00257    else if (!strcasecmp(name, "disposition")) {
00258       if (raw) {
00259          snprintf(workspace, workspacelen, "%ld", cdr->disposition);
00260       } else {
00261          ast_copy_string(workspace, ast_cdr_disp2str(cdr->disposition), workspacelen);
00262       }
00263    } else if (!strcasecmp(name, "amaflags")) {
00264       if (raw) {
00265          snprintf(workspace, workspacelen, "%ld", cdr->amaflags);
00266       } else {
00267          ast_copy_string(workspace, ast_cdr_flags2str(cdr->amaflags), workspacelen);
00268       }
00269    } else if (!strcasecmp(name, "accountcode"))
00270       ast_copy_string(workspace, cdr->accountcode, workspacelen);
00271    else if (!strcasecmp(name, "uniqueid"))
00272       ast_copy_string(workspace, cdr->uniqueid, workspacelen);
00273    else if (!strcasecmp(name, "userfield"))
00274       ast_copy_string(workspace, cdr->userfield, workspacelen);
00275    else if ((varbuf = ast_cdr_getvar_internal(cdr, name, recur)))
00276       ast_copy_string(workspace, varbuf, workspacelen);
00277    else
00278       workspace[0] = '\0';
00279 
00280    if (!ast_strlen_zero(workspace))
00281       *ret = workspace;
00282 }

int ast_cdr_init ( struct ast_cdr cdr,
struct ast_channel chan 
)

Initialize based on a channel.

Parameters:
cdr Call Detail Record to use for channel
chan Channel to bind CDR with Initializes a CDR and associates it with a particular channel
Returns:
0 by default

Definition at line 842 of file cdr.c.

References ast_channel::_state, ast_channel::accountcode, ast_channel::amaflags, AST_CDR_ANSWERED, AST_CDR_FLAG_LOCKED, AST_CDR_NOANSWER, ast_copy_string(), AST_STATE_UP, ast_test_flag, chan, ast_cdr::channel, ast_channel::context, ast_channel::exten, ast_channel::macrocontext, ast_channel::macroexten, ast_channel::name, ast_cdr::next, S_OR, set_one_cid(), and ast_channel::uniqueid.

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

00843 {
00844    char *chan;
00845 
00846    for ( ; cdr ; cdr = cdr->next) {
00847       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
00848          chan = S_OR(cdr->channel, "<unknown>");
00849          ast_copy_string(cdr->channel, c->name, sizeof(cdr->channel));
00850          set_one_cid(cdr, c);
00851 
00852          cdr->disposition = (c->_state == AST_STATE_UP) ?  AST_CDR_ANSWERED : AST_CDR_NOANSWER;
00853          cdr->amaflags = c->amaflags ? c->amaflags :  ast_default_amaflags;
00854          ast_copy_string(cdr->accountcode, c->accountcode, sizeof(cdr->accountcode));
00855          /* Destination information */
00856          ast_copy_string(cdr->dst, S_OR(c->macroexten,c->exten), sizeof(cdr->dst));
00857          ast_copy_string(cdr->dcontext, S_OR(c->macrocontext,c->context), sizeof(cdr->dcontext));
00858          /* Unique call identifier */
00859          ast_copy_string(cdr->uniqueid, c->uniqueid, sizeof(cdr->uniqueid));
00860       }
00861    }
00862    return 0;
00863 }

int ast_cdr_isset_unanswered ( void   ) 

Definition at line 160 of file cdr.c.

References unanswered.

Referenced by ring_entry(), and try_calling().

00161 {
00162    return unanswered;
00163 }

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:
to the cdr to get the goodies
from the cdr to give the goodies

Definition at line 497 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::src, ast_cdr::start, and ast_cdr::userfield.

00498 {
00499    struct ast_cdr *zcdr;
00500    struct ast_cdr *lto = NULL;
00501    struct ast_cdr *lfrom = NULL;
00502    int discard_from = 0;
00503    
00504    if (!to || !from)
00505       return;
00506 
00507    /* don't merge into locked CDR's -- it's bad business */
00508    if (ast_test_flag(to, AST_CDR_FLAG_LOCKED)) {
00509       zcdr = to; /* safety valve? */
00510       while (to->next) {
00511          lto = to;
00512          to = to->next;
00513       }
00514       
00515       if (ast_test_flag(to, AST_CDR_FLAG_LOCKED)) {
00516          ast_log(LOG_WARNING, "Merging into locked CDR... no choice.");
00517          to = zcdr; /* safety-- if all there are is locked CDR's, then.... ?? */
00518          lto = NULL;
00519       }
00520    }
00521 
00522    if (ast_test_flag(from, AST_CDR_FLAG_LOCKED)) {
00523       struct ast_cdr *llfrom = NULL;
00524       discard_from = 1;
00525       if (lto) {
00526          /* insert the from stuff after lto */
00527          lto->next = from;
00528          lfrom = from;
00529          while (lfrom && lfrom->next) {
00530             if (!lfrom->next->next)
00531                llfrom = lfrom;
00532             lfrom = lfrom->next; 
00533          }
00534          /* rip off the last entry and put a copy of the to at the end */
00535          llfrom->next = to;
00536          from = lfrom;
00537       } else {
00538          /* save copy of the current *to cdr */
00539          struct ast_cdr tcdr;
00540          memcpy(&tcdr, to, sizeof(tcdr));
00541          /* copy in the locked from cdr */
00542          memcpy(to, from, sizeof(*to));
00543          lfrom = from;
00544          while (lfrom && lfrom->next) {
00545             if (!lfrom->next->next)
00546                llfrom = lfrom;
00547             lfrom = lfrom->next; 
00548          }
00549          from->next = NULL;
00550          /* rip off the last entry and put a copy of the to at the end */
00551          if (llfrom == from)
00552             to = to->next = ast_cdr_dup(&tcdr);
00553          else
00554             to = llfrom->next = ast_cdr_dup(&tcdr);
00555          from = lfrom;
00556       }
00557    }
00558    
00559    if (!ast_tvzero(from->start)) {
00560       if (!ast_tvzero(to->start)) {
00561          if (ast_tvcmp(to->start, from->start) > 0 ) {
00562             to->start = from->start; /* use the earliest time */
00563             from->start = ast_tv(0,0); /* we actively "steal" these values */
00564          }
00565          /* else nothing to do */
00566       } else {
00567          to->start = from->start;
00568          from->start = ast_tv(0,0); /* we actively "steal" these values */
00569       }
00570    }
00571    if (!ast_tvzero(from->answer)) {
00572       if (!ast_tvzero(to->answer)) {
00573          if (ast_tvcmp(to->answer, from->answer) > 0 ) {
00574             to->answer = from->answer; /* use the earliest time */
00575             from->answer = ast_tv(0,0); /* we actively "steal" these values */
00576          }
00577          /* we got the earliest answer time, so we'll settle for that? */
00578       } else {
00579          to->answer = from->answer;
00580          from->answer = ast_tv(0,0); /* we actively "steal" these values */
00581       }
00582    }
00583    if (!ast_tvzero(from->end)) {
00584       if (!ast_tvzero(to->end)) {
00585          if (ast_tvcmp(to->end, from->end) < 0 ) {
00586             to->end = from->end; /* use the latest time */
00587             from->end = ast_tv(0,0); /* we actively "steal" these values */
00588             to->duration = to->end.tv_sec - to->start.tv_sec;  /* don't forget to update the duration, billsec, when we set end */
00589             to->billsec = ast_tvzero(to->answer) ? 0 : to->end.tv_sec - to->answer.tv_sec;
00590          }
00591          /* else, nothing to do */
00592       } else {
00593          to->end = from->end;
00594          from->end = ast_tv(0,0); /* we actively "steal" these values */
00595          to->duration = to->end.tv_sec - to->start.tv_sec;
00596          to->billsec = ast_tvzero(to->answer) ? 0 : to->end.tv_sec - to->answer.tv_sec;
00597       }
00598    }
00599    if (to->disposition < from->disposition) {
00600       to->disposition = from->disposition;
00601       from->disposition = AST_CDR_NOANSWER;
00602    }
00603    if (ast_strlen_zero(to->lastapp) && !ast_strlen_zero(from->lastapp)) {
00604       ast_copy_string(to->lastapp, from->lastapp, sizeof(to->lastapp));
00605       from->lastapp[0] = 0; /* theft */
00606    }
00607    if (ast_strlen_zero(to->lastdata) && !ast_strlen_zero(from->lastdata)) {
00608       ast_copy_string(to->lastdata, from->lastdata, sizeof(to->lastdata));
00609       from->lastdata[0] = 0; /* theft */
00610    }
00611    if (ast_strlen_zero(to->dcontext) && !ast_strlen_zero(from->dcontext)) {
00612       ast_copy_string(to->dcontext, from->dcontext, sizeof(to->dcontext));
00613       from->dcontext[0] = 0; /* theft */
00614    }
00615    if (ast_strlen_zero(to->dstchannel) && !ast_strlen_zero(from->dstchannel)) {
00616       ast_copy_string(to->dstchannel, from->dstchannel, sizeof(to->dstchannel));
00617       from->dstchannel[0] = 0; /* theft */
00618    }
00619    if (!ast_strlen_zero(from->channel) && (ast_strlen_zero(to->channel) || !strncasecmp(from->channel, "Agent/", 6))) {
00620       ast_copy_string(to->channel, from->channel, sizeof(to->channel));
00621       from->channel[0] = 0; /* theft */
00622    }
00623    if (ast_strlen_zero(to->src) && !ast_strlen_zero(from->src)) {
00624       ast_copy_string(to->src, from->src, sizeof(to->src));
00625       from->src[0] = 0; /* theft */
00626    }
00627    if (ast_strlen_zero(to->clid) && !ast_strlen_zero(from->clid)) {
00628       ast_copy_string(to->clid, from->clid, sizeof(to->clid));
00629       from->clid[0] = 0; /* theft */
00630    }
00631    if (ast_strlen_zero(to->dst) && !ast_strlen_zero(from->dst)) {
00632       ast_copy_string(to->dst, from->dst, sizeof(to->dst));
00633       from->dst[0] = 0; /* theft */
00634    }
00635    if (!to->amaflags)
00636       to->amaflags = AST_CDR_DOCUMENTATION;
00637    if (!from->amaflags)
00638       from->amaflags = AST_CDR_DOCUMENTATION; /* make sure both amaflags are set to something (DOC is default) */
00639    if (ast_test_flag(from, AST_CDR_FLAG_LOCKED) || (to->amaflags == AST_CDR_DOCUMENTATION && from->amaflags != AST_CDR_DOCUMENTATION)) {
00640       to->amaflags = from->amaflags;
00641    }
00642    if (ast_test_flag(from, AST_CDR_FLAG_LOCKED) || (ast_strlen_zero(to->accountcode) && !ast_strlen_zero(from->accountcode))) {
00643       ast_copy_string(to->accountcode, from->accountcode, sizeof(to->accountcode));
00644    }
00645    if (ast_test_flag(from, AST_CDR_FLAG_LOCKED) || (ast_strlen_zero(to->userfield) && !ast_strlen_zero(from->userfield))) {
00646       ast_copy_string(to->userfield, from->userfield, sizeof(to->userfield));
00647    }
00648    /* flags, varsead, ? */
00649    cdr_merge_vars(from, to);
00650 
00651    if (ast_test_flag(from, AST_CDR_FLAG_KEEP_VARS))
00652       ast_set_flag(to, AST_CDR_FLAG_KEEP_VARS);
00653    if (ast_test_flag(from, AST_CDR_FLAG_POSTED))
00654       ast_set_flag(to, AST_CDR_FLAG_POSTED);
00655    if (ast_test_flag(from, AST_CDR_FLAG_LOCKED))
00656       ast_set_flag(to, AST_CDR_FLAG_LOCKED);
00657    if (ast_test_flag(from, AST_CDR_FLAG_CHILD))
00658       ast_set_flag(to, AST_CDR_FLAG_CHILD);
00659    if (ast_test_flag(from, AST_CDR_FLAG_POST_DISABLED))
00660       ast_set_flag(to, AST_CDR_FLAG_POST_DISABLED);
00661 
00662    /* last, but not least, we need to merge any forked CDRs to the 'to' cdr */
00663    while (from->next) {
00664       /* just rip 'em off the 'from' and insert them on the 'to' */
00665       zcdr = from->next;
00666       from->next = zcdr->next;
00667       zcdr->next = NULL;
00668       /* zcdr is now ripped from the current list; */
00669       ast_cdr_append(to, zcdr);
00670    }
00671    if (discard_from)
00672       ast_cdr_discard(from);
00673 }

void ast_cdr_noanswer ( struct ast_cdr cdr  ) 

A call wasn't answered.

Parameters:
cdr the 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 727 of file cdr.c.

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

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

00728 {
00729    char *chan; 
00730 
00731    while (cdr) {
00732       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
00733          chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>";
00734          check_post(cdr);
00735          cdr->disposition = AST_CDR_NOANSWER;
00736       }
00737       cdr = cdr->next;
00738    }
00739 }

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

Register a CDR handling engine.

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

Returns:
0 on success, -1 on failure

Definition at line 108 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::list, LOG_WARNING, and ast_cdr_beitem::name.

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

00109 {
00110    struct ast_cdr_beitem *i = NULL;
00111 
00112    if (!name)
00113       return -1;
00114 
00115    if (!be) {
00116       ast_log(LOG_WARNING, "CDR engine '%s' lacks backend\n", name);
00117       return -1;
00118    }
00119 
00120    AST_RWLIST_WRLOCK(&be_list);
00121    AST_RWLIST_TRAVERSE(&be_list, i, list) {
00122       if (!strcasecmp(name, i->name)) {
00123          ast_log(LOG_WARNING, "Already have a CDR backend called '%s'\n", name);
00124          AST_RWLIST_UNLOCK(&be_list);
00125          return -1;
00126       }
00127    }
00128 
00129    if (!(i = ast_calloc(1, sizeof(*i))))  
00130       return -1;
00131 
00132    i->be = be;
00133    ast_copy_string(i->name, name, sizeof(i->name));
00134    ast_copy_string(i->desc, desc, sizeof(i->desc));
00135 
00136    AST_RWLIST_INSERT_HEAD(&be_list, i, list);
00137    AST_RWLIST_UNLOCK(&be_list);
00138 
00139    return 0;
00140 }

void ast_cdr_reset ( struct ast_cdr cdr,
struct ast_flags flags 
)

Reset the detail record, optionally posting it first.

Parameters:
cdr which 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 1057 of file cdr.c.

References ast_cdr::answer, ast_cdr_detach(), ast_cdr_dup(), 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_flags::flags, ast_cdr::next, and ast_cdr::start.

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

01058 {
01059    struct ast_cdr *duplicate;
01060    struct ast_flags flags = { 0 };
01061 
01062    if (_flags)
01063       ast_copy_flags(&flags, _flags, AST_FLAGS_ALL);
01064 
01065    for ( ; cdr ; cdr = cdr->next) {
01066       /* Detach if post is requested */
01067       if (ast_test_flag(&flags, AST_CDR_FLAG_LOCKED) || !ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
01068          if (ast_test_flag(&flags, AST_CDR_FLAG_POSTED)) {
01069             ast_cdr_end(cdr);
01070             if ((duplicate = ast_cdr_dup(cdr))) {
01071                ast_cdr_detach(duplicate);
01072             }
01073             ast_set_flag(cdr, AST_CDR_FLAG_POSTED);
01074          }
01075 
01076          /* enable CDR only */
01077          if (ast_test_flag(&flags, AST_CDR_FLAG_POST_ENABLE)) {
01078             ast_clear_flag(cdr, AST_CDR_FLAG_POST_DISABLED);
01079             continue;
01080          }
01081 
01082          /* clear variables */
01083          if (!ast_test_flag(&flags, AST_CDR_FLAG_KEEP_VARS)) {
01084             ast_cdr_free_vars(cdr, 0);
01085          }
01086 
01087          /* Reset to initial state */
01088          ast_clear_flag(cdr, AST_FLAGS_ALL); 
01089          memset(&cdr->start, 0, sizeof(cdr->start));
01090          memset(&cdr->end, 0, sizeof(cdr->end));
01091          memset(&cdr->answer, 0, sizeof(cdr->answer));
01092          cdr->billsec = 0;
01093          cdr->duration = 0;
01094          ast_cdr_start(cdr);
01095          cdr->disposition = AST_CDR_NOANSWER;
01096       }
01097    }
01098 }

int ast_cdr_serialize_variables ( struct ast_cdr cdr,
struct ast_str **  buf,
char  delim,
char  sep,
int  recur 
)

Definition at line 362 of file cdr.c.

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

Referenced by handle_showchan().

00363 {
00364    struct ast_var_t *variables;
00365    const char *var, *val;
00366    char *tmp;
00367    char workspace[256];
00368    int total = 0, x = 0, i;
00369 
00370    (*buf)->used = 0;
00371    (*buf)->str[0] = '\0';
00372 
00373    for (; cdr; cdr = recur ? cdr->next : NULL) {
00374       if (++x > 1)
00375          ast_str_append(buf, 0, "\n");
00376 
00377       AST_LIST_TRAVERSE(&cdr->varshead, variables, entries) {
00378          if (variables &&
00379              (var = ast_var_name(variables)) && (val = ast_var_value(variables)) &&
00380              !ast_strlen_zero(var) && !ast_strlen_zero(val)) {
00381             if (ast_str_append(buf, 0, "level %d: %s%c%s%c", x, var, delim, val, sep) < 0) {
00382                ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
00383                break;
00384             } else
00385                total++;
00386          } else 
00387             break;
00388       }
00389 
00390       for (i = 0; cdr_readonly_vars[i]; i++) {
00391          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 */
00392          ast_cdr_getvar(cdr, cdr_readonly_vars[i], &tmp, workspace, sizeof(workspace), 0, 0);
00393          if (!tmp)
00394             continue;
00395          
00396          if (ast_str_append(buf, 0, "level %d: %s%c%s%c", x, cdr_readonly_vars[i], delim, tmp, sep) < 0) {
00397             ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
00398             break;
00399          } else
00400             total++;
00401       }
00402    }
00403 
00404    return total;
00405 }

int ast_cdr_setaccount ( struct ast_channel chan,
const char *  account 
)

Set account code, will generate AMI event.

Definition at line 931 of file cdr.c.

References ast_cdr::accountcode, accountcode, ast_channel::accountcode, AST_CDR_FLAG_LOCKED, ast_copy_string(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, buf, ast_channel::cdr, chan, EVENT_FLAG_CALL, manager_event, 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(), cdr_write(), and rpt_call().

00932 {
00933    struct ast_cdr *cdr = chan->cdr;
00934    char buf[BUFSIZ/2] = "";
00935    if (!ast_strlen_zero(chan->accountcode))
00936       ast_copy_string(buf, chan->accountcode, sizeof(buf));
00937 
00938    ast_string_field_set(chan, accountcode, account);
00939    for ( ; cdr ; cdr = cdr->next) {
00940       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
00941          ast_copy_string(cdr->accountcode, chan->accountcode, sizeof(cdr->accountcode));
00942       }
00943    }
00944 
00945    /* Signal change of account code to manager */
00946    manager_event(EVENT_FLAG_CALL, "NewAccountCode", "Channel: %s\r\nUniqueid: %s\r\nAccountCode: %s\r\nOldAccountCode: %s\r\n", chan->name, chan->uniqueid, chan->accountcode, buf);
00947    return 0;
00948 }

int ast_cdr_setamaflags ( struct ast_channel chan,
const char *  amaflags 
)

Set AMA flags for channel.

Definition at line 950 of file cdr.c.

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

Referenced by cdr_write(), and pbx_builtin_setamaflags().

00951 {
00952    struct ast_cdr *cdr;
00953    int newflag = ast_cdr_amaflags2int(flag);
00954    if (newflag) {
00955       for (cdr = chan->cdr; cdr; cdr = cdr->next) {
00956          if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
00957             cdr->amaflags = newflag;
00958          }
00959       }
00960    }
00961 
00962    return 0;
00963 }

void ast_cdr_setanswer ( struct ast_cdr cdr,
struct timeval  t 
)

Set the answer time for a call.

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

Definition at line 788 of file cdr.c.

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

00789 {
00790 
00791    for (; cdr; cdr = cdr->next) {
00792       if (ast_test_flag(cdr, AST_CDR_FLAG_ANSLOCKED))
00793          continue;
00794       if (ast_test_flag(cdr, AST_CDR_FLAG_DONT_TOUCH) && ast_test_flag(cdr, AST_CDR_FLAG_LOCKED))
00795          continue;
00796       check_post(cdr);
00797       cdr->answer = t;
00798    }
00799 }

void ast_cdr_setapp ( struct ast_cdr cdr,
char *  app,
char *  data 
)

Set the last executed application.

Parameters:
cdr which cdr to act upon
app the name of the app you wish to change it to
data the 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 776 of file cdr.c.

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

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

00777 {
00778 
00779    for (; cdr; cdr = cdr->next) {
00780       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
00781          check_post(cdr);
00782          ast_copy_string(cdr->lastapp, S_OR(app, ""), sizeof(cdr->lastapp));
00783          ast_copy_string(cdr->lastdata, S_OR(data, ""), sizeof(cdr->lastdata));
00784       }
00785    }
00786 }

int ast_cdr_setcid ( struct ast_cdr cdr,
struct ast_channel chan 
)

Initialize based on a channel.

Parameters:
cdr Call Detail Record to use for channel
chan Channel to bind CDR with Initializes a CDR and associates it with a particular channel
Returns:
0 by default

Definition at line 833 of file cdr.c.

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

Referenced by ast_bridge_call(), and callerid_write().

00834 {
00835    for (; cdr; cdr = cdr->next) {
00836       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED))
00837          set_one_cid(cdr, c);
00838    }
00839    return 0;
00840 }

void ast_cdr_setdestchan ( struct ast_cdr cdr,
const char *  chan 
)

Set the destination channel, if there was one.

Parameters:
cdr Which cdr it's applied to
chan Channel to which dest will be Sets the destination channel the CDR is applied to Returns nothing

Definition at line 766 of file cdr.c.

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

Referenced by dial_exec_full(), park_exec_full(), and ring_entry().

00767 {
00768    for (; cdr; cdr = cdr->next) {
00769       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
00770          check_post(cdr);
00771          ast_copy_string(cdr->dstchannel, chann, sizeof(cdr->dstchannel));
00772       }
00773    }
00774 }

void ast_cdr_setdisposition ( struct ast_cdr cdr,
long int  disposition 
)

Set the disposition for a call.

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

Definition at line 801 of file cdr.c.

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

Referenced by ast_bridge_call().

00802 {
00803 
00804    for (; cdr; cdr = cdr->next) {
00805       if (ast_test_flag(cdr, AST_CDR_FLAG_LOCKED))
00806          continue;
00807       check_post(cdr);
00808       cdr->disposition = disposition;
00809    }
00810 }

int ast_cdr_setuserfield ( struct ast_channel chan,
const char *  userfield 
)

Set CDR user field for channel (stored in CDR).

Definition at line 965 of file cdr.c.

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

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

00966 {
00967    struct ast_cdr *cdr = chan->cdr;
00968 
00969    for ( ; cdr ; cdr = cdr->next) {
00970       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) 
00971          ast_copy_string(cdr->userfield, userfield, sizeof(cdr->userfield));
00972    }
00973 
00974    return 0;
00975 }

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 292 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, and ast_cdr::next.

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

00293 {
00294    struct ast_var_t *newvariable;
00295    struct varshead *headp;
00296    int x;
00297    
00298    if (!cdr)  /* don't die if the cdr is null */
00299       return -1;
00300    
00301    for (x = 0; cdr_readonly_vars[x]; x++) {
00302       if (!strcasecmp(name, cdr_readonly_vars[x])) {
00303          ast_log(LOG_ERROR, "Attempt to set the '%s' read-only variable!.\n", name);
00304          return -1;
00305       }
00306    }
00307 
00308    if (!cdr) {
00309       ast_log(LOG_ERROR, "Attempt to set a variable on a nonexistent CDR record.\n");
00310       return -1;
00311    }
00312 
00313    for (; cdr; cdr = recur ? cdr->next : NULL) {
00314       if (ast_test_flag(cdr, AST_CDR_FLAG_DONT_TOUCH) && ast_test_flag(cdr, AST_CDR_FLAG_LOCKED))
00315          continue;
00316       headp = &cdr->varshead;
00317       AST_LIST_TRAVERSE_SAFE_BEGIN(headp, newvariable, entries) {
00318          if (!strcasecmp(ast_var_name(newvariable), name)) {
00319             /* there is already such a variable, delete it */
00320             AST_LIST_REMOVE_CURRENT(entries);
00321             ast_var_delete(newvariable);
00322             break;
00323          }
00324       }
00325       AST_LIST_TRAVERSE_SAFE_END;
00326       
00327       if (value) {
00328          newvariable = ast_var_assign(name, value);
00329          AST_LIST_INSERT_HEAD(headp, newvariable, entries);
00330       }
00331    }
00332 
00333    return 0;
00334 }

void ast_cdr_specialized_reset ( struct ast_cdr cdr,
struct ast_flags flags 
)

Parameters:
cdr which 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 1100 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, ast_flags::flags, and ast_cdr::start.

Referenced by ast_bridge_call().

01101 {
01102    struct ast_flags flags = { 0 };
01103 
01104    if (_flags)
01105       ast_copy_flags(&flags, _flags, AST_FLAGS_ALL);
01106    
01107    /* Reset to initial state */
01108    if (ast_test_flag(cdr, AST_CDR_FLAG_POST_DISABLED)) { /* But do NOT lose the NoCDR() setting */
01109       ast_clear_flag(cdr, AST_FLAGS_ALL); 
01110       ast_set_flag(cdr, AST_CDR_FLAG_POST_DISABLED);
01111    } else {
01112       ast_clear_flag(cdr, AST_FLAGS_ALL); 
01113    }
01114    
01115    memset(&cdr->start, 0, sizeof(cdr->start));
01116    memset(&cdr->end, 0, sizeof(cdr->end));
01117    memset(&cdr->answer, 0, sizeof(cdr->answer));
01118    cdr->billsec = 0;
01119    cdr->duration = 0;
01120    ast_cdr_start(cdr);
01121    cdr->disposition = AST_CDR_NULL;
01122 }

void ast_cdr_start ( struct ast_cdr cdr  ) 

Start a call.

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

Definition at line 675 of file cdr.c.

References AST_CDR_FLAG_LOCKED, ast_test_flag, ast_tvnow(), chan, ast_cdr::channel, check_post(), ast_cdr::next, S_OR, 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().

00676 {
00677    char *chan; 
00678 
00679    for (; cdr; cdr = cdr->next) {
00680       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
00681          chan = S_OR(cdr->channel, "<unknown>");
00682          check_post(cdr);
00683          cdr->start = ast_tvnow();
00684       }
00685    }
00686 }

void ast_cdr_submit_batch ( int  shutdown  ) 

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

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

Definition at line 1178 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().

01179 {
01180    struct ast_cdr_batch_item *oldbatchitems = NULL;
01181    pthread_t batch_post_thread = AST_PTHREADT_NULL;
01182 
01183    /* if there's no batch, or no CDRs in the batch, then there's nothing to do */
01184    if (!batch || !batch->head)
01185       return;
01186 
01187    /* move the old CDRs aside, and prepare a new CDR batch */
01188    ast_mutex_lock(&cdr_batch_lock);
01189    oldbatchitems = batch->head;
01190    reset_batch();
01191    ast_mutex_unlock(&cdr_batch_lock);
01192 
01193    /* if configured, spawn a new thread to post these CDRs,
01194       also try to save as much as possible if we are shutting down safely */
01195    if (batchscheduleronly || do_shutdown) {
01196       ast_debug(1, "CDR single-threaded batch processing begins now\n");
01197       do_batch_backend_process(oldbatchitems);
01198    } else {
01199       if (ast_pthread_create_detached_background(&batch_post_thread, NULL, do_batch_backend_process, oldbatchitems)) {
01200          ast_log(LOG_WARNING, "CDR processing thread could not detach, now trying in this thread\n");
01201          do_batch_backend_process(oldbatchitems);
01202       } else {
01203          ast_debug(1, "CDR multi-threaded batch processing begins now\n");
01204       }
01205    }
01206 }

void ast_cdr_unregister ( const char *  name  ) 

Unregister a CDR handling engine.

unregister a CDR driver

Definition at line 143 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, ast_cdr_beitem::list, and ast_cdr_beitem::name.

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

00144 {
00145    struct ast_cdr_beitem *i = NULL;
00146 
00147    AST_RWLIST_WRLOCK(&be_list);
00148    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&be_list, i, list) {
00149       if (!strcasecmp(name, i->name)) {
00150          AST_RWLIST_REMOVE_CURRENT(list);
00151          ast_verb(2, "Unregistered '%s' CDR backend\n", name);
00152          ast_free(i);
00153          break;
00154       }
00155    }
00156    AST_RWLIST_TRAVERSE_SAFE_END;
00157    AST_RWLIST_UNLOCK(&be_list);
00158 }

int ast_cdr_update ( struct ast_channel chan  ) 

Update CDR on a channel

Definition at line 991 of file cdr.c.

References ast_channel::accountcode, AST_CDR_FLAG_LOCKED, ast_copy_string(), ast_test_flag, ast_channel::cdr, ast_channel::context, ast_channel::exten, ast_channel::macrocontext, ast_channel::macroexten, ast_cdr::next, 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().

00992 {
00993    struct ast_cdr *cdr = c->cdr;
00994 
00995    for ( ; cdr ; cdr = cdr->next) {
00996       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
00997          set_one_cid(cdr, c);
00998 
00999          /* Copy account code et-al */ 
01000          ast_copy_string(cdr->accountcode, c->accountcode, sizeof(cdr->accountcode));
01001          
01002          /* Destination information */ /* XXX privilege macro* ? */
01003          ast_copy_string(cdr->dst, S_OR(c->macroexten, c->exten), sizeof(cdr->dst));
01004          ast_copy_string(cdr->dcontext, S_OR(c->macrocontext, c->context), sizeof(cdr->dcontext));
01005       }
01006    }
01007 
01008    return 0;
01009 }

int check_cdr_enabled ( void   ) 

Return TRUE if CDR subsystem is enabled.

Definition at line 100 of file cdr.c.

References enabled.

Referenced by action_coresettings(), and handle_show_settings().

00101 {
00102    return enabled;
00103 }


Variable Documentation

char ast_default_accountcode[AST_MAX_ACCOUNT_CODE]

Definition at line 55 of file cdr.c.

Referenced by __ast_channel_alloc_ap().

int ast_default_amaflags

Default AMA flag for billing records (CDR's)

Definition at line 54 of file cdr.c.

Referenced by __ast_channel_alloc_ap(), and ast_bridge_call().


Generated on Wed Aug 18 22:34:05 2010 for Asterisk - the Open Source PBX by  doxygen 1.4.7