Mon Mar 20 08:20:18 2006

Asterisk developer's documentation


Main Page | Modules | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

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

Defines

#define AST_CDR_ANSWERED   (1 << 2)
#define AST_CDR_BILLING   (2)
#define AST_CDR_BUSY   (1 << 1)
#define AST_CDR_DOCUMENTATION   (3)
#define AST_CDR_FAILED   (1 << 3)
#define AST_CDR_FLAG_CHILD   (1 << 3)
#define AST_CDR_FLAG_KEEP_VARS   (1 << 0)
#define AST_CDR_FLAG_LOCKED   (1 << 2)
#define AST_CDR_FLAG_POST_DISABLED   (1 << 4)
#define AST_CDR_FLAG_POSTED   (1 << 1)
#define AST_CDR_NOANSWER   (1 << 0)
#define AST_CDR_OMIT   (1)
#define AST_MAX_ACCOUNT_CODE   20
#define AST_MAX_USER_FIELD   256

Typedefs

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

Functions

ast_cdrast_cdr_alloc (void)
 Allocate a CDR record Returns a malloc'd ast_cdr structure, returns NULL on error (malloc failure).
int ast_cdr_amaflags2int (const char *flag)
void ast_cdr_answer (struct ast_cdr *cdr)
ast_cdrast_cdr_append (struct ast_cdr *cdr, struct ast_cdr *newcdr)
int ast_cdr_appenduserfield (struct ast_channel *chan, const char *userfield)
void ast_cdr_busy (struct ast_cdr *cdr)
int ast_cdr_copy_vars (struct ast_cdr *to_cdr, struct ast_cdr *from_cdr)
void ast_cdr_detach (struct ast_cdr *cdr)
char * ast_cdr_disp2str (int disposition)
int ast_cdr_disposition (struct ast_cdr *cdr, int cause)
ast_cdrast_cdr_dup (struct ast_cdr *cdr)
 Duplicate a record Returns a malloc'd ast_cdr structure, returns NULL on error (malloc failure).
void ast_cdr_end (struct ast_cdr *cdr)
int ast_cdr_engine_init (void)
void ast_cdr_engine_reload (void)
void ast_cdr_engine_term (void)
void ast_cdr_failed (struct ast_cdr *cdr)
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 ast_cdr_init (struct ast_cdr *cdr, struct ast_channel *chan)
 Initialize based on a channel.
int ast_cdr_register (char *name, char *desc, ast_cdrbe be)
void ast_cdr_reset (struct ast_cdr *cdr, struct ast_flags *flags)
int ast_cdr_serialize_variables (struct ast_cdr *cdr, char *buf, size_t size, char delim, char sep, int recur)
int ast_cdr_setaccount (struct ast_channel *chan, const char *account)
int ast_cdr_setamaflags (struct ast_channel *chan, const char *amaflags)
void ast_cdr_setapp (struct ast_cdr *cdr, char *app, char *data)
int ast_cdr_setcid (struct ast_cdr *cdr, struct ast_channel *chan)
void ast_cdr_setdestchan (struct ast_cdr *cdr, char *chan)
int ast_cdr_setuserfield (struct ast_channel *chan, const char *userfield)
int ast_cdr_setvar (struct ast_cdr *cdr, const char *name, const char *value, int recur)
void ast_cdr_start (struct ast_cdr *cdr)
void ast_cdr_submit_batch (int shutdown)
void ast_cdr_unregister (char *name)
int ast_cdr_update (struct ast_channel *chan)

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

Definition at line 35 of file cdr.h.

Referenced by ast_cdr_disp2str(), and ast_cdr_init().

#define AST_CDR_BILLING   (2)
 

Definition at line 40 of file cdr.h.

Referenced by ast_cdr_flags2str().

#define AST_CDR_BUSY   (1 << 1)
 

Definition at line 34 of file cdr.h.

Referenced by ast_cdr_disp2str().

#define AST_CDR_DOCUMENTATION   (3)
 

Definition at line 41 of file cdr.h.

Referenced by ast_cdr_flags2str().

#define AST_CDR_FAILED   (1 << 3)
 

Definition at line 36 of file cdr.h.

Referenced by ast_cdr_disp2str().

#define AST_CDR_FLAG_CHILD   (1 << 3)
 

Definition at line 30 of file cdr.h.

Referenced by ast_cdr_fork().

#define AST_CDR_FLAG_KEEP_VARS   (1 << 0)
 

Definition at line 27 of file cdr.h.

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

#define AST_CDR_FLAG_LOCKED   (1 << 2)
 

Definition at line 29 of file cdr.h.

Referenced by ast_cdr_appenduserfield(), ast_cdr_busy(), ast_cdr_failed(), ast_cdr_fork(), ast_cdr_init(), ast_cdr_reset(), ast_cdr_setaccount(), ast_cdr_setapp(), ast_cdr_setcid(), ast_cdr_setdestchan(), ast_cdr_setuserfield(), ast_cdr_start(), and ast_cdr_update().

#define AST_CDR_FLAG_POST_DISABLED   (1 << 4)
 

Definition at line 31 of file cdr.h.

Referenced by ast_cdr_detach(), and ast_cdr_free().

#define AST_CDR_FLAG_POSTED   (1 << 1)
 

Definition at line 28 of file cdr.h.

Referenced by ast_cdr_answer(), ast_cdr_busy(), ast_cdr_end(), ast_cdr_failed(), ast_cdr_free(), ast_cdr_reset(), ast_cdr_setapp(), ast_cdr_setdestchan(), ast_cdr_start(), disa_exec(), and post_cdr().

#define AST_CDR_NOANSWER   (1 << 0)
 

Definition at line 33 of file cdr.h.

Referenced by ast_cdr_disp2str().

#define AST_CDR_OMIT   (1)
 

AMA Flags

Definition at line 39 of file cdr.h.

Referenced by ast_cdr_flags2str().

#define AST_MAX_ACCOUNT_CODE   20
 

Definition at line 44 of file cdr.h.

#define AST_MAX_USER_FIELD   256
 

Definition at line 43 of file cdr.h.


Typedef Documentation

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

