Codename Pineapple

Home page | Mailing list | Docs

Last updated: Sat Feb 3 05:01:03 2007

Asterisk developer's documentation :: Codename Pineapple


cdr.h File Reference


Detailed Description

Call Detail Record API.

Definition in file cdr.h.

#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

Defines

#define AST_CDR_ANSWERED   (1 << 3)
#define AST_CDR_BILLING   (2)
#define AST_CDR_BUSY   (1 << 1)
#define AST_CDR_DOCUMENTATION   (3)
#define AST_CDR_FAILED   (1 << 2)
#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)
int 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 raw)
int ast_cdr_init (struct ast_cdr *cdr, struct ast_channel *chan)
 Initialize based on a channel.
int ast_cdr_register (const char *name, const 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, struct ast_str **buf, 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, const 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 (const char *name)
int ast_cdr_update (struct ast_channel *chan)

Variables

char ast_default_accountcode [AST_MAX_ACCOUNT_CODE]
int ast_default_amaflags


Define Documentation

#define AST_CDR_ANSWERED   (1 << 3)
 

Definition at line 36 of file cdr.h.

Referenced by ast_cdr_answer(), ast_cdr_disp2str(), and ast_cdr_init().

#define AST_CDR_BILLING   (2)
 

Definition at line 40 of file cdr.h.

Referenced by ast_cdr_amaflags2int(), and ast_cdr_flags2str().

#define AST_CDR_BUSY   (1 << 1)
 

Definition at line 34 of file cdr.h.

Referenced by ast_cdr_busy(), and ast_cdr_disp2str().

#define AST_CDR_DOCUMENTATION   (3)
 

Definition at line 41 of file cdr.h.

Referenced by ast_cdr_amaflags2int(), and ast_cdr_flags2str().

#define AST_CDR_FAILED   (1 << 2)
 

Definition at line 35 of file cdr.h.

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

#define AST_CDR_FLAG_CHILD   (1 << 3)
 

Definition at line 30 of file cdr.h.

#define AST_CDR_FLAG_KEEP_VARS   (1 << 0)
 

Definition at line 27 of file cdr.h.

#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_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_free(), ast_cdr_reset(), check_post(), and post_cdr().

#define AST_CDR_NOANSWER   (1 << 0)
 

Definition at line 33 of file cdr.h.

Referenced by ast_cdr_disp2str(), and ast_cdr_init().

#define AST_CDR_OMIT   (1)
 

AMA Flags

Definition at line 39 of file cdr.h.

Referenced by ast_cdr_amaflags2int(), and 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 103 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 437 of file cdr.c.

References ast_calloc.

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

00438 {
00439    return ast_calloc(1, sizeof(struct ast_cdr));
00440 }

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

References AST_CDR_BILLING, AST_CDR_DOCUMENTATION, and AST_CDR_OMIT.

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

00708 {
00709    if (!strcasecmp(flag, "default"))
00710       return 0;
00711    if (!strcasecmp(flag, "omit"))
00712       return AST_CDR_OMIT;
00713    if (!strcasecmp(flag, "billing"))
00714       return AST_CDR_BILLING;
00715    if (!strcasecmp(flag, "documentation"))
00716       return AST_CDR_DOCUMENTATION;
00717    return -1;
00718 }

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 NULL argument is just fine.

Definition at line 456 of file cdr.c.

References ast_cdr::answer, AST_CDR_ANSWERED, check_post(), ast_cdr::disposition, and ast_cdr::next.

Referenced by __ast_answer(), and __ast_read().

00457 {
00458 
00459    for (; cdr; cdr = cdr->next) {
00460       check_post(cdr);
00461       if (cdr->disposition < AST_CDR_ANSWERED)
00462          cdr->disposition = AST_CDR_ANSWERED;
00463       if (ast_tvzero(cdr->answer))
00464          cdr->answer = ast_tvnow();
00465    }
00466 }

struct ast_cdr* ast_cdr_append struct ast_cdr cdr,
struct ast_cdr newcdr
 

Definition at line 778 of file cdr.c.

References ast_cdr::next.

Referenced by attempt_transfer().

00779 {
00780    struct ast_cdr *ret;
00781 
00782    if (cdr) {
00783       ret = cdr;
00784 
00785       while (cdr->next)
00786          cdr = cdr->next;
00787       cdr->next = newcdr;
00788    } else {
00789       ret = newcdr;
00790    }
00791 
00792    return ret;
00793 }

int ast_cdr_appenduserfield struct ast_channel chan,
const char *  userfield
 

Definition at line 674 of file cdr.c.

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

Referenced by ast_bridge_call().

00675 {
00676    struct ast_cdr *cdr = chan->cdr;
00677 
00678    for ( ; cdr ; cdr = cdr->next) {
00679       int len = strlen(cdr->userfield);
00680 
00681       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED))
00682          ast_copy_string(cdr->userfield + len, userfield, sizeof(cdr->userfield) - len);
00683    }
00684 
00685    return 0;
00686 }

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

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

