189 #define DEFAULT_ENABLED "1" 190 #define DEFAULT_BATCHMODE "0" 191 #define DEFAULT_UNANSWERED "0" 192 #define DEFAULT_CONGESTION "0" 193 #define DEFAULT_END_BEFORE_H_EXTEN "1" 194 #define DEFAULT_INITIATED_SECONDS "0" 196 #define DEFAULT_BATCH_SIZE "100" 197 #define MAX_BATCH_SIZE 1000 198 #define DEFAULT_BATCH_TIME "300" 199 #define MAX_BATCH_TIME 86400 200 #define DEFAULT_BATCH_SCHEDULER_ONLY "0" 201 #define DEFAULT_BATCH_SAFE_SHUTDOWN "1" 203 #define cdr_set_debug_mode(mod_cfg) \ 205 cdr_debug_enabled = ast_test_flag(&(mod_cfg)->general->settings, CDR_DEBUG); \ 210 #define CDR_DEBUG(fmt, ...) \ 212 if (cdr_debug_enabled) { \ 213 ast_verbose((fmt), ##__VA_ARGS__); \ 234 .category =
"general",
266 .types =
ACO_TYPES(&general_option, &ignore_option),
483 const char *dial_status);
519 int (*
const process_parking_bridge_enter)(
struct cdr_object *cdr,
638 .
name =
"DialedPending",
718 struct timeval start;
721 struct timeval lastevent;
806 CDR_DEBUG(
"%p - Transitioning CDR for %s from state %s to %s\n",
858 const char *right_key = arg;
866 cmp = strcmp(left->
uniqueid, right_key);
873 cmp = strncmp(left->
uniqueid, right_key, strlen(right_key));
916 const char *right_key = arg;
931 cmp = strncasecmp(left->
party_b_name, right_key, strlen(right_key));
982 for (cur = cdr; cur; cur =
next) {
1081 cdr_last = cdr->
last;
1107 for (it_cdr = cdr; it_cdr->
next; it_cdr = it_cdr->
next) {
1108 it_cdr->
last = new_cdr;
1110 it_cdr->
last = new_cdr;
1111 it_cdr->
next = new_cdr;
1162 && strncasecmp(new_snapshot->
dialplan->
appl,
"appdial", 7)
1244 if (ms % 1000 >= 500
1246 ms = (ms / 1000) + 1;
1295 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->
next) {
1300 ast_debug(1,
"CDR for %s is dialed and has no Party B; discarding\n",
1342 cdr_copy->
end = it_cdr->
end;
1372 cdr_prev->
next = cdr_copy;
1373 cdr_prev = cdr_copy;
1390 CDR_DEBUG(
"%p - Dispatching CDR for Party A %s, Party B %s\n", cdr,
1405 switch (hangupcause) {
1460 ast_debug(1,
"Finalized CDR for %s - start %ld.%06ld answer %ld.%06ld end %ld.%06ld dur %.3f bill %.3f dispo %s\n",
1462 (
long)cdr->
start.tv_sec,
1463 (
long)cdr->
start.tv_usec,
1464 (
long)cdr->
answer.tv_sec,
1465 (
long)cdr->
answer.tv_usec,
1466 (
long)cdr->
end.tv_sec,
1467 (
long)cdr->
end.tv_usec,
1485 && cdr->
fn_table != &finalized_state_fn_table) {
1499 CDR_DEBUG(
"%p - Set answered time to %ld.%06ld\n", cdr,
1500 (
long)cdr->
answer.tv_sec,
1501 (
long)cdr->
answer.tv_usec);
1619 char park_info[128];
1657 CDR_DEBUG(
"%p - Updated Party A %s snapshot\n", cdr,
1661 CDR_DEBUG(
"%p - Updated Party B %s snapshot\n", cdr,
1672 CDR_DEBUG(
"%p - Updated Party A %s snapshot\n", cdr,
1705 CDR_DEBUG(
"%p - Party A %s has new Party B %s\n",
1726 CDR_DEBUG(
"%p - Party A %s has new Party B %s\n",
1757 if (!cand_cdr_master) {
1762 for (cand_cdr = cand_cdr_master; cand_cdr; cand_cdr = cand_cdr->
next) {
1765 if (cand_cdr->
fn_table != &bridge_state_fn_table ||
1830 if (!strcmp(dial_status,
"ANSWER")) {
1832 }
else if (!strcmp(dial_status,
"BUSY")) {
1834 }
else if (!strcmp(dial_status,
"CANCEL") || !strcmp(dial_status,
"NOANSWER")) {
1836 }
else if (!strcmp(dial_status,
"CONGESTION")) {
1842 }
else if (!strcmp(dial_status,
"FAILED")) {
1905 if (!cand_cdr_master) {
1910 for (cand_cdr = cand_cdr_master; cand_cdr; cand_cdr = cand_cdr->
next) {
1913 if (cand_cdr->
fn_table != &bridge_state_fn_table
2091 return (strcmp(dialstatus,
"RINGING") &&
2092 strcmp(dialstatus,
"PROCEEDING") &&
2093 strcmp(dialstatus,
"PROGRESS"));
2113 const char *dial_status =
NULL;
2118 if (!peer && !caller) {
2131 if (dial_status_blob) {
2135 CDR_DEBUG(
"Dial %s message for %s, %s: %u.%08u\n",
2137 caller ? caller->
base->
name :
"(none)",
2138 peer ? peer->
base->
name :
"(none)",
2155 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->
next) {
2161 CDR_DEBUG(
"%p - Processing Dial Begin message for channel %s, peer %s\n",
2163 caller ? caller->
base->
name :
"(none)",
2164 peer ? peer->
base->
name :
"(none)");
2172 CDR_DEBUG(
"%p - Processing Dial End message for channel %s, peer %s\n",
2174 caller ? caller->
base->
name :
"(none)",
2175 peer ? peer->
base->
name :
"(none)");
2236 "CDR for Party A %s(%s) has inconsistent Party B %s name. Message can be ignored but this shouldn't happen.\n",
2307 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->
next) {
2329 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->
next) {
2366 if (cdr->
fn_table == &bridge_state_fn_table
2391 if (!strcmp(bridge->
technology,
"holding_bridge") && strcmp(bridge->
subclass,
"parking")) {
2417 int left_bridge = 0;
2427 CDR_DEBUG(
"Bridge Leave message for %s: %u.%08u\n",
2429 (
unsigned int)leave_data.
lastevent->tv_sec,
2430 (
unsigned int)leave_data.
lastevent->tv_usec);
2441 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->
next) {
2446 CDR_DEBUG(
"%p - Processing Bridge Leave for %s\n",
2457 && strcmp(bridge->
subclass,
"parking")) {
2486 CDR_DEBUG(
"%p - Party A %s has new Party B %s\n",
2510 for (cand_cdr = base_cand_cdr; cand_cdr; cand_cdr = cand_cdr->
next) {
2537 CDR_DEBUG(
"%p - Party A %s has new Party B %s\n",
2546 memset(&cand_cdr->
end, 0,
sizeof(cand_cdr->
end));
2589 const struct timeval *event_time)
2597 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->
next) {
2604 CDR_DEBUG(
"%p - Updating Party A %s snapshot\n", it_cdr,
2630 const struct timeval *event_time)
2640 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->
next) {
2644 CDR_DEBUG(
"%p - Updating Party A %s snapshot\n", it_cdr,
2651 CDR_DEBUG(
"%p - Processing bridge enter for %s\n", it_cdr,
2659 handled_cdr = it_cdr;
2670 handled_cdr = it_cdr;
2724 CDR_DEBUG(
"Bridge Enter message for channel %s: %u.%08u\n",
2736 if (!strcmp(bridge->
subclass,
"parking")) {
2774 CDR_DEBUG(
"Parked Call message for channel %s: %u.%08u\n",
2788 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->
next) {
2873 if (!strcasecmp(name, i->
name)) {
2891 if (!strcasecmp(name, i->
name)) {
2928 if (!strcasecmp(name, cur->
name)) {
2960 if (!strcasecmp(name, match->
name)) {
2972 if (!match->suspended && active_count != 0) {
2975 name, active_count);
2982 ast_verb(2,
"Unregistered '%s' CDR backend\n", name);
3035 static void cdr_get_tv(
struct timeval when,
const char *fmt,
char *
buf,
int bufsize)
3038 snprintf(buf, bufsize,
"%ld.%06ld", (
long)when.tv_sec, (
long)when.tv_usec);
3052 const char *fmt =
"%Y-%m-%d %T";
3061 if (!strcasecmp(name,
"clid")) {
3063 }
else if (!strcasecmp(name,
"src")) {
3065 }
else if (!strcasecmp(name,
"dst")) {
3067 }
else if (!strcasecmp(name,
"dcontext")) {
3069 }
else if (!strcasecmp(name,
"channel")) {
3071 }
else if (!strcasecmp(name,
"dstchannel")) {
3073 }
else if (!strcasecmp(name,
"lastapp")) {
3075 }
else if (!strcasecmp(name,
"lastdata")) {
3077 }
else if (!strcasecmp(name,
"start")) {
3079 }
else if (!strcasecmp(name,
"answer")) {
3081 }
else if (!strcasecmp(name,
"end")) {
3083 }
else if (!strcasecmp(name,
"duration")) {
3085 }
else if (!strcasecmp(name,
"billsec")) {
3087 }
else if (!strcasecmp(name,
"disposition")) {
3089 snprintf(workspace, workspacelen,
"%ld", cdr->
disposition);
3093 }
else if (!strcasecmp(name,
"amaflags")) {
3095 snprintf(workspace, workspacelen,
"%ld", cdr->
amaflags);
3099 }
else if (!strcasecmp(name,
"accountcode")) {
3101 }
else if (!strcasecmp(name,
"peeraccount")) {
3103 }
else if (!strcasecmp(name,
"uniqueid")) {
3105 }
else if (!strcasecmp(name,
"linkedid")) {
3107 }
else if (!strcasecmp(name,
"userfield")) {
3109 }
else if (!strcasecmp(name,
"sequence")) {
3110 snprintf(workspace, workspacelen,
"%d", cdr->
sequence);
3114 workspace[0] =
'\0';
3129 const char *
name = arg;
3145 const char *
name = arg;
3186 for (x = 0; cdr_readonly_vars[x]; x++) {
3187 if (!strcasecmp(name, cdr_readonly_vars[x])) {
3201 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->
next) {
3204 if (it_cdr->
fn_table == &finalized_state_fn_table && it_cdr->
next !=
NULL) {
3248 if (!strcasecmp(name,
"clid")) {
3250 }
else if (!strcasecmp(name,
"src")) {
3252 }
else if (!strcasecmp(name,
"dst")) {
3254 }
else if (!strcasecmp(name,
"dcontext")) {
3256 }
else if (!strcasecmp(name,
"channel")) {
3258 }
else if (!strcasecmp(name,
"dstchannel")) {
3264 }
else if (!strcasecmp(name,
"lastapp")) {
3266 }
else if (!strcasecmp(name,
"lastdata")) {
3268 }
else if (!strcasecmp(name,
"start")) {
3270 }
else if (!strcasecmp(name,
"answer")) {
3272 }
else if (!strcasecmp(name,
"end")) {
3274 }
else if (!strcasecmp(name,
"duration")) {
3276 }
else if (!strcasecmp(name,
"billsec")) {
3278 }
else if (!strcasecmp(name,
"disposition")) {
3279 snprintf(value, length,
"%u", cdr_obj->
disposition);
3280 }
else if (!strcasecmp(name,
"amaflags")) {
3281 snprintf(value, length,
"%d", party_a->
amaflags);
3282 }
else if (!strcasecmp(name,
"accountcode")) {
3284 }
else if (!strcasecmp(name,
"peeraccount")) {
3290 }
else if (!strcasecmp(name,
"uniqueid")) {
3292 }
else if (!strcasecmp(name,
"linkedid")) {
3294 }
else if (!strcasecmp(name,
"userfield")) {
3296 }
else if (!strcasecmp(name,
"sequence")) {
3297 snprintf(value, length,
"%u", cdr_obj->
sequence);
3341 cdr_obj = cdr->
last;
3359 char workspace[256];
3360 int total = 0, x = 0, i;
3373 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->
next) {
3391 for (i = 0; cdr_readonly_vars[i]; i++) {
3399 &&
ast_str_append(buf, 0,
"level %d: %s%c%s%c", x, cdr_readonly_vars[i], delim, workspace, sep) < 0) {
3432 switch (disposition) {
3444 return "CONGESTION";
3459 if ((cdr->
fn_table != &finalized_state_fn_table || !cdr->
next)
3490 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->
next) {
3491 if (it_cdr->
fn_table == &finalized_state_fn_table && it_cdr->
next !=
NULL) {
3518 for (; cdr ; cdr = cdr->
next) {
3523 ast_debug(1,
"Skipping CDR for %s since we weren't answered\n", cdr->
channel);
3539 if (!i->suspended) {
3559 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->
next) {
3560 if (it_cdr->
fn_table == &finalized_state_fn_table) {
3586 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->
next) {
3587 if (it_cdr->
fn_table == &finalized_state_fn_table) {
3610 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->
next) {
3612 if (!keep_variables) {
3624 memset(&it_cdr->
start, 0,
sizeof(it_cdr->
start));
3625 memset(&it_cdr->
end, 0,
sizeof(it_cdr->
end));
3652 cdr_obj = cdr->
last;
3653 if (cdr_obj->
fn_table == &finalized_state_fn_table) {
3713 for (it_cdr = cdr; it_cdr != new_cdr; it_cdr = it_cdr->
next) {
3714 if (it_cdr->
fn_table == &finalized_state_fn_table) {
3758 processeditem = batchitem;
3759 batchitem = batchitem->
next;
3790 ast_debug(1,
"CDR single-threaded batch processing begins now\n");
3794 ast_log(
LOG_WARNING,
"CDR processing thread could not detach, now trying in this thread\n");
3797 ast_debug(1,
"CDR multi-threaded batch processing begins now\n");
3846 int submit_batch = 0;
3867 ast_debug(1,
"CDR detaching from this thread\n");
3870 if (!(newtail =
ast_calloc(1,
sizeof(*newtail)))) {
3892 if (curr >= (mod_cfg->general->batch_settings.size - 1)) {
3905 struct timespec timeout;
3916 timeout.tv_sec = now.tv_sec;
3917 timeout.tv_nsec = now.tv_usec * 1000;
3923 ast_debug(2,
"Processed %d CDR batches from the run queue\n", numevents);
3935 e->
command =
"cdr set debug [on|off]";
3936 e->
usage =
"Enable or disable extra debugging in the CDR Engine. Note\n" 3937 "that this will dump debug information to the VERBOSE setting\n" 3938 "and should only be used when debugging information from the\n" 3939 "CDR engine is needed.\n";
3951 ast_cli(a->
fd,
"Could not set CDR debugging mode\n");
3954 if (!strcasecmp(a->
argv[3],
"on")
3957 ast_cli(a->
fd,
"CDR debugging enabled\n");
3958 }
else if (!strcasecmp(a->
argv[3],
"off")
3961 ast_cli(a->
fd,
"CDR debugging disabled\n");
3972 int wordlen = strlen(a->
word);
3995 char start_time_buffer[64];
3996 char answer_time_buffer[64];
3997 char end_time_buffer[64];
3999 #define TITLE_STRING "%-25.25s %-25.25s %-15.15s %-8.8s %-8.8s %-8.8s %-8.8s %-8.8s\n" 4000 #define FORMAT_STRING "%-25.25s %-25.25s %-15.15s %-8.8s %-8.8s %-8.8s %-8.8ld %-8.8ld\n" 4003 ast_cli(a->
fd,
"Channels with Call Detail Record (CDR) Information\n");
4004 ast_cli(a->
fd,
"--------------------------------------------------\n");
4005 ast_cli(a->
fd,
TITLE_STRING,
"Channel",
"Dst. Channel",
"LastApp",
"Start",
"Answer",
"End",
"Billsec",
"Duration");
4010 struct timeval start_time = { 0, };
4011 struct timeval answer_time = { 0, };
4012 struct timeval end_time = { 0, };
4019 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->
next) {
4024 start_time = it_cdr->
start;
4027 answer_time = it_cdr->
answer;
4038 cdr_get_tv(start_time,
"%T", start_time_buffer,
sizeof(start_time_buffer));
4039 cdr_get_tv(answer_time,
"%T", answer_time_buffer,
sizeof(answer_time_buffer));
4040 cdr_get_tv(end_time,
"%T", end_time_buffer,
sizeof(end_time_buffer));
4051 #undef FORMAT_STRING 4059 char start_time_buffer[64];
4060 char answer_time_buffer[64];
4061 char end_time_buffer[64];
4062 const char *channel_name = a->
argv[3];
4065 #define TITLE_STRING "%-10.10s %-20.20s %-25.25s %-15.15s %-15.15s %-8.8s %-8.8s %-8.8s %-8.8s %-8.8s\n" 4066 #define FORMAT_STRING "%-10.10s %-20.20s %-25.25s %-15.15s %-15.15s %-8.8s %-8.8s %-8.8s %-8.8ld %-8.8ld\n" 4070 ast_cli(a->
fd,
"Unknown channel: %s\n", channel_name);
4075 ast_cli(a->
fd,
"Call Detail Record (CDR) Information for %s\n", channel_name);
4076 ast_cli(a->
fd,
"--------------------------------------------------\n");
4077 ast_cli(a->
fd,
TITLE_STRING,
"AccountCode",
"CallerID",
"Dst. Channel",
"LastApp",
"Data",
"Start",
"Answer",
"End",
"Billsec",
"Duration");
4080 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->
next) {
4092 cdr_get_tv(it_cdr->
start,
"%T", start_time_buffer,
sizeof(start_time_buffer));
4093 cdr_get_tv(it_cdr->
answer,
"%T", answer_time_buffer,
sizeof(answer_time_buffer));
4094 cdr_get_tv(end,
"%T", end_time_buffer,
sizeof(end_time_buffer));
4111 #undef FORMAT_STRING 4119 e->
command =
"cdr show active";
4121 "Usage: cdr show active [channel]\n" 4122 " Displays a summary of all Call Detail Records when [channel]\n" 4123 " is omitted; displays all of the Call Detail Records\n" 4124 " currently in flight for a given [channel] when [channel] is\n" 4126 " Note that this will not display Call Detail Records that\n" 4127 " have already been dispatched to a backend storage, nor for\n" 4128 " channels that are no longer active.\n";
4136 }
else if (a->
argc < 4) {
4150 long nextbatchtime = 0;
4154 e->
command =
"cdr show status";
4156 "Usage: cdr show status\n" 4157 " Displays the Call Detail Record engine system status.\n";
4173 ast_cli(a->
fd,
"Call Detail Record (CDR) settings\n");
4174 ast_cli(a->
fd,
"----------------------------------\n");
4181 ast_cli(a->
fd,
"* Batch Mode Settings\n");
4182 ast_cli(a->
fd,
" -------------------\n");
4189 ast_cli(a->
fd,
" Current batch size: %d record%s\n", cnt,
ESS(cnt));
4192 ast_cli(a->
fd,
" Next batch processing time: %ld second%s\n\n", nextbatchtime,
ESS(nextbatchtime));
4194 ast_cli(a->
fd,
"* Registered Backends\n");
4195 ast_cli(a->
fd,
" -------------------\n");
4201 ast_cli(a->
fd,
" %s%s\n", beitem->
name, beitem->suspended ?
" (suspended) " :
"");
4220 "Usage: cdr submit\n" 4221 "Posts all pending batched CDR data to the configured CDR\n" 4222 "backend engine modules.\n";
4237 ast_cli(a->
fd,
"Cannot submit CDR batch: CDR engine disabled.\n");
4239 ast_cli(a->
fd,
"Cannot submit CDR batch: batch mode not enabled.\n");
4242 ast_cli(a->
fd,
"Submitted CDRs to backend engines for processing. This may take a while.\n");
4266 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->
next) {
4293 if (!stasis_router) {
4320 if (channel_subscription || bridge_subscription || parking_subscription) {
4325 if (!channel_subscription) {
4329 if (!bridge_subscription) {
4333 if (!parking_subscription) {
4356 aco_option_register(&cfg_info,
"size",
ACO_EXACT, general_options,
DEFAULT_BATCH_SIZE,
OPT_UINT_T,
PARSE_IN_RANGE,
FLDSET(
struct ast_cdr_config, batch_settings.size), 0,
MAX_BATCH_SIZE);
4357 aco_option_register(&cfg_info,
"time",
ACO_EXACT, general_options,
DEFAULT_BATCH_TIME,
OPT_UINT_T,
PARSE_IN_RANGE,
FLDSET(
struct ast_cdr_config, batch_settings.time), 1,
MAX_BATCH_TIME);
4388 stasis_router =
NULL;
4409 active_cdrs_master =
NULL;
4413 active_cdrs_all =
NULL;
4430 ast_log(
LOG_NOTICE,
"CDR batch mode logging enabled, first of either size %u or time %u seconds.\n",
4453 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->
next) {
4454 prnt(where,
"Party A: %s; Party B: %s; Bridge %s\n",
4479 prnt(where,
"Party A: %s; Party B: %s; Bridge %s",
4512 return mod_cfg ? 0 : -1;
4534 if (!stasis_router) {
4553 if (!active_cdrs_master) {
4560 if (!active_cdrs_all) {
4588 if (cdr_sync_message_type()) {
4592 if (!stasis_router) {
4602 ast_debug(1,
"CDR Engine termination request received; waiting on messages...\n");
4650 .requires =
"extconfig",
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
static int base_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
static enum process_bridge_enter_results dialed_pending_state_process_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
static struct stasis_message_router * stasis_router
Message router for stasis messages regarding channel state.
const ast_string_field data
static int cdr_object_get_by_name_cb(void *obj, void *arg, int flags)
static long cdr_object_get_billsec(struct cdr_object *cdr)
Compute the billsec for a cdr_object.
struct ao2_container * channels
static char exten[AST_MAX_EXTENSION]
char accountcode[AST_MAX_ACCOUNT_CODE]
#define AST_CLI_DEFINE(fn, txt,...)
struct ast_bridge_snapshot * bridge
static int cdr_object_update_party_b_userfield_cb(void *obj, void *arg, void *data, int flags)
Callback used to update the userfield on Party B on all CDRs.
struct ast_channel_snapshot_base * base
Asterisk locking-related definitions:
static void * module_config_alloc(void)
Create a new module config object.
Asterisk main include file. File version handling, generic pbx functions.
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
struct cdr_batch_item * tail
struct varshead variables
int ast_cdr_reset(const char *channel_name, int keep_variables)
Reset the detail record.
static int cdr_master_cmp_fn(void *obj, void *arg, int flags)
static void reset_batch(void)
static void * do_batch_backend_process(void *data)
static int bridge_state_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
#define AST_RWLIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a read/write list of specified type, statically initialized...
struct ast_cdr_config * ast_cdr_get_config(void)
Obtain the current CDR configuration.
struct stasis_message_type * ast_channel_entered_bridge_type(void)
Message type for channel enter bridge blob messages.
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
struct ast_channel_snapshot * channel
char dstchannel[AST_MAX_EXTENSION]
int ast_sched_runq(struct ast_sched_context *con)
Runs the queue.
int(*const process_parked_channel)(struct cdr_object *cdr, struct ast_parked_call_payload *parking_info)
Process an update informing us that the channel got itself parked.
static void cdr_all_unlink(struct cdr_object *cdr)
#define cdr_set_debug_mode(mod_cfg)
const ast_string_field name
static void * do_cdr(void *data)
static void bridge_candidate_process(struct cdr_object *cdr, struct cdr_object *base_cand_cdr)
Process a single bridge_candidate.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
The arg parameter is a search key, but is not an object.
struct ast_flags settings
#define ast_test_flag(p, flag)
static void cdr_object_format_var_internal(struct cdr_object *cdr, const char *name, char *value, size_t length)
Format a variable on a cdr_object.
static void update(int code_size, int y, int wi, int fi, int dq, int sr, int dqsez, struct g726_state *state_ptr)
struct ast_channel_snapshot * snapshot
const char * ast_var_value(const struct ast_var_t *var)
static const char * ignore_categories[]
static void handle_bridge_leave_message(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Handler for when a channel leaves a bridge.
int stasis_message_router_add(struct stasis_message_router *router, struct stasis_message_type *message_type, stasis_subscription_cb callback, void *data)
Add a route to a message router.
#define STASIS_MESSAGE_TYPE_INIT(name)
Boiler-plate messaging macro for initializing message types.
static int is_cdr_flag_set(unsigned int cdr_flag)
int ast_cdr_set_property(const char *channel_name, enum ast_cdr_options option)
Set a property on a CDR for a channel.
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
const char * ast_var_name(const struct ast_var_t *var)
struct stasis_message_type * ast_channel_left_bridge_type(void)
Message type for channel leave bridge blob messages.
#define ast_set_flag(p, flag)
static void handle_parking_bridge_enter_message(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel, const struct timeval *event_time)
Handle entering into a parking bridge.
Stasis Message Bus API. See Stasis Message Bus API for detailed documentation.
descriptor for a cli entry.
static void post_cdr(struct ast_cdr *cdr)
struct stasis_message_type * ast_parked_call_type(void)
accessor for the parked call stasis message type
#define AST_TASKPROCESSOR_HIGH_WATER_LEVEL
static void cdr_object_dtor(void *obj)
cdr_object Destructor
#define ao2_callback(c, flags, cb_fn, arg)
static int single_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer)
struct ast_cdr * ast_cdr_alloc(void)
Allocate a CDR record.
Structure that contains a snapshot of information about a bridge.
#define aco_option_register(info, name, matchtype, types, default_val, opt_type, flags,...)
Register a config option.
static int cdr_master_hash_fn(const void *obj, const int flags)
char dcontext[AST_MAX_EXTENSION]