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


Go to the source code of this file.
Data Structures | |
| struct | ast_cdr |
| Responsible for call detail data. More... | |
Defines | |
| #define | AST_MAX_ACCOUNT_CODE 20 |
| #define | AST_MAX_USER_FIELD 256 |
CDR Flags - Disposition | |
| #define | AST_CDR_ANSWERED (1 << 3) |
| #define | AST_CDR_BUSY (1 << 2) |
| #define | AST_CDR_FAILED (1 << 1) |
| #define | AST_CDR_NOANSWER 0 |
| #define | AST_CDR_NULL (1 << 0) |
CDR AMA Flags | |
| #define | AST_CDR_BILLING (2) |
| #define | AST_CDR_DOCUMENTATION (3) |
| #define | AST_CDR_OMIT (1) |
CDR Flags | |
| #define | AST_CDR_FLAG_ANSLOCKED (1 << 8) |
| #define | AST_CDR_FLAG_BRIDGED (1 << 5) |
| #define | AST_CDR_FLAG_CHILD (1 << 3) |
| #define | AST_CDR_FLAG_DIALED (1 << 11) |
| #define | AST_CDR_FLAG_DONT_TOUCH (1 << 9) |
| #define | AST_CDR_FLAG_ENABLE (1 << 7) |
| #define | AST_CDR_FLAG_KEEP_VARS (1 << 0) |
| #define | AST_CDR_FLAG_LOCKED (1 << 2) |
| #define | AST_CDR_FLAG_MAIN (1 << 6) |
| #define | AST_CDR_FLAG_ORIGINATED (1 << 12) |
| #define | AST_CDR_FLAG_POST_DISABLED (1 << 4) |
| #define | AST_CDR_FLAG_POST_ENABLE (1 << 10) |
| #define | AST_CDR_FLAG_POSTED (1 << 1) |
Typedefs | |
| typedef int(* | ast_cdrbe )(struct ast_cdr *cdr) |
| CDR backend callback. | |
Functions | |
| struct ast_cdr * | ast_cdr_alloc (void) |
| Allocate a CDR record. | |
| int | ast_cdr_amaflags2int (const char *flag) |
| Convert a string to a detail record AMA flag. | |
| void | ast_cdr_answer (struct ast_cdr *cdr) |
| Answer a call. | |
| struct ast_cdr * | ast_cdr_append (struct ast_cdr *cdr, struct ast_cdr *newcdr) |
| int | ast_cdr_appenduserfield (struct ast_channel *chan, const char *userfield) |
| Append to CDR user field for channel (stored in CDR). | |
| void | ast_cdr_busy (struct ast_cdr *cdr) |
| Busy a call. | |
| int | ast_cdr_copy_vars (struct ast_cdr *to_cdr, struct ast_cdr *from_cdr) |
| void | ast_cdr_detach (struct ast_cdr *cdr) |
| Detaches the detail record for posting (and freeing) either now or at a later time in bulk with other records during batch mode operation. | |
| void | ast_cdr_discard (struct ast_cdr *cdr) |
| Discard and free a CDR record. | |
| char * | ast_cdr_disp2str (int disposition) |
| Disposition to a string. | |
| int | ast_cdr_disposition (struct ast_cdr *cdr, int cause) |
| Save the result of the call based on the AST_CAUSE_*. | |
| struct ast_cdr * | ast_cdr_dup (struct ast_cdr *cdr) |
| Duplicate a record. | |
| void | ast_cdr_end (struct ast_cdr *cdr) |
| End a call. | |
| int | ast_cdr_engine_init (void) |
| Load the configuration file cdr.conf and possibly start the CDR scheduling thread. | |
| int | ast_cdr_engine_reload (void) |
| Reload the configuration file cdr.conf and start/stop CDR scheduling thread. | |
| void | ast_cdr_engine_term (void) |
| void | ast_cdr_failed (struct ast_cdr *cdr) |
| Fail a call. | |
| char * | ast_cdr_flags2str (int flags) |
| void | ast_cdr_free (struct ast_cdr *cdr) |
| Free a CDR record. | |
| void | ast_cdr_free_vars (struct ast_cdr *cdr, int recur) |
| void | ast_cdr_getvar (struct ast_cdr *cdr, const char *name, char **ret, char *workspace, int workspacelen, int recur, int raw) |
| int | ast_cdr_init (struct ast_cdr *cdr, struct ast_channel *chan) |
| Initialize based on a channel. | |
| int | ast_cdr_isset_unanswered (void) |
| void | ast_cdr_merge (struct ast_cdr *to, struct ast_cdr *from) |
| Move the non-null data from the "from" cdr to the "to" cdr. | |
| void | ast_cdr_noanswer (struct ast_cdr *cdr) |
| A call wasn't answered. | |
| int | ast_cdr_register (const char *name, const char *desc, ast_cdrbe be) |
| Register a CDR handling engine. | |
| void | ast_cdr_reset (struct ast_cdr *cdr, struct ast_flags *flags) |
| Reset the detail record, optionally posting it first. | |
| int | ast_cdr_serialize_variables (struct ast_cdr *cdr, struct ast_str **buf, char delim, char sep, int recur) |
| int | ast_cdr_setaccount (struct ast_channel *chan, const char *account) |
| Set account code, will generate AMI event. | |
| int | ast_cdr_setamaflags (struct ast_channel *chan, const char *amaflags) |
| Set AMA flags for channel. | |
| void | ast_cdr_setanswer (struct ast_cdr *cdr, struct timeval t) |
| Set the answer time for a call. | |
| void | ast_cdr_setapp (struct ast_cdr *cdr, const char *app, const char *data) |
| Set the last executed application. | |
| int | ast_cdr_setcid (struct ast_cdr *cdr, struct ast_channel *chan) |
| Initialize based on a channel. | |
| void | ast_cdr_setdestchan (struct ast_cdr *cdr, const char *chan) |
| Set the destination channel, if there was one. | |
| void | ast_cdr_setdisposition (struct ast_cdr *cdr, long int disposition) |
| Set the disposition for a call. | |
| int | ast_cdr_setuserfield (struct ast_channel *chan, const char *userfield) |
| Set CDR user field for channel (stored in CDR). | |
| int | ast_cdr_setvar (struct ast_cdr *cdr, const char *name, const char *value, int recur) |
| void | ast_cdr_specialized_reset (struct ast_cdr *cdr, struct ast_flags *flags) |
| void | ast_cdr_start (struct ast_cdr *cdr) |
| Start a call. | |
| void | ast_cdr_submit_batch (int shutdown) |
| Spawns (possibly) a new thread to submit a batch of CDRs to the backend engines. | |
| void | ast_cdr_unregister (const char *name) |
| Unregister a CDR handling engine. | |
| int | ast_cdr_update (struct ast_channel *chan) |
| int | check_cdr_enabled (void) |
| Return TRUE if CDR subsystem is enabled. | |
Variables | |
| char | ast_default_accountcode [AST_MAX_ACCOUNT_CODE] |
| int | ast_default_amaflags |
Definition in file cdr.h.
| #define AST_CDR_ANSWERED (1 << 3) |
Definition at line 51 of file cdr.h.
Referenced by ast_bridge_call(), ast_cdr_answer(), ast_cdr_disp2str(), ast_cdr_end(), ast_cdr_init(), post_cdr(), and wait_for_answer().
| #define AST_CDR_BILLING (2) |
| #define AST_CDR_BUSY (1 << 2) |
| #define AST_CDR_DOCUMENTATION (3) |
Definition at line 58 of file cdr.h.
Referenced by ast_cdr_amaflags2int(), ast_cdr_flags2str(), and ast_cdr_merge().
| #define AST_CDR_FAILED (1 << 1) |
Definition at line 49 of file cdr.h.
Referenced by ast_cdr_disp2str(), ast_cdr_end(), and ast_cdr_failed().
| #define AST_CDR_FLAG_ANSLOCKED (1 << 8) |
Definition at line 38 of file cdr.h.
Referenced by ast_cdr_answer(), ast_cdr_fork(), and ast_cdr_setanswer().
| #define AST_CDR_FLAG_BRIDGED (1 << 5) |
| #define AST_CDR_FLAG_CHILD (1 << 3) |
| #define AST_CDR_FLAG_DIALED (1 << 11) |
Definition at line 41 of file cdr.h.
Referenced by ast_bridge_call(), ast_call(), ast_hangup(), dial_exec_full(), and post_cdr().
| #define AST_CDR_FLAG_DONT_TOUCH (1 << 9) |
Definition at line 39 of file cdr.h.
Referenced by ast_cdr_answer(), ast_cdr_end(), ast_cdr_fork(), ast_cdr_setanswer(), and ast_cdr_setvar().
| #define AST_CDR_FLAG_KEEP_VARS (1 << 0) |
Definition at line 30 of file cdr.h.
Referenced by ast_cdr_fork(), ast_cdr_merge(), ast_cdr_reset(), and forkcdr_exec().
| #define AST_CDR_FLAG_LOCKED (1 << 2) |
Definition at line 32 of file cdr.h.
Referenced by ast_cdr_answer(), ast_cdr_appenduserfield(), ast_cdr_busy(), ast_cdr_end(), ast_cdr_failed(), ast_cdr_fork(), ast_cdr_init(), ast_cdr_merge(), ast_cdr_noanswer(), ast_cdr_reset(), ast_cdr_setaccount(), ast_cdr_setamaflags(), ast_cdr_setanswer(), ast_cdr_setapp(), ast_cdr_setcid(), ast_cdr_setdestchan(), ast_cdr_setdisposition(), ast_cdr_setuserfield(), ast_cdr_setvar(), ast_cdr_start(), ast_cdr_update(), cdr_read(), pick_unlocked_cdr(), and try_calling().
| #define AST_CDR_FLAG_MAIN (1 << 6) |
| #define AST_CDR_FLAG_ORIGINATED (1 << 12) |
Definition at line 42 of file cdr.h.
Referenced by __ast_request_and_dial(), ast_call_forward(), and post_cdr().
| #define AST_CDR_FLAG_POST_DISABLED (1 << 4) |
Definition at line 34 of file cdr.h.
Referenced by ast_bridge_call(), ast_cdr_detach(), ast_cdr_merge(), ast_cdr_reset(), ast_cdr_specialized_reset(), ast_hangup(), connect_link(), nocdr_exec(), post_cdr(), rpt(), rpt_call(), rpt_exec(), rpt_tele_thread(), and try_calling().
| #define AST_CDR_FLAG_POST_ENABLE (1 << 10) |
| #define AST_CDR_FLAG_POSTED (1 << 1) |
Definition at line 31 of file cdr.h.
Referenced by ast_cdr_merge(), ast_cdr_reset(), check_post(), disa_exec(), and post_cdr().
| #define AST_CDR_NOANSWER 0 |
Definition at line 47 of file cdr.h.
Referenced by ast_cdr_disp2str(), ast_cdr_init(), ast_cdr_merge(), ast_cdr_noanswer(), and ast_cdr_reset().
| #define AST_CDR_NULL (1 << 0) |
Definition at line 48 of file cdr.h.
Referenced by ast_bridge_call(), ast_cdr_disp2str(), ast_cdr_specialized_reset(), and ast_hangup().
| #define AST_CDR_OMIT (1) |
| struct ast_cdr* ast_cdr_alloc | ( | void | ) | [read] |
Allocate a CDR record.
| a | malloc'd ast_cdr structure | |
| NULL | on error (malloc failure) |
Definition at line 460 of file cdr.c.
References ast_calloc, ast_log(), and LOG_ERROR.
Referenced by __agent_start_monitoring(), __ast_channel_alloc_ap(), __ast_request_and_dial(), ast_bridge_call(), ast_cdr_dup(), builtin_blindtransfer(), clear_caller(), findmeexec(), and start_monitor_exec().
00461 { 00462 struct ast_cdr *x; 00463 x = ast_calloc(1, sizeof(*x)); 00464 if (!x) 00465 ast_log(LOG_ERROR,"Allocation Failure for a CDR!\n"); 00466 return x; 00467 }
| int ast_cdr_amaflags2int | ( | const char * | flag | ) |
Convert a string to a detail record AMA flag.
| flag | string form of flag Converts the string form of the flag to the binary form. |
Definition at line 1021 of file cdr.c.
References AST_CDR_BILLING, AST_CDR_DOCUMENTATION, and AST_CDR_OMIT.
Referenced by ast_cdr_setamaflags(), build_device(), build_gateway(), build_peer(), build_user(), config_parse_variables(), process_dahdi(), and set_config().
01022 { 01023 if (!strcasecmp(flag, "default")) 01024 return 0; 01025 if (!strcasecmp(flag, "omit")) 01026 return AST_CDR_OMIT; 01027 if (!strcasecmp(flag, "billing")) 01028 return AST_CDR_BILLING; 01029 if (!strcasecmp(flag, "documentation")) 01030 return AST_CDR_DOCUMENTATION; 01031 return -1; 01032 }
| void ast_cdr_answer | ( | struct ast_cdr * | cdr | ) |
Answer a call.
| 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 695 of file cdr.c.
References ast_cdr::answer, AST_CDR_ANSWERED, AST_CDR_FLAG_ANSLOCKED, AST_CDR_FLAG_DONT_TOUCH, AST_CDR_FLAG_LOCKED, ast_test_flag, ast_tvnow(), ast_tvzero(), check_post(), ast_cdr::disposition, and ast_cdr::next.
Referenced by __ast_request_and_dial(), ast_bridge_call(), and ast_raw_answer().
00696 { 00697 00698 for (; cdr; cdr = cdr->next) { 00699 if (ast_test_flag(cdr, AST_CDR_FLAG_ANSLOCKED)) 00700 continue; 00701 if (ast_test_flag(cdr, AST_CDR_FLAG_DONT_TOUCH) && ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) 00702 continue; 00703 check_post(cdr); 00704 if (cdr->disposition < AST_CDR_ANSWERED) 00705 cdr->disposition = AST_CDR_ANSWERED; 00706 if (ast_tvzero(cdr->answer)) 00707 cdr->answer = ast_tvnow(); 00708 } 00709 }
Definition at line 1134 of file cdr.c.
References ast_cdr::next.
Referenced by ast_cdr_fork(), ast_cdr_merge(), and attempt_transfer().
01135 { 01136 struct ast_cdr *ret; 01137 01138 if (cdr) { 01139 ret = cdr; 01140 01141 while (cdr->next) 01142 cdr = cdr->next; 01143 cdr->next = newcdr; 01144 } else { 01145 ret = newcdr; 01146 } 01147 01148 return ret; 01149 }
| int ast_cdr_appenduserfield | ( | struct ast_channel * | chan, | |
| const char * | userfield | |||
| ) |
Append to CDR user field for channel (stored in CDR).
Definition at line 987 of file cdr.c.
References AST_CDR_FLAG_LOCKED, ast_copy_string(), ast_test_flag, ast_channel::cdr, len(), ast_cdr::next, and ast_cdr::userfield.
00988 { 00989 struct ast_cdr *cdr = chan->cdr; 00990 00991 for ( ; cdr ; cdr = cdr->next) { 00992 int len = strlen(cdr->userfield); 00993 00994 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) 00995 ast_copy_string(cdr->userfield + len, userfield, sizeof(cdr->userfield) - len); 00996 } 00997 00998 return 0; 00999 }
| void ast_cdr_busy | ( | struct ast_cdr * | cdr | ) |
Busy a call.
| cdr | the cdr you wish to associate with the call Marks the channel disposition as "BUSY" Will skip CDR's in chain with ANS_LOCK bit set. (see forkCDR() application. Returns nothing |
Definition at line 711 of file cdr.c.
References AST_CDR_BUSY, AST_CDR_FLAG_LOCKED, ast_test_flag, check_post(), ast_cdr::disposition, and ast_cdr::next.
Referenced by __ast_request_and_dial(), ast_cdr_disposition(), handle_cause(), pbx_builtin_busy(), ring_entry(), and wait_for_answer().
00712 { 00713 00714 for (; cdr; cdr = cdr->next) { 00715 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) { 00716 check_post(cdr); 00717 cdr->disposition = AST_CDR_BUSY; 00718 } 00719 } 00720 }
Definition at line 344 of file cdr.c.
References AST_LIST_INSERT_HEAD, AST_LIST_TRAVERSE, ast_strlen_zero(), ast_var_assign(), ast_var_name(), ast_var_value(), var, and ast_cdr::varshead.
Referenced by ast_cdr_dup().
00345 { 00346 struct ast_var_t *variables, *newvariable = NULL; 00347 struct varshead *headpa, *headpb; 00348 const char *var, *val; 00349 int x = 0; 00350 00351 if (!to_cdr || !from_cdr) /* don't die if one of the pointers is null */ 00352 return 0; 00353 00354 headpa = &from_cdr->varshead; 00355 headpb = &to_cdr->varshead; 00356 00357 AST_LIST_TRAVERSE(headpa,variables,entries) { 00358 if (variables && 00359 (var = ast_var_name(variables)) && (val = ast_var_value(variables)) && 00360 !ast_strlen_zero(var) && !ast_strlen_zero(val)) { 00361 newvariable = ast_var_assign(var, val); 00362 AST_LIST_INSERT_HEAD(headpb, newvariable, entries); 00363 x++; 00364 } 00365 } 00366 00367 return x; 00368 }
| void ast_cdr_detach | ( | struct ast_cdr * | cdr | ) |
Detaches the detail record for posting (and freeing) either now or at a later time in bulk with other records during batch mode operation.
| cdr | Which CDR to detach from the channel thread Prevents the channel thread from blocking on the CDR handling Returns nothing |
Definition at line 1239 of file cdr.c.
References ast_calloc, AST_CDR_FLAG_POST_DISABLED, ast_cdr_free(), ast_debug, ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, batch, batchmode, batchsize, ast_cdr_batch_item::cdr, cdr_batch_lock, enabled, ast_cdr_batch::head, init_batch(), ast_cdr_batch_item::next, post_cdr(), ast_cdr_batch::size, submit_unscheduled_batch(), and ast_cdr_batch::tail.
Referenced by ast_bridge_call(), ast_cdr_reset(), ast_hangup(), and ast_pbx_outgoing_cdr_failed().
01240 { 01241 struct ast_cdr_batch_item *newtail; 01242 int curr; 01243 01244 if (!cdr) 01245 return; 01246 01247 /* maybe they disabled CDR stuff completely, so just drop it */ 01248 if (!enabled) { 01249 ast_debug(1, "Dropping CDR !\n"); 01250 ast_set_flag(cdr, AST_CDR_FLAG_POST_DISABLED); 01251 ast_cdr_free(cdr); 01252 return; 01253 } 01254 01255 /* post stuff immediately if we are not in batch mode, this is legacy behaviour */ 01256 if (!batchmode) { 01257 post_cdr(cdr); 01258 ast_cdr_free(cdr); 01259 return; 01260 } 01261 01262 /* otherwise, each CDR gets put into a batch list (at the end) */ 01263 ast_debug(1, "CDR detaching from this thread\n"); 01264 01265 /* we'll need a new tail for every CDR */ 01266 if (!(newtail = ast_calloc(1, sizeof(*newtail)))) { 01267 post_cdr(cdr); 01268 ast_cdr_free(cdr); 01269 return; 01270 } 01271 01272 /* don't traverse a whole list (just keep track of the tail) */ 01273 ast_mutex_lock(&cdr_batch_lock); 01274 if (!batch) 01275 init_batch(); 01276 if (!batch->head) { 01277 /* new batch is empty, so point the head at the new tail */ 01278 batch->head = newtail; 01279 } else { 01280 /* already got a batch with something in it, so just append a new tail */ 01281 batch->tail->next = newtail; 01282 } 01283 newtail->cdr = cdr; 01284 batch->tail = newtail; 01285 curr = batch->size++; 01286 ast_mutex_unlock(&cdr_batch_lock); 01287 01288 /* if we have enough stuff to post, then do it */ 01289 if (curr >= (batchsize - 1)) 01290 submit_unscheduled_batch(); 01291 }
| void ast_cdr_discard | ( | struct ast_cdr * | cdr | ) |
Discard and free a CDR record.
| cdr | ast_cdr structure to free Returns nothing -- same as free, but no checks or complaints |
Definition at line 449 of file cdr.c.
References ast_cdr_free_vars(), ast_free, ast_cdr::next, and ast_cdr_beitem::next.
Referenced by ast_async_goto(), ast_bridge_call(), ast_cdr_merge(), and ast_channel_free().
00450 { 00451 while (cdr) { 00452 struct ast_cdr *next = cdr->next; 00453 00454 ast_cdr_free_vars(cdr, 0); 00455 ast_free(cdr); 00456 cdr = next; 00457 } 00458 }
| char* ast_cdr_disp2str | ( | int | disposition | ) |
Disposition to a string.
| disposition | input binary form Converts the binary form of a disposition to string form. |
Definition at line 910 of file cdr.c.
References AST_CDR_ANSWERED, AST_CDR_BUSY, AST_CDR_FAILED, AST_CDR_NOANSWER, and AST_CDR_NULL.
Referenced by ast_cdr_getvar(), build_csv_record(), build_radius_record(), csv_log(), execute_cb(), manager_log(), and tds_log().
00911 { 00912 switch (disposition) { 00913 case AST_CDR_NULL: 00914 return "NO ANSWER"; /* by default, for backward compatibility */ 00915 case AST_CDR_NOANSWER: 00916 return "NO ANSWER"; 00917 case AST_CDR_FAILED: 00918 return "FAILED"; 00919 case AST_CDR_BUSY: 00920 return "BUSY"; 00921 case AST_CDR_ANSWERED: 00922 return "ANSWERED"; 00923 } 00924 return "UNKNOWN"; 00925 }
| int ast_cdr_disposition | ( | struct ast_cdr * | cdr, | |
| int | cause | |||
| ) |
Save the result of the call based on the AST_CAUSE_*.
| cdr | the cdr you wish to associate with the call | |
| cause | the AST_CAUSE_* Returns nothing |
Definition at line 751 of file cdr.c.
References AST_CAUSE_BUSY, AST_CAUSE_NO_ANSWER, AST_CAUSE_NORMAL, ast_cdr_busy(), ast_cdr_noanswer(), and ast_cdr::next.
Referenced by __ast_request_and_dial(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), clear_caller(), and findmeexec().
00752 { 00753 int res = 0; 00754 00755 for (; cdr; cdr = cdr->next) { 00756 switch (cause) { /* handle all the non failure, busy cases, return 0 not to set disposition, 00757 return -1 to set disposition to FAILED */ 00758 case AST_CAUSE_BUSY: 00759 ast_cdr_busy(cdr); 00760 break; 00761 case AST_CAUSE_NO_ANSWER: 00762 ast_cdr_noanswer(cdr); 00763 break; 00764 case AST_CAUSE_NORMAL: 00765 break; 00766 default: 00767 res = -1; 00768 } 00769 } 00770 return res; 00771 }
Duplicate a record.
| a | malloc'd ast_cdr structure, | |
| NULL | on error (malloc failure) |
Definition at line 176 of file cdr.c.
References ast_cdr_alloc(), ast_cdr_copy_vars(), ast_cdr::next, and ast_cdr::varshead.
Referenced by ast_async_goto(), ast_bridge_call(), ast_cdr_fork(), ast_cdr_merge(), and ast_cdr_reset().
00177 { 00178 struct ast_cdr *newcdr; 00179 00180 if (!cdr) /* don't die if we get a null cdr pointer */ 00181 return NULL; 00182 newcdr = ast_cdr_alloc(); 00183 if (!newcdr) 00184 return NULL; 00185 00186 memcpy(newcdr, cdr, sizeof(*newcdr)); 00187 /* The varshead is unusable, volatile even, after the memcpy so we take care of that here */ 00188 memset(&newcdr->varshead, 0, sizeof(newcdr->varshead)); 00189 ast_cdr_copy_vars(newcdr, cdr); 00190 newcdr->next = NULL; 00191 00192 return newcdr; 00193 }
| void ast_cdr_end | ( | struct ast_cdr * | cdr | ) |
End a call.
| cdr | the cdr you have associated the call with Registers the end of call time in the cdr structure. Returns nothing |
Definition at line 884 of file cdr.c.
References ast_cdr::answer, AST_CDR_ANSWERED, AST_CDR_FAILED, AST_CDR_FLAG_DONT_TOUCH, AST_CDR_FLAG_LOCKED, ast_log(), AST_OPT_FLAG_INITIATED_SECONDS, ast_options, ast_test_flag, ast_tvnow(), ast_tvzero(), ast_cdr::billsec, ast_cdr::channel, check_post(), ast_cdr::disposition, ast_cdr::duration, ast_cdr::end, LOG_WARNING, ast_cdr::next, S_OR, and ast_cdr::start.
Referenced by __ast_pbx_run(), __ast_request_and_dial(), ast_bridge_call(), ast_cdr_fork(), ast_cdr_reset(), ast_hangup(), ast_pbx_outgoing_cdr_failed(), clear_caller(), and findmeexec().
00885 { 00886 for ( ; cdr ; cdr = cdr->next) { 00887 if (ast_test_flag(cdr, AST_CDR_FLAG_DONT_TOUCH) && ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) 00888 continue; 00889 check_post(cdr); 00890 if (ast_tvzero(cdr->end)) 00891 cdr->end = ast_tvnow(); 00892 if (ast_tvzero(cdr->start)) { 00893 ast_log(LOG_WARNING, "CDR on channel '%s' has not started\n", S_OR(cdr->channel, "<unknown>")); 00894 cdr->disposition = AST_CDR_FAILED; 00895 } else 00896 cdr->duration = cdr->end.tv_sec - cdr->start.tv_sec; 00897 if (ast_tvzero(cdr->answer)) { 00898 if (cdr->disposition == AST_CDR_ANSWERED) { 00899 ast_log(LOG_WARNING, "CDR on channel '%s' has no answer time but is 'ANSWERED'\n", S_OR(cdr->channel, "<unknown>")); 00900 cdr->disposition = AST_CDR_FAILED; 00901 } 00902 } else { 00903 cdr->billsec = cdr->end.tv_sec - cdr->answer.tv_sec; 00904 if (ast_test_flag(&ast_options, AST_OPT_FLAG_INITIATED_SECONDS)) 00905 cdr->billsec += cdr->end.tv_usec > cdr->answer.tv_usec ? 1 : 0; 00906 } 00907 } 00908 }
| int ast_cdr_engine_init | ( | void | ) |
Load the configuration file cdr.conf and possibly start the CDR scheduling thread.
Definition at line 1532 of file cdr.c.
References ast_cli_register(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), cdr_batch_lock, cli_status, do_reload(), init_batch(), LOG_ERROR, and sched_context_create().
Referenced by main().
01533 { 01534 int res; 01535 01536 sched = sched_context_create(); 01537 if (!sched) { 01538 ast_log(LOG_ERROR, "Unable to create schedule context.\n"); 01539 return -1; 01540 } 01541 01542 ast_cli_register(&cli_status); 01543 01544 res = do_reload(0); 01545 if (res) { 01546 ast_mutex_lock(&cdr_batch_lock); 01547 res = init_batch(); 01548 ast_mutex_unlock(&cdr_batch_lock); 01549 } 01550 01551 return res; 01552 }
| int ast_cdr_engine_reload | ( | void | ) |
Reload the configuration file cdr.conf and start/stop CDR scheduling thread.
Definition at line 1561 of file cdr.c.
References do_reload().
01562 { 01563 return do_reload(1); 01564 }
| void ast_cdr_engine_term | ( | void | ) |
Submit any remaining CDRs and prepare for shutdown
Definition at line 1556 of file cdr.c.
References ast_cdr_submit_batch(), and batchsafeshutdown.
Referenced by do_reload(), and quit_handler().
01557 { 01558 ast_cdr_submit_batch(batchsafeshutdown); 01559 }
| void ast_cdr_failed | ( | struct ast_cdr * | cdr | ) |
Fail a call.
| cdr | the cdr you wish to associate with the call Marks the channel disposition as "FAILED" Will skip CDR's in chain with ANS_LOCK bit set. (see forkCDR() application. Returns nothing |
Definition at line 722 of file cdr.c.
References AST_CDR_FAILED, AST_CDR_FLAG_LOCKED, ast_test_flag, check_post(), ast_cdr::disposition, and ast_cdr::next.
Referenced by __ast_request_and_dial(), ast_pbx_outgoing_app(), ast_pbx_outgoing_cdr_failed(), ast_pbx_outgoing_exten(), clear_caller(), findmeexec(), handle_cause(), try_calling(), and wait_for_answer().
00723 { 00724 for (; cdr; cdr = cdr->next) { 00725 check_post(cdr); 00726 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) { 00727 check_post(cdr); 00728 if (cdr->disposition < AST_CDR_FAILED) 00729 cdr->disposition = AST_CDR_FAILED; 00730 } 00731 } 00732 }
| char* ast_cdr_flags2str | ( | int | flag | ) |
Flags to a string
| flags | binary flag Converts binary flags to string flags Returns string with flag name |
Definition at line 928 of file cdr.c.
References AST_CDR_BILLING, AST_CDR_DOCUMENTATION, and AST_CDR_OMIT.
Referenced by _sip_show_peer(), _skinny_show_line(), ast_cdr_getvar(), build_csv_record(), build_radius_record(), csv_log(), manager_log(), sip_show_user(), and tds_log().
00929 { 00930 switch (flag) { 00931 case AST_CDR_OMIT: 00932 return "OMIT"; 00933 case AST_CDR_BILLING: 00934 return "BILLING"; 00935 case AST_CDR_DOCUMENTATION: 00936 return "DOCUMENTATION"; 00937 } 00938 return "Unknown"; 00939 }
| void ast_cdr_free | ( | struct ast_cdr * | cdr | ) |
Free a CDR record.
| cdr | ast_cdr structure to free Returns nothing |
Definition at line 436 of file cdr.c.
References ast_cdr_free_vars(), ast_free, ast_cdr::next, and ast_cdr_beitem::next.
Referenced by ast_cdr_detach(), and do_batch_backend_process().
00437 { 00438 00439 while (cdr) { 00440 struct ast_cdr *next = cdr->next; 00441 00442 ast_cdr_free_vars(cdr, 0); 00443 ast_free(cdr); 00444 cdr = next; 00445 } 00446 }
| void ast_cdr_free_vars | ( | struct ast_cdr * | cdr, | |
| int | recur | |||
| ) |
Definition at line 415 of file cdr.c.
References AST_LIST_REMOVE_HEAD, ast_var_delete(), ast_cdr::next, and ast_cdr::varshead.
Referenced by ast_cdr_discard(), ast_cdr_fork(), ast_cdr_free(), and ast_cdr_reset().
00416 { 00417 00418 /* clear variables */ 00419 for (; cdr; cdr = recur ? cdr->next : NULL) { 00420 struct ast_var_t *vardata; 00421 struct varshead *headp = &cdr->varshead; 00422 while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries))) 00423 ast_var_delete(vardata); 00424 } 00425 }
| void ast_cdr_getvar | ( | struct ast_cdr * | cdr, | |
| const char * | name, | |||
| char ** | ret, | |||
| char * | workspace, | |||
| int | workspacelen, | |||
| int | recur, | |||
| int | raw | |||
| ) |
CDR channel variable retrieval
Definition at line 227 of file cdr.c.
References ast_cdr::accountcode, ast_cdr::amaflags, ast_cdr::answer, ast_cdr_disp2str(), ast_cdr_flags2str(), ast_cdr_getvar_internal(), ast_copy_string(), ast_strlen_zero(), ast_tvdiff_ms(), ast_tvnow(), ast_cdr::billsec, cdr_get_tv(), ast_cdr::channel, ast_cdr::clid, ast_cdr::dcontext, ast_cdr::disposition, ast_cdr::dst, ast_cdr::dstchannel, ast_cdr::duration, ast_cdr::end, ast_cdr::lastapp, ast_cdr::lastdata, ast_cdr::src, ast_cdr::start, ast_cdr::uniqueid, and ast_cdr::userfield.
Referenced by ast_cdr_serialize_variables(), cdr_handler(), cdr_read(), odbc_log(), and pgsql_log().
00228 { 00229 const char *fmt = "%Y-%m-%d %T"; 00230 const char *varbuf; 00231 00232 if (!cdr) /* don't die if the cdr is null */ 00233 return; 00234 00235 *ret = NULL; 00236 /* special vars (the ones from the struct ast_cdr when requested by name) 00237 I'd almost say we should convert all the stringed vals to vars */ 00238 00239 if (!strcasecmp(name, "clid")) 00240 ast_copy_string(workspace, cdr->clid, workspacelen); 00241 else if (!strcasecmp(name, "src")) 00242 ast_copy_string(workspace, cdr->src, workspacelen); 00243 else if (!strcasecmp(name, "dst")) 00244 ast_copy_string(workspace, cdr->dst, workspacelen); 00245 else if (!strcasecmp(name, "dcontext")) 00246 ast_copy_string(workspace, cdr->dcontext, workspacelen); 00247 else if (!strcasecmp(name, "channel")) 00248 ast_copy_string(workspace, cdr->channel, workspacelen); 00249 else if (!strcasecmp(name, "dstchannel")) 00250 ast_copy_string(workspace, cdr->dstchannel, workspacelen); 00251 else if (!strcasecmp(name, "lastapp")) 00252 ast_copy_string(workspace, cdr->lastapp, workspacelen); 00253 else if (!strcasecmp(name, "lastdata")) 00254 ast_copy_string(workspace, cdr->lastdata, workspacelen); 00255 else if (!strcasecmp(name, "start")) 00256 cdr_get_tv(cdr->start, raw ? NULL : fmt, workspace, workspacelen); 00257 else if (!strcasecmp(name, "answer")) 00258 cdr_get_tv(cdr->answer, raw ? NULL : fmt, workspace, workspacelen); 00259 else if (!strcasecmp(name, "end")) 00260 cdr_get_tv(cdr->end, raw ? NULL : fmt, workspace, workspacelen); 00261 else if (!strcasecmp(name, "duration")) 00262 snprintf(workspace, workspacelen, "%ld", cdr->duration ? cdr->duration : (long)ast_tvdiff_ms(ast_tvnow(), cdr->start) / 1000); 00263 else if (!strcasecmp(name, "billsec")) 00264 snprintf(workspace, workspacelen, "%ld", cdr->billsec || cdr->answer.tv_sec == 0 ? cdr->billsec : (long)ast_tvdiff_ms(ast_tvnow(), cdr->answer) / 1000); 00265 else if (!strcasecmp(name, "disposition")) { 00266 if (raw) { 00267 snprintf(workspace, workspacelen, "%ld", cdr->disposition); 00268 } else { 00269 ast_copy_string(workspace, ast_cdr_disp2str(cdr->disposition), workspacelen); 00270 } 00271 } else if (!strcasecmp(name, "amaflags")) { 00272 if (raw) { 00273 snprintf(workspace, workspacelen, "%ld", cdr->amaflags); 00274 } else { 00275 ast_copy_string(workspace, ast_cdr_flags2str(cdr->amaflags), workspacelen); 00276 } 00277 } else if (!strcasecmp(name, "accountcode")) 00278 ast_copy_string(workspace, cdr->accountcode, workspacelen); 00279 else if (!strcasecmp(name, "uniqueid")) 00280 ast_copy_string(workspace, cdr->uniqueid, workspacelen); 00281 else if (!strcasecmp(name, "userfield")) 00282 ast_copy_string(workspace, cdr->userfield, workspacelen); 00283 else if ((varbuf = ast_cdr_getvar_internal(cdr, name, recur))) 00284 ast_copy_string(workspace, varbuf, workspacelen); 00285 else 00286 workspace[0] = '\0'; 00287 00288 if (!ast_strlen_zero(workspace)) 00289 *ret = workspace; 00290 }
| int ast_cdr_init | ( | struct ast_cdr * | cdr, | |
| struct ast_channel * | chan | |||
| ) |
Initialize based on a channel.
| cdr | Call Detail Record to use for channel | |
| chan | Channel to bind CDR with Initializes a CDR and associates it with a particular channel |
Definition at line 849 of file cdr.c.
References ast_channel::_state, ast_channel::accountcode, ast_cdr::accountcode, ast_channel::amaflags, ast_cdr::amaflags, AST_CDR_ANSWERED, AST_CDR_FLAG_LOCKED, AST_CDR_NOANSWER, ast_copy_string(), AST_STATE_UP, ast_test_flag, chan, ast_cdr::channel, ast_channel::context, ast_cdr::dcontext, ast_cdr::disposition, ast_cdr::dst, ast_channel::exten, ast_channel::macrocontext, ast_channel::macroexten, ast_channel::name, ast_cdr::next, S_OR, set_one_cid(), ast_channel::uniqueid, and ast_cdr::uniqueid.
Referenced by __ast_channel_alloc_ap(), __ast_request_and_dial(), ast_pbx_outgoing_cdr_failed(), builtin_blindtransfer(), clear_caller(), and findmeexec().
00850 { 00851 char *chan; 00852 00853 for ( ; cdr ; cdr = cdr->next) { 00854 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) { 00855 chan = S_OR(cdr->channel, "<unknown>"); 00856 ast_copy_string(cdr->channel, c->name, sizeof(cdr->channel)); 00857 set_one_cid(cdr, c); 00858 00859 cdr->disposition = (c->_state == AST_STATE_UP) ? AST_CDR_ANSWERED : AST_CDR_NOANSWER; 00860 cdr->amaflags = c->amaflags ? c->amaflags : ast_default_amaflags; 00861 ast_copy_string(cdr->accountcode, c->accountcode, sizeof(cdr->accountcode)); 00862 /* Destination information */ 00863 ast_copy_string(cdr->dst, S_OR(c->macroexten,c->exten), sizeof(cdr->dst)); 00864 ast_copy_string(cdr->dcontext, S_OR(c->macrocontext,c->context), sizeof(cdr->dcontext)); 00865 /* Unique call identifier */ 00866 ast_copy_string(cdr->uniqueid, c->uniqueid, sizeof(cdr->uniqueid)); 00867 } 00868 } 00869 return 0; 00870 }
| int ast_cdr_isset_unanswered | ( | void | ) |
Definition at line 168 of file cdr.c.
References unanswered.
Referenced by ring_entry(), and try_calling().
00169 { 00170 return unanswered; 00171 }
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 504 of file cdr.c.
References ast_cdr::accountcode, ast_cdr::amaflags, ast_cdr::answer, ast_cdr_append(), ast_cdr_discard(), AST_CDR_DOCUMENTATION, ast_cdr_dup(), AST_CDR_FLAG_CHILD, AST_CDR_FLAG_KEEP_VARS, AST_CDR_FLAG_LOCKED, AST_CDR_FLAG_POST_DISABLED, AST_CDR_FLAG_POSTED, AST_CDR_NOANSWER, ast_copy_string(), ast_log(), ast_set_flag, ast_strlen_zero(), ast_test_flag, ast_tv(), ast_tvcmp(), ast_tvzero(), ast_cdr::billsec, cdr_merge_vars(), ast_cdr::channel, ast_cdr::clid, ast_cdr::dcontext, ast_cdr::disposition, ast_cdr::dst, ast_cdr::dstchannel, ast_cdr::duration, ast_cdr::end, ast_cdr::lastapp, ast_cdr::lastdata, LOG_WARNING, ast_cdr::next, ast_cdr::src, ast_cdr::start, and ast_cdr::userfield.
00505 { 00506 struct ast_cdr *zcdr; 00507 struct ast_cdr *lto = NULL; 00508 struct ast_cdr *lfrom = NULL; 00509 int discard_from = 0; 00510 00511 if (!to || !from) 00512 return; 00513 00514 /* don't merge into locked CDR's -- it's bad business */ 00515 if (ast_test_flag(to, AST_CDR_FLAG_LOCKED)) { 00516 zcdr = to; /* safety valve? */ 00517 while (to->next) { 00518 lto = to; 00519 to = to->next; 00520 } 00521 00522 if (ast_test_flag(to, AST_CDR_FLAG_LOCKED)) { 00523 ast_log(LOG_WARNING, "Merging into locked CDR... no choice."); 00524 to = zcdr; /* safety-- if all there are is locked CDR's, then.... ?? */ 00525 lto = NULL; 00526 } 00527 } 00528 00529 if (ast_test_flag(from, AST_CDR_FLAG_LOCKED)) { 00530 struct ast_cdr *llfrom = NULL; 00531 discard_from = 1; 00532 if (lto) { 00533 /* insert the from stuff after lto */ 00534 lto->next = from; 00535 lfrom = from; 00536 while (lfrom && lfrom->next) { 00537 if (!lfrom->next->next) 00538 llfrom = lfrom; 00539 lfrom = lfrom->next; 00540 } 00541 /* rip off the last entry and put a copy of the to at the end */ 00542 llfrom->next = to; 00543 from = lfrom; 00544 } else { 00545 /* save copy of the current *to cdr */ 00546 struct ast_cdr tcdr; 00547 memcpy(&tcdr, to, sizeof(tcdr)); 00548 /* copy in the locked from cdr */ 00549 memcpy(to, from, sizeof(*to)); 00550 lfrom = from; 00551 while (lfrom && lfrom->next) { 00552 if (!lfrom->next->next) 00553 llfrom = lfrom; 00554 lfrom = lfrom->next; 00555 } 00556 from->next = NULL; 00557 /* rip off the last entry and put a copy of the to at the end */ 00558 if (llfrom == from) 00559 to = to->next = ast_cdr_dup(&tcdr); 00560 else 00561 to = llfrom->next = ast_cdr_dup(&tcdr); 00562 from = lfrom; 00563 } 00564 } 00565 00566 if (!ast_tvzero(from->start)) { 00567 if (!ast_tvzero(to->start)) { 00568 if (ast_tvcmp(to->start, from->start) > 0 ) { 00569 to->start = from->start; /* use the earliest time */ 00570 from->start = ast_tv(0,0); /* we actively "steal" these values */ 00571 } 00572 /* else nothing to do */ 00573 } else { 00574 to->start = from->start; 00575 from->start = ast_tv(0,0); /* we actively "steal" these values */ 00576 } 00577 } 00578 if (!ast_tvzero(from->answer)) { 00579 if (!ast_tvzero(to->answer)) { 00580 if (ast_tvcmp(to->answer, from->answer) > 0 ) { 00581 to->answer = from->answer; /* use the earliest time */ 00582 from->answer = ast_tv(0,0); /* we actively "steal" these values */ 00583 } 00584 /* we got the earliest answer time, so we'll settle for that? */ 00585 } else { 00586 to->answer = from->answer; 00587 from->answer = ast_tv(0,0); /* we actively "steal" these values */ 00588 } 00589 } 00590 if (!ast_tvzero(from->end)) { 00591 if (!ast_tvzero(to->end)) { 00592 if (ast_tvcmp(to->end, from->end) < 0 ) { 00593 to->end = from->end; /* use the latest time */ 00594 from->end = ast_tv(0,0); /* we actively "steal" these values */ 00595 to->duration = to->end.tv_sec - to->start.tv_sec; /* don't forget to update the duration, billsec, when we set end */ 00596 to->billsec = ast_tvzero(to->answer) ? 0 : to->end.tv_sec - to->answer.tv_sec; 00597 } 00598 /* else, nothing to do */ 00599 } else { 00600 to->end = from->end; 00601 from->end = ast_tv(0,0); /* we actively "steal" these values */ 00602 to->duration = to->end.tv_sec - to->start.tv_sec; 00603 to->billsec = ast_tvzero(to->answer) ? 0 : to->end.tv_sec - to->answer.tv_sec; 00604 } 00605 } 00606 if (to->disposition < from->disposition) { 00607 to->disposition = from->disposition; 00608 from->disposition = AST_CDR_NOANSWER; 00609 } 00610 if (ast_strlen_zero(to->lastapp) && !ast_strlen_zero(from->lastapp)) { 00611 ast_copy_string(to->lastapp, from->lastapp, sizeof(to->lastapp)); 00612 from->lastapp[0] = 0; /* theft */ 00613 } 00614 if (ast_strlen_zero(to->lastdata) && !ast_strlen_zero(from->lastdata)) { 00615 ast_copy_string(to->lastdata, from->lastdata, sizeof(to->lastdata)); 00616 from->lastdata[0] = 0; /* theft */ 00617 } 00618 if (ast_strlen_zero(to->dcontext) && !ast_strlen_zero(from->dcontext)) { 00619 ast_copy_string(to->dcontext, from->dcontext, sizeof(to->dcontext)); 00620 from->dcontext[0] = 0; /* theft */ 00621 } 00622 if (ast_strlen_zero(to->dstchannel) && !ast_strlen_zero(from->dstchannel)) { 00623 ast_copy_string(to->dstchannel, from->dstchannel, sizeof(to->dstchannel)); 00624 from->dstchannel[0] = 0; /* theft */ 00625 } 00626 if (!ast_strlen_zero(from->channel) && (ast_strlen_zero(to->channel) || !strncasecmp(from->channel, "Agent/", 6))) { 00627 ast_copy_string(to->channel, from->channel, sizeof(to->channel)); 00628 from->channel[0] = 0; /* theft */ 00629 } 00630 if (ast_strlen_zero(to->src) && !ast_strlen_zero(from->src)) { 00631 ast_copy_string(to->src, from->src, sizeof(to->src)); 00632 from->src[0] = 0; /* theft */ 00633 } 00634 if (ast_strlen_zero(to->clid) && !ast_strlen_zero(from->clid)) { 00635 ast_copy_string(to->clid, from->clid, sizeof(to->clid)); 00636 from->clid[0] = 0; /* theft */ 00637 } 00638 if (ast_strlen_zero(to->dst) && !ast_strlen_zero(from->dst)) { 00639 ast_copy_string(to->dst, from->dst, sizeof(to->dst)); 00640 from->dst[0] = 0; /* theft */ 00641 } 00642 if (!to->amaflags) 00643 to->amaflags = AST_CDR_DOCUMENTATION; 00644 if (!from->amaflags) 00645 from->amaflags = AST_CDR_DOCUMENTATION; /* make sure both amaflags are set to something (DOC is default) */ 00646 if (ast_test_flag(from, AST_CDR_FLAG_LOCKED) || (to->amaflags == AST_CDR_DOCUMENTATION && from->amaflags != AST_CDR_DOCUMENTATION)) { 00647 to->amaflags = from->amaflags; 00648 } 00649 if (ast_test_flag(from, AST_CDR_FLAG_LOCKED) || (ast_strlen_zero(to->accountcode) && !ast_strlen_zero(from->accountcode))) { 00650 ast_copy_string(to->accountcode, from->accountcode, sizeof(to->accountcode)); 00651 } 00652 if (ast_test_flag(from, AST_CDR_FLAG_LOCKED) || (ast_strlen_zero(to->userfield) && !ast_strlen_zero(from->userfield))) { 00653 ast_copy_string(to->userfield, from->userfield, sizeof(to->userfield)); 00654 } 00655 /* flags, varsead, ? */ 00656 cdr_merge_vars(from, to); 00657 00658 if (ast_test_flag(from, AST_CDR_FLAG_KEEP_VARS)) 00659 ast_set_flag(to, AST_CDR_FLAG_KEEP_VARS); 00660 if (ast_test_flag(from, AST_CDR_FLAG_POSTED)) 00661 ast_set_flag(to, AST_CDR_FLAG_POSTED); 00662 if (ast_test_flag(from, AST_CDR_FLAG_LOCKED)) 00663 ast_set_flag(to, AST_CDR_FLAG_LOCKED); 00664 if (ast_test_flag(from, AST_CDR_FLAG_CHILD)) 00665 ast_set_flag(to, AST_CDR_FLAG_CHILD); 00666 if (ast_test_flag(from, AST_CDR_FLAG_POST_DISABLED)) 00667 ast_set_flag(to, AST_CDR_FLAG_POST_DISABLED); 00668 00669 /* last, but not least, we need to merge any forked CDRs to the 'to' cdr */ 00670 while (from->next) { 00671 /* just rip 'em off the 'from' and insert them on the 'to' */ 00672 zcdr = from->next; 00673 from->next = zcdr->next; 00674 zcdr->next = NULL; 00675 /* zcdr is now ripped from the current list; */ 00676 ast_cdr_append(to, zcdr); 00677 } 00678 if (discard_from) 00679 ast_cdr_discard(from); 00680 }
| void ast_cdr_noanswer | ( | struct ast_cdr * | cdr | ) |
A call wasn't answered.
| cdr | the cdr you wish to associate with the call Marks the channel disposition as "NO ANSWER" Will skip CDR's in chain with ANS_LOCK bit set. (see forkCDR() application. |
Definition at line 734 of file cdr.c.
References AST_CDR_FLAG_LOCKED, AST_CDR_NOANSWER, ast_strlen_zero(), ast_test_flag, chan, ast_cdr::channel, check_post(), ast_cdr::disposition, and ast_cdr::next.
Referenced by ast_cdr_disposition(), handle_cause(), and wait_for_answer().
00735 { 00736 char *chan; 00737 00738 while (cdr) { 00739 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) { 00740 chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>"; 00741 check_post(cdr); 00742 cdr->disposition = AST_CDR_NOANSWER; 00743 } 00744 cdr = cdr->next; 00745 } 00746 }
| int ast_cdr_register | ( | const char * | name, | |
| const char * | desc, | |||
| ast_cdrbe | be | |||
| ) |
Register a CDR handling engine.
| name | name associated with the particular CDR handler | |
| desc | description of the CDR handler | |
| be | function pointer to a CDR handler Used to register a Call Detail Record handler. |
| 0 | on success. | |
| -1 | on error |
Definition at line 116 of file cdr.c.
References ast_calloc, ast_copy_string(), ast_log(), AST_RWLIST_INSERT_HEAD, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_cdr_beitem::be, ast_cdr_beitem::desc, ast_cdr_beitem::list, LOG_WARNING, and ast_cdr_beitem::name.
Referenced by config_module(), load_config(), load_module(), odbc_load_module(), and unload_module().
00117 { 00118 struct ast_cdr_beitem *i = NULL; 00119 00120 if (!name) 00121 return -1; 00122 00123 if (!be) { 00124 ast_log(LOG_WARNING, "CDR engine '%s' lacks backend\n", name); 00125 return -1; 00126 } 00127 00128 AST_RWLIST_WRLOCK(&be_list); 00129 AST_RWLIST_TRAVERSE(&be_list, i, list) { 00130 if (!strcasecmp(name, i->name)) { 00131 ast_log(LOG_WARNING, "Already have a CDR backend called '%s'\n", name); 00132 AST_RWLIST_UNLOCK(&be_list); 00133 return -1; 00134 } 00135 } 00136 00137 if (!(i = ast_calloc(1, sizeof(*i)))) 00138 return -1; 00139 00140 i->be = be; 00141 ast_copy_string(i->name, name, sizeof(i->name)); 00142 ast_copy_string(i->desc, desc, sizeof(i->desc)); 00143 00144 AST_RWLIST_INSERT_HEAD(&be_list, i, list); 00145 AST_RWLIST_UNLOCK(&be_list); 00146 00147 return 0; 00148 }
Reset the detail record, optionally posting it first.
| cdr | which cdr to act upon | |
| flags | |AST_CDR_FLAG_POSTED whether or not to post the cdr first before resetting it |AST_CDR_FLAG_LOCKED whether or not to reset locked CDR's |
Definition at line 1067 of file cdr.c.
References ast_cdr::answer, ast_cdr_detach(), ast_cdr_dup(), ast_cdr_end(), AST_CDR_FLAG_KEEP_VARS, AST_CDR_FLAG_LOCKED, AST_CDR_FLAG_POST_DISABLED, AST_CDR_FLAG_POST_ENABLE, AST_CDR_FLAG_POSTED, ast_cdr_free_vars(), AST_CDR_NOANSWER, ast_cdr_start(), ast_clear_flag, ast_copy_flags, AST_FLAGS_ALL, ast_set_flag, ast_test_flag, ast_cdr::billsec, ast_cdr::disposition, ast_cdr::duration, ast_cdr::end, ast_cdr::next, and ast_cdr::start.
Referenced by ast_cdr_fork(), dial_exec_full(), disa_exec(), and pbx_builtin_resetcdr().
01068 { 01069 struct ast_cdr *duplicate; 01070 struct ast_flags flags = { 0 }; 01071 01072 if (_flags) 01073 ast_copy_flags(&flags, _flags, AST_FLAGS_ALL); 01074 01075 for ( ; cdr ; cdr = cdr->next) { 01076 /* Detach if post is requested */ 01077 if (ast_test_flag(&flags, AST_CDR_FLAG_LOCKED) || !ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) { 01078 if (ast_test_flag(&flags, AST_CDR_FLAG_POSTED)) { 01079 ast_cdr_end(cdr); 01080 if ((duplicate = ast_cdr_dup(cdr))) { 01081 ast_cdr_detach(duplicate); 01082 } 01083 ast_set_flag(cdr, AST_CDR_FLAG_POSTED); 01084 } 01085 01086 /* enable CDR only */ 01087 if (ast_test_flag(&flags, AST_CDR_FLAG_POST_ENABLE)) { 01088 ast_clear_flag(cdr, AST_CDR_FLAG_POST_DISABLED); 01089 continue; 01090 } 01091 01092 /* clear variables */ 01093 if (!ast_test_flag(&flags, AST_CDR_FLAG_KEEP_VARS)) { 01094 ast_cdr_free_vars(cdr, 0); 01095 } 01096 01097 /* Reset to initial state */ 01098 ast_clear_flag(cdr, AST_FLAGS_ALL); 01099 memset(&cdr->start, 0, sizeof(cdr->start)); 01100 memset(&cdr->end, 0, sizeof(cdr->end)); 01101 memset(&cdr->answer, 0, sizeof(cdr->answer)); 01102 cdr->billsec = 0; 01103 cdr->duration = 0; 01104 ast_cdr_start(cdr); 01105 cdr->disposition = AST_CDR_NOANSWER; 01106 } 01107 } 01108 }
| int ast_cdr_serialize_variables | ( | struct ast_cdr * | cdr, | |
| struct ast_str ** | buf, | |||
| char | delim, | |||
| char | sep, | |||
| int | recur | |||
| ) |
Definition at line 370 of file cdr.c.
References ast_cdr_getvar(), AST_LIST_TRAVERSE, ast_log(), ast_str_append(), ast_str_reset(), ast_var_name(), ast_var_value(), cdr_readonly_vars, ast_var_t::entries, LOG_ERROR, ast_cdr::next, S_OR, total, var, and ast_cdr::varshead.
Referenced by handle_showchan().
00371 { 00372 struct ast_var_t *variables; 00373 const char *var; 00374 char *tmp; 00375 char workspace[256]; 00376 int total = 0, x = 0, i; 00377 00378 ast_str_reset(*buf); 00379 00380 for (; cdr; cdr = recur ? cdr->next : NULL) { 00381 if (++x > 1) 00382 ast_str_append(buf, 0, "\n"); 00383 00384 AST_LIST_TRAVERSE(&cdr->varshead, variables, entries) { 00385 if (!(var = ast_var_name(variables))) { 00386 continue; 00387 } 00388 00389 if (ast_str_append(buf, 0, "level %d: %s%c%s%c", x, var, delim, S_OR(ast_var_value(variables), ""), sep) < 0) { 00390 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n"); 00391 break; 00392 } 00393 00394 total++; 00395 } 00396 00397 for (i = 0; cdr_readonly_vars[i]; i++) { 00398 workspace[0] = 0; /* null out the workspace, because the cdr_get_tv() won't write anything if time is NULL, so you get old vals */ 00399 ast_cdr_getvar(cdr, cdr_readonly_vars[i], &tmp, workspace, sizeof(workspace), 0, 0); 00400 if (!tmp) 00401 continue; 00402 00403 if (ast_str_append(buf, 0, "level %d: %s%c%s%c", x, cdr_readonly_vars[i], delim, tmp, sep) < 0) { 00404 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n"); 00405 break; 00406 } else 00407 total++; 00408 } 00409 } 00410 00411 return total; 00412 }
| int ast_cdr_setaccount | ( | struct ast_channel * | chan, | |
| const char * | account | |||
| ) |
Set account code, will generate AMI event.
Definition at line 941 of file cdr.c.
References ast_cdr::accountcode, accountcode, ast_channel::accountcode, AST_CDR_FLAG_LOCKED, ast_copy_string(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, buf, ast_channel::cdr, EVENT_FLAG_CALL, manager_event, ast_channel::name, ast_cdr::next, and ast_channel::uniqueid.
Referenced by __ast_request_and_dial(), ast_bridge_call(), ast_call_forward(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), auth_exec(), cdr_write(), and rpt_call().
00942 { 00943 struct ast_cdr *cdr = chan->cdr; 00944 char buf[BUFSIZ/2] = ""; 00945 if (!ast_strlen_zero(chan->accountcode)) 00946 ast_copy_string(buf, chan->accountcode, sizeof(buf)); 00947 00948 ast_string_field_set(chan, accountcode, account); 00949 for ( ; cdr ; cdr = cdr->next) { 00950 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) { 00951 ast_copy_string(cdr->accountcode, chan->accountcode, sizeof(cdr->accountcode)); 00952 } 00953 } 00954 00955 /* Signal change of account code to manager */ 00956 manager_event(EVENT_FLAG_CALL, "NewAccountCode", "Channel: %s\r\nUniqueid: %s\r\nAccountCode: %s\r\nOldAccountCode: %s\r\n", chan->name, chan->uniqueid, chan->accountcode, buf); 00957 return 0; 00958 }
| int ast_cdr_setamaflags | ( | struct ast_channel * | chan, | |
| const char * | amaflags | |||
| ) |
Set AMA flags for channel.
Definition at line 960 of file cdr.c.
References ast_cdr::amaflags, ast_cdr_amaflags2int(), AST_CDR_FLAG_LOCKED, ast_test_flag, ast_channel::cdr, and ast_cdr::next.
Referenced by cdr_write(), and pbx_builtin_setamaflags().
00961 { 00962 struct ast_cdr *cdr; 00963 int newflag = ast_cdr_amaflags2int(flag); 00964 if (newflag) { 00965 for (cdr = chan->cdr; cdr; cdr = cdr->next) { 00966 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) { 00967 cdr->amaflags = newflag; 00968 } 00969 } 00970 } 00971 00972 return 0; 00973 }
| void ast_cdr_setanswer | ( | struct ast_cdr * | cdr, | |
| struct timeval | t | |||
| ) |
Set the answer time for a call.
| cdr | the cdr you wish to associate with the call | |
| t | the answer time Starts all CDR stuff necessary for doing CDR when answering a call NULL argument is just fine. |
Definition at line 795 of file cdr.c.
References ast_cdr::answer, AST_CDR_FLAG_ANSLOCKED, AST_CDR_FLAG_DONT_TOUCH, AST_CDR_FLAG_LOCKED, ast_test_flag, check_post(), and ast_cdr::next.
Referenced by ast_bridge_call().
00796 { 00797 00798 for (; cdr; cdr = cdr->next) { 00799 if (ast_test_flag(cdr, AST_CDR_FLAG_ANSLOCKED)) 00800 continue; 00801 if (ast_test_flag(cdr, AST_CDR_FLAG_DONT_TOUCH) && ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) 00802 continue; 00803 check_post(cdr); 00804 cdr->answer = t; 00805 } 00806 }
| void ast_cdr_setapp | ( | struct ast_cdr * | cdr, | |
| const char * | app, | |||
| const char * | data | |||
| ) |
Set the last executed application.
| cdr | which cdr to act upon | |
| app | the name of the app you wish to change it to | |
| data | the data you want in the data field of app you set it to Changes the value of the last executed app Returns nothing |
Definition at line 783 of file cdr.c.
References AST_CDR_FLAG_LOCKED, ast_copy_string(), ast_test_flag, check_post(), ast_cdr::lastapp, ast_cdr::lastdata, ast_cdr::next, and S_OR.
Referenced by __ast_request_and_dial(), agi_handle_command(), clear_caller(), findmeexec(), and pbx_exec().
00784 { 00785 00786 for (; cdr; cdr = cdr->next) { 00787 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) { 00788 check_post(cdr); 00789 ast_copy_string(cdr->lastapp, S_OR(app, ""), sizeof(cdr->lastapp)); 00790 ast_copy_string(cdr->lastdata, S_OR(data, ""), sizeof(cdr->lastdata)); 00791 } 00792 } 00793 }
| int ast_cdr_setcid | ( | struct ast_cdr * | cdr, | |
| struct ast_channel * | chan | |||
| ) |
Initialize based on a channel.
| cdr | Call Detail Record to use for channel | |
| chan | Channel to bind CDR with Initializes a CDR and associates it with a particular channel |
Definition at line 840 of file cdr.c.
References AST_CDR_FLAG_LOCKED, ast_test_flag, ast_cdr::next, and set_one_cid().
Referenced by ast_bridge_call(), ast_set_callerid(), and callerid_write().
00841 { 00842 for (; cdr; cdr = cdr->next) { 00843 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) 00844 set_one_cid(cdr, c); 00845 } 00846 return 0; 00847 }
| void ast_cdr_setdestchan | ( | struct ast_cdr * | cdr, | |
| const char * | chan | |||
| ) |
Set the destination channel, if there was one.
| cdr | Which cdr it's applied to | |
| chan | Channel to which dest will be Sets the destination channel the CDR is applied to Returns nothing |
Definition at line 773 of file cdr.c.
References AST_CDR_FLAG_LOCKED, ast_copy_string(), ast_test_flag, check_post(), ast_cdr::dstchannel, and ast_cdr::next.
Referenced by dial_exec_full(), park_exec_full(), ring_entry(), and try_calling().
00774 { 00775 for (; cdr; cdr = cdr->next) { 00776 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) { 00777 check_post(cdr); 00778 ast_copy_string(cdr->dstchannel, chann, sizeof(cdr->dstchannel)); 00779 } 00780 } 00781 }
| void ast_cdr_setdisposition | ( | struct ast_cdr * | cdr, | |
| long int | disposition | |||
| ) |
Set the disposition for a call.
| cdr | the cdr you wish to associate with the call | |
| disposition | the new disposition Set the disposition on a call. NULL argument is just fine. |
Definition at line 808 of file cdr.c.
References AST_CDR_FLAG_LOCKED, ast_test_flag, check_post(), ast_cdr::disposition, and ast_cdr::next.
Referenced by ast_bridge_call().
00809 { 00810 00811 for (; cdr; cdr = cdr->next) { 00812 if (ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) 00813 continue; 00814 check_post(cdr); 00815 cdr->disposition = disposition; 00816 } 00817 }
| int ast_cdr_setuserfield | ( | struct ast_channel * | chan, | |
| const char * | userfield | |||
| ) |
Set CDR user field for channel (stored in CDR).
Definition at line 975 of file cdr.c.
References AST_CDR_FLAG_LOCKED, ast_copy_string(), ast_test_flag, ast_channel::cdr, ast_cdr::next, and ast_cdr::userfield.
Referenced by __agent_start_monitoring(), cdr_write(), handle_request_info(), and start_monitor_exec().
00976 { 00977 struct ast_cdr *cdr = chan->cdr; 00978 00979 for ( ; cdr ; cdr = cdr->next) { 00980 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) 00981 ast_copy_string(cdr->userfield, userfield, sizeof(cdr->userfield)); 00982 } 00983 00984 return 0; 00985 }
| int ast_cdr_setvar | ( | struct ast_cdr * | cdr, | |
| const char * | name, | |||
| const char * | value, | |||
| int | recur | |||
| ) |
Set a CDR channel variable
Definition at line 300 of file cdr.c.
References AST_CDR_FLAG_DONT_TOUCH, AST_CDR_FLAG_LOCKED, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), ast_test_flag, ast_var_assign(), ast_var_delete(), ast_var_name(), cdr_readonly_vars, LOG_ERROR, ast_cdr::next, and ast_cdr::varshead.
Referenced by ast_cdr_fork(), cdr_write(), and set_one_cid().
00301 { 00302 struct ast_var_t *newvariable; 00303 struct varshead *headp; 00304 int x; 00305 00306 if (!cdr) /* don't die if the cdr is null */ 00307 return -1; 00308 00309 for (x = 0; cdr_readonly_vars[x]; x++) { 00310 if (!strcasecmp(name, cdr_readonly_vars[x])) { 00311 ast_log(LOG_ERROR, "Attempt to set the '%s' read-only variable!.\n", name); 00312 return -1; 00313 } 00314 } 00315 00316 if (!cdr) { 00317 ast_log(LOG_ERROR, "Attempt to set a variable on a nonexistent CDR record.\n"); 00318 return -1; 00319 } 00320 00321 for (; cdr; cdr = recur ? cdr->next : NULL) { 00322 if (ast_test_flag(cdr, AST_CDR_FLAG_DONT_TOUCH) && ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) 00323 continue; 00324 headp = &cdr->varshead; 00325 AST_LIST_TRAVERSE_SAFE_BEGIN(headp, newvariable, entries) { 00326 if (!strcasecmp(ast_var_name(newvariable), name)) { 00327 /* there is already such a variable, delete it */ 00328 AST_LIST_REMOVE_CURRENT(entries); 00329 ast_var_delete(newvariable); 00330 break; 00331 } 00332 } 00333 AST_LIST_TRAVERSE_SAFE_END; 00334 00335 if (value) { 00336 newvariable = ast_var_assign(name, value); 00337 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 00338 } 00339 } 00340 00341 return 0; 00342 }
Reset the detail record times, flags
| cdr | which cdr to act upon | |
| flags | |AST_CDR_FLAG_POSTED whether or not to post the cdr first before resetting it |AST_CDR_FLAG_LOCKED whether or not to reset locked CDR's |
Definition at line 1110 of file cdr.c.
References ast_cdr::answer, AST_CDR_FLAG_POST_DISABLED, AST_CDR_NULL, ast_cdr_start(), ast_clear_flag, ast_copy_flags, AST_FLAGS_ALL, ast_set_flag, ast_test_flag, ast_cdr::billsec, ast_cdr::disposition, ast_cdr::duration, ast_cdr::end, and ast_cdr::start.
Referenced by ast_bridge_call().
01111 { 01112 struct ast_flags flags = { 0 }; 01113 01114 if (_flags) 01115 ast_copy_flags(&flags, _flags, AST_FLAGS_ALL); 01116 01117 /* Reset to initial state */ 01118 if (ast_test_flag(cdr, AST_CDR_FLAG_POST_DISABLED)) { /* But do NOT lose the NoCDR() setting */ 01119 ast_clear_flag(cdr, AST_FLAGS_ALL); 01120 ast_set_flag(cdr, AST_CDR_FLAG_POST_DISABLED); 01121 } else { 01122 ast_clear_flag(cdr, AST_FLAGS_ALL); 01123 } 01124 01125 memset(&cdr->start, 0, sizeof(cdr->start)); 01126 memset(&cdr->end, 0, sizeof(cdr->end)); 01127 memset(&cdr->answer, 0, sizeof(cdr->answer)); 01128 cdr->billsec = 0; 01129 cdr->duration = 0; 01130 ast_cdr_start(cdr); 01131 cdr->disposition = AST_CDR_NULL; 01132 }
| void ast_cdr_start | ( | struct ast_cdr * | cdr | ) |
Start a call.
| cdr | the cdr you wish to associate with the call Starts all CDR stuff necessary for monitoring a call Returns nothing |
Definition at line 682 of file cdr.c.
References AST_CDR_FLAG_LOCKED, ast_test_flag, ast_tvnow(), chan, ast_cdr::channel, check_post(), ast_cdr::next, S_OR, and ast_cdr::start.
Referenced by __ast_channel_alloc_ap(), __ast_request_and_dial(), ast_bridge_call(), ast_cdr_reset(), ast_cdr_specialized_reset(), ast_pbx_outgoing_cdr_failed(), builtin_blindtransfer(), clear_caller(), and findmeexec().
00683 { 00684 char *chan; 00685 00686 for (; cdr; cdr = cdr->next) { 00687 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) { 00688 chan = S_OR(cdr->channel, "<unknown>"); 00689 check_post(cdr); 00690 cdr->start = ast_tvnow(); 00691 } 00692 } 00693 }
| void ast_cdr_submit_batch | ( | int | shutdown | ) |
Spawns (possibly) a new thread to submit a batch of CDRs to the backend engines.
| shutdown | Whether or not we are shutting down Blocks the asterisk shutdown procedures until the CDR data is submitted. Returns nothing |
Definition at line 1188 of file cdr.c.
References ast_debug, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create_detached_background, AST_PTHREADT_NULL, batch, batchscheduleronly, cdr_batch_lock, do_batch_backend_process(), ast_cdr_batch::head, LOG_WARNING, and reset_batch().
Referenced by ast_cdr_engine_term(), and submit_scheduled_batch().
01189 { 01190 struct ast_cdr_batch_item *oldbatchitems = NULL; 01191 pthread_t batch_post_thread = AST_PTHREADT_NULL; 01192 01193 /* if there's no batch, or no CDRs in the batch, then there's nothing to do */ 01194 if (!batch || !batch->head) 01195 return; 01196 01197 /* move the old CDRs aside, and prepare a new CDR batch */ 01198 ast_mutex_lock(&cdr_batch_lock); 01199 oldbatchitems = batch->head; 01200 reset_batch(); 01201 ast_mutex_unlock(&cdr_batch_lock); 01202 01203 /* if configured, spawn a new thread to post these CDRs, 01204 also try to save as much as possible if we are shutting down safely */ 01205 if (batchscheduleronly || do_shutdown) { 01206 ast_debug(1, "CDR single-threaded batch processing begins now\n"); 01207 do_batch_backend_process(oldbatchitems); 01208 } else { 01209 if (ast_pthread_create_detached_background(&batch_post_thread, NULL, do_batch_backend_process, oldbatchitems)) { 01210 ast_log(LOG_WARNING, "CDR processing thread could not detach, now trying in this thread\n"); 01211 do_batch_backend_process(oldbatchitems); 01212 } else { 01213 ast_debug(1, "CDR multi-threaded batch processing begins now\n"); 01214 } 01215 } 01216 }
| void ast_cdr_unregister | ( | const char * | name | ) |
Unregister a CDR handling engine.
| name | name of CDR handler to unregister Unregisters a CDR by it's name |
Definition at line 151 of file cdr.c.
References ast_free, AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, ast_cdr_beitem::list, and ast_cdr_beitem::name.
Referenced by load_config(), reload(), tds_unload_module(), and unload_module().
00152 { 00153 struct ast_cdr_beitem *i = NULL; 00154 00155 AST_RWLIST_WRLOCK(&be_list); 00156 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&be_list, i, list) { 00157 if (!strcasecmp(name, i->name)) { 00158 AST_RWLIST_REMOVE_CURRENT(list); 00159 ast_verb(2, "Unregistered '%s' CDR backend\n", name); 00160 ast_free(i); 00161 break; 00162 } 00163 } 00164 AST_RWLIST_TRAVERSE_SAFE_END; 00165 AST_RWLIST_UNLOCK(&be_list); 00166 }
| int ast_cdr_update | ( | struct ast_channel * | chan | ) |
Update CDR on a channel
Definition at line 1001 of file cdr.c.
References ast_channel::accountcode, ast_cdr::accountcode, AST_CDR_FLAG_LOCKED, ast_copy_string(), ast_test_flag, ast_channel::cdr, ast_channel::context, ast_cdr::dcontext, ast_cdr::dst, ast_channel::exten, ast_channel::macrocontext, ast_channel::macroexten, ast_cdr::next, S_OR, and set_one_cid().
Referenced by __ast_pbx_run(), __ast_request_and_dial(), ast_bridge_call(), cb_events(), clear_caller(), findmeexec(), and local_call().
01002 { 01003 struct ast_cdr *cdr = c->cdr; 01004 01005 for ( ; cdr ; cdr = cdr->next) { 01006 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) { 01007 set_one_cid(cdr, c); 01008 01009 /* Copy account code et-al */ 01010 ast_copy_string(cdr->accountcode, c->accountcode, sizeof(cdr->accountcode)); 01011 01012 /* Destination information */ /* XXX privilege macro* ? */ 01013 ast_copy_string(cdr->dst, S_OR(c->macroexten, c->exten), sizeof(cdr->dst)); 01014 ast_copy_string(cdr->dcontext, S_OR(c->macrocontext, c->context), sizeof(cdr->dcontext)); 01015 } 01016 } 01017 01018 return 0; 01019 }
| int check_cdr_enabled | ( | void | ) |
Return TRUE if CDR subsystem is enabled.
Definition at line 108 of file cdr.c.
References enabled.
Referenced by action_coresettings(), and handle_show_settings().
00109 { 00110 return enabled; 00111 }
| char ast_default_accountcode[AST_MAX_ACCOUNT_CODE] |
Default AMA flag for billing records (CDR's)
Definition at line 54 of file cdr.c.
Referenced by __ast_channel_alloc_ap(), and ast_bridge_call().
1.5.6