Referenced by ast_cdr_disposition().

00469 {
00470 
00471    for (; cdr; cdr = cdr->next) {
00472       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
00473          check_post(cdr);
00474          if (cdr->disposition < AST_CDR_BUSY)
00475             cdr->disposition = AST_CDR_BUSY;
00476       }
00477    }
00478 }

int ast_cdr_copy_vars struct ast_cdr to_cdr,
struct ast_cdr from_cdr
 

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

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

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

References ast_calloc, AST_CDR_FLAG_POST_DISABLED, ast_cdr_free(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, batch, batchmode, batchsize, ast_cdr_batch_item::cdr, enabled, ast_cdr_batch::head, init_batch(), LOG_DEBUG, ast_cdr_batch_item::next, option_debug, 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().

00891 {
00892    struct ast_cdr_batch_item *newtail;
00893    int curr;
00894 
00895    /* maybe they disabled CDR stuff completely, so just drop it */
00896    if (!enabled) {
00897       if (option_debug)
00898          ast_log(LOG_DEBUG, "Dropping CDR !\n");
00899       ast_set_flag(cdr, AST_CDR_FLAG_POST_DISABLED);
00900       ast_cdr_free(cdr);
00901       return;
00902    }
00903 
00904    /* post stuff immediately if we are not in batch mode, this is legacy behaviour */
00905    if (!batchmode) {
00906       post_cdr(cdr);
00907       ast_cdr_free(cdr);
00908       return;
00909    }
00910 
00911    /* otherwise, each CDR gets put into a batch list (at the end) */
00912    if (option_debug)
00913       ast_log(LOG_DEBUG, "CDR detaching from this thread\n");
00914 
00915    /* we'll need a new tail for every CDR */
00916    if (!(newtail = ast_calloc(1, sizeof(*newtail)))) {
00917       post_cdr(cdr);
00918       ast_cdr_free(cdr);
00919       return;
00920    }
00921 
00922    /* don't traverse a whole list (just keep track of the tail) */
00923    ast_mutex_lock(&cdr_batch_lock);
00924    if (!batch)
00925       init_batch();
00926    if (!batch->head) {
00927       /* new batch is empty, so point the head at the new tail */
00928       batch->head = newtail;
00929    } else {
00930       /* already got a batch with something in it, so just append a new tail */
00931       batch->tail->next = newtail;
00932    }
00933    newtail->cdr = cdr;
00934    batch->tail = newtail;
00935    curr = batch->size++;
00936    ast_mutex_unlock(&cdr_batch_lock);
00937 
00938    /* if we have enough stuff to post, then do it */
00939    if (curr >= (batchsize - 1))
00940       submit_unscheduled_batch();
00941 }

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

References AST_CDR_ANSWERED, AST_CDR_BUSY, AST_CDR_FAILED, and AST_CDR_NOANSWER.

Referenced by ast_cdr_getvar().

00610 {
00611    switch (disposition) {
00612    case AST_CDR_NOANSWER:
00613       return "NO ANSWER";
00614    case AST_CDR_FAILED:
00615       return "FAILED";     
00616    case AST_CDR_BUSY:
00617       return "BUSY";    
00618    case AST_CDR_ANSWERED:
00619       return "ANSWERED";
00620    }
00621    return "UNKNOWN";
00622 }

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 491 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_pbx_outgoing_app(), and ast_pbx_outgoing_exten().

00492 {
00493    int res = 0;
00494 
00495    for (; cdr; cdr = cdr->next) {
00496       switch (cause) {
00497       case AST_CAUSE_BUSY:
00498          ast_cdr_busy(cdr);
00499          break;
00500       case AST_CAUSE_FAILURE:
00501          ast_cdr_failed(cdr);
00502          break;
00503       case AST_CAUSE_NORMAL:
00504          break;
00505       case AST_CAUSE_NOTDEFINED:
00506          res = -1;
00507          break;
00508       default:
00509          res = -1;
00510          ast_log(LOG_WARNING, "Cause not handled\n");
00511       }
00512    }
00513    return res;
00514 }

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(), and ast_cdr_copy_vars().

Referenced by ast_cdr_reset().

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

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

References AST_CDR_FAILED, ast_log(), ast_cdr::channel, check_post(), ast_cdr::disposition, ast_cdr::end, LOG_WARNING, ast_cdr::next, S_OR, and ast_cdr::start.

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

00595 {
00596    for ( ; cdr ; cdr = cdr->next) {
00597       check_post(cdr);
00598       if (ast_tvzero(cdr->end))
00599          cdr->end = ast_tvnow();
00600       if (ast_tvzero(cdr->start)) {
00601          ast_log(LOG_WARNING, "CDR on channel '%s' has not started\n", S_OR(cdr->channel, "<unknown>"));
00602          cdr->disposition = AST_CDR_FAILED;
00603       } else
00604          cdr->duration = cdr->end.tv_sec - cdr->start.tv_sec;
00605       cdr->billsec = ast_tvzero(cdr->answer) ? 0 : cdr->end.tv_sec - cdr->answer.tv_sec;
00606    }
00607 }

int ast_cdr_engine_init void   ) 
 

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