Definition at line 105 of file cdr.h.


Function Documentation

struct ast_cdr* ast_cdr_alloc void   ) 
 

Allocate a CDR record Returns a malloc'd ast_cdr structure, returns NULL on error (malloc failure).

Definition at line 455 of file cdr.c.

References malloc.

Referenced by __agent_start_monitoring(), __ast_pbx_run(), __ast_request_and_dial(), ast_cdr_dup(), ast_feature_request_and_dial(), ast_pbx_outgoing_app(), ast_pbx_outgoing_cdr_failed(), ast_pbx_outgoing_exten(), and start_monitor_exec().

00456 {
00457    struct ast_cdr *cdr;
00458 
00459    cdr = malloc(sizeof(*cdr));
00460    if (cdr)
00461       memset(cdr, 0, sizeof(*cdr));
00462 
00463    return cdr;
00464 }

int ast_cdr_amaflags2int const char *  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 786 of file cdr.c.

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

00787 {
00788    if (!strcasecmp(flag, "default"))
00789       return 0;
00790    if (!strcasecmp(flag, "omit"))
00791       return AST_CDR_OMIT;
00792    if (!strcasecmp(flag, "billing"))
00793       return AST_CDR_BILLING;
00794    if (!strcasecmp(flag, "documentation"))
00795       return AST_CDR_DOCUMENTATION;
00796    return -1;
00797 }

void ast_cdr_answer struct ast_cdr cdr  ) 
 

Parameters:
cdr the cdr you wish to associate with the call Starts all CDR stuff necessary for doing CDR when answering a call

Definition at line 483 of file cdr.c.

References ast_cdr::answer, AST_CDR_FLAG_POSTED, ast_log(), ast_strlen_zero(), ast_test_flag, ast_cdr::channel, ast_cdr::disposition, LOG_WARNING, and ast_cdr::next.

Referenced by ast_answer(), and ast_read().

00484 {
00485    char *chan; 
00486 
00487    while (cdr) {
00488       chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>";
00489       if (ast_test_flag(cdr, AST_CDR_FLAG_POSTED))
00490          ast_log(LOG_WARNING, "CDR on channel '%s' already posted\n", chan);
00491       if (cdr->disposition < AST_CDR_ANSWERED)
00492          cdr->disposition = AST_CDR_ANSWERED;
00493       if (ast_tvzero(cdr->answer))
00494          cdr->answer = ast_tvnow();
00495       cdr = cdr->next;
00496    }
00497 }

struct ast_cdr* ast_cdr_append struct ast_cdr cdr,
struct ast_cdr newcdr
 

Definition at line 866 of file cdr.c.

References ast_cdr::next.

Referenced by ast_cdr_fork(), and attempt_transfer().

00867 {
00868    struct ast_cdr *ret;
00869 
00870    if (cdr) {
00871       ret = cdr;
00872 
00873       while (cdr->next)
00874          cdr = cdr->next;
00875       cdr->next = newcdr;
00876    } else {
00877       ret = newcdr;
00878    }
00879 
00880    return ret;
00881 }

int ast_cdr_appenduserfield struct ast_channel chan,
const char *  userfield
 

Definition at line 739 of file cdr.c.

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

Referenced by action_setcdruserfield(), appendcdruserfield_exec(), and ast_bridge_call().

00740 {
00741    struct ast_cdr *cdr = chan->cdr;
00742 
00743    while (cdr) {
00744       int len = strlen(cdr->userfield);
00745 
00746       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED))
00747          strncpy(cdr->userfield+len, userfield, sizeof(cdr->userfield) - len - 1);
00748 
00749       cdr = cdr->next;
00750    }
00751 
00752    return 0;
00753 }

void ast_cdr_busy struct ast_cdr cdr  ) 
 

Parameters:
cdr the cdr you wish to associate with the call Returns nothing important

Definition at line 499 of file cdr.c.

References AST_CDR_FLAG_LOCKED, AST_CDR_FLAG_POSTED, ast_log(), ast_strlen_zero(), ast_test_flag, ast_cdr::channel, ast_cdr::disposition, LOG_WARNING, and ast_cdr::next.

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

00500 {
00501    char *chan; 
00502 
00503    while (cdr) {
00504       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
00505          chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>";
00506          if (ast_test_flag(cdr, AST_CDR_FLAG_POSTED))
00507             ast_log(LOG_WARNING, "CDR on channel '%s' already posted\n", chan);
00508          if (cdr->disposition < AST_CDR_BUSY)
00509             cdr->disposition = AST_CDR_BUSY;
00510       }
00511       cdr = cdr->next;
00512    }
00513 }

int ast_cdr_copy_vars struct ast_cdr to_cdr,
struct ast_cdr from_cdr
 

Definition at line 326 of file cdr.c.

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

Referenced by ast_cdr_dup().

00327 {
00328    struct ast_var_t *variables, *newvariable = NULL;
00329    struct varshead *headpa, *headpb;
00330    char *var, *val;
00331    int x = 0;
00332 
00333    headpa = &from_cdr->varshead;
00334    headpb = &to_cdr->varshead;
00335 
00336    AST_LIST_TRAVERSE(headpa,variables,entries) {
00337       if (variables &&
00338           (var = ast_var_name(variables)) && (val = ast_var_value(variables)) &&
00339           !ast_strlen_zero(var) && !ast_strlen_zero(val)) {
00340          newvariable = ast_var_assign(var, val);
00341          AST_LIST_INSERT_HEAD(headpb, newvariable, entries);
00342          x++;
00343       }
00344    }
00345 
00346    return x;
00347 }

void ast_cdr_detach struct ast_cdr cdr  ) 
 

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

