Thu Oct 11 06:48:05 2012

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"

Include dependency graph for cdr.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

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

Defines

#define AST_MAX_ACCOUNT_CODE   20
#define AST_MAX_USER_FIELD   256
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)

Typedefs

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

Functions

struct 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.
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).
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_*.
struct 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, const char *app, const 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)

#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(), dial_exec_full(), 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(), ast_cdr_reset(), and forkcdr_exec().

#define AST_CDR_FLAG_LOCKED   (1 << 2)

#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)

#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(), disa_exec(), 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   )  [read]

Allocate a CDR record.

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

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

00461 {
00462    struct ast_cdr *x;
00463    x = ast_calloc(1, sizeof(*x));
00464    if (!x)
00465       ast_log(LOG_ERROR,"Allocation Failure for a CDR!\n");
00466    return x;
00467 }

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

01022 {
01023    if (!strcasecmp(flag, "default"))
01024       return 0;
01025    if (!strcasecmp(flag, "omit"))
01026       return AST_CDR_OMIT;
01027    if (!strcasecmp(flag, "billing"))
01028       return AST_CDR_BILLING;
01029    if (!strcasecmp(flag, "documentation"))
01030       return AST_CDR_DOCUMENTATION;
01031    return -1;
01032 }

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

00696 {
00697 
00698    for (; cdr; cdr = cdr->next) {
00699       if (ast_test_flag(cdr, AST_CDR_FLAG_ANSLOCKED)) 
00700          continue;
00701       if (ast_test_flag(cdr, AST_CDR_FLAG_DONT_TOUCH) && ast_test_flag(cdr, AST_CDR_FLAG_LOCKED))
00702          continue;
00703       check_post(cdr);
00704       if (cdr->disposition < AST_CDR_ANSWERED)
00705          cdr->disposition = AST_CDR_ANSWERED;
00706       if (ast_tvzero(cdr->answer))
00707          cdr->answer = ast_tvnow();
00708    }
00709 }

struct ast_cdr* ast_cdr_append ( struct ast_cdr cdr,
struct ast_cdr newcdr 
) [read]

Definition at line 1134 of file cdr.c.

References ast_cdr::next.

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

01135 {
01136    struct ast_cdr *ret;
01137 
01138    if (cdr) {
01139       ret = cdr;
01140 
01141       while (cdr->next)
01142          cdr = cdr->next;
01143       cdr->next = newcdr;
01144    } else {
01145       ret = newcdr;
01146    }
01147 
01148    return ret;
01149 }

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

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

Definition at line 987 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.

00988 {
00989    struct ast_cdr *cdr = chan->cdr;
00990 
00991    for ( ; cdr ; cdr = cdr->next) {
00992       int len = strlen(cdr->userfield);
00993 
00994       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED))
00995          ast_copy_string(cdr->userfield + len, userfield, sizeof(cdr->userfield) - len);
00996    }
00997 
00998    return 0;
00999 }

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 711 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(), ring_entry(), and wait_for_answer().

00712 {
00713 
00714    for (; cdr; cdr = cdr->next) {
00715       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
00716          check_post(cdr);
00717          cdr->disposition = AST_CDR_BUSY;
00718       }
00719    }
00720 }

int ast_cdr_copy_vars ( struct ast_cdr to_cdr,
struct ast_cdr from_cdr 
)

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

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

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

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

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

00450 {
00451    while (cdr) {
00452       struct ast_cdr *next = cdr->next;
00453 
00454       ast_cdr_free_vars(cdr, 0);
00455       ast_free(cdr);
00456       cdr = next;
00457    }
00458 }

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

00911 {
00912    switch (disposition) {
00913    case AST_CDR_NULL:
00914       return "NO ANSWER"; /* by default, for backward compatibility */
00915    case AST_CDR_NOANSWER:
00916       return "NO ANSWER";
00917    case AST_CDR_FAILED:
00918       return "FAILED";     
00919    case AST_CDR_BUSY:
00920       return "BUSY";    
00921    case AST_CDR_ANSWERED:
00922       return "ANSWERED";
00923    }
00924    return "UNKNOWN";
00925 }

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

00752 {
00753    int res = 0;
00754 
00755    for (; cdr; cdr = cdr->next) {
00756       switch (cause) {  /* handle all the non failure, busy cases, return 0 not to set disposition,
00757                      return -1 to set disposition to FAILED */
00758       case AST_CAUSE_BUSY:
00759          ast_cdr_busy(cdr);
00760          break;
00761       case AST_CAUSE_NO_ANSWER:
00762          ast_cdr_noanswer(cdr);
00763          break;
00764       case AST_CAUSE_NORMAL:
00765          break;
00766       default:
00767          res = -1;
00768       }
00769    }
00770    return res;
00771 }