Definition at line 1141 of file cdr.c.

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

01142 {
01143    int res;
01144 
01145    sched = sched_context_create();
01146    if (!sched) {
01147       ast_log(LOG_ERROR, "Unable to create schedule context.\n");
01148       return -1;
01149    }
01150 
01151    ast_cli_register(&cli_status);
01152 
01153    res = do_reload();
01154    if (res) {
01155       ast_mutex_lock(&cdr_batch_lock);
01156       res = init_batch();
01157       ast_mutex_unlock(&cdr_batch_lock);
01158    }
01159 
01160    return res;
01161 }

int ast_cdr_engine_reload void   ) 
 

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

Definition at line 1170 of file cdr.c.

References do_reload().

01171 {
01172    return do_reload();
01173 }

void ast_cdr_engine_term void   ) 
 

Submit any remaining CDRs and prepare for shutdown

Definition at line 1165 of file cdr.c.

References ast_cdr_submit_batch(), and batchsafeshutdown.

Referenced by do_reload(), and quit_handler().

01166 {
01167    ast_cdr_submit_batch(batchsafeshutdown);
01168 }

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 480 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_cdr_disposition(), ast_pbx_outgoing_app(), ast_pbx_outgoing_cdr_failed(), and ast_pbx_outgoing_exten().

00481 {
00482    for (; cdr; cdr = cdr->next) {
00483       check_post(cdr);
00484       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
00485          if (cdr->disposition < AST_CDR_FAILED)
00486             cdr->disposition = AST_CDR_FAILED;
00487       }
00488    }
00489 }

char* ast_cdr_flags2str int  flag  ) 
 

Converts AMA flag to printable string

Definition at line 625 of file cdr.c.

References AST_CDR_BILLING, AST_CDR_DOCUMENTATION, and AST_CDR_OMIT.