References AST_CDR_FLAG_POST_DISABLED, ast_cdr_free(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, batch, batchsize, ast_cdr_batch_item::cdr, ast_cdr_batch::head, init_batch(), LOG_DEBUG, LOG_WARNING, malloc, ast_cdr_batch_item::next, post_cdr(), ast_cdr_batch::size, submit_unscheduled_batch(), and ast_cdr_batch::tail.

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

00981 {
00982    struct ast_cdr_batch_item *newtail;
00983    int curr;
00984 
00985    /* maybe they disabled CDR stuff completely, so just drop it */
00986    if (!enabled) {
00987       if (option_debug)
00988          ast_log(LOG_DEBUG, "Dropping CDR !\n");
00989       ast_set_flag(cdr, AST_CDR_FLAG_POST_DISABLED);
00990       ast_cdr_free(cdr);
00991       return;
00992    }
00993 
00994    /* post stuff immediately if we are not in batch mode, this is legacy behaviour */
00995    if (!batchmode) {
00996       post_cdr(cdr);
00997       ast_cdr_free(cdr);
00998       return;
00999    }
01000 
01001    /* otherwise, each CDR gets put into a batch list (at the end) */
01002    if (option_debug)
01003       ast_log(LOG_DEBUG, "CDR detaching from this thread\n");
01004 
01005    /* we'll need a new tail for every CDR */
01006    newtail = malloc(sizeof(*newtail));
01007    if (!newtail) {
01008       ast_log(LOG_WARNING, "CDR: out of memory while trying to detach, will try in this thread instead\n");
01009       post_cdr(cdr);
01010       ast_cdr_free(cdr);
01011       return;
01012    }
01013    memset(newtail, 0, sizeof(*newtail));
01014 
01015    /* don't traverse a whole list (just keep track of the tail) */
01016    ast_mutex_lock(&cdr_batch_lock);
01017    if (!batch)
01018       init_batch();
01019    if (!batch->head) {
01020       /* new batch is empty, so point the head at the new tail */
01021       batch->head = newtail;
01022    } else {
01023       /* already got a batch with something in it, so just append a new tail */
01024       batch->tail->next = newtail;
01025    }
01026    newtail->cdr = cdr;
01027    batch->tail = newtail;
01028    curr = batch->size++;
01029    ast_mutex_unlock(&cdr_batch_lock);
01030 
01031    /* if we have enough stuff to post, then do it */
01032    if (curr >= (batchsize - 1))
01033       submit_unscheduled_batch();
01034 }

char* ast_cdr_disp2str int  disposition  ) 
 

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

References AST_CDR_ANSWERED, AST_CDR_BUSY, AST_CDR_FAILED, and AST_CDR_NOANSWER.

Referenced by ast_cdr_getvar(), build_csv_record(), csv_log(), manager_log(), odbc_log(), pgsql_log(), and tds_log().

00670 {
00671    switch (disposition) {
00672    case AST_CDR_NOANSWER:
00673       return "NO ANSWER";
00674    case AST_CDR_FAILED:
00675       return "FAILED";     
00676    case AST_CDR_BUSY:
00677       return "BUSY";    
00678    case AST_CDR_ANSWERED:
00679       return "ANSWERED";
00680    }
00681    return "UNKNOWN";
00682 }

int ast_cdr_disposition struct ast_cdr cdr,
int  cause
 

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

Definition at line 529 of file cdr.c.

References AST_CAUSE_BUSY, AST_CAUSE_FAILURE, AST_CAUSE_NORMAL, AST_CAUSE_NOTDEFINED, ast_cdr_busy(), ast_cdr_failed(), ast_log(), LOG_WARNING, and ast_cdr::next.

Referenced by __ast_request_and_dial(), ast_feature_request_and_dial(), ast_pbx_outgoing_app(), and ast_pbx_outgoing_exten().

00530 {
00531    int res = 0;
00532 
00533    while (cdr) {
00534       switch(cause) {
00535       case AST_CAUSE_BUSY:
00536          ast_cdr_busy(cdr);
00537          break;
00538       case AST_CAUSE_FAILURE:
00539          ast_cdr_failed(cdr);
00540          break;
00541       case AST_CAUSE_NORMAL:
00542          break;
00543       case AST_CAUSE_NOTDEFINED:
00544          res = -1;
00545          break;
00546       default:
00547          res = -1;
00548          ast_log(LOG_WARNING, "Cause not handled\n");
00549       }
00550       cdr = cdr->next;
00551    }
00552    return res;
00553 }

struct ast_cdr* ast_cdr_dup struct ast_cdr cdr  ) 
 

Duplicate a record Returns a malloc'd ast_cdr structure, returns NULL on error (malloc failure).

Duplicate a CDR record

Returns:
Pointer to new CDR record

Definition at line 167 of file cdr.c.

References ast_cdr_alloc(), ast_cdr_copy_vars(), ast_log(), LOG_ERROR, and ast_cdr::next.

Referenced by ast_cdr_fork(), and ast_cdr_reset().

00168 {
00169    struct ast_cdr *newcdr;
00170 
00171    if (!(newcdr = ast_cdr_alloc())) {
00172       ast_log(LOG_ERROR, "Memory Error!\n");
00173       return NULL;
00174    }
00175 
00176    memcpy(newcdr, cdr, sizeof(*newcdr));
00177    /* The varshead is unusable, volatile even, after the memcpy so we take care of that here */
00178    memset(&newcdr->varshead, 0, sizeof(newcdr->varshead));
00179    ast_cdr_copy_vars(newcdr, cdr);
00180    newcdr->next = NULL;
00181 
00182    return newcdr;
00183 }

void ast_cdr_end struct ast_cdr cdr  ) 
 

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

Definition at line 653 of file cdr.c.

References AST_CDR_FLAG_POSTED, ast_log(), ast_strlen_zero(), ast_test_flag, ast_cdr::channel, ast_cdr::end, LOG_WARNING, ast_cdr::next, and ast_cdr::start.

Referenced by __ast_request_and_dial(), ast_cdr_reset(), ast_feature_request_and_dial(), ast_hangup(), ast_pbx_outgoing_cdr_failed(), and ast_read().

00654 {
00655    char *chan;
00656 
00657    while (cdr) {
00658       chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>";
00659       if (ast_test_flag(cdr, AST_CDR_FLAG_POSTED))
00660          ast_log(LOG_WARNING, "CDR on channel '%s' already posted\n", chan);
00661       if (ast_tvzero(cdr->start))
00662          ast_log(LOG_WARNING, "CDR on channel '%s' has not started\n", chan);
00663       if (ast_tvzero(cdr->end))
00664          cdr->end = ast_tvnow();
00665       cdr = cdr->next;
00666    }
00667 }