struct ast_cdr* ast_cdr_dup ( struct ast_cdr cdr  )  [read]

Duplicate a record.

Return values:
a malloc'd ast_cdr structure,
NULL on error (malloc failure)
Duplicate a CDR record
Returns:
Pointer to new CDR record

Definition at line 176 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_bridge_call(), ast_cdr_fork(), ast_cdr_merge(), and ast_cdr_reset().

00177 {
00178    struct ast_cdr *newcdr;
00179    
00180    if (!cdr) /* don't die if we get a null cdr pointer */
00181       return NULL;
00182    newcdr = ast_cdr_alloc();
00183    if (!newcdr)
00184       return NULL;
00185 
00186    memcpy(newcdr, cdr, sizeof(*newcdr));
00187    /* The varshead is unusable, volatile even, after the memcpy so we take care of that here */
00188    memset(&newcdr->varshead, 0, sizeof(newcdr->varshead));
00189    ast_cdr_copy_vars(newcdr, cdr);
00190    newcdr->next = NULL;
00191 
00192    return newcdr;
00193 }

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

00885 {
00886    for ( ; cdr ; cdr = cdr->next) {
00887       if (ast_test_flag(cdr, AST_CDR_FLAG_DONT_TOUCH) && ast_test_flag(cdr, AST_CDR_FLAG_LOCKED))
00888          continue;
00889       check_post(cdr);
00890       if (ast_tvzero(cdr->end))
00891          cdr->end = ast_tvnow();
00892       if (ast_tvzero(cdr->start)) {
00893          ast_log(LOG_WARNING, "CDR on channel '%s' has not started\n", S_OR(cdr->channel, "<unknown>"));
00894          cdr->disposition = AST_CDR_FAILED;
00895       } else
00896          cdr->duration = cdr->end.tv_sec - cdr->start.tv_sec;
00897       if (ast_tvzero(cdr->answer)) {
00898          if (cdr->disposition == AST_CDR_ANSWERED) {
00899             ast_log(LOG_WARNING, "CDR on channel '%s' has no answer time but is 'ANSWERED'\n", S_OR(cdr->channel, "<unknown>"));
00900             cdr->disposition = AST_CDR_FAILED;
00901          }
00902       } else {
00903          cdr->billsec = cdr->end.tv_sec - cdr->answer.tv_sec;
00904          if (ast_test_flag(&ast_options, AST_OPT_FLAG_INITIATED_SECONDS))
00905             cdr->billsec += cdr->end.tv_usec > cdr->answer.tv_usec ? 1 : 0;
00906       }
00907    }
00908 }

int ast_cdr_engine_init ( void   ) 

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

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

01533 {
01534    int res;
01535 
01536    sched = sched_context_create();
01537    if (!sched) {
01538       ast_log(LOG_ERROR, "Unable to create schedule context.\n");
01539       return -1;
01540    }
01541 
01542    ast_cli_register(&cli_status);
01543 
01544    res = do_reload(0);
01545    if (res) {
01546       ast_mutex_lock(&cdr_batch_lock);
01547       res = init_batch();
01548       ast_mutex_unlock(&cdr_batch_lock);
01549    }
01550 
01551    return res;
01552 }

int ast_cdr_engine_reload ( void   ) 

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

Definition at line 1561 of file cdr.c.

References do_reload().

01562 {
01563    return do_reload(1);
01564 }

void ast_cdr_engine_term ( void   ) 

Submit any remaining CDRs and prepare for shutdown

Definition at line 1556 of file cdr.c.

References ast_cdr_submit_batch(), and batchsafeshutdown.

Referenced by do_reload(), and quit_handler().

01557 {
01558    ast_cdr_submit_batch(batchsafeshutdown);
01559 }

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

00723 {
00724    for (; cdr; cdr = cdr->next) {
00725       check_post(cdr);
00726       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
00727          check_post(cdr);
00728          if (cdr->disposition < AST_CDR_FAILED)
00729             cdr->disposition = AST_CDR_FAILED;
00730       }
00731    }
00732 }

char* ast_cdr_flags2str ( int  flag  ) 

Flags to a string

Parameters:
flags binary flag Converts binary flags to string flags Returns string with flag name
Converts AMA flag to printable string

Definition at line 928 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(), build_csv_record(), build_radius_record(), csv_log(), manager_log(), sip_show_user(), and tds_log().

00929 {
00930    switch (flag) {
00931    case AST_CDR_OMIT:
00932       return "OMIT";
00933    case AST_CDR_BILLING:
00934       return "BILLING";
00935    case AST_CDR_DOCUMENTATION:
00936       return "DOCUMENTATION";
00937    }
00938    return "Unknown";
00939 }

