#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 << 0) |
#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 << 2) |
#define | AST_CDR_NULL 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_cdr * | ast_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_cdr * | ast_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) |
void | ast_cdr_discard (struct ast_cdr *cdr) |
Discard and free a CDR record. | |
char * | ast_cdr_disp2str (int disposition) |
int | ast_cdr_disposition (struct ast_cdr *cdr, int cause) |
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). | |
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. | |
void | ast_cdr_merge (struct ast_cdr *to, struct ast_cdr *from) |
void | ast_cdr_noanswer (struct ast_cdr *cdr) |
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, 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, 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 |
Definition in file cdr.h.
#define AST_CDR_ANSWERED (1 << 3) |
Definition at line 37 of file cdr.h.
Referenced by ast_cdr_answer(), ast_cdr_disp2str(), ast_cdr_init(), and post_cdr().
#define AST_CDR_BILLING (2) |
#define AST_CDR_BUSY (1 << 1) |
#define AST_CDR_DOCUMENTATION (3) |
Definition at line 42 of file cdr.h.
Referenced by ast_cdr_amaflags2int(), ast_cdr_flags2str(), and ast_cdr_merge().
#define AST_CDR_FAILED (1 << 0) |
Definition at line 34 of file cdr.h.
Referenced by ast_cdr_disp2str(), ast_cdr_end(), and ast_cdr_failed().
#define AST_CDR_FLAG_CHILD (1 << 3) |
#define AST_CDR_FLAG_KEEP_VARS (1 << 0) |
Definition at line 27 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) |
Definition at line 29 of file cdr.h.
Referenced by ast_bridge_call(), ast_cdr_answer(), ast_cdr_appenduserfield(), ast_cdr_busy(), ast_cdr_end(), ast_cdr_failed(), ast_cdr_fork(), ast_cdr_init(), ast_cdr_merge(), ast_cdr_noanswer(), ast_cdr_reset(), ast_cdr_setaccount(), ast_cdr_setamaflags(), ast_cdr_setapp(), ast_cdr_setcid(), ast_cdr_setdestchan(), ast_cdr_setuserfield(), ast_cdr_setvar(), ast_cdr_start(), ast_cdr_update(), and try_calling().
#define AST_CDR_FLAG_POST_DISABLED (1 << 4) |
Definition at line 31 of file cdr.h.
Referenced by ast_cdr_detach(), ast_cdr_free(), ast_cdr_merge(), connect_link(), nocdr_exec(), post_cdr(), rpt(), rpt_call(), and rpt_tele_thread().
#define AST_CDR_FLAG_POSTED (1 << 1) |
Definition at line 28 of file cdr.h.
Referenced by ast_cdr_free(), ast_cdr_merge(), ast_cdr_noanswer(), ast_cdr_reset(), check_post(), disa_exec(), and post_cdr().
#define AST_CDR_NOANSWER (1 << 2) |
Definition at line 36 of file cdr.h.
Referenced by ast_cdr_disp2str(), ast_cdr_merge(), and ast_cdr_noanswer().
#define AST_CDR_NULL 0 |
Definition at line 33 of file cdr.h.
Referenced by ast_cdr_disp2str(), ast_cdr_init(), and ast_cdr_reset().
#define AST_CDR_OMIT (1) |
AMA Flags
Definition at line 40 of file cdr.h.
Referenced by ast_cdr_amaflags2int(), and ast_cdr_flags2str().
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 459 of file cdr.c.
References ast_calloc, ast_log(), and LOG_ERROR.
Referenced by __agent_start_monitoring(), __ast_pbx_run(), __ast_read(), __ast_request_and_dial(), ast_bridge_call(), ast_cdr_dup(), ast_feature_request_and_dial(), ast_pbx_outgoing_app(), builtin_blindtransfer(), clear_caller(), findmeexec(), and start_monitor_exec().
00460 { 00461 struct ast_cdr *x = ast_calloc(1, sizeof(struct ast_cdr)); 00462 if (!x) 00463 ast_log(LOG_ERROR,"Allocation Failure for a CDR!\n"); 00464 return x; 00465 }
int ast_cdr_amaflags2int | ( | const char * | flag | ) |
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 965 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(), process_zap(), and set_config().
00966 { 00967 if (!strcasecmp(flag, "default")) 00968 return 0; 00969 if (!strcasecmp(flag, "omit")) 00970 return AST_CDR_OMIT; 00971 if (!strcasecmp(flag, "billing")) 00972 return AST_CDR_BILLING; 00973 if (!strcasecmp(flag, "documentation")) 00974 return AST_CDR_DOCUMENTATION; 00975 return -1; 00976 }
void ast_cdr_answer | ( | struct ast_cdr * | cdr | ) |
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 695 of file cdr.c.
References AST_CDR_ANSWERED, AST_CDR_FLAG_LOCKED, ast_test_flag, check_post(), and ast_cdr::next.
Referenced by __ast_read(), and ast_answer().
00696 { 00697 00698 for (; cdr; cdr = cdr->next) { 00699 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) { 00700 check_post(cdr); 00701 if (cdr->disposition < AST_CDR_ANSWERED) 00702 cdr->disposition = AST_CDR_ANSWERED; 00703 if (ast_tvzero(cdr->answer)) 00704 cdr->answer = ast_tvnow(); 00705 } 00706 } 00707 }
Definition at line 1044 of file cdr.c.
References ast_cdr::next.
Referenced by ast_cdr_fork(), ast_cdr_merge(), and attempt_transfer().
01045 { 01046 struct ast_cdr *ret; 01047 01048 if (cdr) { 01049 ret = cdr; 01050 01051 while (cdr->next) 01052 cdr = cdr->next; 01053 cdr->next = newcdr; 01054 } else { 01055 ret = newcdr; 01056 } 01057 01058 return ret; 01059 }
int ast_cdr_appenduserfield | ( | struct ast_channel * | chan, | |
const char * | userfield | |||
) |
Definition at line 931 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 action_setcdruserfield(), appendcdruserfield_exec(), and ast_bridge_call().
00932 { 00933 struct ast_cdr *cdr = chan->cdr; 00934 00935 for ( ; cdr ; cdr = cdr->next) { 00936 int len = strlen(cdr->userfield); 00937 00938 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) 00939 ast_copy_string(cdr->userfield + len, userfield, sizeof(cdr->userfield) - len); 00940 } 00941 00942 return 0; 00943 }
void ast_cdr_busy | ( | struct ast_cdr * | cdr | ) |
cdr | the cdr you wish to associate with the call Returns nothing |
Definition at line 709 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(), and ring_entry().
00710 { 00711 00712 for (; cdr; cdr = cdr->next) { 00713 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) { 00714 check_post(cdr); 00715 if (cdr->disposition < AST_CDR_BUSY) 00716 cdr->disposition = AST_CDR_BUSY; 00717 } 00718 } 00719 }
Definition at line 337 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().
00338 { 00339 struct ast_var_t *variables, *newvariable = NULL; 00340 struct varshead *headpa, *headpb; 00341 const char *var, *val; 00342 int x = 0; 00343 00344 if (!to_cdr || !from_cdr) /* don't die if one of the pointers is null */ 00345 return 0; 00346 00347 headpa = &from_cdr->varshead; 00348 headpb = &to_cdr->varshead; 00349 00350 AST_LIST_TRAVERSE(headpa,variables,entries) { 00351 if (variables && 00352 (var = ast_var_name(variables)) && (val = ast_var_value(variables)) && 00353 !ast_strlen_zero(var) && !ast_strlen_zero(val)) { 00354 newvariable = ast_var_assign(var, val); 00355 AST_LIST_INSERT_HEAD(headpb, newvariable, entries); 00356 x++; 00357 } 00358 } 00359 00360 return x; 00361 }
void ast_cdr_detach | ( | struct ast_cdr * | cdr | ) |
cdr | Which CDR to detach from the channel thread Prevents the channel thread from blocking on the CDR handling Returns nothing |
Definition at line 1155 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().
01156 { 01157 struct ast_cdr_batch_item *newtail; 01158 int curr; 01159 01160 if (!cdr) 01161 return; 01162 01163 /* maybe they disabled CDR stuff completely, so just drop it */ 01164 if (!enabled) { 01165 if (option_debug) 01166 ast_log(LOG_DEBUG, "Dropping CDR !\n"); 01167 ast_set_flag(cdr, AST_CDR_FLAG_POST_DISABLED); 01168 ast_cdr_free(cdr); 01169 return; 01170 } 01171 01172 /* post stuff immediately if we are not in batch mode, this is legacy behaviour */ 01173 if (!batchmode) { 01174 post_cdr(cdr); 01175 ast_cdr_free(cdr); 01176 return; 01177 } 01178 01179 /* otherwise, each CDR gets put into a batch list (at the end) */ 01180 if (option_debug) 01181 ast_log(LOG_DEBUG, "CDR detaching from this thread\n"); 01182 01183 /* we'll need a new tail for every CDR */ 01184 if (!(newtail = ast_calloc(1, sizeof(*newtail)))) { 01185 post_cdr(cdr); 01186 ast_cdr_free(cdr); 01187 return; 01188 } 01189 01190 /* don't traverse a whole list (just keep track of the tail) */ 01191 ast_mutex_lock(&cdr_batch_lock); 01192 if (!batch) 01193 init_batch(); 01194 if (!batch->head) { 01195 /* new batch is empty, so point the head at the new tail */ 01196 batch->head = newtail; 01197 } else { 01198 /* already got a batch with something in it, so just append a new tail */ 01199 batch->tail->next = newtail; 01200 } 01201 newtail->cdr = cdr; 01202 batch->tail = newtail; 01203 curr = batch->size++; 01204 ast_mutex_unlock(&cdr_batch_lock); 01205 01206 /* if we have enough stuff to post, then do it */ 01207 if (curr >= (batchsize - 1)) 01208 submit_unscheduled_batch(); 01209 }
void ast_cdr_discard | ( | struct ast_cdr * | cdr | ) |
Discard and free a CDR record.
cdr | ast_cdr structure to free Returns nothing -- same as free, but no checks or complaints |
Definition at line 448 of file cdr.c.
References ast_cdr_free_vars(), free, and ast_cdr::next.
Referenced by ast_async_goto(), ast_bridge_call(), and ast_cdr_merge().
00449 { 00450 while (cdr) { 00451 struct ast_cdr *next = cdr->next; 00452 00453 ast_cdr_free_vars(cdr, 0); 00454 free(cdr); 00455 cdr = next; 00456 } 00457 }
char* ast_cdr_disp2str | ( | int | disposition | ) |
disposition | input binary form Converts the binary form of a disposition to string form. Returns a pointer to the string form |
Definition at line 860 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(), manager_log(), mysql_log(), odbc_log(), pgsql_log(), and tds_log().
00861 { 00862 switch (disposition) { 00863 case AST_CDR_NULL: 00864 return "NO ANSWER"; /* by default, for backward compatibility */ 00865 case AST_CDR_NOANSWER: 00866 return "NO ANSWER"; 00867 case AST_CDR_FAILED: 00868 return "FAILED"; 00869 case AST_CDR_BUSY: 00870 return "BUSY"; 00871 case AST_CDR_ANSWERED: 00872 return "ANSWERED"; 00873 } 00874 return "UNKNOWN"; 00875 }
int ast_cdr_disposition | ( | struct ast_cdr * | cdr, | |
int | cause | |||
) |
cdr | the cdr you wish to associate with the call Returns nothing | |
cause | the AST_CAUSE_* |
Definition at line 751 of file cdr.c.
References AST_CAUSE_BUSY, AST_CAUSE_NORMAL, ast_cdr_busy(), and ast_cdr::next.
Referenced by __ast_request_and_dial(), ast_feature_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_NORMAL: 00762 break; 00763 default: 00764 res = -1; 00765 } 00766 } 00767 return res; 00768 }
Duplicate a record Returns a malloc'd ast_cdr structure, returns NULL on error (malloc failure).
Duplicate a CDR record
Definition at line 168 of file cdr.c.
References ast_cdr_alloc(), and ast_cdr_copy_vars().
Referenced by ast_async_goto(), ast_cdr_fork(), ast_cdr_merge(), and ast_cdr_reset().
00169 { 00170 struct ast_cdr *newcdr; 00171 00172 if (!cdr) /* don't die if we get a null cdr pointer */ 00173 return NULL; 00174 newcdr = ast_cdr_alloc(); 00175 if (!newcdr) 00176 return NULL; 00177 00178 memcpy(newcdr, cdr, sizeof(*newcdr)); 00179 /* The varshead is unusable, volatile even, after the memcpy so we take care of that here */ 00180 memset(&newcdr->varshead, 0, sizeof(newcdr->varshead)); 00181 ast_cdr_copy_vars(newcdr, cdr); 00182 newcdr->next = NULL; 00183 00184 return newcdr; 00185 }
void ast_cdr_end | ( | struct ast_cdr * | cdr | ) |
cdr | the cdr you have associated the call with Registers the end of call time in the cdr structure. Returns nothing |
Definition at line 843 of file cdr.c.
References ast_cdr::answer, AST_CDR_FAILED, AST_CDR_FLAG_LOCKED, ast_log(), ast_test_flag, ast_cdr::billsec, check_post(), ast_cdr::duration, 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_feature_request_and_dial(), ast_hangup(), ast_pbx_outgoing_cdr_failed(), clear_caller(), and findmeexec().
00844 { 00845 for ( ; cdr ; cdr = cdr->next) { 00846 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) { 00847 check_post(cdr); 00848 if (ast_tvzero(cdr->end)) 00849 cdr->end = ast_tvnow(); 00850 if (ast_tvzero(cdr->start)) { 00851 ast_log(LOG_WARNING, "CDR on channel '%s' has not started\n", S_OR(cdr->channel, "<unknown>")); 00852 cdr->disposition = AST_CDR_FAILED; 00853 } else 00854 cdr->duration = cdr->end.tv_sec - cdr->start.tv_sec; 00855 cdr->billsec = ast_tvzero(cdr->answer) ? 0 : cdr->end.tv_sec - cdr->answer.tv_sec; 00856 } 00857 } 00858 }
int ast_cdr_engine_init | ( | void | ) |
Load the configuration file cdr.conf and possibly start the CDR scheduling thread
Definition at line 1413 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().
Referenced by main().
01414 { 01415 int res; 01416 01417 sched = sched_context_create(); 01418 if (!sched) { 01419 ast_log(LOG_ERROR, "Unable to create schedule context.\n"); 01420 return -1; 01421 } 01422 01423 ast_cli_register(&cli_status); 01424 01425 res = do_reload(); 01426 if (res) { 01427 ast_mutex_lock(&cdr_batch_lock); 01428 res = init_batch(); 01429 ast_mutex_unlock(&cdr_batch_lock); 01430 } 01431 01432 return res; 01433 }
int ast_cdr_engine_reload | ( | void | ) |
Reload the configuration file cdr.conf and start/stop CDR scheduling thread
Definition at line 1442 of file cdr.c.
References do_reload().
01443 { 01444 return do_reload(); 01445 }
void ast_cdr_engine_term | ( | void | ) |
Submit any remaining CDRs and prepare for shutdown
Definition at line 1437 of file cdr.c.
References ast_cdr_submit_batch(), and batchsafeshutdown.
Referenced by do_reload(), and quit_handler().
01438 { 01439 ast_cdr_submit_batch(batchsafeshutdown); 01440 }
void ast_cdr_failed | ( | struct ast_cdr * | cdr | ) |
cdr | the cdr you wish to associate with the call Returns nothing |
Definition at line 721 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_feature_request_and_dial(), ast_pbx_outgoing_app(), ast_pbx_outgoing_cdr_failed(), ast_pbx_outgoing_exten(), clear_caller(), and findmeexec().
00722 { 00723 for (; cdr; cdr = cdr->next) { 00724 check_post(cdr); 00725 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) { 00726 if (cdr->disposition < AST_CDR_FAILED) 00727 cdr->disposition = AST_CDR_FAILED; 00728 } 00729 } 00730 }
char* ast_cdr_flags2str | ( | int | flag | ) |
Converts AMA flag to printable string
Definition at line 878 of file cdr.c.
References AST_CDR_BILLING, AST_CDR_DOCUMENTATION, and AST_CDR_OMIT.
Referenced by _sip_show_peer(), ast_cdr_getvar(), build_csv_record(), build_radius_record(), csv_log(), manager_log(), sip_show_user(), and tds_log().
00879 { 00880 switch(flag) { 00881 case AST_CDR_OMIT: 00882 return "OMIT"; 00883 case AST_CDR_BILLING: 00884 return "BILLING"; 00885 case AST_CDR_DOCUMENTATION: 00886 return "DOCUMENTATION"; 00887 } 00888 return "Unknown"; 00889 }
void ast_cdr_free | ( | struct ast_cdr * | cdr | ) |
Free a CDR record.
cdr | ast_cdr structure to free Returns nothing |
Definition at line 428 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().
00429 { 00430 00431 while (cdr) { 00432 struct ast_cdr *next = cdr->next; 00433 char *chan = S_OR(cdr->channel, "<unknown>"); 00434 if (!ast_test_flag(cdr, AST_CDR_FLAG_POSTED) && !ast_test_flag(cdr, AST_CDR_FLAG_POST_DISABLED)) 00435 ast_log(LOG_NOTICE, "CDR on channel '%s' not posted\n", chan); 00436 if (ast_tvzero(cdr->end)) 00437 ast_log(LOG_NOTICE, "CDR on channel '%s' lacks end\n", chan); 00438 if (ast_tvzero(cdr->start)) 00439 ast_log(LOG_NOTICE, "CDR on channel '%s' lacks start\n", chan); 00440 00441 ast_cdr_free_vars(cdr, 0); 00442 free(cdr); 00443 cdr = next; 00444 } 00445 }
void ast_cdr_free_vars | ( | struct ast_cdr * | cdr, | |
int | recur | |||
) |
Definition at line 407 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().
00408 { 00409 00410 /* clear variables */ 00411 for (; cdr; cdr = recur ? cdr->next : NULL) { 00412 struct ast_var_t *vardata; 00413 struct varshead *headp = &cdr->varshead; 00414 while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries))) 00415 ast_var_delete(vardata); 00416 } 00417 }
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 220 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(), and cdr_read().
00221 { 00222 const char *fmt = "%Y-%m-%d %T"; 00223 const char *varbuf; 00224 00225 if (!cdr) /* don't die if the cdr is null */ 00226 return; 00227 00228 *ret = NULL; 00229 /* special vars (the ones from the struct ast_cdr when requested by name) 00230 I'd almost say we should convert all the stringed vals to vars */ 00231 00232 if (!strcasecmp(name, "clid")) 00233 ast_copy_string(workspace, cdr->clid, workspacelen); 00234 else if (!strcasecmp(name, "src")) 00235 ast_copy_string(workspace, cdr->src, workspacelen); 00236 else if (!strcasecmp(name, "dst")) 00237 ast_copy_string(workspace, cdr->dst, workspacelen); 00238 else if (!strcasecmp(name, "dcontext")) 00239 ast_copy_string(workspace, cdr->dcontext, workspacelen); 00240 else if (!strcasecmp(name, "channel")) 00241 ast_copy_string(workspace, cdr->channel, workspacelen); 00242 else if (!strcasecmp(name, "dstchannel")) 00243 ast_copy_string(workspace, cdr->dstchannel, workspacelen); 00244 else if (!strcasecmp(name, "lastapp")) 00245 ast_copy_string(workspace, cdr->lastapp, workspacelen); 00246 else if (!strcasecmp(name, "lastdata")) 00247 ast_copy_string(workspace, cdr->lastdata, workspacelen); 00248 else if (!strcasecmp(name, "start")) 00249 cdr_get_tv(cdr->start, raw ? NULL : fmt, workspace, workspacelen); 00250 else if (!strcasecmp(name, "answer")) 00251 cdr_get_tv(cdr->answer, raw ? NULL : fmt, workspace, workspacelen); 00252 else if (!strcasecmp(name, "end")) 00253 cdr_get_tv(cdr->end, raw ? NULL : fmt, workspace, workspacelen); 00254 else if (!strcasecmp(name, "duration")) 00255 snprintf(workspace, workspacelen, "%ld", cdr->duration); 00256 else if (!strcasecmp(name, "billsec")) 00257 snprintf(workspace, workspacelen, "%ld", cdr->billsec); 00258 else if (!strcasecmp(name, "disposition")) { 00259 if (raw) { 00260 snprintf(workspace, workspacelen, "%ld", cdr->disposition); 00261 } else { 00262 ast_copy_string(workspace, ast_cdr_disp2str(cdr->disposition), workspacelen); 00263 } 00264 } else if (!strcasecmp(name, "amaflags")) { 00265 if (raw) { 00266 snprintf(workspace, workspacelen, "%ld", cdr->amaflags); 00267 } else { 00268 ast_copy_string(workspace, ast_cdr_flags2str(cdr->amaflags), workspacelen); 00269 } 00270 } else if (!strcasecmp(name, "accountcode")) 00271 ast_copy_string(workspace, cdr->accountcode, workspacelen); 00272 else if (!strcasecmp(name, "uniqueid")) 00273 ast_copy_string(workspace, cdr->uniqueid, workspacelen); 00274 else if (!strcasecmp(name, "userfield")) 00275 ast_copy_string(workspace, cdr->userfield, workspacelen); 00276 else if ((varbuf = ast_cdr_getvar_internal(cdr, name, recur))) 00277 ast_copy_string(workspace, varbuf, workspacelen); 00278 else 00279 workspace[0] = '\0'; 00280 00281 if (!ast_strlen_zero(workspace)) 00282 *ret = workspace; 00283 }
int ast_cdr_init | ( | struct ast_cdr * | cdr, | |
struct ast_channel * | chan | |||
) |
Initialize based on a channel.
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 820 of file cdr.c.
References ast_channel::_state, ast_channel::amaflags, AST_CDR_ANSWERED, AST_CDR_FLAG_LOCKED, AST_CDR_NULL, AST_STATE_UP, ast_test_flag, ast_cdr::channel, ast_channel::context, ast_channel::exten, ast_channel::macrocontext, ast_channel::macroexten, ast_cdr::next, S_OR, and set_one_cid().
Referenced by __ast_pbx_run(), __ast_read(), __ast_request_and_dial(), ast_bridge_call(), ast_feature_request_and_dial(), ast_pbx_outgoing_app(), ast_pbx_outgoing_cdr_failed(), builtin_blindtransfer(), clear_caller(), and findmeexec().
00821 { 00822 char *chan; 00823 00824 for ( ; cdr ; cdr = cdr->next) { 00825 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) { 00826 chan = S_OR(cdr->channel, "<unknown>"); 00827 ast_copy_string(cdr->channel, c->name, sizeof(cdr->channel)); 00828 set_one_cid(cdr, c); 00829 00830 cdr->disposition = (c->_state == AST_STATE_UP) ? AST_CDR_ANSWERED : AST_CDR_NULL; 00831 cdr->amaflags = c->amaflags ? c->amaflags : ast_default_amaflags; 00832 ast_copy_string(cdr->accountcode, c->accountcode, sizeof(cdr->accountcode)); 00833 /* Destination information */ 00834 ast_copy_string(cdr->dst, S_OR(c->macroexten,c->exten), sizeof(cdr->dst)); 00835 ast_copy_string(cdr->dcontext, S_OR(c->macrocontext,c->context), sizeof(cdr->dcontext)); 00836 /* Unique call identifier */ 00837 ast_copy_string(cdr->uniqueid, c->uniqueid, sizeof(cdr->uniqueid)); 00838 } 00839 } 00840 return 0; 00841 }
Move the non-null data from the "from" cdr to the "to" cdr
to | the cdr to get the goodies | |
from | the cdr to give the goodies |
Definition at line 503 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_log(), ast_set_flag, ast_strlen_zero(), ast_test_flag, 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.
Referenced by ast_bridge_call().
00504 { 00505 struct ast_cdr *zcdr; 00506 struct ast_cdr *lto = NULL; 00507 struct ast_cdr *lfrom = NULL; 00508 int discard_from = 0; 00509 00510 if (!to || !from) 00511 return; 00512 00513 /* don't merge into locked CDR's -- it's bad business */ 00514 if (ast_test_flag(to, AST_CDR_FLAG_LOCKED)) { 00515 zcdr = to; /* safety valve? */ 00516 while (to->next) { 00517 lto = to; 00518 to = to->next; 00519 } 00520 00521 if (ast_test_flag(to, AST_CDR_FLAG_LOCKED)) { 00522 ast_log(LOG_WARNING, "Merging into locked CDR... no choice."); 00523 to = zcdr; /* safety-- if all there are is locked CDR's, then.... ?? */ 00524 lto = NULL; 00525 } 00526 } 00527 00528 if (ast_test_flag(from, AST_CDR_FLAG_LOCKED)) { 00529 discard_from = 1; 00530 if (lto) { 00531 struct ast_cdr *llfrom = NULL; 00532 /* insert the from stuff after lto */ 00533 lto->next = from; 00534 lfrom = from; 00535 while (lfrom && lfrom->next) { 00536 if (!lfrom->next->next) 00537 llfrom = lfrom; 00538 lfrom = lfrom->next; 00539 } 00540 /* rip off the last entry and put a copy of the to at the end */ 00541 llfrom->next = to; 00542 from = lfrom; 00543 } else { 00544 /* save copy of the current *to cdr */ 00545 struct ast_cdr tcdr; 00546 struct ast_cdr *llfrom = NULL; 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 | ) |
cdr | the cdr you wish to associate with the call Marks the channel disposition as "NO ANSWER" |
Definition at line 732 of file cdr.c.
References AST_CDR_FLAG_LOCKED, AST_CDR_FLAG_POSTED, AST_CDR_NOANSWER, ast_log(), ast_strlen_zero(), ast_test_flag, ast_cdr::channel, ast_cdr::disposition, LOG_WARNING, and ast_cdr::next.
Referenced by wait_for_answer().
00733 { 00734 char *chan; 00735 00736 while (cdr) { 00737 chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>"; 00738 if (ast_test_flag(cdr, AST_CDR_FLAG_POSTED)) 00739 ast_log(LOG_WARNING, "CDR on channel '%s' already posted\n", chan); 00740 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) { 00741 if (cdr->disposition < AST_CDR_NOANSWER) 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 driver. Each registered CDR driver generates a CDR
Definition at line 109 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.
Referenced by load_module(), my_load_module(), odbc_load_module(), process_my_load_module(), and tds_load_module().
00110 { 00111 struct ast_cdr_beitem *i; 00112 00113 if (!name) 00114 return -1; 00115 if (!be) { 00116 ast_log(LOG_WARNING, "CDR engine '%s' lacks backend\n", name); 00117 return -1; 00118 } 00119 00120 AST_LIST_LOCK(&be_list); 00121 AST_LIST_TRAVERSE(&be_list, i, list) { 00122 if (!strcasecmp(name, i->name)) 00123 break; 00124 } 00125 AST_LIST_UNLOCK(&be_list); 00126 00127 if (i) { 00128 ast_log(LOG_WARNING, "Already have a CDR backend called '%s'\n", name); 00129 return -1; 00130 } 00131 00132 if (!(i = ast_calloc(1, sizeof(*i)))) 00133 return -1; 00134 00135 i->be = be; 00136 ast_copy_string(i->name, name, sizeof(i->name)); 00137 ast_copy_string(i->desc, desc, sizeof(i->desc)); 00138 00139 AST_LIST_LOCK(&be_list); 00140 AST_LIST_INSERT_HEAD(&be_list, i, list); 00141 AST_LIST_UNLOCK(&be_list); 00142 00143 return 0; 00144 }
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 1007 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_NULL, ast_cdr_start(), ast_clear_flag, ast_copy_flags, AST_FLAGS_ALL, ast_set_flag, ast_test_flag, ast_cdr::billsec, ast_cdr::disposition, ast_cdr::duration, ast_cdr::end, ast_flags::flags, ast_cdr::next, and ast_cdr::start.
Referenced by ast_bridge_call_thread(), ast_cdr_fork(), disa_exec(), and pbx_builtin_resetcdr().
01008 { 01009 struct ast_cdr *dup; 01010 struct ast_flags flags = { 0 }; 01011 01012 if (_flags) 01013 ast_copy_flags(&flags, _flags, AST_FLAGS_ALL); 01014 01015 for ( ; cdr ; cdr = cdr->next) { 01016 /* Detach if post is requested */ 01017 if (ast_test_flag(&flags, AST_CDR_FLAG_LOCKED) || !ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) { 01018 if (ast_test_flag(&flags, AST_CDR_FLAG_POSTED)) { 01019 ast_cdr_end(cdr); 01020 if ((dup = ast_cdr_dup(cdr))) { 01021 ast_cdr_detach(dup); 01022 } 01023 ast_set_flag(cdr, AST_CDR_FLAG_POSTED); 01024 } 01025 01026 /* clear variables */ 01027 if (!ast_test_flag(&flags, AST_CDR_FLAG_KEEP_VARS)) { 01028 ast_cdr_free_vars(cdr, 0); 01029 } 01030 01031 /* Reset to initial state */ 01032 ast_clear_flag(cdr, AST_FLAGS_ALL); 01033 memset(&cdr->start, 0, sizeof(cdr->start)); 01034 memset(&cdr->end, 0, sizeof(cdr->end)); 01035 memset(&cdr->answer, 0, sizeof(cdr->answer)); 01036 cdr->billsec = 0; 01037 cdr->duration = 0; 01038 ast_cdr_start(cdr); 01039 cdr->disposition = AST_CDR_NULL; 01040 } 01041 } 01042 }
int ast_cdr_serialize_variables | ( | struct ast_cdr * | cdr, | |
char * | buf, | |||
size_t | size, | |||
char | delim, | |||
char | sep, | |||
int | recur | |||
) |
Definition at line 363 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(), cdr_readonly_vars, LOG_ERROR, ast_cdr::next, total, var, and ast_cdr::varshead.
Referenced by handle_showchan(), and handle_showchan_deprecated().
00364 { 00365 struct ast_var_t *variables; 00366 const char *var, *val; 00367 char *tmp; 00368 char workspace[256]; 00369 int total = 0, x = 0, i; 00370 00371 memset(buf, 0, size); 00372 00373 for (; cdr; cdr = recur ? cdr->next : NULL) { 00374 if (++x > 1) 00375 ast_build_string(&buf, &size, "\n"); 00376 00377 AST_LIST_TRAVERSE(&cdr->varshead, variables, entries) { 00378 if (variables && 00379 (var = ast_var_name(variables)) && (val = ast_var_value(variables)) && 00380 !ast_strlen_zero(var) && !ast_strlen_zero(val)) { 00381 if (ast_build_string(&buf, &size, "level %d: %s%c%s%c", x, var, delim, val, sep)) { 00382 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n"); 00383 break; 00384 } else 00385 total++; 00386 } else 00387 break; 00388 } 00389 00390 for (i = 0; cdr_readonly_vars[i]; i++) { 00391 ast_cdr_getvar(cdr, cdr_readonly_vars[i], &tmp, workspace, sizeof(workspace), 0, 0); 00392 if (!tmp) 00393 continue; 00394 00395 if (ast_build_string(&buf, &size, "level %d: %s%c%s%c", x, cdr_readonly_vars[i], delim, tmp, sep)) { 00396 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n"); 00397 break; 00398 } else 00399 total++; 00400 } 00401 } 00402 00403 return total; 00404 }
int ast_cdr_setaccount | ( | struct ast_channel * | chan, | |
const char * | account | |||
) |
Definition at line 891 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(), ast_pbx_outgoing_exten(), auth_exec(), cdr_write(), and rpt_call().
00892 { 00893 struct ast_cdr *cdr = chan->cdr; 00894 00895 ast_string_field_set(chan, accountcode, account); 00896 for ( ; cdr ; cdr = cdr->next) { 00897 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) { 00898 ast_copy_string(cdr->accountcode, chan->accountcode, sizeof(cdr->accountcode)); 00899 } 00900 } 00901 return 0; 00902 }
int ast_cdr_setamaflags | ( | struct ast_channel * | chan, | |
const char * | amaflags | |||
) |
Definition at line 904 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().
00905 { 00906 struct ast_cdr *cdr; 00907 int newflag = ast_cdr_amaflags2int(flag); 00908 if (newflag) { 00909 for (cdr = chan->cdr; cdr; cdr = cdr->next) { 00910 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) { 00911 cdr->amaflags = newflag; 00912 } 00913 } 00914 } 00915 00916 return 0; 00917 }
void ast_cdr_setapp | ( | struct ast_cdr * | cdr, | |
char * | app, | |||
char * | data | |||
) |
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 779 of file cdr.c.
References AST_CDR_FLAG_LOCKED, ast_test_flag, check_post(), ast_cdr::next, and S_OR.
Referenced by __ast_request_and_dial(), ast_feature_request_and_dial(), builtin_blindtransfer(), clear_caller(), findmeexec(), and pbx_exec().
00780 { 00781 00782 for (; cdr; cdr = cdr->next) { 00783 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) { 00784 check_post(cdr); 00785 ast_copy_string(cdr->lastapp, S_OR(app, ""), sizeof(cdr->lastapp)); 00786 ast_copy_string(cdr->lastdata, S_OR(data, ""), sizeof(cdr->lastdata)); 00787 } 00788 } 00789 }
int ast_cdr_setcid | ( | struct ast_cdr * | cdr, | |
struct ast_channel * | chan | |||
) |
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 811 of file cdr.c.
References AST_CDR_FLAG_LOCKED, ast_test_flag, ast_cdr::next, and set_one_cid().
Referenced by ast_set_callerid().
00812 { 00813 for (; cdr; cdr = cdr->next) { 00814 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) 00815 set_one_cid(cdr, c); 00816 } 00817 return 0; 00818 }
void ast_cdr_setdestchan | ( | struct ast_cdr * | cdr, | |
const char * | chan | |||
) |
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 770 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(), ast_bridge_call_thread(), builtin_blindtransfer(), park_exec(), and try_calling().
00771 { 00772 for (; cdr; cdr = cdr->next) { 00773 check_post(cdr); 00774 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) 00775 ast_copy_string(cdr->dstchannel, chann, sizeof(cdr->dstchannel)); 00776 } 00777 }
int ast_cdr_setuserfield | ( | struct ast_channel * | chan, | |
const char * | userfield | |||
) |
Definition at line 919 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(), cdr_write(), handle_request_info(), setcdruserfield_exec(), and start_monitor_exec().
00920 { 00921 struct ast_cdr *cdr = chan->cdr; 00922 00923 for ( ; cdr ; cdr = cdr->next) { 00924 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) 00925 ast_copy_string(cdr->userfield, userfield, sizeof(cdr->userfield)); 00926 } 00927 00928 return 0; 00929 }
int ast_cdr_setvar | ( | struct ast_cdr * | cdr, | |
const char * | name, | |||
const char * | value, | |||
int | recur | |||
) |
Set a CDR channel variable
Definition at line 293 of file cdr.c.
References 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 cdr_write().
00294 { 00295 struct ast_var_t *newvariable; 00296 struct varshead *headp; 00297 int x; 00298 00299 if (!cdr) /* don't die if the cdr is null */ 00300 return -1; 00301 00302 for(x = 0; cdr_readonly_vars[x]; x++) { 00303 if (!strcasecmp(name, cdr_readonly_vars[x])) { 00304 ast_log(LOG_ERROR, "Attempt to set the '%s' read-only variable!.\n", name); 00305 return -1; 00306 } 00307 } 00308 00309 if (!cdr) { 00310 ast_log(LOG_ERROR, "Attempt to set a variable on a nonexistent CDR record.\n"); 00311 return -1; 00312 } 00313 00314 for (; cdr; cdr = recur ? cdr->next : NULL) { 00315 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) { 00316 headp = &cdr->varshead; 00317 AST_LIST_TRAVERSE_SAFE_BEGIN(headp, newvariable, entries) { 00318 if (!strcasecmp(ast_var_name(newvariable), name)) { 00319 /* there is already such a variable, delete it */ 00320 AST_LIST_REMOVE_CURRENT(headp, entries); 00321 ast_var_delete(newvariable); 00322 break; 00323 } 00324 } 00325 AST_LIST_TRAVERSE_SAFE_END; 00326 00327 if (value) { 00328 newvariable = ast_var_assign(name, value); 00329 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 00330 } 00331 } 00332 } 00333 00334 return 0; 00335 }
void ast_cdr_start | ( | struct ast_cdr * | cdr | ) |
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_cdr::channel, check_post(), ast_cdr::next, S_OR, and ast_cdr::start.
Referenced by __ast_pbx_run(), __ast_read(), __ast_request_and_dial(), ast_bridge_call(), ast_cdr_reset(), ast_feature_request_and_dial(), ast_pbx_outgoing_app(), 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 | ) |
shutdown | Whether or not we are shutting down Blocks the asterisk shutdown procedures until the CDR data is submitted. Returns nothing |
Definition at line 1098 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().
01099 { 01100 struct ast_cdr_batch_item *oldbatchitems = NULL; 01101 pthread_attr_t attr; 01102 pthread_t batch_post_thread = AST_PTHREADT_NULL; 01103 01104 /* if there's no batch, or no CDRs in the batch, then there's nothing to do */ 01105 if (!batch || !batch->head) 01106 return; 01107 01108 /* move the old CDRs aside, and prepare a new CDR batch */ 01109 ast_mutex_lock(&cdr_batch_lock); 01110 oldbatchitems = batch->head; 01111 reset_batch(); 01112 ast_mutex_unlock(&cdr_batch_lock); 01113 01114 /* if configured, spawn a new thread to post these CDRs, 01115 also try to save as much as possible if we are shutting down safely */ 01116 if (batchscheduleronly || shutdown) { 01117 if (option_debug) 01118 ast_log(LOG_DEBUG, "CDR single-threaded batch processing begins now\n"); 01119 do_batch_backend_process(oldbatchitems); 01120 } else { 01121 pthread_attr_init(&attr); 01122 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 01123 if (ast_pthread_create_background(&batch_post_thread, &attr, do_batch_backend_process, oldbatchitems)) { 01124 ast_log(LOG_WARNING, "CDR processing thread could not detach, now trying in this thread\n"); 01125 do_batch_backend_process(oldbatchitems); 01126 } else { 01127 if (option_debug) 01128 ast_log(LOG_DEBUG, "CDR multi-threaded batch processing begins now\n"); 01129 } 01130 pthread_attr_destroy(&attr); 01131 } 01132 }
void ast_cdr_unregister | ( | const char * | name | ) |
unregister a CDR driver
Definition at line 147 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.
Referenced by my_unload_module(), odbc_unload_module(), tds_unload_module(), and unload_module().
00148 { 00149 struct ast_cdr_beitem *i = NULL; 00150 00151 AST_LIST_LOCK(&be_list); 00152 AST_LIST_TRAVERSE_SAFE_BEGIN(&be_list, i, list) { 00153 if (!strcasecmp(name, i->name)) { 00154 AST_LIST_REMOVE_CURRENT(&be_list, list); 00155 if (option_verbose > 1) 00156 ast_verbose(VERBOSE_PREFIX_2 "Unregistered '%s' CDR backend\n", name); 00157 free(i); 00158 break; 00159 } 00160 } 00161 AST_LIST_TRAVERSE_SAFE_END; 00162 AST_LIST_UNLOCK(&be_list); 00163 }
int ast_cdr_update | ( | struct ast_channel * | chan | ) |
Definition at line 945 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_feature_request_and_dial(), ast_parseable_goto(), cb_events(), clear_caller(), and findmeexec().
00946 { 00947 struct ast_cdr *cdr = c->cdr; 00948 00949 for ( ; cdr ; cdr = cdr->next) { 00950 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) { 00951 set_one_cid(cdr, c); 00952 00953 /* Copy account code et-al */ 00954 ast_copy_string(cdr->accountcode, c->accountcode, sizeof(cdr->accountcode)); 00955 00956 /* Destination information */ /* XXX privilege macro* ? */ 00957 ast_copy_string(cdr->dst, S_OR(c->macroexten, c->exten), sizeof(cdr->dst)); 00958 ast_copy_string(cdr->dcontext, S_OR(c->macrocontext, c->context), sizeof(cdr->dcontext)); 00959 } 00960 } 00961 00962 return 0; 00963 }
char ast_default_accountcode[AST_MAX_ACCOUNT_CODE] |