int ast_cdr_engine_init void   ) 
 

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

Definition at line 1234 of file cdr.c.

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

Referenced by main().

01235 {
01236    int res;
01237 
01238    sched = sched_context_create();
01239    if (!sched) {
01240       ast_log(LOG_ERROR, "Unable to create schedule context.\n");
01241       return -1;
01242    }
01243 
01244    ast_cli_register(&cli_status);
01245 
01246    res = do_reload();
01247    if (res) {
01248       ast_mutex_lock(&cdr_batch_lock);
01249       res = init_batch();
01250       ast_mutex_unlock(&cdr_batch_lock);
01251    }
01252 
01253    return res;
01254 }

void ast_cdr_engine_reload void   ) 
 

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

Definition at line 1263 of file cdr.c.

References do_reload().

Referenced by ast_module_reload().

01264 {
01265    do_reload();
01266 }

void ast_cdr_engine_term void   ) 
 

Submit any remaining CDRs and prepare for shutdown

Definition at line 1258 of file cdr.c.

References ast_cdr_submit_batch(), and batchsafeshutdown.

Referenced by do_reload(), and quit_handler().

01259 {
01260    ast_cdr_submit_batch(batchsafeshutdown);
01261 }

void ast_cdr_failed struct ast_cdr cdr  ) 
 

Parameters:
cdr the cdr you wish to associate with the call Returns nothing important

Definition at line 515 of file cdr.c.

References AST_CDR_FLAG_LOCKED, AST_CDR_FLAG_POSTED, ast_log(), ast_strlen_zero(), ast_test_flag, ast_cdr::channel, ast_cdr::disposition, LOG_WARNING, and ast_cdr::next.

Referenced by __ast_request_and_dial(), ast_cdr_disposition(), ast_feature_request_and_dial(), ast_pbx_outgoing_app(), ast_pbx_outgoing_cdr_failed(), and ast_pbx_outgoing_exten().

00516 {
00517    char *chan; 
00518 
00519    while (cdr) {
00520       chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>";
00521       if (ast_test_flag(cdr, AST_CDR_FLAG_POSTED))
00522          ast_log(LOG_WARNING, "CDR on channel '%s' already posted\n", chan);
00523       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED))
00524          cdr->disposition = AST_CDR_FAILED;
00525       cdr = cdr->next;
00526    }
00527 }

char* ast_cdr_flags2str int  flag  ) 
 

Converts AMA flag to printable string

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

00686 {
00687    switch(flag) {
00688    case AST_CDR_OMIT:
00689       return "OMIT";
00690    case AST_CDR_BILLING:
00691       return "BILLING";
00692    case AST_CDR_DOCUMENTATION:
00693       return "DOCUMENTATION";
00694    }
00695    return "Unknown";
00696 }

void ast_cdr_free struct ast_cdr cdr  ) 
 

Free a CDR record.

Parameters:
cdr ast_cdr structure to free Returns nothing important

Definition at line 434 of file cdr.c.

References AST_CDR_FLAG_POST_DISABLED, AST_CDR_FLAG_POSTED, ast_cdr_free_vars(), ast_log(), ast_strlen_zero(), ast_test_flag, ast_cdr::channel, ast_cdr::end, free, LOG_WARNING, ast_cdr::next, and ast_cdr::start.

Referenced by ast_cdr_detach(), do_batch_backend_process(), and nocdr_exec().

00435 {
00436    char *chan;
00437    struct ast_cdr *next; 
00438 
00439    while (cdr) {
00440       next = cdr->next;
00441       chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>";
00442       if (!ast_test_flag(cdr, AST_CDR_FLAG_POSTED) && !ast_test_flag(cdr, AST_CDR_FLAG_POST_DISABLED))
00443          ast_log(LOG_WARNING, "CDR on channel '%s' not posted\n", chan);
00444       if (ast_tvzero(cdr->end))
00445          ast_log(LOG_WARNING, "CDR on channel '%s' lacks end\n", chan);
00446       if (ast_tvzero(cdr->start))
00447          ast_log(LOG_WARNING, "CDR on channel '%s' lacks start\n", chan);
00448 
00449       ast_cdr_free_vars(cdr, 0);
00450       free(cdr);
00451       cdr = next;
00452    }
00453 }

void ast_cdr_free_vars struct ast_cdr cdr,
int  recur
 

Definition at line 413 of file cdr.c.

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

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

00414 {
00415    struct varshead *headp;
00416    struct ast_var_t *vardata;
00417 
00418    /* clear variables */
00419    while (cdr) {
00420       headp = &cdr->varshead;
00421       while (!AST_LIST_EMPTY(headp)) {
00422          vardata = AST_LIST_REMOVE_HEAD(headp, entries);
00423          ast_var_delete(vardata);
00424       }
00425 
00426       if (!recur) {
00427          break;
00428       }
00429 
00430       cdr = cdr->next;
00431    }
00432 }

void ast_cdr_getvar struct ast_cdr cdr,
const char *  name,
char **  ret,
char *  workspace,
int  workspacelen,
int  recur
 

CDR channel variable retrieval

Definition at line 208 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_strlen_zero(), ast_cdr::billsec, ast_cdr::channel, ast_cdr::clid, ast_cdr::dcontext, ast_cdr::disposition, ast_cdr::dst, ast_cdr::dstchannel, ast_cdr::duration, ast_cdr::end, fmt, ast_cdr::lastapp, ast_cdr::lastdata, name, ast_cdr::src, ast_cdr::start, ast_cdr::uniqueid, and ast_cdr::userfield.

Referenced by ast_cdr_serialize_variables(), builtin_function_cdr_read(), and pickup_exec().