Referenced by _sip_show_device(), _sip_show_peer(), ast_cdr_getvar(), and sip_show_user().

00626 {
00627    switch (flag) {
00628    case AST_CDR_OMIT:
00629       return "OMIT";
00630    case AST_CDR_BILLING:
00631       return "BILLING";
00632    case AST_CDR_DOCUMENTATION:
00633       return "DOCUMENTATION";
00634    }
00635    return "Unknown";
00636 }

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

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

Referenced by ast_cdr_detach(), and do_batch_backend_process().

00419 {
00420 
00421    while (cdr) {
00422       struct ast_cdr *next = cdr->next;
00423       char *chan = S_OR(cdr->channel, "<unknown>");
00424       if (!ast_test_flag(cdr, AST_CDR_FLAG_POSTED) && !ast_test_flag(cdr, AST_CDR_FLAG_POST_DISABLED))
00425          ast_log(LOG_NOTICE, "CDR on channel '%s' not posted\n", chan);
00426       if (ast_tvzero(cdr->end))
00427          ast_log(LOG_NOTICE, "CDR on channel '%s' lacks end\n", chan);
00428       if (ast_tvzero(cdr->start))
00429          ast_log(LOG_NOTICE, "CDR on channel '%s' lacks start\n", chan);
00430 
00431       ast_cdr_free_vars(cdr, 0);
00432       free(cdr);
00433       cdr = next;
00434    }
00435 }

void ast_cdr_free_vars struct ast_cdr cdr,
int  recur
 

Definition at line 392 of file cdr.c.

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

Referenced by ast_cdr_free().

00393 {
00394 
00395    /* clear variables */
00396    for (; cdr; cdr = recur ? cdr->next : NULL) {
00397       struct ast_var_t *vardata;
00398       struct varshead *headp = &cdr->varshead;
00399       while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries)))
00400          ast_var_delete(vardata);
00401    }
00402 }

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 215 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, 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, fmt, 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().

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

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

References ast_channel::_state, ast_cdr::accountcode, ast_channel::amaflags, ast_cdr::amaflags, AST_CDR_ANSWERED, AST_CDR_FLAG_LOCKED, AST_CDR_NOANSWER, ast_default_amaflags, ast_log(), AST_STATE_UP, ast_strlen_zero(), ast_test_flag, ast_cdr::channel, ast_channel::context, ast_cdr::dcontext, ast_cdr::disposition, ast_cdr::dst, ast_channel::exten, LOG_WARNING, ast_cdr::next, S_OR, set_one_cid(), and ast_cdr::uniqueid.

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

00570 {
00571    char *chan;
00572 
00573    for ( ; cdr ; cdr = cdr->next) {
00574       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
00575          chan = S_OR(cdr->channel, "<unknown>");
00576          if (!ast_strlen_zero(cdr->channel)) 
00577             ast_log(LOG_WARNING, "CDR already initialized on '%s'\n", chan); 
00578          ast_copy_string(cdr->channel, c->name, sizeof(cdr->channel));
00579          set_one_cid(cdr, c);
00580 
00581          cdr->disposition = (c->_state == AST_STATE_UP) ?  AST_CDR_ANSWERED : AST_CDR_NOANSWER;
00582          cdr->amaflags = c->amaflags ? c->amaflags :  ast_default_amaflags;
00583          ast_copy_string(cdr->accountcode, c->accountcode, sizeof(cdr->accountcode));
00584          /* Destination information */
00585          ast_copy_string(cdr->dst, c->exten, sizeof(cdr->dst));
00586          ast_copy_string(cdr->dcontext, c->context, sizeof(cdr->dcontext));
00587          /* Unique call identifier */
00588          ast_copy_string(cdr->uniqueid, c->uniqueid, sizeof(cdr->uniqueid));
00589       }
00590    }
00591    return 0;
00592 }

int ast_cdr_register const char *  name,
const 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 108 of file cdr.c.

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

