#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <signal.h>
#include "asterisk.h"
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/cdr.h"
#include "asterisk/logger.h"
#include "asterisk/callerid.h"
#include "asterisk/causes.h"
#include "asterisk/options.h"
#include "asterisk/linkedlists.h"
#include "asterisk/utils.h"
#include "asterisk/sched.h"
#include "asterisk/config.h"
#include "asterisk/cli.h"
#include "asterisk/module.h"

Go to the source code of this file.
Data Structures | |
| struct | ast_cdr_batch |
| struct | ast_cdr_batch_item |
| struct | ast_cdr_beitem |
Defines | |
| #define | BATCH_SAFE_SHUTDOWN_DEFAULT 1 |
| #define | BATCH_SCHEDULER_ONLY_DEFAULT 0 |
| #define | BATCH_SIZE_DEFAULT 100 |
| #define | BATCH_TIME_DEFAULT 300 |
Functions | |
| struct 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) |
| 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) |
| void | ast_cdr_busy (struct ast_cdr *cdr) |
| int | ast_cdr_copy_vars (struct ast_cdr *to_cdr, struct ast_cdr *from_cdr) |
| void | ast_cdr_detach (struct ast_cdr *cdr) |
| char * | ast_cdr_disp2str (int disposition) |
| int | ast_cdr_disposition (struct ast_cdr *cdr, int cause) |
| struct ast_cdr * | ast_cdr_dup (struct ast_cdr *cdr) |
| Duplicate a record Returns a malloc'd ast_cdr structure, returns NULL on error (malloc failure). | |
| void | ast_cdr_end (struct ast_cdr *cdr) |
| int | ast_cdr_engine_init (void) |
| void | ast_cdr_engine_reload (void) |
| void | ast_cdr_engine_term (void) |
| void | ast_cdr_failed (struct ast_cdr *cdr) |
| char * | ast_cdr_flags2str (int flag) |
| 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) |
| static const char * | ast_cdr_getvar_internal (struct ast_cdr *cdr, const char *name, int recur) |
| int | ast_cdr_init (struct ast_cdr *cdr, struct ast_channel *c) |
| Initialize based on a channel. | |
| void | ast_cdr_noanswer (struct ast_cdr *cdr) |
| int | ast_cdr_register (char *name, char *desc, ast_cdrbe be) |
| void | ast_cdr_reset (struct ast_cdr *cdr, struct ast_flags *_flags) |
| int | ast_cdr_serialize_variables (struct ast_cdr *cdr, char *buf, size_t size, char delim, char sep, int recur) |
| int | ast_cdr_setaccount (struct ast_channel *chan, const char *account) |
| int | ast_cdr_setamaflags (struct ast_channel *chan, const char *flag) |
| void | ast_cdr_setapp (struct ast_cdr *cdr, char *app, char *data) |
| int | ast_cdr_setcid (struct ast_cdr *cdr, struct ast_channel *c) |
| void | ast_cdr_setdestchan (struct ast_cdr *cdr, char *chann) |
| int | ast_cdr_setuserfield (struct ast_channel *chan, const char *userfield) |
| int | ast_cdr_setvar (struct ast_cdr *cdr, const char *name, const char *value, int recur) |
| void | ast_cdr_start (struct ast_cdr *cdr) |
| void | ast_cdr_submit_batch (int shutdown) |
| void | ast_cdr_unregister (char *name) |
| int | ast_cdr_update (struct ast_channel *c) |
| static | AST_LIST_HEAD_STATIC (be_list, ast_cdr_beitem) |
| AST_MUTEX_DEFINE_STATIC (cdr_pending_lock) | |
| AST_MUTEX_DEFINE_STATIC (cdr_batch_lock) | |
| static void * | do_batch_backend_process (void *data) |
| static void * | do_cdr (void *data) |
| static int | do_reload (void) |
| static int | handle_cli_status (int fd, int argc, char *argv[]) |
| static int | handle_cli_submit (int fd, int argc, char *argv[]) |
| static int | init_batch (void) |
| static void | post_cdr (struct ast_cdr *cdr) |
| static void | reset_batch (void) |
| static int | submit_scheduled_batch (void *data) |
| static void | submit_unscheduled_batch (void) |
Variables | |
| char | ast_default_accountcode [AST_MAX_ACCOUNT_CODE] = "" |
| int | ast_default_amaflags = AST_CDR_DOCUMENTATION |
| static struct ast_cdr_batch * | batch |
| static int | batchmode |
| static int | batchsafeshutdown |
| static int | batchscheduleronly |
| static int | batchsize |
| static int | batchtime |
| static ast_cond_t | cdr_pending_cond |
| static int | cdr_sched = -1 |
| static pthread_t | cdr_thread = AST_PTHREADT_NULL |
| static struct ast_cli_entry | cli_status |
| static struct ast_cli_entry | cli_submit |
| static int | enabled |
| static struct sched_context * | sched |
Includes code and algorithms from the Zapata library.
Definition in file cdr.c.
| #define BATCH_SAFE_SHUTDOWN_DEFAULT 1 |
| #define BATCH_SCHEDULER_ONLY_DEFAULT 0 |
| #define BATCH_SIZE_DEFAULT 100 |
| #define BATCH_TIME_DEFAULT 300 |
| struct ast_cdr* ast_cdr_alloc | ( | void | ) | [read] |
Allocate a CDR record Returns a malloc'd ast_cdr structure, returns NULL on error (malloc failure).
Definition at line 455 of file cdr.c.
References malloc.
Referenced by __agent_start_monitoring(), __ast_pbx_run(), __ast_request_and_dial(), ast_cdr_dup(), ast_feature_request_and_dial(), ast_pbx_outgoing_app(), ast_pbx_outgoing_cdr_failed(), ast_pbx_outgoing_exten(), and start_monitor_exec().
00456 { 00457 struct ast_cdr *cdr; 00458 00459 cdr = malloc(sizeof(*cdr)); 00460 if (cdr) 00461 memset(cdr, 0, sizeof(*cdr)); 00462 00463 return cdr; 00464 }
| int ast_cdr_amaflags2int | ( | const char * | flag | ) |
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. Returns the binary form of the flag |
Definition at line 809 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(), set_config(), and setup_zap().
00810 { 00811 if (!strcasecmp(flag, "default")) 00812 return 0; 00813 if (!strcasecmp(flag, "omit")) 00814 return AST_CDR_OMIT; 00815 if (!strcasecmp(flag, "billing")) 00816 return AST_CDR_BILLING; 00817 if (!strcasecmp(flag, "documentation")) 00818 return AST_CDR_DOCUMENTATION; 00819 return -1; 00820 }
| 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 483 of file cdr.c.
References ast_cdr::answer, AST_CDR_ANSWERED, AST_CDR_FLAG_POSTED, ast_log(), ast_strlen_zero(), ast_test_flag, ast_cdr::channel, ast_cdr::disposition, LOG_WARNING, and ast_cdr::next.
Referenced by ast_answer(), and ast_read().
00484 { 00485 char *chan; 00486 00487 while (cdr) { 00488 chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>"; 00489 if (ast_test_flag(cdr, AST_CDR_FLAG_POSTED)) 00490 ast_log(LOG_WARNING, "CDR on channel '%s' already posted\n", chan); 00491 if (cdr->disposition < AST_CDR_ANSWERED) 00492 cdr->disposition = AST_CDR_ANSWERED; 00493 if (ast_tvzero(cdr->answer)) 00494 cdr->answer = ast_tvnow(); 00495 cdr = cdr->next; 00496 } 00497 }
Definition at line 891 of file cdr.c.
References ast_cdr::next.
Referenced by ast_cdr_fork(), and attempt_transfer().
00892 { 00893 struct ast_cdr *ret; 00894 00895 if (cdr) { 00896 ret = cdr; 00897 00898 while (cdr->next) 00899 cdr = cdr->next; 00900 cdr->next = newcdr; 00901 } else { 00902 ret = newcdr; 00903 } 00904 00905 return ret; 00906 }
| int ast_cdr_appenduserfield | ( | struct ast_channel * | chan, | |
| const char * | userfield | |||
| ) |
Definition at line 760 of file cdr.c.
References AST_CDR_FLAG_LOCKED, ast_test_flag, ast_channel::cdr, ast_cdr::next, and ast_cdr::userfield.
Referenced by action_setcdruserfield(), appendcdruserfield_exec(), and ast_bridge_call().
00761 { 00762 struct ast_cdr *cdr = chan->cdr; 00763 00764 while (cdr) { 00765 int len = strlen(cdr->userfield); 00766 00767 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) 00768 strncpy(cdr->userfield+len, userfield, sizeof(cdr->userfield) - len - 1); 00769 00770 cdr = cdr->next; 00771 } 00772 00773 return 0; 00774 }
| void ast_cdr_busy | ( | struct ast_cdr * | cdr | ) |
Busy a call
| cdr | the cdr you wish to associate with the call Returns nothing important |
Definition at line 499 of file cdr.c.
References AST_CDR_BUSY, AST_CDR_FLAG_LOCKED, AST_CDR_FLAG_POSTED, ast_log(), ast_strlen_zero(), ast_test_flag, ast_cdr::channel, ast_cdr::disposition, LOG_WARNING, and ast_cdr::next.
Referenced by ast_cdr_disposition(), ring_entry(), and wait_for_answer().
00500 { 00501 char *chan; 00502 00503 while (cdr) { 00504 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) { 00505 chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>"; 00506 if (ast_test_flag(cdr, AST_CDR_FLAG_POSTED)) 00507 ast_log(LOG_WARNING, "CDR on channel '%s' already posted\n", chan); 00508 if (cdr->disposition < AST_CDR_BUSY) 00509 cdr->disposition = AST_CDR_BUSY; 00510 } 00511 cdr = cdr->next; 00512 } 00513 }
Definition at line 326 of file cdr.c.
References AST_LIST_INSERT_HEAD, AST_LIST_TRAVERSE, ast_strlen_zero(), ast_var_assign(), ast_var_name(), ast_var_value(), var, and ast_cdr::varshead.
Referenced by ast_cdr_dup().
00327 { 00328 struct ast_var_t *variables, *newvariable = NULL; 00329 struct varshead *headpa, *headpb; 00330 char *var, *val; 00331 int x = 0; 00332 00333 headpa = &from_cdr->varshead; 00334 headpb = &to_cdr->varshead; 00335 00336 AST_LIST_TRAVERSE(headpa,variables,entries) { 00337 if (variables && 00338 (var = ast_var_name(variables)) && (val = ast_var_value(variables)) && 00339 !ast_strlen_zero(var) && !ast_strlen_zero(val)) { 00340 newvariable = ast_var_assign(var, val); 00341 AST_LIST_INSERT_HEAD(headpb, newvariable, entries); 00342 x++; 00343 } 00344 } 00345 00346 return x; 00347 }
| void ast_cdr_detach | ( | struct ast_cdr * | cdr | ) |
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 1006 of file cdr.c.
References AST_CDR_FLAG_POST_DISABLED, ast_cdr_free(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, batch, batchmode, batchsize, ast_cdr_batch_item::cdr, enabled, ast_cdr_batch::head, init_batch(), LOG_DEBUG, LOG_WARNING, malloc, 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().
01007 { 01008 struct ast_cdr_batch_item *newtail; 01009 int curr; 01010 01011 /* maybe they disabled CDR stuff completely, so just drop it */ 01012 if (!enabled) { 01013 if (option_debug) 01014 ast_log(LOG_DEBUG, "Dropping CDR !\n"); 01015 ast_set_flag(cdr, AST_CDR_FLAG_POST_DISABLED); 01016 ast_cdr_free(cdr); 01017 return; 01018 } 01019 01020 /* post stuff immediately if we are not in batch mode, this is legacy behaviour */ 01021 if (!batchmode) { 01022 post_cdr(cdr); 01023 ast_cdr_free(cdr); 01024 return; 01025 } 01026 01027 /* otherwise, each CDR gets put into a batch list (at the end) */ 01028 if (option_debug) 01029 ast_log(LOG_DEBUG, "CDR detaching from this thread\n"); 01030 01031 /* we'll need a new tail for every CDR */ 01032 newtail = malloc(sizeof(*newtail)); 01033 if (!newtail) { 01034 ast_log(LOG_WARNING, "CDR: out of memory while trying to detach, will try in this thread instead\n"); 01035 post_cdr(cdr); 01036 ast_cdr_free(cdr); 01037 return; 01038 } 01039 memset(newtail, 0, sizeof(*newtail)); 01040 01041 /* don't traverse a whole list (just keep track of the tail) */ 01042 ast_mutex_lock(&cdr_batch_lock); 01043 if (!batch) 01044 init_batch(); 01045 if (!batch->head) { 01046 /* new batch is empty, so point the head at the new tail */ 01047 batch->head = newtail; 01048 } else { 01049 /* already got a batch with something in it, so just append a new tail */ 01050 batch->tail->next = newtail; 01051 } 01052 newtail->cdr = cdr; 01053 batch->tail = newtail; 01054 curr = batch->size++; 01055 ast_mutex_unlock(&cdr_batch_lock); 01056 01057 /* if we have enough stuff to post, then do it */ 01058 if (curr >= (batchsize - 1)) 01059 submit_unscheduled_batch(); 01060 }
| char* ast_cdr_disp2str | ( | int | disposition | ) |
Disposition to a string
| disposition | input binary form Converts the binary form of a disposition to string form. Returns a pointer to the string form |
Definition at line 687 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(), csv_log(), manager_log(), odbc_log(), pgsql_log(), and tds_log().
00688 { 00689 switch (disposition) { 00690 case AST_CDR_NULL: 00691 return "NO ANSWER"; /* by default, for backward compatibility */ 00692 case AST_CDR_NOANSWER: 00693 return "NO ANSWER"; 00694 case AST_CDR_FAILED: 00695 return "FAILED"; 00696 case AST_CDR_BUSY: 00697 return "BUSY"; 00698 case AST_CDR_ANSWERED: 00699 return "ANSWERED"; 00700 } 00701 return "UNKNOWN"; 00702 }
| 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 Returns nothing important | |
| cause | the AST_CAUSE_* |
Definition at line 547 of file cdr.c.
References AST_CAUSE_BUSY, AST_CAUSE_FAILURE, AST_CAUSE_NORMAL, AST_CAUSE_NOTDEFINED, ast_cdr_busy(), ast_cdr_failed(), ast_log(), LOG_WARNING, and ast_cdr::next.
Referenced by __ast_request_and_dial(), ast_feature_request_and_dial(), ast_pbx_outgoing_app(), and ast_pbx_outgoing_exten().
00548 { 00549 int res = 0; 00550 00551 while (cdr) { 00552 switch(cause) { 00553 case AST_CAUSE_BUSY: 00554 ast_cdr_busy(cdr); 00555 break; 00556 case AST_CAUSE_FAILURE: 00557 ast_cdr_failed(cdr); 00558 break; 00559 case AST_CAUSE_NORMAL: 00560 break; 00561 case AST_CAUSE_NOTDEFINED: 00562 res = -1; 00563 break; 00564 default: 00565 res = -1; 00566 ast_log(LOG_WARNING, "Cause not handled\n"); 00567 } 00568 cdr = cdr->next; 00569 } 00570 return res; 00571 }
Duplicate a record Returns a malloc'd ast_cdr structure, returns NULL on error (malloc failure).
Duplicate a CDR record
Definition at line 167 of file cdr.c.
References ast_cdr_alloc(), ast_cdr_copy_vars(), ast_log(), LOG_ERROR, ast_cdr::next, and ast_cdr::varshead.
Referenced by ast_cdr_fork(), and ast_cdr_reset().
00168 { 00169 struct ast_cdr *newcdr; 00170 00171 if (!(newcdr = ast_cdr_alloc())) { 00172 ast_log(LOG_ERROR, "Memory Error!\n"); 00173 return NULL; 00174 } 00175 00176 memcpy(newcdr, cdr, sizeof(*newcdr)); 00177 /* The varshead is unusable, volatile even, after the memcpy so we take care of that here */ 00178 memset(&newcdr->varshead, 0, sizeof(newcdr->varshead)); 00179 ast_cdr_copy_vars(newcdr, cdr); 00180 newcdr->next = NULL; 00181 00182 return newcdr; 00183 }
| void ast_cdr_end | ( | struct ast_cdr * | cdr | ) |
End a call
| cdr | the cdr you have associated the call with Registers the end of call time in the cdr structure. Returns nothing important |
Definition at line 671 of file cdr.c.
References AST_CDR_FLAG_POSTED, ast_log(), ast_strlen_zero(), ast_test_flag, ast_cdr::channel, ast_cdr::end, LOG_WARNING, ast_cdr::next, and ast_cdr::start.
Referenced by __ast_request_and_dial(), ast_cdr_reset(), ast_feature_request_and_dial(), ast_hangup(), ast_pbx_outgoing_cdr_failed(), and ast_read().
00672 { 00673 char *chan; 00674 00675 while (cdr) { 00676 chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>"; 00677 if (ast_test_flag(cdr, AST_CDR_FLAG_POSTED)) 00678 ast_log(LOG_WARNING, "CDR on channel '%s' already posted\n", chan); 00679 if (ast_tvzero(cdr->start)) 00680 ast_log(LOG_WARNING, "CDR on channel '%s' has not started\n", chan); 00681 if (ast_tvzero(cdr->end)) 00682 cdr->end = ast_tvnow(); 00683 cdr = cdr->next; 00684 } 00685 }
| int ast_cdr_engine_init | ( | void | ) |
Load the configuration file cdr.conf and possibly start the CDR scheduling thread
Definition at line 1261 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().
01262 { 01263 int res; 01264 01265 sched = sched_context_create(); 01266 if (!sched) { 01267 ast_log(LOG_ERROR, "Unable to create schedule context.\n"); 01268 return -1; 01269 } 01270 01271 ast_cli_register(&cli_status); 01272 01273 res = do_reload(); 01274 if (res) { 01275 ast_mutex_lock(&cdr_batch_lock); 01276 res = init_batch(); 01277 ast_mutex_unlock(&cdr_batch_lock); 01278 } 01279 01280 return res; 01281 }
| void ast_cdr_engine_reload | ( | void | ) |
Reload the configuration file cdr.conf and start/stop CDR scheduling thread
Definition at line 1290 of file cdr.c.
References do_reload().
Referenced by ast_module_reload().
01291 { 01292 do_reload(); 01293 }
| void ast_cdr_engine_term | ( | void | ) |
Submit any remaining CDRs and prepare for shutdown
Definition at line 1285 of file cdr.c.
References ast_cdr_submit_batch(), and batchsafeshutdown.
Referenced by do_reload(), and quit_handler().
01286 { 01287 ast_cdr_submit_batch(batchsafeshutdown); 01288 }
| void ast_cdr_failed | ( | struct ast_cdr * | cdr | ) |
Fail a call
| cdr | the cdr you wish to associate with the call Returns nothing important |
Definition at line 515 of file cdr.c.
References AST_CDR_FAILED, AST_CDR_FLAG_LOCKED, AST_CDR_FLAG_POSTED, ast_log(), ast_strlen_zero(), ast_test_flag, ast_cdr::channel, ast_cdr::disposition, LOG_WARNING, and ast_cdr::next.
Referenced by __ast_request_and_dial(), ast_cdr_disposition(), ast_feature_request_and_dial(), ast_pbx_outgoing_app(), ast_pbx_outgoing_cdr_failed(), and ast_pbx_outgoing_exten().
00516 { 00517 char *chan; 00518 00519 while (cdr) { 00520 chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>"; 00521 if (ast_test_flag(cdr, AST_CDR_FLAG_POSTED)) 00522 ast_log(LOG_WARNING, "CDR on channel '%s' already posted\n", chan); 00523 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) { 00524 if (cdr->disposition < AST_CDR_FAILED) 00525 cdr->disposition = AST_CDR_FAILED; 00526 } 00527 cdr = cdr->next; 00528 } 00529 }
| char* ast_cdr_flags2str | ( | int | flag | ) |
Converts AMA flag to printable string
Definition at line 705 of file cdr.c.
References AST_CDR_BILLING, AST_CDR_DOCUMENTATION, and AST_CDR_OMIT.
Referenced by _sip_show_peer(), ast_cdr_getvar(), build_csv_record(), csv_log(), manager_log(), sip_show_user(), and tds_log().
00706 { 00707 switch(flag) { 00708 case AST_CDR_OMIT: 00709 return "OMIT"; 00710 case AST_CDR_BILLING: 00711 return "BILLING"; 00712 case AST_CDR_DOCUMENTATION: 00713 return "DOCUMENTATION"; 00714 } 00715 return "Unknown"; 00716 }
| void ast_cdr_free | ( | struct ast_cdr * | cdr | ) |
Free a CDR record.
| cdr | ast_cdr structure to free Returns nothing important |
Definition at line 434 of file cdr.c.
References AST_CDR_FLAG_POST_DISABLED, AST_CDR_FLAG_POSTED, ast_cdr_free_vars(), ast_log(), ast_strlen_zero(), ast_test_flag, ast_cdr::channel, ast_cdr::end, free, LOG_NOTICE, ast_cdr::next, and ast_cdr::start.
Referenced by ast_cdr_detach(), do_batch_backend_process(), and nocdr_exec().
00435 { 00436 char *chan; 00437 struct ast_cdr *next; 00438 00439 while (cdr) { 00440 next = cdr->next; 00441 chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>"; 00442 if (!ast_test_flag(cdr, AST_CDR_FLAG_POSTED) && !ast_test_flag(cdr, AST_CDR_FLAG_POST_DISABLED)) 00443 ast_log(LOG_NOTICE, "CDR on channel '%s' not posted\n", chan); 00444 if (ast_tvzero(cdr->end)) 00445 ast_log(LOG_NOTICE, "CDR on channel '%s' lacks end\n", chan); 00446 if (ast_tvzero(cdr->start)) 00447 ast_log(LOG_NOTICE, "CDR on channel '%s' lacks start\n", chan); 00448 00449 ast_cdr_free_vars(cdr, 0); 00450 free(cdr); 00451 cdr = next; 00452 } 00453 }
| void ast_cdr_free_vars | ( | struct ast_cdr * | cdr, | |
| int | recur | |||
| ) |
Definition at line 413 of file cdr.c.
References AST_LIST_EMPTY, AST_LIST_REMOVE_HEAD, ast_var_delete(), ast_cdr::next, and ast_cdr::varshead.
Referenced by ast_cdr_fork(), ast_cdr_free(), and ast_cdr_reset().
00414 { 00415 struct varshead *headp; 00416 struct ast_var_t *vardata; 00417 00418 /* clear variables */ 00419 while (cdr) { 00420 headp = &cdr->varshead; 00421 while (!AST_LIST_EMPTY(headp)) { 00422 vardata = AST_LIST_REMOVE_HEAD(headp, entries); 00423 ast_var_delete(vardata); 00424 } 00425 00426 if (!recur) { 00427 break; 00428 } 00429 00430 cdr = cdr->next; 00431 } 00432 }
| void ast_cdr_getvar | ( | struct ast_cdr * | cdr, | |
| const char * | name, | |||
| char ** | ret, | |||
| char * | workspace, | |||
| int | workspacelen, | |||
| int | recur | |||
| ) |
CDR channel variable retrieval
Definition at line 208 of file cdr.c.
References ast_cdr::accountcode, ast_cdr::amaflags, ast_cdr::answer, ast_cdr_disp2str(), ast_cdr_flags2str(), ast_cdr_getvar_internal(), ast_strlen_zero(), ast_cdr::billsec, ast_cdr::channel, ast_cdr::clid, ast_cdr::dcontext, ast_cdr::disposition, ast_cdr::dst, ast_cdr::dstchannel, ast_cdr::duration, ast_cdr::end, fmt, ast_cdr::lastapp, ast_cdr::lastdata, ast_cdr::src, ast_cdr::start, t, ast_cdr::uniqueid, and ast_cdr::userfield.
Referenced by ast_cdr_serialize_variables(), builtin_function_cdr_read(), and pickup_exec().
00209 { 00210 struct tm tm; 00211 time_t t; 00212 const char *fmt = "%Y-%m-%d %T"; 00213 const char *varbuf; 00214 00215 *ret = NULL; 00216 /* special vars (the ones from the struct ast_cdr when requested by name) 00217 I'd almost say we should convert all the stringed vals to vars */ 00218 00219 if (!strcasecmp(name, "clid")) 00220 ast_copy_string(workspace, cdr->clid, workspacelen); 00221 else if (!strcasecmp(name, "src")) 00222 ast_copy_string(workspace, cdr->src, workspacelen); 00223 else if (!strcasecmp(name, "dst")) 00224 ast_copy_string(workspace, cdr->dst, workspacelen); 00225 else if (!strcasecmp(name, "dcontext")) 00226 ast_copy_string(workspace, cdr->dcontext, workspacelen); 00227 else if (!strcasecmp(name, "channel")) 00228 ast_copy_string(workspace, cdr->channel, workspacelen); 00229 else if (!strcasecmp(name, "dstchannel")) 00230 ast_copy_string(workspace, cdr->dstchannel, workspacelen); 00231 else if (!strcasecmp(name, "lastapp")) 00232 ast_copy_string(workspace, cdr->lastapp, workspacelen); 00233 else if (!strcasecmp(name, "lastdata")) 00234 ast_copy_string(workspace, cdr->lastdata, workspacelen); 00235 else if (!strcasecmp(name, "start")) { 00236 t = cdr->start.tv_sec; 00237 if (t) { 00238 localtime_r(&t, &tm); 00239 strftime(workspace, workspacelen, fmt, &tm); 00240 } 00241 } else if (!strcasecmp(name, "answer")) { 00242 t = cdr->answer.tv_sec; 00243 if (t) { 00244 localtime_r(&t, &tm); 00245 strftime(workspace, workspacelen, fmt, &tm); 00246 } 00247 } else if (!strcasecmp(name, "end")) { 00248 t = cdr->end.tv_sec; 00249 if (t) { 00250 localtime_r(&t, &tm); 00251 strftime(workspace, workspacelen, fmt, &tm); 00252 } 00253 } else if (!strcasecmp(name, "duration")) 00254 snprintf(workspace, workspacelen, "%ld", cdr->duration); 00255 else if (!strcasecmp(name, "billsec")) 00256 snprintf(workspace, workspacelen, "%ld", cdr->billsec); 00257 else if (!strcasecmp(name, "disposition")) 00258 ast_copy_string(workspace, ast_cdr_disp2str(cdr->disposition), workspacelen); 00259 else if (!strcasecmp(name, "amaflags")) 00260 ast_copy_string(workspace, ast_cdr_flags2str(cdr->amaflags), workspacelen); 00261 else if (!strcasecmp(name, "accountcode")) 00262 ast_copy_string(workspace, cdr->accountcode, workspacelen); 00263 else if (!strcasecmp(name, "uniqueid")) 00264 ast_copy_string(workspace, cdr->uniqueid, workspacelen); 00265 else if (!strcasecmp(name, "userfield")) 00266 ast_copy_string(workspace, cdr->userfield, workspacelen); 00267 else if ((varbuf = ast_cdr_getvar_internal(cdr, name, recur))) 00268 ast_copy_string(workspace, varbuf, workspacelen); 00269 00270 if (!ast_strlen_zero(workspace)) 00271 *ret = workspace; 00272 }
| static const char* ast_cdr_getvar_internal | ( | struct ast_cdr * | cdr, | |
| const char * | name, | |||
| int | recur | |||
| ) | [static] |
Definition at line 185 of file cdr.c.
References AST_LIST_TRAVERSE, ast_strlen_zero(), ast_var_name(), ast_var_value(), ast_cdr::next, and ast_cdr::varshead.
Referenced by ast_cdr_getvar().
00186 { 00187 struct ast_var_t *variables; 00188 struct varshead *headp; 00189 00190 if (ast_strlen_zero(name)) 00191 return NULL; 00192 00193 while (cdr) { 00194 headp = &cdr->varshead; 00195 AST_LIST_TRAVERSE(headp, variables, entries) { 00196 if (!strcasecmp(name, ast_var_name(variables))) 00197 return ast_var_value(variables); 00198 } 00199 if (!recur) 00200 break; 00201 cdr = cdr->next; 00202 } 00203 00204 return NULL; 00205 }
| 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 633 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_NULL, ast_log(), AST_MAX_EXTENSION, AST_STATE_UP, ast_strlen_zero(), ast_test_flag, ast_cdr::channel, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_name, ast_callerid::cid_num, ast_cdr::clid, ast_channel::context, ast_cdr::dcontext, ast_cdr::disposition, ast_cdr::dst, ast_channel::exten, LOG_WARNING, ast_channel::name, ast_cdr::next, ast_cdr::src, ast_channel::uniqueid, and ast_cdr::uniqueid.
Referenced by __ast_pbx_run(), __ast_request_and_dial(), ast_feature_request_and_dial(), ast_pbx_outgoing_app(), ast_pbx_outgoing_cdr_failed(), and ast_pbx_outgoing_exten().
00634 { 00635 char *chan; 00636 char *num; 00637 char tmp[AST_MAX_EXTENSION] = ""; 00638 00639 while (cdr) { 00640 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) { 00641 chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>"; 00642 if (!ast_strlen_zero(cdr->channel)) 00643 ast_log(LOG_WARNING, "CDR already initialized on '%s'\n", chan); 00644 ast_copy_string(cdr->channel, c->name, sizeof(cdr->channel)); 00645 /* Grab source from ANI or normal Caller*ID */ 00646 num = c->cid.cid_ani ? c->cid.cid_ani : c->cid.cid_num; 00647 00648 if (c->cid.cid_name && num) 00649 snprintf(tmp, sizeof(tmp), "\"%s\" <%s>", c->cid.cid_name, num); 00650 else if (c->cid.cid_name) 00651 ast_copy_string(tmp, c->cid.cid_name, sizeof(tmp)); 00652 else if (num) 00653 ast_copy_string(tmp, num, sizeof(tmp)); 00654 ast_copy_string(cdr->clid, tmp, sizeof(cdr->clid)); 00655 ast_copy_string(cdr->src, num ? num : "", sizeof(cdr->src)); 00656 00657 cdr->disposition = (c->_state == AST_STATE_UP) ? AST_CDR_ANSWERED : AST_CDR_NULL; 00658 cdr->amaflags = c->amaflags ? c->amaflags : ast_default_amaflags; 00659 ast_copy_string(cdr->accountcode, c->accountcode, sizeof(cdr->accountcode)); 00660 /* Destination information */ 00661 ast_copy_string(cdr->dst, c->exten, sizeof(cdr->dst)); 00662 ast_copy_string(cdr->dcontext, c->context, sizeof(cdr->dcontext)); 00663 /* Unique call identifier */ 00664 ast_copy_string(cdr->uniqueid, c->uniqueid, sizeof(cdr->uniqueid)); 00665 } 00666 cdr = cdr->next; 00667 } 00668 return 0; 00669 }
| 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" |
Definition at line 531 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().
00532 { 00533 char *chan; 00534 00535 while (cdr) { 00536 chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>"; 00537 if (ast_test_flag(cdr, AST_CDR_FLAG_POSTED)) 00538 ast_log(LOG_WARNING, "CDR on channel '%s' already posted\n", chan); 00539 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) { 00540 if (cdr->disposition < AST_CDR_NOANSWER) 00541 cdr->disposition = AST_CDR_NOANSWER; 00542 } 00543 cdr = cdr->next; 00544 } 00545 }
| int ast_cdr_register | ( | char * | name, | |
| char * | desc, | |||
| ast_cdrbe | be | |||
| ) |
Register a CDR driver. Each registered CDR driver generates a CDR
Definition at line 106 of file cdr.c.
References AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_cdr_beitem::be, ast_cdr_beitem::desc, list, LOG_WARNING, malloc, and ast_cdr_beitem::name.
Referenced by load_module(), odbc_load_module(), process_my_load_module(), and tds_load_module().
00107 { 00108 struct ast_cdr_beitem *i; 00109 00110 if (!name) 00111 return -1; 00112 if (!be) { 00113 ast_log(LOG_WARNING, "CDR engine '%s' lacks backend\n", name); 00114 return -1; 00115 } 00116 00117 AST_LIST_LOCK(&be_list); 00118 AST_LIST_TRAVERSE(&be_list, i, list) { 00119 if (!strcasecmp(name, i->name)) 00120 break; 00121 } 00122 AST_LIST_UNLOCK(&be_list); 00123 00124 if (i) { 00125 ast_log(LOG_WARNING, "Already have a CDR backend called '%s'\n", name); 00126 return -1; 00127 } 00128 00129 i = malloc(sizeof(*i)); 00130 if (!i) 00131 return -1; 00132 00133 memset(i, 0, sizeof(*i)); 00134 i->be = be; 00135 ast_copy_string(i->name, name, sizeof(i->name)); 00136 ast_copy_string(i->desc, desc, sizeof(i->desc)); 00137 00138 AST_LIST_LOCK(&be_list); 00139 AST_LIST_INSERT_HEAD(&be_list, i, list); 00140 AST_LIST_UNLOCK(&be_list); 00141 00142 return 0; 00143 }
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 852 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_cdr::next, and ast_cdr::start.
Referenced by ast_bridge_call_thread(), ast_cdr_fork(), dial_exec_full(), disa_exec(), and pbx_builtin_resetcdr().
00853 { 00854 struct ast_cdr *dup; 00855 struct ast_flags flags = { 0 }; 00856 00857 if (_flags) 00858 ast_copy_flags(&flags, _flags, AST_FLAGS_ALL); 00859 00860 while (cdr) { 00861 /* Detach if post is requested */ 00862 if (ast_test_flag(&flags, AST_CDR_FLAG_LOCKED) || !ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) { 00863 if (ast_test_flag(&flags, AST_CDR_FLAG_POSTED)) { 00864 ast_cdr_end(cdr); 00865 if ((dup = ast_cdr_dup(cdr))) { 00866 ast_cdr_detach(dup); 00867 } 00868 ast_set_flag(cdr, AST_CDR_FLAG_POSTED); 00869 } 00870 00871 /* clear variables */ 00872 if (!ast_test_flag(&flags, AST_CDR_FLAG_KEEP_VARS)) { 00873 ast_cdr_free_vars(cdr, 0); 00874 } 00875 00876 /* Reset to initial state */ 00877 ast_clear_flag(cdr, AST_FLAGS_ALL); 00878 memset(&cdr->start, 0, sizeof(cdr->start)); 00879 memset(&cdr->end, 0, sizeof(cdr->end)); 00880 memset(&cdr->answer, 0, sizeof(cdr->answer)); 00881 cdr->billsec = 0; 00882 cdr->duration = 0; 00883 ast_cdr_start(cdr); 00884 cdr->disposition = AST_CDR_NULL; 00885 } 00886 00887 cdr = cdr->next; 00888 } 00889 }
| int ast_cdr_serialize_variables | ( | struct ast_cdr * | cdr, | |
| char * | buf, | |||
| size_t | size, | |||
| char | delim, | |||
| char | sep, | |||
| int | recur | |||
| ) |
Definition at line 349 of file cdr.c.
References ast_build_string(), ast_cdr_getvar(), AST_LIST_TRAVERSE, ast_log(), ast_strlen_zero(), ast_var_name(), ast_var_value(), LOG_ERROR, ast_cdr::next, total, var, and ast_cdr::varshead.
Referenced by handle_showchan().
00350 { 00351 struct ast_var_t *variables; 00352 char *var, *val; 00353 char *tmp; 00354 char workspace[256]; 00355 int total = 0, x = 0, i; 00356 const char *cdrcols[] = { 00357 "clid", 00358 "src", 00359 "dst", 00360 "dcontext", 00361 "channel", 00362 "dstchannel", 00363 "lastapp", 00364 "lastdata", 00365 "start", 00366 "answer", 00367 "end", 00368 "duration", 00369 "billsec", 00370 "disposition", 00371 "amaflags", 00372 "accountcode", 00373 "uniqueid", 00374 "userfield" 00375 }; 00376 00377 memset(buf, 0, size); 00378 00379 for (; cdr; cdr = recur ? cdr->next : NULL) { 00380 if (++x > 1) 00381 ast_build_string(&buf, &size, "\n"); 00382 00383 AST_LIST_TRAVERSE(&cdr->varshead, variables, entries) { 00384 if (variables && 00385 (var = ast_var_name(variables)) && (val = ast_var_value(variables)) && 00386 !ast_strlen_zero(var) && !ast_strlen_zero(val)) { 00387 if (ast_build_string(&buf, &size, "level %d: %s%c%s%c", x, var, delim, val, sep)) { 00388 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n"); 00389 break; 00390 } else 00391 total++; 00392 } else 00393 break; 00394 } 00395 00396 for (i = 0; i < (sizeof(cdrcols) / sizeof(cdrcols[0])); i++) { 00397 ast_cdr_getvar(cdr, cdrcols[i], &tmp, workspace, sizeof(workspace), 0); 00398 if (!tmp) 00399 continue; 00400 00401 if (ast_build_string(&buf, &size, "level %d: %s%c%s%c", x, cdrcols[i], delim, tmp, sep)) { 00402 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n"); 00403 break; 00404 } else 00405 total++; 00406 } 00407 } 00408 00409 return total; 00410 }
| int ast_cdr_setaccount | ( | struct ast_channel * | chan, | |
| const char * | account | |||
| ) |
Definition at line 718 of file cdr.c.
References ast_cdr::accountcode, ast_channel::accountcode, AST_CDR_FLAG_LOCKED, ast_test_flag, ast_channel::cdr, and ast_cdr::next.
Referenced by __ast_request_and_dial(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), auth_exec(), builtin_function_cdr_write(), and pbx_builtin_setaccount().
00719 { 00720 struct ast_cdr *cdr = chan->cdr; 00721 00722 ast_copy_string(chan->accountcode, account, sizeof(chan->accountcode)); 00723 while (cdr) { 00724 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) 00725 ast_copy_string(cdr->accountcode, chan->accountcode, sizeof(cdr->accountcode)); 00726 cdr = cdr->next; 00727 } 00728 return 0; 00729 }
| int ast_cdr_setamaflags | ( | struct ast_channel * | chan, | |
| const char * | flag | |||
| ) |
Definition at line 731 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 pbx_builtin_setamaflags().
00732 { 00733 struct ast_cdr *cdr; 00734 int newflag; 00735 00736 newflag = ast_cdr_amaflags2int(flag); 00737 if (newflag) { 00738 for (cdr = chan->cdr; cdr; cdr = cdr->next) { 00739 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) 00740 cdr->amaflags = newflag; 00741 } 00742 } 00743 00744 return 0; 00745 }
| void ast_cdr_setapp | ( | struct ast_cdr * | cdr, | |
| char * | app, | |||
| 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 587 of file cdr.c.
References AST_CDR_FLAG_LOCKED, AST_CDR_FLAG_POSTED, ast_log(), ast_strlen_zero(), ast_test_flag, ast_cdr::channel, ast_cdr::lastapp, ast_cdr::lastdata, LOG_WARNING, and ast_cdr::next.
Referenced by __ast_request_and_dial(), ast_feature_request_and_dial(), and pbx_exec().
00588 { 00589 char *chan; 00590 00591 while (cdr) { 00592 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) { 00593 chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>"; 00594 if (ast_test_flag(cdr, AST_CDR_FLAG_POSTED)) 00595 ast_log(LOG_WARNING, "CDR on channel '%s' already posted\n", chan); 00596 if (!app) 00597 app = ""; 00598 ast_copy_string(cdr->lastapp, app, sizeof(cdr->lastapp)); 00599 if (!data) 00600 data = ""; 00601 ast_copy_string(cdr->lastdata, data, sizeof(cdr->lastdata)); 00602 } 00603 cdr = cdr->next; 00604 } 00605 }
| 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 Return is negligible. (returns 0 by default) |
Definition at line 607 of file cdr.c.
References AST_CDR_FLAG_LOCKED, AST_MAX_EXTENSION, ast_test_flag, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_name, ast_callerid::cid_num, ast_cdr::clid, ast_cdr::next, and ast_cdr::src.
Referenced by ast_set_callerid().
00608 { 00609 char tmp[AST_MAX_EXTENSION] = ""; 00610 char *num; 00611 00612 while (cdr) { 00613 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) { 00614 /* Grab source from ANI or normal Caller*ID */ 00615 num = c->cid.cid_ani ? c->cid.cid_ani : c->cid.cid_num; 00616 00617 if (c->cid.cid_name && num) 00618 snprintf(tmp, sizeof(tmp), "\"%s\" <%s>", c->cid.cid_name, num); 00619 else if (c->cid.cid_name) 00620 ast_copy_string(tmp, c->cid.cid_name, sizeof(tmp)); 00621 else if (num) 00622 ast_copy_string(tmp, num, sizeof(tmp)); 00623 ast_copy_string(cdr->clid, tmp, sizeof(cdr->clid)); 00624 ast_copy_string(cdr->src, num ? num : "", sizeof(cdr->src)); 00625 } 00626 cdr = cdr->next; 00627 } 00628 00629 return 0; 00630 }
| void ast_cdr_setdestchan | ( | struct ast_cdr * | cdr, | |
| 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 573 of file cdr.c.
References AST_CDR_FLAG_LOCKED, AST_CDR_FLAG_POSTED, ast_log(), ast_strlen_zero(), ast_test_flag, ast_cdr::channel, ast_cdr::dstchannel, LOG_WARNING, and ast_cdr::next.
Referenced by ast_bridge_call_thread(), dial_exec_full(), and try_calling().
00574 { 00575 char *chan; 00576 00577 while (cdr) { 00578 chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>"; 00579 if (ast_test_flag(cdr, AST_CDR_FLAG_POSTED)) 00580 ast_log(LOG_WARNING, "CDR on channel '%s' already posted\n", chan); 00581 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) 00582 ast_copy_string(cdr->dstchannel, chann, sizeof(cdr->dstchannel)); 00583 cdr = cdr->next; 00584 } 00585 }
| int ast_cdr_setuserfield | ( | struct ast_channel * | chan, | |
| const char * | userfield | |||
| ) |
Definition at line 747 of file cdr.c.
References AST_CDR_FLAG_LOCKED, ast_test_flag, ast_channel::cdr, ast_cdr::next, and ast_cdr::userfield.
Referenced by __agent_start_monitoring(), action_setcdruserfield(), ast_bridge_call(), builtin_function_cdr_write(), handle_request_info(), setcdruserfield_exec(), and start_monitor_exec().
00748 { 00749 struct ast_cdr *cdr = chan->cdr; 00750 00751 while (cdr) { 00752 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) 00753 ast_copy_string(cdr->userfield, userfield, sizeof(cdr->userfield)); 00754 cdr = cdr->next; 00755 } 00756 00757 return 0; 00758 }
| int ast_cdr_setvar | ( | struct ast_cdr * | cdr, | |
| const char * | name, | |||
| const char * | value, | |||
| int | recur | |||
| ) |
Set a CDR channel variable
Definition at line 277 of file cdr.c.
References AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), ast_var_assign(), ast_var_delete(), ast_var_name(), LOG_ERROR, ast_cdr::next, and ast_cdr::varshead.
Referenced by builtin_function_cdr_write().
00278 { 00279 struct ast_var_t *newvariable; 00280 struct varshead *headp; 00281 const char *read_only[] = { "clid", "src", "dst", "dcontext", "channel", "dstchannel", 00282 "lastapp", "lastdata", "start", "answer", "end", "duration", 00283 "billsec", "disposition", "amaflags", "accountcode", "uniqueid", 00284 "userfield", NULL }; 00285 int x; 00286 00287 for(x = 0; read_only[x]; x++) { 00288 if (!strcasecmp(name, read_only[x])) { 00289 ast_log(LOG_ERROR, "Attempt to set a read-only variable!.\n"); 00290 return -1; 00291 } 00292 } 00293 00294 if (!cdr) { 00295 ast_log(LOG_ERROR, "Attempt to set a variable on a nonexistent CDR record.\n"); 00296 return -1; 00297 } 00298 00299 while (cdr) { 00300 headp = &cdr->varshead; 00301 AST_LIST_TRAVERSE_SAFE_BEGIN(headp, newvariable, entries) { 00302 if (!strcasecmp(ast_var_name(newvariable), name)) { 00303 /* there is already such a variable, delete it */ 00304 AST_LIST_REMOVE_CURRENT(headp, entries); 00305 ast_var_delete(newvariable); 00306 break; 00307 } 00308 } 00309 AST_LIST_TRAVERSE_SAFE_END; 00310 00311 if (value) { 00312 newvariable = ast_var_assign(name, value); 00313 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 00314 } 00315 00316 if (!recur) { 00317 break; 00318 } 00319 00320 cdr = cdr->next; 00321 } 00322 00323 return 0; 00324 }
| void ast_cdr_start | ( | struct ast_cdr * | cdr | ) |
Start a call
| cdr | the cdr you wish to associate with the call Starts all CDR stuff necessary for monitoring a call Returns nothing important |
Definition at line 466 of file cdr.c.
References AST_CDR_FLAG_LOCKED, AST_CDR_FLAG_POSTED, ast_log(), ast_strlen_zero(), ast_test_flag, ast_cdr::channel, LOG_WARNING, ast_cdr::next, and ast_cdr::start.
Referenced by __ast_pbx_run(), __ast_request_and_dial(), ast_cdr_reset(), ast_feature_request_and_dial(), ast_pbx_outgoing_app(), ast_pbx_outgoing_cdr_failed(), and ast_pbx_outgoing_exten().
00467 { 00468 char *chan; 00469 00470 while (cdr) { 00471 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) { 00472 chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>"; 00473 if (ast_test_flag(cdr, AST_CDR_FLAG_POSTED)) 00474 ast_log(LOG_WARNING, "CDR on channel '%s' already posted\n", chan); 00475 if (!ast_tvzero(cdr->start)) 00476 ast_log(LOG_WARNING, "CDR on channel '%s' already started\n", chan); 00477 cdr->start = ast_tvnow(); 00478 } 00479 cdr = cdr->next; 00480 } 00481 }
| void ast_cdr_submit_batch | ( | int | shutdown | ) |
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 948 of file cdr.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create, 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().
00949 { 00950 struct ast_cdr_batch_item *oldbatchitems = NULL; 00951 pthread_attr_t attr; 00952 pthread_t batch_post_thread = AST_PTHREADT_NULL; 00953 00954 /* if there's no batch, or no CDRs in the batch, then there's nothing to do */ 00955 if (!batch || !batch->head) 00956 return; 00957 00958 /* move the old CDRs aside, and prepare a new CDR batch */ 00959 ast_mutex_lock(&cdr_batch_lock); 00960 oldbatchitems = batch->head; 00961 reset_batch(); 00962 ast_mutex_unlock(&cdr_batch_lock); 00963 00964 /* if configured, spawn a new thread to post these CDRs, 00965 also try to save as much as possible if we are shutting down safely */ 00966 if (batchscheduleronly || shutdown) { 00967 if (option_debug) 00968 ast_log(LOG_DEBUG, "CDR single-threaded batch processing begins now\n"); 00969 do_batch_backend_process(oldbatchitems); 00970 } else { 00971 pthread_attr_init(&attr); 00972 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 00973 if (ast_pthread_create(&batch_post_thread, &attr, do_batch_backend_process, oldbatchitems)) { 00974 ast_log(LOG_WARNING, "CDR processing thread could not detach, now trying in this thread\n"); 00975 do_batch_backend_process(oldbatchitems); 00976 } else { 00977 if (option_debug) 00978 ast_log(LOG_DEBUG, "CDR multi-threaded batch processing begins now\n"); 00979 } 00980 pthread_attr_destroy(&attr); 00981 } 00982 }
| void ast_cdr_unregister | ( | char * | name | ) |
unregister a CDR driver
Definition at line 146 of file cdr.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_verbose(), free, list, ast_cdr_beitem::name, option_verbose, and VERBOSE_PREFIX_2.
Referenced by my_unload_module(), odbc_unload_module(), tds_unload_module(), and unload_module().
00147 { 00148 struct ast_cdr_beitem *i = NULL; 00149 00150 AST_LIST_LOCK(&be_list); 00151 AST_LIST_TRAVERSE_SAFE_BEGIN(&be_list, i, list) { 00152 if (!strcasecmp(name, i->name)) { 00153 AST_LIST_REMOVE_CURRENT(&be_list, list); 00154 if (option_verbose > 1) 00155 ast_verbose(VERBOSE_PREFIX_2 "Unregistered '%s' CDR backend\n", name); 00156 free(i); 00157 break; 00158 } 00159 } 00160 AST_LIST_TRAVERSE_SAFE_END; 00161 AST_LIST_UNLOCK(&be_list); 00162 }
| int ast_cdr_update | ( | struct ast_channel * | c | ) |
Definition at line 776 of file cdr.c.
References ast_channel::accountcode, ast_cdr::accountcode, AST_CDR_FLAG_LOCKED, ast_check_hangup(), AST_MAX_EXTENSION, ast_strlen_zero(), ast_test_flag, ast_channel::cdr, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_name, ast_callerid::cid_num, ast_cdr::clid, ast_channel::context, ast_cdr::dcontext, ast_cdr::dst, ast_channel::exten, ast_channel::macrocontext, ast_channel::macroexten, ast_cdr::next, and ast_cdr::src.
Referenced by __ast_pbx_run(), __ast_request_and_dial(), ast_feature_request_and_dial(), ast_parseable_goto(), and cb_events().
00777 { 00778 struct ast_cdr *cdr = c->cdr; 00779 char *num; 00780 char tmp[AST_MAX_EXTENSION] = ""; 00781 00782 while (cdr) { 00783 if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) { 00784 num = c->cid.cid_ani ? c->cid.cid_ani : c->cid.cid_num; 00785 00786 if (c->cid.cid_name && num) 00787 snprintf(tmp, sizeof(tmp), "\"%s\" <%s>", c->cid.cid_name, num); 00788 else if (c->cid.cid_name) 00789 ast_copy_string(tmp, c->cid.cid_name, sizeof(tmp)); 00790 else if (num) 00791 ast_copy_string(tmp, num, sizeof(tmp)); 00792 ast_copy_string(cdr->clid, tmp, sizeof(cdr->clid)); 00793 ast_copy_string(cdr->src, num ? num : "", sizeof(cdr->src)); 00794 00795 /* Copy account code et-al */ 00796 ast_copy_string(cdr->accountcode, c->accountcode, sizeof(cdr->accountcode)); 00797 if (!ast_check_hangup(c)) { 00798 /* Destination information */ /* XXX privilege macro* ? */ 00799 ast_copy_string(cdr->dst, (ast_strlen_zero(c->macroexten)) ? c->exten : c->macroexten, sizeof(cdr->dst)); 00800 ast_copy_string(cdr->dcontext, (ast_strlen_zero(c->macrocontext)) ? c->context : c->macrocontext, sizeof(cdr->dcontext)); 00801 } 00802 } 00803 cdr = cdr->next; 00804 } 00805 00806 return 0; 00807 }
| static AST_LIST_HEAD_STATIC | ( | be_list | , | |
| ast_cdr_beitem | ||||
| ) | [static] |
| AST_MUTEX_DEFINE_STATIC | ( | cdr_pending_lock | ) |
| AST_MUTEX_DEFINE_STATIC | ( | cdr_batch_lock | ) |
| static void* do_batch_backend_process | ( | void * | data | ) | [static] |
Definition at line 931 of file cdr.c.
References ast_cdr_free(), ast_cdr_batch_item::cdr, free, ast_cdr_batch_item::next, and post_cdr().
Referenced by ast_cdr_submit_batch().
00932 { 00933 struct ast_cdr_batch_item *processeditem; 00934 struct ast_cdr_batch_item *batchitem = data; 00935 00936 /* Push each CDR into storage mechanism(s) and free all the memory */ 00937 while (batchitem) { 00938 post_cdr(batchitem->cdr); 00939 ast_cdr_free(batchitem->cdr); 00940 processeditem = batchitem; 00941 batchitem = batchitem->next; 00942 free(processeditem); 00943 } 00944 00945 return NULL; 00946 }
| static void* do_cdr | ( | void * | data | ) | [static] |
Definition at line 1062 of file cdr.c.
References ast_cond_timedwait(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_runq(), ast_sched_wait(), ast_tvadd(), cdr_pending_cond, LOG_DEBUG, and option_debug.
Referenced by do_reload().
01063 { 01064 struct timespec timeout; 01065 int schedms; 01066 int numevents = 0; 01067 01068 for(;;) { 01069 struct timeval now; 01070 schedms = ast_sched_wait(sched); 01071 /* this shouldn't happen, but provide a 1 second default just in case */ 01072 if (schedms <= 0) 01073 schedms = 1000; 01074 now = ast_tvadd(ast_tvnow(), ast_samp2tv(schedms, 1000)); 01075 timeout.tv_sec = now.tv_sec; 01076 timeout.tv_nsec = now.tv_usec * 1000; 01077 /* prevent stuff from clobbering cdr_pending_cond, then wait on signals sent to it until the timeout expires */ 01078 ast_mutex_lock(&cdr_pending_lock); 01079 ast_cond_timedwait(&cdr_pending_cond, &cdr_pending_lock, &timeout); 01080 numevents = ast_sched_runq(sched); 01081 ast_mutex_unlock(&cdr_pending_lock); 01082 if (option_debug > 1) 01083 ast_log(LOG_DEBUG, "Processed %d scheduled CDR batches from the run queue\n", numevents); 01084 } 01085 01086 return NULL; 01087 }
| static int do_reload | ( | void | ) | [static] |
Definition at line 1152 of file cdr.c.
References ast_cdr_engine_term(), ast_cli_register(), ast_cli_unregister(), ast_cond_destroy(), ast_cond_init(), ast_config_destroy(), ast_config_load(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create, AST_PTHREADT_NULL, ast_register_atexit(), ast_sched_add(), ast_sched_del(), ast_true(), ast_unregister_atexit(), ast_variable_retrieve(), BATCH_SAFE_SHUTDOWN_DEFAULT, BATCH_SCHEDULER_ONLY_DEFAULT, BATCH_SIZE_DEFAULT, BATCH_TIME_DEFAULT, batchmode, batchsafeshutdown, batchscheduleronly, batchsize, batchtime, cdr_pending_cond, cdr_sched, cdr_thread, cli_submit, config, do_cdr(), enabled, LOG_ERROR, LOG_NOTICE, LOG_WARNING, and submit_scheduled_batch().
Referenced by ast_cdr_engine_init(), ast_cdr_engine_reload(), dnsmgr_init(), dnsmgr_reload(), and handle_cli_reload().
01153 { 01154 struct ast_config *config; 01155 const char *enabled_value; 01156 const char *batched_value; 01157 const char *scheduleronly_value; 01158 const char *batchsafeshutdown_value; 01159 const char *size_value; 01160 const char *time_value; 01161 int cfg_size; 01162 int cfg_time; 01163 int was_enabled; 01164 int was_batchmode; 01165 int res=0; 01166 01167 ast_mutex_lock(&cdr_batch_lock); 01168 01169 batchsize = BATCH_SIZE_DEFAULT; 01170 batchtime = BATCH_TIME_DEFAULT; 01171 batchscheduleronly = BATCH_SCHEDULER_ONLY_DEFAULT; 01172 batchsafeshutdown = BATCH_SAFE_SHUTDOWN_DEFAULT; 01173 was_enabled = enabled; 01174 was_batchmode = batchmode; 01175 enabled = 1; 01176 batchmode = 0; 01177 01178 /* don't run the next scheduled CDR posting while reloading */ 01179 if (cdr_sched > -1) 01180 ast_sched_del(sched, cdr_sched); 01181 01182 if ((config = ast_config_load("cdr.conf"))) { 01183 if ((enabled_value = ast_variable_retrieve(config, "general", "enable"))) { 01184 enabled = ast_true(enabled_value); 01185 } 01186 if ((batched_value = ast_variable_retrieve(config, "general", "batch"))) { 01187 batchmode = ast_true(batched_value); 01188 } 01189 if ((scheduleronly_value = ast_variable_retrieve(config, "general", "scheduleronly"))) { 01190 batchscheduleronly = ast_true(scheduleronly_value); 01191 } 01192 if ((batchsafeshutdown_value = ast_variable_retrieve(config, "general", "safeshutdown"))) { 01193 batchsafeshutdown = ast_true(batchsafeshutdown_value); 01194 } 01195 if ((size_value = ast_variable_retrieve(config, "general", "size"))) { 01196 if (sscanf(size_value, "%30d", &cfg_size) < 1) 01197 ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", size_value); 01198 else if (size_value < 0) 01199 ast_log(LOG_WARNING, "Invalid maximum batch size '%d' specified, using default\n", cfg_size); 01200 else 01201 batchsize = cfg_size; 01202 } 01203 if ((time_value = ast_variable_retrieve(config, "general", "time"))) { 01204 if (sscanf(time_value, "%30d", &cfg_time) < 1) 01205 ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", time_value); 01206 else if (time_value < 0) 01207 ast_log(LOG_WARNING, "Invalid maximum batch time '%d' specified, using default\n", cfg_time); 01208 else 01209 batchtime = cfg_time; 01210 } 01211 } 01212 01213 if (enabled && !batchmode) { 01214 ast_log(LOG_NOTICE, "CDR simple logging enabled.\n"); 01215 } else if (enabled && batchmode) { 01216 cdr_sched = ast_sched_add(sched, batchtime * 1000, submit_scheduled_batch, NULL); 01217 ast_log(LOG_NOTICE, "CDR batch mode logging enabled, first of either size %d or time %d seconds.\n", batchsize, batchtime); 01218 } else { 01219 ast_log(LOG_NOTICE, "CDR logging disabled, data will be lost.\n"); 01220 } 01221 01222 /* if this reload enabled the CDR batch mode, create the background thread 01223 if it does not exist */ 01224 if (enabled && batchmode && (!was_enabled || !was_batchmode) && (cdr_thread == AST_PTHREADT_NULL)) { 01225 ast_cond_init(&cdr_pending_cond, NULL); 01226 if (ast_pthread_create(&cdr_thread, NULL, do_cdr, NULL) < 0) { 01227 ast_log(LOG_ERROR, "Unable to start CDR thread.\n"); 01228 ast_sched_del(sched, cdr_sched); 01229 } else { 01230 ast_cli_register(&cli_submit); 01231 ast_register_atexit(ast_cdr_engine_term); 01232 res = 0; 01233 } 01234 /* if this reload disabled the CDR and/or batch mode and there is a background thread, 01235 kill it */ 01236 } else if (((!enabled && was_enabled) || (!batchmode && was_batchmode)) && (cdr_thread != AST_PTHREADT_NULL)) { 01237 /* wake up the thread so it will exit */ 01238 pthread_cancel(cdr_thread); 01239 pthread_kill(cdr_thread, SIGURG); 01240 pthread_join(cdr_thread, NULL); 01241 cdr_thread = AST_PTHREADT_NULL; 01242 ast_cond_destroy(&cdr_pending_cond); 01243 ast_cli_unregister(&cli_submit); 01244 ast_unregister_atexit(ast_cdr_engine_term); 01245 res = 0; 01246 /* if leaving batch mode, then post the CDRs in the batch, 01247 and don't reschedule, since we are stopping CDR logging */ 01248 if (!batchmode && was_batchmode) { 01249 ast_cdr_engine_term(); 01250 } 01251 } else { 01252 res = 0; 01253 } 01254 01255 ast_mutex_unlock(&cdr_batch_lock); 01256 ast_config_destroy(config); 01257 01258 return res; 01259 }
| static int handle_cli_status | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 1089 of file cdr.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_sched_when(), batch, batchmode, batchsafeshutdown, batchscheduleronly, batchsize, batchtime, cdr_sched, enabled, list, ast_cdr_beitem::name, RESULT_SHOWUSAGE, and ast_cdr_batch::size.
01090 { 01091 struct ast_cdr_beitem *beitem=NULL; 01092 int cnt=0; 01093 long nextbatchtime=0; 01094 01095 if (argc > 2) 01096 return RESULT_SHOWUSAGE; 01097 01098 ast_cli(fd, "CDR logging: %s\n", enabled ? "enabled" : "disabled"); 01099 ast_cli(fd, "CDR mode: %s\n", batchmode ? "batch" : "simple"); 01100 if (enabled) { 01101 if (batchmode) { 01102 if (batch) 01103 cnt = batch->size; 01104 if (cdr_sched > -1) 01105 nextbatchtime = ast_sched_when(sched, cdr_sched); 01106 ast_cli(fd, "CDR safe shut down: %s\n", batchsafeshutdown ? "enabled" : "disabled"); 01107 ast_cli(fd, "CDR batch threading model: %s\n", batchscheduleronly ? "scheduler only" : "scheduler plus separate threads"); 01108 ast_cli(fd, "CDR current batch size: %d record%s\n", cnt, (cnt != 1) ? "s" : ""); 01109 ast_cli(fd, "CDR maximum batch size: %d record%s\n", batchsize, (batchsize != 1) ? "s" : ""); 01110 ast_cli(fd, "CDR maximum batch time: %d second%s\n", batchtime, (batchtime != 1) ? "s" : ""); 01111 ast_cli(fd, "CDR next scheduled batch processing time: %ld second%s\n", nextbatchtime, (nextbatchtime != 1) ? "s" : ""); 01112 } 01113 AST_LIST_LOCK(&be_list); 01114 AST_LIST_TRAVERSE(&be_list, beitem, list) { 01115 ast_cli(fd, "CDR registered backend: %s\n", beitem->name); 01116 } 01117 AST_LIST_UNLOCK(&be_list); 01118 } 01119 01120 return 0; 01121 }
| static int handle_cli_submit | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 1123 of file cdr.c.
References ast_cli(), RESULT_SHOWUSAGE, and submit_unscheduled_batch().
01124 { 01125 if (argc > 2) 01126 return RESULT_SHOWUSAGE; 01127 01128 submit_unscheduled_batch(); 01129 ast_cli(fd, "Submitted CDRs to backend engines for processing. This may take a while.\n"); 01130 01131 return 0; 01132 }
| static int init_batch | ( | void | ) | [static] |
Definition at line 917 of file cdr.c.
References ast_log(), batch, LOG_WARNING, malloc, and reset_batch().
Referenced by ast_cdr_detach(), and ast_cdr_engine_init().
00918 { 00919 /* This is the single meta-batch used to keep track of all CDRs during the entire life of the program */ 00920 batch = malloc(sizeof(*batch)); 00921 if (!batch) { 00922 ast_log(LOG_WARNING, "CDR: out of memory while trying to handle batched records, data will most likely be lost\n"); 00923 return -1; 00924 } 00925 00926 reset_batch(); 00927 00928 return 0; 00929 }
| static void post_cdr | ( | struct ast_cdr * | cdr | ) | [static] |
Definition at line 822 of file cdr.c.
References ast_cdr::answer, AST_CDR_FAILED, AST_CDR_FLAG_POSTED, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_set_flag, ast_strlen_zero(), ast_test_flag, ast_cdr_beitem::be, ast_cdr::billsec, ast_cdr::channel, ast_cdr::disposition, ast_cdr::duration, ast_cdr::end, list, LOG_NOTICE, ast_cdr::next, and ast_cdr::start.
Referenced by ast_cdr_detach(), and do_batch_backend_process().
00823 { 00824 char *chan; 00825 struct ast_cdr_beitem *i; 00826 00827 while (cdr) { 00828 chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>"; 00829 if (ast_test_flag(cdr, AST_CDR_FLAG_POSTED)) 00830 ast_log(LOG_NOTICE, "CDR on channel '%s' already posted\n", chan); 00831 if (ast_tvzero(cdr->end)) 00832 ast_log(LOG_NOTICE, "CDR on channel '%s' lacks end\n", chan); 00833 if (ast_tvzero(cdr->start)) { 00834 ast_log(LOG_NOTICE, "CDR on channel '%s' lacks start\n", chan); 00835 cdr->disposition = AST_CDR_FAILED; 00836 } else 00837 cdr->duration = cdr->end.tv_sec - cdr->start.tv_sec; 00838 if (!ast_tvzero(cdr->answer)) 00839 cdr->billsec = cdr->end.tv_sec - cdr->answer.tv_sec; 00840 else 00841 cdr->billsec = 0; 00842 ast_set_flag(cdr, AST_CDR_FLAG_POSTED); 00843 AST_LIST_LOCK(&be_list); 00844 AST_LIST_TRAVERSE(&be_list, i, list) { 00845 i->be(cdr); 00846 } 00847 AST_LIST_UNLOCK(&be_list); 00848 cdr = cdr->next; 00849 } 00850 }
| static void reset_batch | ( | void | ) | [static] |
Definition at line 909 of file cdr.c.
References batch, ast_cdr_batch::head, ast_cdr_batch::size, and ast_cdr_batch::tail.
Referenced by ast_cdr_submit_batch(), and init_batch().
| static int submit_scheduled_batch | ( | void * | data | ) | [static] |
Definition at line 984 of file cdr.c.
References ast_cdr_submit_batch(), ast_sched_add(), batchtime, and cdr_sched.
Referenced by do_reload(), and submit_unscheduled_batch().
00985 { 00986 ast_cdr_submit_batch(0); 00987 /* manually reschedule from this point in time */ 00988 cdr_sched = ast_sched_add(sched, batchtime * 1000, submit_scheduled_batch, NULL); 00989 /* returning zero so the scheduler does not automatically reschedule */ 00990 return 0; 00991 }
| static void submit_unscheduled_batch | ( | void | ) | [static] |
Definition at line 993 of file cdr.c.
References ast_cond_signal(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_sched_del(), cdr_pending_cond, cdr_sched, and submit_scheduled_batch().
Referenced by ast_cdr_detach(), and handle_cli_submit().
00994 { 00995 /* this is okay since we are not being called from within the scheduler */ 00996 if (cdr_sched > -1) 00997 ast_sched_del(sched, cdr_sched); 00998 /* schedule the submission to occur ASAP (1 ms) */ 00999 cdr_sched = ast_sched_add(sched, 1, submit_scheduled_batch, NULL); 01000 /* signal the do_cdr thread to wakeup early and do some work (that lazy thread ;) */ 01001 ast_mutex_lock(&cdr_pending_lock); 01002 ast_cond_signal(&cdr_pending_cond); 01003 ast_mutex_unlock(&cdr_pending_lock); 01004 }
| char ast_default_accountcode[AST_MAX_ACCOUNT_CODE] = "" |
| int ast_default_amaflags = AST_CDR_DOCUMENTATION |
Default AMA flag for billing records (CDR's)
Definition at line 57 of file cdr.c.
Referenced by ast_channel_alloc().
struct ast_cdr_batch * batch [static] |
Referenced by ast_cdr_detach(), ast_cdr_submit_batch(), handle_cli_status(), init_batch(), and reset_batch().
int batchmode [static] |
Definition at line 90 of file cdr.c.
Referenced by ast_cdr_detach(), do_reload(), and handle_cli_status().
int batchsafeshutdown [static] |
Definition at line 94 of file cdr.c.
Referenced by ast_cdr_engine_term(), do_reload(), and handle_cli_status().
int batchscheduleronly [static] |
Definition at line 93 of file cdr.c.
Referenced by ast_cdr_submit_batch(), do_reload(), and handle_cli_status().
int batchsize [static] |
Definition at line 91 of file cdr.c.
Referenced by ast_cdr_detach(), do_reload(), and handle_cli_status().
int batchtime [static] |
Definition at line 92 of file cdr.c.
Referenced by do_reload(), handle_cli_status(), and submit_scheduled_batch().
ast_cond_t cdr_pending_cond [static] |
Definition at line 100 of file cdr.c.
Referenced by do_cdr(), do_reload(), and submit_unscheduled_batch().
int cdr_sched = -1 [static] |
Definition at line 81 of file cdr.c.
Referenced by do_reload(), handle_cli_status(), submit_scheduled_batch(), and submit_unscheduled_batch().
pthread_t cdr_thread = AST_PTHREADT_NULL [static] |
struct ast_cli_entry cli_status [static] |
struct ast_cli_entry cli_submit [static] |
int enabled [static] |
Definition at line 89 of file cdr.c.
Referenced by ast_cdr_detach(), ast_dnsmgr_lookup(), do_reload(), handle_cli_status(), and load_odbc_config().
struct sched_context* sched [static] |
1.5.6