00209 {
00210    struct tm tm;
00211    time_t t;
00212    const char *fmt = "%Y-%m-%d %T";
00213    const char *varbuf;
00214 
00215    *ret = NULL;
00216    /* special vars (the ones from the struct ast_cdr when requested by name) 
00217       I'd almost say we should convert all the stringed vals to vars */
00218 
00219    if (!strcasecmp(name, "clid"))
00220       ast_copy_string(workspace, cdr->clid, workspacelen);
00221    else if (!strcasecmp(name, "src"))
00222       ast_copy_string(workspace, cdr->src, workspacelen);
00223    else if (!strcasecmp(name, "dst"))
00224       ast_copy_string(workspace, cdr->dst, workspacelen);
00225    else if (!strcasecmp(name, "dcontext"))
00226       ast_copy_string(workspace, cdr->dcontext, workspacelen);
00227    else if (!strcasecmp(name, "channel"))
00228       ast_copy_string(workspace, cdr->channel, workspacelen);
00229    else if (!strcasecmp(name, "dstchannel"))
00230       ast_copy_string(workspace, cdr->dstchannel, workspacelen);
00231    else if (!strcasecmp(name, "lastapp"))
00232       ast_copy_string(workspace, cdr->lastapp, workspacelen);
00233    else if (!strcasecmp(name, "lastdata"))
00234       ast_copy_string(workspace, cdr->lastdata, workspacelen);
00235    else if (!strcasecmp(name, "start")) {
00236       t = cdr->start.tv_sec;
00237       if (t) {
00238          localtime_r(&t, &tm);
00239          strftime(workspace, workspacelen, fmt, &tm);
00240       }
00241    } else if (!strcasecmp(name, "answer")) {
00242       t = cdr->answer.tv_sec;
00243       if (t) {
00244          localtime_r(&t, &tm);
00245          strftime(workspace, workspacelen, fmt, &tm);
00246       }
00247    } else if (!strcasecmp(name, "end")) {
00248       t = cdr->end.tv_sec;
00249       if (t) {
00250          localtime_r(&t, &tm);
00251          strftime(workspace, workspacelen, fmt, &tm);
00252       }
00253    } else if (!strcasecmp(name, "duration"))
00254       snprintf(workspace, workspacelen, "%ld", cdr->duration);
00255    else if (!strcasecmp(name, "billsec"))
00256       snprintf(workspace, workspacelen, "%ld", cdr->billsec);
00257    else if (!strcasecmp(name, "disposition"))
00258       ast_copy_string(workspace, ast_cdr_disp2str(cdr->disposition), workspacelen);
00259    else if (!strcasecmp(name, "amaflags"))
00260       ast_copy_string(workspace, ast_cdr_flags2str(cdr->amaflags), workspacelen);
00261    else if (!strcasecmp(name, "accountcode"))
00262       ast_copy_string(workspace, cdr->accountcode, workspacelen);
00263    else if (!strcasecmp(name, "uniqueid"))
00264       ast_copy_string(workspace, cdr->uniqueid, workspacelen);
00265    else if (!strcasecmp(name, "userfield"))
00266       ast_copy_string(workspace, cdr->userfield, workspacelen);
00267    else if ((varbuf = ast_cdr_getvar_internal(cdr, name, recur)))
00268       ast_copy_string(workspace, varbuf, workspacelen);
00269 
00270    if (!ast_strlen_zero(workspace))
00271       *ret = workspace;
00272 }

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 Return is negligible. (returns 0 by default)

Definition at line 615 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_log(), ast_strlen_zero(), ast_test_flag, ast_cdr::channel, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_name, ast_callerid::cid_num, ast_cdr::clid, ast_channel::context, ast_cdr::dcontext, ast_cdr::disposition, ast_cdr::dst, ast_channel::exten, LOG_WARNING, ast_channel::name, ast_cdr::next, ast_cdr::src, ast_channel::uniqueid, and ast_cdr::uniqueid.

Referenced by __ast_pbx_run(), __ast_request_and_dial(), ast_feature_request_and_dial(), ast_pbx_outgoing_app(), ast_pbx_outgoing_cdr_failed(), and ast_pbx_outgoing_exten().

00616 {
00617    char *chan;
00618    char *num;
00619    char tmp[AST_MAX_EXTENSION] = "";
00620 
00621    while (cdr) {
00622       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
00623          chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>";
00624          if (!ast_strlen_zero(cdr->channel)) 
00625             ast_log(LOG_WARNING, "CDR already initialized on '%s'\n", chan); 
00626          ast_copy_string(cdr->channel, c->name, sizeof(cdr->channel));
00627          /* Grab source from ANI or normal Caller*ID */
00628          num = c->cid.cid_ani ? c->cid.cid_ani : c->cid.cid_num;
00629          
00630          if (c->cid.cid_name && num)
00631             snprintf(tmp, sizeof(tmp), "\"%s\" <%s>", c->cid.cid_name, num);
00632          else if (c->cid.cid_name)
00633             ast_copy_string(tmp, c->cid.cid_name, sizeof(tmp));
00634          else if (num)
00635             ast_copy_string(tmp, num, sizeof(tmp));
00636          ast_copy_string(cdr->clid, tmp, sizeof(cdr->clid));
00637          ast_copy_string(cdr->src, num ? num : "", sizeof(cdr->src));
00638 
00639          cdr->disposition = (c->_state == AST_STATE_UP) ?  AST_CDR_ANSWERED : AST_CDR_NOANSWER;
00640          cdr->amaflags = c->amaflags ? c->amaflags :  ast_default_amaflags;
00641          ast_copy_string(cdr->accountcode, c->accountcode, sizeof(cdr->accountcode));
00642          /* Destination information */
00643          ast_copy_string(cdr->dst, c->exten, sizeof(cdr->dst));
00644          ast_copy_string(cdr->dcontext, c->context, sizeof(cdr->dcontext));
00645          /* Unique call identifier */
00646          ast_copy_string(cdr->uniqueid, c->uniqueid, sizeof(cdr->uniqueid));
00647       }
00648       cdr = cdr->next;
00649    }
00650    return 0;
00651 }

int ast_cdr_register char *  name,
char *  desc,
ast_cdrbe  be
 

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

Returns:
0 on success, -1 on failure

Definition at line 106 of file cdr.c.

References AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_cdr_beitem::be, LOG_WARNING, malloc, ast_cdr_beitem::name, and name.

Referenced by load_module(), odbc_load_module(), process_my_load_module(), and tds_load_module().

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

void ast_cdr_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 827 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_POSTED, ast_cdr_free_vars(), 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_bridge_call_thread(), ast_cdr_fork(), dial_exec_full(), disa_exec(), and pbx_builtin_resetcdr().

00828 {
00829    struct ast_cdr *dup;
00830    struct ast_flags flags = { 0 };
00831 
00832    if (_flags)
00833       ast_copy_flags(&flags, _flags, AST_FLAGS_ALL);
00834 
00835    while (cdr) {
00836       /* Detach if post is requested */
00837       if (ast_test_flag(&flags, AST_CDR_FLAG_LOCKED) || !ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
00838          if (ast_test_flag(&flags, AST_CDR_FLAG_POSTED)) {
00839             ast_cdr_end(cdr);
00840             if ((dup = ast_cdr_dup(cdr))) {
00841                ast_cdr_detach(dup);
00842             }
00843             ast_set_flag(cdr, AST_CDR_FLAG_POSTED);
00844          }
00845 
00846          /* clear variables */
00847          if (!ast_test_flag(&flags, AST_CDR_FLAG_KEEP_VARS)) {
00848             ast_cdr_free_vars(cdr, 0);
00849          }
00850 
00851          /* Reset to initial state */
00852          ast_clear_flag(cdr, AST_FLAGS_ALL); 
00853          memset(&cdr->start, 0, sizeof(cdr->start));
00854          memset(&cdr->end, 0, sizeof(cdr->end));
00855          memset(&cdr->answer, 0, sizeof(cdr->answer));
00856          cdr->billsec = 0;
00857          cdr->duration = 0;
00858          ast_cdr_start(cdr);
00859          cdr->disposition = AST_CDR_NOANSWER;
00860       }
00861          
00862       cdr = cdr->next;
00863    }
00864 }

int ast_cdr_serialize_variables struct ast_cdr cdr,
char *  buf,
size_t  size,
char  delim,
char  sep,
int  recur
 

Definition at line 349 of file cdr.c.

References ast_build_string(), ast_cdr_getvar(), AST_LIST_TRAVERSE, ast_log(), ast_strlen_zero(), ast_var_name(), ast_var_value(), LOG_ERROR, ast_cdr::next, val, var, and ast_cdr::varshead.

Referenced by handle_showchan().

00350 {
00351    struct ast_var_t *variables;
00352    char *var, *val;
00353    char *tmp;
00354    char workspace[256];
00355    int total = 0, x = 0, i;
00356    const char *cdrcols[] = { 
00357       "clid",
00358       "src",
00359       "dst",
00360       "dcontext",
00361       "channel",
00362       "dstchannel",
00363       "lastapp",
00364       "lastdata",
00365       "start",
00366       "answer",
00367       "end",
00368       "duration",
00369       "billsec",
00370       "disposition",
00371       "amaflags",
00372       "accountcode",
00373       "uniqueid",
00374       "userfield"
00375    };
00376 
00377    memset(buf, 0, size);
00378 
00379    for (; cdr; cdr = recur ? cdr->next : NULL) {
00380       if (++x > 1)
00381          ast_build_string(&buf, &size, "\n");
00382 
00383       AST_LIST_TRAVERSE(&cdr->varshead, variables, entries) {
00384          if (variables &&
00385              (var = ast_var_name(variables)) && (val = ast_var_value(variables)) &&
00386              !ast_strlen_zero(var) && !ast_strlen_zero(val)) {
00387             if (ast_build_string(&buf, &size, "level %d: %s%c%s%c", x, var, delim, val, sep)) {
00388                ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
00389                break;
00390             } else
00391                total++;
00392          } else 
00393             break;
00394       }
00395 
00396       for (i = 0; i < (sizeof(cdrcols) / sizeof(cdrcols[0])); i++) {
00397          ast_cdr_getvar(cdr, cdrcols[i], &tmp, workspace, sizeof(workspace), 0);
00398          if (!tmp)
00399             continue;
00400          
00401          if (ast_build_string(&buf, &size, "level %d: %s%c%s%c", x, cdrcols[i], delim, tmp, sep)) {
00402             ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
00403             break;
00404          } else
00405             total++;
00406       }
00407    }
00408 
00409    return total;
00410 }

int ast_cdr_setaccount struct ast_channel chan,
const char *  account
 

Definition at line 698 of file cdr.c.

References ast_cdr::accountcode, ast_channel::accountcode, AST_CDR_FLAG_LOCKED, ast_test_flag, ast_channel::cdr, and ast_cdr::next.

Referenced by __ast_request_and_dial(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), auth_exec(), builtin_function_cdr_write(), and pbx_builtin_setaccount().

00699 {
00700    struct ast_cdr *cdr = chan->cdr;
00701 
00702    ast_copy_string(chan->accountcode, account, sizeof(chan->accountcode));
00703    while (cdr) {
00704       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED))
00705          ast_copy_string(cdr->accountcode, chan->accountcode, sizeof(cdr->accountcode));
00706       cdr = cdr->next;
00707    }
00708    return 0;
00709 }

int ast_cdr_setamaflags struct ast_channel chan,
const char *  amaflags
 

Definition at line 711 of file cdr.c.

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

Referenced by pbx_builtin_setamaflags().

00712 {
00713    struct ast_cdr *cdr;
00714    int newflag;
00715 
00716    newflag = ast_cdr_amaflags2int(flag);
00717    if (newflag) {
00718       for (cdr = chan->cdr; cdr; cdr = cdr->next) {
00719          cdr->amaflags = newflag;
00720       }
00721    }
00722 
00723    return 0;
00724 }

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

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

References AST_CDR_FLAG_LOCKED, AST_CDR_FLAG_POSTED, ast_log(), ast_strlen_zero(), ast_test_flag, ast_cdr::channel, ast_cdr::lastapp, ast_cdr::lastdata, LOG_WARNING, and ast_cdr::next.

Referenced by __ast_request_and_dial(), ast_feature_request_and_dial(), and pbx_exec().