00109 {
00110    struct ast_cdr_beitem *i;
00111 
00112    if (!name)
00113       return -1;
00114    if (!be) {
00115       ast_log(LOG_WARNING, "CDR engine '%s' lacks backend\n", name);
00116       return -1;
00117    }
00118 
00119    AST_LIST_LOCK(&be_list);
00120    AST_LIST_TRAVERSE(&be_list, i, list) {
00121       if (!strcasecmp(name, i->name))
00122          break;
00123    }
00124    AST_LIST_UNLOCK(&be_list);
00125 
00126    if (i) {
00127       ast_log(LOG_WARNING, "Already have a CDR backend called '%s'\n", name);
00128       return -1;
00129    }
00130 
00131    if (!(i = ast_calloc(1, sizeof(*i))))  
00132       return -1;
00133 
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 741 of file cdr.c.

References ast_cdr_detach(), ast_cdr_dup(), ast_cdr_end(), AST_CDR_FLAG_LOCKED, AST_CDR_FLAG_POSTED, ast_copy_flags, AST_FLAGS_ALL, ast_test_flag, and ast_cdr::next.

Referenced by ast_bridge_call_thread(), and pbx_builtin_resetcdr().

00742 {
00743    struct ast_cdr *dup;
00744    struct ast_flags flags = { 0 };
00745 
00746    if (_flags)
00747       ast_copy_flags(&flags, _flags, AST_FLAGS_ALL);
00748 
00749    for ( ; cdr ; cdr = cdr->next) {
00750       /* Detach if post is requested */
00751       if (ast_test_flag(&flags, AST_CDR_FLAG_LOCKED) || !ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
00752          if (ast_test_flag(&flags, AST_CDR_FLAG_POSTED)) {
00753             ast_cdr_end(cdr);
00754             if ((dup = ast_cdr_dup(cdr))) {
00755                ast_cdr_detach(dup);
00756             }
00757             ast_set_flag(cdr, AST_CDR_FLAG_POSTED);
00758          }
00759 
00760          /* clear variables */
00761          if (!ast_test_flag(&flags, AST_CDR_FLAG_KEEP_VARS)) {
00762             ast_cdr_free_vars(cdr, 0);
00763          }
00764 
00765          /* Reset to initial state */
00766          ast_clear_flag(cdr, AST_FLAGS_ALL); 
00767          memset(&cdr->start, 0, sizeof(cdr->start));
00768          memset(&cdr->end, 0, sizeof(cdr->end));
00769          memset(&cdr->answer, 0, sizeof(cdr->answer));
00770          cdr->billsec = 0;
00771          cdr->duration = 0;
00772          ast_cdr_start(cdr);
00773          cdr->disposition = AST_CDR_NOANSWER;
00774       }
00775    }
00776 }

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

Definition at line 347 of file cdr.c.

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

Referenced by handle_showchan().

00348 {
00349    struct ast_var_t *variables;
00350    const char *var, *val;
00351    char *tmp;
00352    char workspace[256];
00353    int total = 0, x = 0, i;
00354 
00355    (*buf)->used = 0;
00356    (*buf)->str[0] = '\0';
00357 
00358    for (; cdr; cdr = recur ? cdr->next : NULL) {
00359       if (++x > 1)
00360          ast_str_append(buf, 0, "\n");
00361 
00362       AST_LIST_TRAVERSE(&cdr->varshead, variables, entries) {
00363          if (variables &&
00364              (var = ast_var_name(variables)) && (val = ast_var_value(variables)) &&
00365              !ast_strlen_zero(var) && !ast_strlen_zero(val)) {
00366             if (ast_str_append(buf, 0, "level %d: %s%c%s%c", x, var, delim, val, sep) < 0) {
00367                ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
00368                break;
00369             } else
00370                total++;
00371          } else 
00372             break;
00373       }
00374 
00375       for (i = 0; cdr_readonly_vars[i]; i++) {
00376          ast_cdr_getvar(cdr, cdr_readonly_vars[i], &tmp, workspace, sizeof(workspace), 0, 0);
00377          if (!tmp)
00378             continue;
00379          
00380          if (ast_str_append(buf, 0, "level %d: %s%c%s%c", x, cdr_readonly_vars[i], delim, tmp, sep) < 0) {
00381             ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
00382             break;
00383          } else
00384             total++;
00385       }
00386    }
00387 
00388    return total;
00389 }

int ast_cdr_setaccount struct ast_channel chan,
const char *  account
 

Definition at line 638 of file cdr.c.

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

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

00639 {
00640    struct ast_cdr *cdr = chan->cdr;
00641 
00642    ast_string_field_set(chan, accountcode, account);
00643    for ( ; cdr ; cdr = cdr->next) {
00644       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED))
00645          ast_copy_string(cdr->accountcode, chan->accountcode, sizeof(cdr->accountcode));
00646    }
00647    return 0;
00648 }