void ast_cdr_free ( struct ast_cdr cdr  ) 

Free a CDR record.

Parameters:
cdr ast_cdr structure to free Returns nothing

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

00437 {
00438 
00439    while (cdr) {
00440       struct ast_cdr *next = cdr->next;
00441 
00442       ast_cdr_free_vars(cdr, 0);
00443       ast_free(cdr);
00444       cdr = next;
00445    }
00446 }

void ast_cdr_free_vars ( struct ast_cdr cdr,
int  recur 
)

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

00416 {
00417 
00418    /* clear variables */
00419    for (; cdr; cdr = recur ? cdr->next : NULL) {
00420       struct ast_var_t *vardata;
00421       struct varshead *headp = &cdr->varshead;
00422       while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries)))
00423          ast_var_delete(vardata);
00424    }
00425 }

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

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

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

References ast_channel::_state, ast_channel::accountcode, ast_cdr::accountcode, ast_channel::amaflags, ast_cdr::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_cdr::dcontext, ast_cdr::disposition, ast_cdr::dst, ast_channel::exten, ast_channel::macrocontext, ast_channel::macroexten, ast_channel::name, ast_cdr::next, S_OR, set_one_cid(), ast_channel::uniqueid, and ast_cdr::uniqueid.

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

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

int ast_cdr_isset_unanswered ( void   ) 

Definition at line 168 of file cdr.c.

References unanswered.

Referenced by ring_entry(), and try_calling().

00169 {
00170    return unanswered;
00171 }

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

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

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

00735 {
00736    char *chan; 
00737 
00738    while (cdr) {
00739       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
00740          chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>";
00741          check_post(cdr);
00742          cdr->disposition = AST_CDR_NOANSWER;
00743       }
00744       cdr = cdr->next;
00745    }
00746 }

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

Register a CDR handling engine.

Parameters:
name name associated with the particular CDR handler
desc description of the CDR handler
be function pointer to a CDR handler Used to register a Call Detail Record handler.
Return values:
0 on success.
-1 on error
Register a CDR driver. Each registered CDR driver generates a CDR
Returns:
0 on success, -1 on failure

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

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

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 1067 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_cdr::next, and ast_cdr::start.

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

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

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

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

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

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

Set account code, will generate AMI event.

Definition at line 941 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, 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(), auth_exec(), cdr_write(), and rpt_call().

00942 {
00943    struct ast_cdr *cdr = chan->cdr;
00944    char buf[BUFSIZ/2] = "";
00945    if (!ast_strlen_zero(chan->accountcode))
00946       ast_copy_string(buf, chan->accountcode, sizeof(buf));
00947 
00948    ast_string_field_set(chan, accountcode, account);
00949    for ( ; cdr ; cdr = cdr->next) {
00950       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
00951          ast_copy_string(cdr->accountcode, chan->accountcode, sizeof(cdr->accountcode));
00952       }
00953    }
00954 
00955    /* Signal change of account code to manager */
00956    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);
00957    return 0;
00958 }

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

Set AMA flags for channel.

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

00961 {
00962    struct ast_cdr *cdr;
00963    int newflag = ast_cdr_amaflags2int(flag);
00964    if (newflag) {
00965       for (cdr = chan->cdr; cdr; cdr = cdr->next) {
00966          if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
00967             cdr->amaflags = newflag;
00968          }
00969       }
00970    }
00971 
00972    return 0;
00973 }

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

00796 {
00797 
00798    for (; cdr; cdr = cdr->next) {
00799       if (ast_test_flag(cdr, AST_CDR_FLAG_ANSLOCKED))
00800          continue;
00801       if (ast_test_flag(cdr, AST_CDR_FLAG_DONT_TOUCH) && ast_test_flag(cdr, AST_CDR_FLAG_LOCKED))
00802          continue;
00803       check_post(cdr);
00804       cdr->answer = t;
00805    }
00806 }

void ast_cdr_setapp ( struct ast_cdr cdr,
const char *  app,
const 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 783 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().

00784 {
00785 
00786    for (; cdr; cdr = cdr->next) {
00787       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
00788          check_post(cdr);
00789          ast_copy_string(cdr->lastapp, S_OR(app, ""), sizeof(cdr->lastapp));
00790          ast_copy_string(cdr->lastdata, S_OR(data, ""), sizeof(cdr->lastdata));
00791       }
00792    }
00793 }

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 840 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_set_callerid(), and callerid_write().

00841 {
00842    for (; cdr; cdr = cdr->next) {
00843       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED))
00844          set_one_cid(cdr, c);
00845    }
00846    return 0;
00847 }

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 773 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(), park_exec_full(), ring_entry(), and try_calling().