00570 {
00571    char *chan; 
00572 
00573    while (cdr) {
00574       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
00575          chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>";
00576          if (ast_test_flag(cdr, AST_CDR_FLAG_POSTED))
00577             ast_log(LOG_WARNING, "CDR on channel '%s' already posted\n", chan);
00578          if (!app)
00579             app = "";
00580          ast_copy_string(cdr->lastapp, app, sizeof(cdr->lastapp));
00581          if (!data)
00582             data = "";
00583          ast_copy_string(cdr->lastdata, data, sizeof(cdr->lastdata));
00584       }
00585       cdr = cdr->next;
00586    }
00587 }

int ast_cdr_setcid struct ast_cdr cdr,
struct ast_channel chan
 

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 Return is negligible. (returns 0 by default)

Definition at line 589 of file cdr.c.

References AST_CDR_FLAG_LOCKED, ast_test_flag, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_name, ast_callerid::cid_num, ast_cdr::clid, ast_cdr::next, and ast_cdr::src.

Referenced by ast_set_callerid().

00590 {
00591    char tmp[AST_MAX_EXTENSION] = "";
00592    char *num;
00593 
00594    while (cdr) {
00595       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
00596          /* Grab source from ANI or normal Caller*ID */
00597          num = c->cid.cid_ani ? c->cid.cid_ani : c->cid.cid_num;
00598          
00599          if (c->cid.cid_name && num)
00600             snprintf(tmp, sizeof(tmp), "\"%s\" <%s>", c->cid.cid_name, num);
00601          else if (c->cid.cid_name)
00602             ast_copy_string(tmp, c->cid.cid_name, sizeof(tmp));
00603          else if (num)
00604             ast_copy_string(tmp, num, sizeof(tmp));
00605          ast_copy_string(cdr->clid, tmp, sizeof(cdr->clid));
00606          ast_copy_string(cdr->src, num ? num : "", sizeof(cdr->src));
00607       }
00608       cdr = cdr->next;
00609    }
00610 
00611    return 0;
00612 }

void ast_cdr_setdestchan struct ast_cdr cdr,
char *  chan
 

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

References AST_CDR_FLAG_LOCKED, AST_CDR_FLAG_POSTED, ast_log(), ast_strlen_zero(), ast_test_flag, ast_cdr::channel, ast_cdr::dstchannel, LOG_WARNING, and ast_cdr::next.

Referenced by ast_bridge_call_thread(), dial_exec_full(), and try_calling().

00556 {
00557    char *chan; 
00558 
00559    while (cdr) {
00560       chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>";
00561       if (ast_test_flag(cdr, AST_CDR_FLAG_POSTED))
00562          ast_log(LOG_WARNING, "CDR on channel '%s' already posted\n", chan);
00563       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED))
00564          ast_copy_string(cdr->dstchannel, chann, sizeof(cdr->dstchannel));
00565       cdr = cdr->next;
00566    }
00567 }

int ast_cdr_setuserfield struct ast_channel chan,
const char *  userfield
 

Definition at line 726 of file cdr.c.

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

Referenced by __agent_start_monitoring(), action_setcdruserfield(), ast_bridge_call(), builtin_function_cdr_write(), handle_request_info(), setcdruserfield_exec(), and start_monitor_exec().

00727 {
00728    struct ast_cdr *cdr = chan->cdr;
00729 
00730    while (cdr) {
00731       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) 
00732          ast_copy_string(cdr->userfield, userfield, sizeof(cdr->userfield));
00733       cdr = cdr->next;
00734    }
00735 
00736    return 0;
00737 }

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

References AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, ast_log(), ast_var_assign(), ast_var_delete(), ast_var_name(), LOG_ERROR, name, ast_cdr::next, and ast_cdr::varshead.

Referenced by builtin_function_cdr_write().

00278 {
00279    struct ast_var_t *newvariable;
00280    struct varshead *headp;
00281    const char *read_only[] = { "clid", "src", "dst", "dcontext", "channel", "dstchannel",
00282                 "lastapp", "lastdata", "start", "answer", "end", "duration",
00283                 "billsec", "disposition", "amaflags", "accountcode", "uniqueid",
00284                 "userfield", NULL };
00285    int x;
00286    
00287    for(x = 0; read_only[x]; x++) {
00288       if (!strcasecmp(name, read_only[x])) {
00289          ast_log(LOG_ERROR, "Attempt to set a read-only variable!.\n");
00290          return -1;
00291       }
00292    }
00293 
00294    if (!cdr) {
00295       ast_log(LOG_ERROR, "Attempt to set a variable on a nonexistent CDR record.\n");
00296       return -1;
00297    }
00298 
00299    while (cdr) {
00300       headp = &cdr->varshead;
00301       AST_LIST_TRAVERSE_SAFE_BEGIN(headp, newvariable, entries) {
00302          if (!strcasecmp(ast_var_name(newvariable), name)) {
00303             /* there is already such a variable, delete it */
00304             AST_LIST_REMOVE_CURRENT(headp, entries);
00305             ast_var_delete(newvariable);
00306             break;
00307          }
00308       }
00309       AST_LIST_TRAVERSE_SAFE_END;
00310 
00311       if (value) {
00312          newvariable = ast_var_assign(name, value);
00313          AST_LIST_INSERT_HEAD(headp, newvariable, entries);
00314       }
00315 
00316       if (!recur) {
00317          break;
00318       }
00319 
00320       cdr = cdr->next;
00321    }
00322 
00323    return 0;
00324 }

void ast_cdr_start struct ast_cdr cdr  ) 
 

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

Definition at line 466 of file cdr.c.

References AST_CDR_FLAG_LOCKED, AST_CDR_FLAG_POSTED, ast_log(), ast_strlen_zero(), ast_test_flag, ast_cdr::channel, LOG_WARNING, ast_cdr::next, and ast_cdr::start.

Referenced by __ast_pbx_run(), __ast_request_and_dial(), ast_cdr_reset(), ast_feature_request_and_dial(), ast_pbx_outgoing_app(), ast_pbx_outgoing_cdr_failed(), and ast_pbx_outgoing_exten().