int ast_cdr_setamaflags struct ast_channel chan,
const char *  amaflags
 

Definition at line 650 of file cdr.c.

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

Referenced by pbx_builtin_setamaflags().

00651 {
00652    struct ast_cdr *cdr;
00653    int newflag = ast_cdr_amaflags2int(flag);
00654    if (newflag) {
00655       for (cdr = chan->cdr; cdr; cdr = cdr->next)
00656          cdr->amaflags = newflag;
00657    }
00658 
00659    return 0;
00660 }

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

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

Referenced by __ast_request_and_dial(), and pbx_exec().

00526 {
00527 
00528    for (; cdr; cdr = cdr->next) {
00529       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
00530          check_post(cdr);
00531          if (!app)
00532             app = "";
00533          ast_copy_string(cdr->lastapp, app, sizeof(cdr->lastapp));
00534          if (!data)
00535             data = "";
00536          ast_copy_string(cdr->lastdata, data, sizeof(cdr->lastdata));
00537       }
00538    }
00539 }

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

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

Referenced by ast_set_callerid().

00561 {
00562    for (; cdr; cdr = cdr->next) {
00563       if (ast_test_flag(cdr, AST_CDR_FLAG_LOCKED))
00564          set_one_cid(cdr, c);
00565    }
00566    return 0;
00567 }

void ast_cdr_setdestchan struct ast_cdr cdr,
const 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 516 of file cdr.c.

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

Referenced by ast_bridge_call_thread(), and park_exec().

00517 {
00518    for (; cdr; cdr = cdr->next) {
00519       check_post(cdr);
00520       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED))
00521          ast_copy_string(cdr->dstchannel, chann, sizeof(cdr->dstchannel));
00522    }
00523 }

int ast_cdr_setuserfield struct ast_channel chan,
const char *  userfield
 

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

00663 {
00664    struct ast_cdr *cdr = chan->cdr;
00665 
00666    for ( ; cdr ; cdr = cdr->next) {
00667       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) 
00668          ast_copy_string(cdr->userfield, userfield, sizeof(cdr->userfield));
00669    }
00670 
00671    return 0;
00672 }

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

References ast_log(), and LOG_ERROR.

00286 {
00287    struct ast_var_t *newvariable;
00288    struct varshead *headp;
00289    int x;
00290    
00291    for (x = 0; cdr_readonly_vars[x]; x++) {
00292       if (!strcasecmp(name, cdr_readonly_vars[x])) {
00293          ast_log(LOG_ERROR, "Attempt to set the '%s' read-only variable!.\n", name);
00294          return -1;
00295       }
00296    }
00297 
00298    if (!cdr) {
00299       ast_log(LOG_ERROR, "Attempt to set a variable on a nonexistent CDR record.\n");
00300       return -1;
00301    }
00302 
00303    for (; cdr; cdr = recur ? cdr->next : NULL) {
00304       headp = &cdr->varshead;
00305       AST_LIST_TRAVERSE_SAFE_BEGIN(headp, newvariable, entries) {
00306          if (!strcasecmp(ast_var_name(newvariable), name)) {
00307             /* there is already such a variable, delete it */
00308             AST_LIST_REMOVE_CURRENT(headp, entries);
00309             ast_var_delete(newvariable);
00310             break;
00311          }
00312       }
00313       AST_LIST_TRAVERSE_SAFE_END;
00314 
00315       if (value) {
00316          newvariable = ast_var_assign(name, value);
00317          AST_LIST_INSERT_HEAD(headp, newvariable, entries);
00318       }
00319    }
00320 
00321    return 0;
00322 }

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

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

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