00774 {
00775    for (; cdr; cdr = cdr->next) {
00776       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
00777          check_post(cdr);
00778          ast_copy_string(cdr->dstchannel, chann, sizeof(cdr->dstchannel));
00779       }
00780    }
00781 }

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

00809 {
00810 
00811    for (; cdr; cdr = cdr->next) {
00812       if (ast_test_flag(cdr, AST_CDR_FLAG_LOCKED))
00813          continue;
00814       check_post(cdr);
00815       cdr->disposition = disposition;
00816    }
00817 }

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

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

Definition at line 975 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(), cdr_write(), handle_request_info(), and start_monitor_exec().

00976 {
00977    struct ast_cdr *cdr = chan->cdr;
00978 
00979    for ( ; cdr ; cdr = cdr->next) {
00980       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) 
00981          ast_copy_string(cdr->userfield, userfield, sizeof(cdr->userfield));
00982    }
00983 
00984    return 0;
00985 }

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

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

void ast_cdr_specialized_reset ( struct ast_cdr cdr,
struct ast_flags flags 
)

Reset the detail record times, 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 1110 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().

01111 {
01112    struct ast_flags flags = { 0 };
01113 
01114    if (_flags)
01115       ast_copy_flags(&flags, _flags, AST_FLAGS_ALL);
01116    
01117    /* Reset to initial state */
01118    if (ast_test_flag(cdr, AST_CDR_FLAG_POST_DISABLED)) { /* But do NOT lose the NoCDR() setting */
01119       ast_clear_flag(cdr, AST_FLAGS_ALL); 
01120       ast_set_flag(cdr, AST_CDR_FLAG_POST_DISABLED);
01121    } else {
01122       ast_clear_flag(cdr, AST_FLAGS_ALL); 
01123    }
01124    
01125    memset(&cdr->start, 0, sizeof(cdr->start));
01126    memset(&cdr->end, 0, sizeof(cdr->end));
01127    memset(&cdr->answer, 0, sizeof(cdr->answer));
01128    cdr->billsec = 0;
01129    cdr->duration = 0;
01130    ast_cdr_start(cdr);
01131    cdr->disposition = AST_CDR_NULL;
01132 }

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

00683 {
00684    char *chan; 
00685 
00686    for (; cdr; cdr = cdr->next) {
00687       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
00688          chan = S_OR(cdr->channel, "<unknown>");
00689          check_post(cdr);
00690          cdr->start = ast_tvnow();
00691       }
00692    }
00693 }

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

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

void ast_cdr_unregister ( const char *  name  ) 

Unregister a CDR handling engine.

Parameters:
name name of CDR handler to unregister Unregisters a CDR by it's name
unregister a CDR driver

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

00152 {
00153    struct ast_cdr_beitem *i = NULL;
00154 
00155    AST_RWLIST_WRLOCK(&be_list);
00156    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&be_list, i, list) {
00157       if (!strcasecmp(name, i->name)) {
00158          AST_RWLIST_REMOVE_CURRENT(list);
00159          ast_verb(2, "Unregistered '%s' CDR backend\n", name);
00160          ast_free(i);
00161          break;
00162       }
00163    }
00164    AST_RWLIST_TRAVERSE_SAFE_END;
00165    AST_RWLIST_UNLOCK(&be_list);
00166 }

int ast_cdr_update ( struct ast_channel chan  ) 

Update CDR on a channel

Definition at line 1001 of file cdr.c.

References ast_channel::accountcode, ast_cdr::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_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().

01002 {
01003    struct ast_cdr *cdr = c->cdr;
01004 
01005    for ( ; cdr ; cdr = cdr->next) {
01006       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
01007          set_one_cid(cdr, c);
01008 
01009          /* Copy account code et-al */ 
01010          ast_copy_string(cdr->accountcode, c->accountcode, sizeof(cdr->accountcode));
01011          
01012          /* Destination information */ /* XXX privilege macro* ? */
01013          ast_copy_string(cdr->dst, S_OR(c->macroexten, c->exten), sizeof(cdr->dst));
01014          ast_copy_string(cdr->dcontext, S_OR(c->macrocontext, c->context), sizeof(cdr->dcontext));
01015       }
01016    }
01017 
01018    return 0;
01019 }

int check_cdr_enabled ( void   ) 

Return TRUE if CDR subsystem is enabled.

Definition at line 108 of file cdr.c.

References enabled.

Referenced by action_coresettings(), and handle_show_settings().

00109 {
00110    return enabled;
00111 }


Variable Documentation

char ast_default_accountcode[AST_MAX_ACCOUNT_CODE]

Definition at line 55 of file cdr.c.

Referenced by __ast_channel_alloc_ap().

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 Thu Oct 11 06:48:06 2012 for Asterisk - the Open Source PBX by  doxygen 1.5.6