00467 {
00468    char *chan; 
00469 
00470    while (cdr) {
00471       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
00472          chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>";
00473          if (ast_test_flag(cdr, AST_CDR_FLAG_POSTED))
00474             ast_log(LOG_WARNING, "CDR on channel '%s' already posted\n", chan);
00475          if (!ast_tvzero(cdr->start))
00476             ast_log(LOG_WARNING, "CDR on channel '%s' already started\n", chan);
00477          cdr->start = ast_tvnow();
00478       }
00479       cdr = cdr->next;
00480    }
00481 }

void ast_cdr_submit_batch int  shutdown  ) 
 

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

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create, batch, batchscheduleronly, do_batch_backend_process(), ast_cdr_batch::head, LOG_DEBUG, LOG_WARNING, and reset_batch().

Referenced by ast_cdr_engine_term(), and submit_scheduled_batch().

00924 {
00925    struct ast_cdr_batch_item *oldbatchitems = NULL;
00926    pthread_attr_t attr;
00927    pthread_t batch_post_thread = AST_PTHREADT_NULL;
00928 
00929    /* if there's no batch, or no CDRs in the batch, then there's nothing to do */
00930    if (!batch || !batch->head)
00931       return;
00932 
00933    /* move the old CDRs aside, and prepare a new CDR batch */
00934    ast_mutex_lock(&cdr_batch_lock);
00935    oldbatchitems = batch->head;
00936    reset_batch();
00937    ast_mutex_unlock(&cdr_batch_lock);
00938 
00939    /* if configured, spawn a new thread to post these CDRs,
00940       also try to save as much as possible if we are shutting down safely */
00941    if (batchscheduleronly || shutdown) {
00942       if (option_debug)
00943          ast_log(LOG_DEBUG, "CDR single-threaded batch processing begins now\n");
00944       do_batch_backend_process(oldbatchitems);
00945    } else {
00946       pthread_attr_init(&attr);
00947       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
00948       if (ast_pthread_create(&batch_post_thread, &attr, do_batch_backend_process, oldbatchitems)) {
00949          ast_log(LOG_WARNING, "CDR processing thread could not detach, now trying in this thread\n");
00950          do_batch_backend_process(oldbatchitems);
00951       } else {
00952          if (option_debug)
00953             ast_log(LOG_DEBUG, "CDR multi-threaded batch processing begins now\n");
00954       }
00955    }
00956 }

void ast_cdr_unregister char *  name  ) 
 

unregister a CDR driver

Definition at line 146 of file cdr.c.

References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_UNLOCK, ast_verbose(), free, ast_cdr_beitem::name, name, option_verbose, and VERBOSE_PREFIX_2.

Referenced by my_unload_module(), odbc_unload_module(), tds_unload_module(), and unload_module().

00147 {
00148    struct ast_cdr_beitem *i = NULL;
00149 
00150    AST_LIST_LOCK(&be_list);
00151    AST_LIST_TRAVERSE_SAFE_BEGIN(&be_list, i, list) {
00152       if (!strcasecmp(name, i->name)) {
00153          AST_LIST_REMOVE_CURRENT(&be_list, list);
00154          if (option_verbose > 1)
00155             ast_verbose(VERBOSE_PREFIX_2 "Unregistered '%s' CDR backend\n", name);
00156          free(i);
00157          break;
00158       }
00159    }
00160    AST_LIST_TRAVERSE_SAFE_END;
00161    AST_LIST_UNLOCK(&be_list);
00162 }

int ast_cdr_update struct ast_channel chan  ) 
 

Definition at line 755 of file cdr.c.

References ast_channel::accountcode, ast_cdr::accountcode, AST_CDR_FLAG_LOCKED, ast_test_flag, ast_channel::cdr, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_name, ast_callerid::cid_num, ast_cdr::clid, ast_channel::context, ast_cdr::dcontext, ast_cdr::dst, ast_channel::exten, ast_channel::macrocontext, ast_channel::macroexten, ast_cdr::next, and ast_cdr::src.

Referenced by __ast_pbx_run(), __ast_request_and_dial(), ast_feature_request_and_dial(), ast_parseable_goto(), and cb_events().

00756 {
00757    struct ast_cdr *cdr = c->cdr;
00758    char *num;
00759    char tmp[AST_MAX_EXTENSION] = "";
00760 
00761    while (cdr) {
00762       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
00763          num = c->cid.cid_ani ? c->cid.cid_ani : c->cid.cid_num;
00764          
00765          if (c->cid.cid_name && num)
00766             snprintf(tmp, sizeof(tmp), "\"%s\" <%s>", c->cid.cid_name, num);
00767          else if (c->cid.cid_name)
00768             ast_copy_string(tmp, c->cid.cid_name, sizeof(tmp));
00769          else if (num)
00770             ast_copy_string(tmp, num, sizeof(tmp));
00771          ast_copy_string(cdr->clid, tmp, sizeof(cdr->clid));
00772          ast_copy_string(cdr->src, num ? num : "", sizeof(cdr->src));
00773 
00774          /* Copy account code et-al */ 
00775          ast_copy_string(cdr->accountcode, c->accountcode, sizeof(cdr->accountcode));
00776          /* Destination information */
00777          ast_copy_string(cdr->dst, (ast_strlen_zero(c->macroexten)) ? c->exten : c->macroexten, sizeof(cdr->dst));
00778          ast_copy_string(cdr->dcontext, (ast_strlen_zero(c->macrocontext)) ? c->context : c->macrocontext, sizeof(cdr->dcontext));
00779       }
00780       cdr = cdr->next;
00781    }
00782 
00783    return 0;
00784 }


Variable Documentation

char ast_default_accountcode[AST_MAX_ACCOUNT_CODE]
 

Definition at line 58 of file cdr.c.

Referenced by ast_channel_alloc().

int ast_default_amaflags
 

Default AMA flag for billing records (CDR's)

Definition at line 57 of file cdr.c.


Generated on Mon Mar 20 08:20:18 2006 for Asterisk - the Open Source PBX by  doxygen 1.3.9.1