00443 {
00444    char *chan; 
00445 
00446    for (; cdr; cdr = cdr->next) {
00447       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
00448          chan = S_OR(cdr->channel, "<unknown>");
00449          check_post(cdr);
00450          check_start(cdr);
00451          cdr->start = ast_tvnow();
00452       }
00453    }
00454 }

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

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

Referenced by ast_cdr_engine_term(), and submit_scheduled_batch().

00833 {
00834    struct ast_cdr_batch_item *oldbatchitems = NULL;
00835    pthread_attr_t attr;
00836    pthread_t batch_post_thread = AST_PTHREADT_NULL;
00837 
00838    /* if there's no batch, or no CDRs in the batch, then there's nothing to do */
00839    if (!batch || !batch->head)
00840       return;
00841 
00842    /* move the old CDRs aside, and prepare a new CDR batch */
00843    ast_mutex_lock(&cdr_batch_lock);
00844    oldbatchitems = batch->head;
00845    reset_batch();
00846    ast_mutex_unlock(&cdr_batch_lock);
00847 
00848    /* if configured, spawn a new thread to post these CDRs,
00849       also try to save as much as possible if we are shutting down safely */
00850    if (batchscheduleronly || shutdown) {
00851       if (option_debug)
00852          ast_log(LOG_DEBUG, "CDR single-threaded batch processing begins now\n");
00853       do_batch_backend_process(oldbatchitems);
00854    } else {
00855       pthread_attr_init(&attr);
00856       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
00857       if (ast_pthread_create_background(&batch_post_thread, &attr, do_batch_backend_process, oldbatchitems)) {
00858          ast_log(LOG_WARNING, "CDR processing thread could not detach, now trying in this thread\n");
00859          do_batch_backend_process(oldbatchitems);
00860       } else {
00861          if (option_debug)
00862             ast_log(LOG_DEBUG, "CDR multi-threaded batch processing begins now\n");
00863       }
00864       pthread_attr_destroy(&attr);
00865    }
00866 }

void ast_cdr_unregister const 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_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_verbose(), free, ast_cdr_beitem::name, option_verbose, and VERBOSE_PREFIX_2.

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

References AST_CDR_FLAG_LOCKED, ast_test_flag, ast_channel::cdr, ast_channel::context, ast_channel::exten, ast_channel::macrocontext, ast_channel::macroexten, ast_cdr::next, S_OR, and set_one_cid().

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

00689 {
00690    struct ast_cdr *cdr = c->cdr;
00691 
00692    for ( ; cdr ; cdr = cdr->next) {
00693       if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
00694          set_one_cid(cdr, c);
00695 
00696          /* Copy account code et-al */ 
00697          ast_copy_string(cdr->accountcode, c->accountcode, sizeof(cdr->accountcode));
00698          /* Destination information */ /* XXX privilege macro* ? */
00699          ast_copy_string(cdr->dst, S_OR(c->macroexten, c->exten), sizeof(cdr->dst));
00700          ast_copy_string(cdr->dcontext, S_OR(c->macrocontext, c->context), sizeof(cdr->dcontext));
00701       }
00702    }
00703 
00704    return 0;
00705 }


Variable Documentation

char ast_default_accountcode[AST_MAX_ACCOUNT_CODE]
 

Definition at line 60 of file cdr.c.

int ast_default_amaflags
 

Default AMA flag for billing records (CDR's)

Definition at line 59 of file cdr.c.

Referenced by ast_cdr_init().


Asterisk is a trademark for Digium, inc.. | Edvina.net | Asterisk.org | This documentation was generated with Doxygen