2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 1999 - 2006, Digium, Inc.
6 * Mark Spencer <markster@digium.com>
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
21 * \brief Call Detail Record API
23 * \author Mark Spencer <markster@digium.com>
25 * \note Includes code and algorithms from the Zapata library.
27 * \note We do a lot of checking here in the CDR code to try to be sure we don't ever let a CDR slip
28 * through our fingers somehow. If someone allocates a CDR, it must be completely handled normally
29 * or a WARNING shall be logged, so that we can best keep track of any escape condition where the CDR
30 * isn't properly generated and posted.
33 /*! \li \ref cdr.c uses the configuration file \ref cdr.conf
34 * \addtogroup configuration_file Configuration Files
38 * \page cdr.conf cdr.conf
39 * \verbinclude cdr.conf.sample
43 <support_level>core</support_level>
51 #include "asterisk/lock.h"
52 #include "asterisk/channel.h"
53 #include "asterisk/cdr.h"
54 #include "asterisk/callerid.h"
55 #include "asterisk/manager.h"
56 #include "asterisk/causes.h"
57 #include "asterisk/linkedlists.h"
58 #include "asterisk/utils.h"
59 #include "asterisk/sched.h"
60 #include "asterisk/config.h"
61 #include "asterisk/cli.h"
62 #include "asterisk/stringfields.h"
63 #include "asterisk/config_options.h"
64 #include "asterisk/json.h"
65 #include "asterisk/parking.h"
66 #include "asterisk/stasis.h"
67 #include "asterisk/stasis_channels.h"
68 #include "asterisk/stasis_bridges.h"
69 #include "asterisk/stasis_message_router.h"
70 #include "asterisk/astobj2.h"
71 #include "asterisk/taskprocessor.h"
74 <configInfo name="cdr" language="en_US">
75 <synopsis>Call Detail Record configuration</synopsis>
77 <para>CDR is Call Detail Record, which provides logging services via a variety of
78 pluggable backend modules. Detailed call information can be recorded to
79 databases, files, etc. Useful for billing, fraud prevention, compliance with
80 Sarbanes-Oxley aka The Enron Act, QOS evaluations, and more.</para>
82 <configFile name="cdr.conf">
83 <configObject name="general">
84 <synopsis>Global settings applied to the CDR engine.</synopsis>
85 <configOption name="debug">
86 <synopsis>Enable/disable verbose CDR debugging.</synopsis>
87 <description><para>When set to <literal>True</literal>, verbose updates
88 of changes in CDR information will be logged. Note that this is only
89 of use when debugging CDR behavior.</para>
92 <configOption name="enable">
93 <synopsis>Enable/disable CDR logging.</synopsis>
94 <description><para>Define whether or not to use CDR logging. Setting this to "no" will override
95 any loading of backend CDR modules. Default is "yes".</para>
98 <configOption name="unanswered">
99 <synopsis>Log calls that are never answered and don't set an outgoing party.</synopsis>
101 Define whether or not to log unanswered calls that don't involve an outgoing party. Setting
102 this to "yes" will make calls to extensions that don't answer and don't set a side B channel
103 (such as by using the Dial application) receive CDR log entries. If this option is set to
104 "no", then those log entries will not be created. Unanswered calls which get offered to an
105 outgoing line will always receive log entries regardless of this option, and that is the
110 <configOption name="congestion">
111 <synopsis>Log congested calls.</synopsis>
112 <description><para>Define whether or not to log congested calls. Setting this to "yes" will
113 report each call that fails to complete due to congestion conditions.</para>
116 <configOption name="endbeforehexten">
117 <synopsis>Don't produce CDRs while executing hangup logic</synopsis>
119 <para>As each CDR for a channel is finished, its end time is updated
120 and the CDR is finalized. When a channel is hung up and hangup
121 logic is present (in the form of a hangup handler or the
122 <literal>h</literal> extension), a new CDR is generated for the
123 channel. Any statistics are gathered from this new CDR. By enabling
124 this option, no new CDR is created for the dialplan logic that is
125 executed in <literal>h</literal> extensions or attached hangup handler
126 subroutines. The default value is <literal>yes</literal>, indicating
127 that a CDR will be generated during hangup logic.</para>
130 <configOption name="initiatedseconds">
131 <synopsis>Count microseconds for billsec purposes</synopsis>
132 <description><para>Normally, the <literal>billsec</literal> field logged to the CDR backends
133 is simply the end time (hangup time) minus the answer time in seconds. Internally,
134 asterisk stores the time in terms of microseconds and seconds. By setting
135 initiatedseconds to <literal>yes</literal>, you can force asterisk to report any seconds
136 that were initiated (a sort of round up method). Technically, this is
137 when the microsecond part of the end time is greater than the microsecond
138 part of the answer time, then the billsec time is incremented one second.</para>
141 <configOption name="batch">
142 <synopsis>Submit CDRs to the backends for processing in batches</synopsis>
143 <description><para>Define the CDR batch mode, where instead of posting the CDR at the end of
144 every call, the data will be stored in a buffer to help alleviate load on the
145 asterisk server.</para>
146 <warning><para>Use of batch mode may result in data loss after unsafe asterisk termination,
147 i.e., software crash, power failure, kill -9, etc.</para>
151 <configOption name="size">
152 <synopsis>The maximum number of CDRs to accumulate before triggering a batch</synopsis>
153 <description><para>Define the maximum number of CDRs to accumulate in the buffer before posting
154 them to the backend engines. batch must be set to <literal>yes</literal>.</para>
157 <configOption name="time">
158 <synopsis>The maximum time to accumulate CDRs before triggering a batch</synopsis>
159 <description><para>Define the maximum time to accumulate CDRs before posting them in a batch to the
160 backend engines. If this time limit is reached, then it will post the records, regardless of the value
161 defined for size. batch must be set to <literal>yes</literal>.</para>
162 <note><para>Time is expressed in seconds.</para></note>
165 <configOption name="scheduleronly">
166 <synopsis>Post batched CDRs on their own thread instead of the scheduler</synopsis>
167 <description><para>The CDR engine uses the internal asterisk scheduler to determine when to post
168 records. Posting can either occur inside the scheduler thread, or a new
169 thread can be spawned for the submission of every batch. For small batches,
170 it might be acceptable to just use the scheduler thread, so set this to <literal>yes</literal>.
171 For large batches, say anything over size=10, a new thread is recommended, so
172 set this to <literal>no</literal>.</para>
175 <configOption name="safeshutdown">
176 <synopsis>Block shutdown of Asterisk until CDRs are submitted</synopsis>
177 <description><para>When shutting down asterisk, you can block until the CDRs are submitted. If
178 you don't, then data will likely be lost. You can always check the size of
179 the CDR batch buffer with the CLI <astcli>cdr status</astcli> command. To enable blocking on
180 submission of CDR data during asterisk shutdown, set this to <literal>yes</literal>.</para>
189 /* The prime here should be similar in size to the channel container. */
191 #define NUM_CDR_BUCKETS 61
193 #define NUM_CDR_BUCKETS 769
196 #define DEFAULT_ENABLED "1"
197 #define DEFAULT_BATCHMODE "0"
198 #define DEFAULT_UNANSWERED "0"
199 #define DEFAULT_CONGESTION "0"
200 #define DEFAULT_END_BEFORE_H_EXTEN "1"
201 #define DEFAULT_INITIATED_SECONDS "0"
203 #define DEFAULT_BATCH_SIZE "100"
204 #define MAX_BATCH_SIZE 1000
205 #define DEFAULT_BATCH_TIME "300"
206 #define MAX_BATCH_TIME 86400
207 #define DEFAULT_BATCH_SCHEDULER_ONLY "0"
208 #define DEFAULT_BATCH_SAFE_SHUTDOWN "1"
210 #define CDR_DEBUG(mod_cfg, fmt, ...) \
212 if (ast_test_flag(&(mod_cfg)->general->settings, CDR_DEBUG)) { \
213 ast_verbose((fmt), ##__VA_ARGS__); \
217 static void cdr_detach(struct ast_cdr *cdr);
218 static void cdr_submit_batch(int shutdown);
219 static int cdr_toggle_runtime_options(void);
221 /*! \brief The configuration settings for this module */
222 struct module_config {
223 struct ast_cdr_config *general; /*< CDR global settings */
226 /*! \brief The container for the module configuration */
227 static AO2_GLOBAL_OBJ_STATIC(module_configs);
229 /*! \brief The type definition for general options */
230 static struct aco_type general_option = {
233 .item_offset = offsetof(struct module_config, general),
234 .category = "^general$",
235 .category_match = ACO_WHITELIST,
238 static void *module_config_alloc(void);
239 static void module_config_destructor(void *obj);
241 /*! \brief The file definition */
242 static struct aco_file module_file_conf = {
243 .filename = "cdr.conf",
244 .skip_category = "(^csv$|^custom$|^manager$|^odbc$|^pgsql$|^radius$|^sqlite$|^tds$|^mysql$)",
245 .types = ACO_TYPES(&general_option),
248 CONFIG_INFO_CORE("cdr", cfg_info, module_configs, module_config_alloc,
249 .files = ACO_FILES(&module_file_conf),
252 static struct aco_type *general_options[] = ACO_TYPES(&general_option);
254 /*! \brief Dispose of a module config object */
255 static void module_config_destructor(void *obj)
257 struct module_config *cfg = obj;
262 ao2_ref(cfg->general, -1);
265 /*! \brief Create a new module config object */
266 static void *module_config_alloc(void)
268 struct module_config *mod_cfg;
269 struct ast_cdr_config *cdr_config;
271 mod_cfg = ao2_alloc(sizeof(*mod_cfg), module_config_destructor);
276 cdr_config = ao2_alloc(sizeof(*cdr_config), NULL);
278 ao2_ref(cdr_config, -1);
281 mod_cfg->general = cdr_config;
286 /*! \brief Registration object for CDR backends */
291 AST_RWLIST_ENTRY(cdr_beitem) list;
295 /*! \brief List of registered backends */
296 static AST_RWLIST_HEAD_STATIC(be_list, cdr_beitem);
298 /*! \brief List of registered modifiers */
299 static AST_RWLIST_HEAD_STATIC(mo_list, cdr_beitem);
301 /*! \brief Queued CDR waiting to be batched */
302 struct cdr_batch_item {
304 struct cdr_batch_item *next;
307 /*! \brief The actual batch queue */
308 static struct cdr_batch {
310 struct cdr_batch_item *head;
311 struct cdr_batch_item *tail;
314 /*! \brief The global sequence counter used for CDRs */
315 static int global_cdr_sequence = 0;
317 /*! \brief Scheduler items */
318 static struct ast_sched_context *sched;
319 static int cdr_sched = -1;
320 AST_MUTEX_DEFINE_STATIC(cdr_sched_lock);
321 static pthread_t cdr_thread = AST_PTHREADT_NULL;
323 /*! \brief Lock protecting modifications to the batch queue */
324 AST_MUTEX_DEFINE_STATIC(cdr_batch_lock);
326 /*! \brief These are used to wake up the CDR thread when there's work to do */
327 AST_MUTEX_DEFINE_STATIC(cdr_pending_lock);
328 static ast_cond_t cdr_pending_cond;
330 /*! \brief A container of the active CDRs indexed by Party A channel id */
331 static struct ao2_container *active_cdrs_by_channel;
333 /*! \brief Message router for stasis messages regarding channel state */
334 static struct stasis_message_router *stasis_router;
336 /*! \brief Our subscription for bridges */
337 static struct stasis_forward *bridge_subscription;
339 /*! \brief Our subscription for channels */
340 static struct stasis_forward *channel_subscription;
342 /*! \brief Our subscription for parking */
343 static struct stasis_forward *parking_subscription;
345 /*! \brief The parent topic for all topics we want to aggregate for CDRs */
346 static struct stasis_topic *cdr_topic;
348 /*! \brief A message type used to synchronize with the CDR topic */
349 STASIS_MESSAGE_TYPE_DEFN_LOCAL(cdr_sync_message_type);
353 /*! \brief Return types for \ref process_bridge_enter functions */
354 enum process_bridge_enter_results {
356 * The CDR was the only party in the bridge.
358 BRIDGE_ENTER_ONLY_PARTY,
360 * The CDR was able to obtain a Party B from some other party already in the bridge
362 BRIDGE_ENTER_OBTAINED_PARTY_B,
364 * The CDR was not able to obtain a Party B
366 BRIDGE_ENTER_NO_PARTY_B,
368 * This CDR can't handle a bridge enter message and a new CDR needs to be created
370 BRIDGE_ENTER_NEED_CDR,
374 * \brief A virtual table used for \ref cdr_object.
376 * Note that all functions are optional - if a subclass does not need an
377 * implementation, it is safe to leave it NULL.
379 struct cdr_object_fn_table {
380 /*! \brief Name of the subclass */
384 * \brief An initialization function. This will be called automatically
385 * when a \ref cdr_object is switched to this type in
386 * \ref cdr_object_transition_state
388 * \param cdr The \ref cdr_object that was just transitioned
390 void (* const init_function)(struct cdr_object *cdr);
393 * \brief Process a Party A update for the \ref cdr_object
395 * \param cdr The \ref cdr_object to process the update
396 * \param snapshot The snapshot for the CDR's Party A
397 * \retval 0 the CDR handled the update or ignored it
398 * \retval 1 the CDR is finalized and a new one should be made to handle it
400 int (* const process_party_a)(struct cdr_object *cdr,
401 struct ast_channel_snapshot *snapshot);
404 * \brief Process a Party B update for the \ref cdr_object
406 * \param cdr The \ref cdr_object to process the update
407 * \param snapshot The snapshot for the CDR's Party B
409 void (* const process_party_b)(struct cdr_object *cdr,
410 struct ast_channel_snapshot *snapshot);
413 * \brief Process the beginning of a dial. A dial message implies one of two
415 * The \ref cdr_object's Party A has been originated
416 * The \ref cdr_object's Party A is dialing its Party B
418 * \param cdr The \ref cdr_object
419 * \param caller The originator of the dial attempt
420 * \param peer The destination of the dial attempt
422 * \retval 0 if the parties in the dial were handled by this CDR
423 * \retval 1 if the parties could not be handled by this CDR
425 int (* const process_dial_begin)(struct cdr_object *cdr,
426 struct ast_channel_snapshot *caller,
427 struct ast_channel_snapshot *peer);
430 * \brief Process the end of a dial. At the end of a dial, a CDR can be
431 * transitioned into one of two states - DialedPending
432 * (\ref dialed_pending_state_fn_table) or Finalized
433 * (\ref finalized_state_fn_table).
435 * \param cdr The \ref cdr_object
436 * \param caller The originator of the dial attempt
437 * \param peer the Destination of the dial attempt
438 * \param dial_status What happened
440 * \retval 0 if the parties in the dial were handled by this CDR
441 * \retval 1 if the parties could not be handled by this CDR
443 int (* const process_dial_end)(struct cdr_object *cdr,
444 struct ast_channel_snapshot *caller,
445 struct ast_channel_snapshot *peer,
446 const char *dial_status);
449 * \brief Process the entering of a bridge by this CDR. The purpose of this
450 * callback is to have the CDR prepare itself for the bridge and attempt to
451 * find a valid Party B. The act of creating new CDRs based on the entering
452 * of this channel into the bridge is handled by the higher level message
455 * Note that this handler is for when a channel enters into a "normal"
456 * bridge, where people actually talk to each other. Parking is its own
459 * \param cdr The \ref cdr_object
460 * \param bridge The bridge that the Party A just entered into
461 * \param channel The \ref ast_channel_snapshot for this CDR's Party A
463 * \retval process_bridge_enter_results Defines whether or not this CDR was able
464 * to fully handle the bridge enter message.
466 enum process_bridge_enter_results (* const process_bridge_enter)(
467 struct cdr_object *cdr,
468 struct ast_bridge_snapshot *bridge,
469 struct ast_channel_snapshot *channel);
472 * \brief Process entering into a parking bridge.
474 * \param cdr The \ref cdr_object
475 * \param bridge The parking bridge that Party A just entered into
476 * \param channel The \ref ast_channel_snapshot for this CDR's Party A
478 * \retval 0 This CDR successfully transitioned itself into the parked state
479 * \retval 1 This CDR couldn't handle the parking transition and we need a
482 int (* const process_parking_bridge_enter)(struct cdr_object *cdr,
483 struct ast_bridge_snapshot *bridge,
484 struct ast_channel_snapshot *channel);
487 * \brief Process the leaving of a bridge by this CDR.
489 * \param cdr The \ref cdr_object
490 * \param bridge The bridge that the Party A just left
491 * \param channel The \ref ast_channel_snapshot for this CDR's Party A
493 * \retval 0 This CDR left successfully
496 int (* const process_bridge_leave)(struct cdr_object *cdr,
497 struct ast_bridge_snapshot *bridge,
498 struct ast_channel_snapshot *channel);
501 * \brief Process an update informing us that the channel got itself parked
503 * \param cdr The \ref cdr_object
504 * \param channel The parking information for this CDR's party A
506 * \retval 0 This CDR successfully parked itself
507 * \retval 1 This CDR couldn't handle the park
509 int (* const process_parked_channel)(struct cdr_object *cdr,
510 struct ast_parked_call_payload *parking_info);
513 static int base_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot);
514 static enum process_bridge_enter_results base_process_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
515 static int base_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
516 static int base_process_dial_end(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer, const char *dial_status);
517 static int base_process_parked_channel(struct cdr_object *cdr, struct ast_parked_call_payload *parking_info);
519 static void single_state_init_function(struct cdr_object *cdr);
520 static void single_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot);
521 static int single_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer);
522 static enum process_bridge_enter_results single_state_process_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
523 static int single_state_process_parking_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
526 * \brief The virtual table for the Single state.
528 * A \ref cdr_object starts off in this state. This represents a channel that
529 * has no Party B information itself.
531 * A \ref cdr_object from this state can go into any of the following states:
532 * * \ref dial_state_fn_table
533 * * \ref bridge_state_fn_table
534 * * \ref finalized_state_fn_table
536 struct cdr_object_fn_table single_state_fn_table = {
538 .init_function = single_state_init_function,
539 .process_party_a = base_process_party_a,
540 .process_party_b = single_state_process_party_b,
541 .process_dial_begin = single_state_process_dial_begin,
542 .process_dial_end = base_process_dial_end,
543 .process_bridge_enter = single_state_process_bridge_enter,
544 .process_parking_bridge_enter = single_state_process_parking_bridge_enter,
545 .process_bridge_leave = base_process_bridge_leave,
546 .process_parked_channel = base_process_parked_channel,
549 static void dial_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot);
550 static int dial_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer);
551 static int dial_state_process_dial_end(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer, const char *dial_status);
552 static enum process_bridge_enter_results dial_state_process_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
555 * \brief The virtual table for the Dial state.
557 * A \ref cdr_object that has begun a dial operation. This state is entered when
558 * the Party A for a CDR is determined to be dialing out to a Party B or when
559 * a CDR is for an originated channel (in which case the Party A information is
560 * the originated channel, and there is no Party B).
562 * A \ref cdr_object from this state can go in any of the following states:
563 * * \ref dialed_pending_state_fn_table
564 * * \ref bridge_state_fn_table
565 * * \ref finalized_state_fn_table
567 struct cdr_object_fn_table dial_state_fn_table = {
569 .process_party_a = base_process_party_a,
570 .process_party_b = dial_state_process_party_b,
571 .process_dial_begin = dial_state_process_dial_begin,
572 .process_dial_end = dial_state_process_dial_end,
573 .process_bridge_enter = dial_state_process_bridge_enter,
574 .process_bridge_leave = base_process_bridge_leave,
577 static int dialed_pending_state_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot);
578 static int dialed_pending_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer);
579 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);
580 static int dialed_pending_state_process_parking_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
583 * \brief The virtual table for the Dialed Pending state.
585 * A \ref cdr_object that has successfully finished a dial operation, but we
586 * don't know what they're going to do yet. It's theoretically possible to dial
587 * a party and then have that party not be bridged with the caller; likewise,
588 * an origination can complete and the channel go off and execute dialplan. The
589 * pending state acts as a bridge between either:
590 * * Entering a bridge
591 * * Getting a new CDR for new dialplan execution
592 * * Switching from being originated to executing dialplan
594 * A \ref cdr_object from this state can go in any of the following states:
595 * * \ref single_state_fn_table
596 * * \ref dialed_pending_state_fn_table
597 * * \ref bridge_state_fn_table
598 * * \ref finalized_state_fn_table
600 struct cdr_object_fn_table dialed_pending_state_fn_table = {
601 .name = "DialedPending",
602 .process_party_a = dialed_pending_state_process_party_a,
603 .process_dial_begin = dialed_pending_state_process_dial_begin,
604 .process_bridge_enter = dialed_pending_state_process_bridge_enter,
605 .process_parking_bridge_enter = dialed_pending_state_process_parking_bridge_enter,
606 .process_bridge_leave = base_process_bridge_leave,
607 .process_parked_channel = base_process_parked_channel,
610 static void bridge_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot);
611 static int bridge_state_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
614 * \brief The virtual table for the Bridged state
616 * A \ref cdr_object enters this state when it receives notification that the
617 * channel has entered a bridge.
619 * A \ref cdr_object from this state can go to:
620 * * \ref finalized_state_fn_table
622 struct cdr_object_fn_table bridge_state_fn_table = {
624 .process_party_a = base_process_party_a,
625 .process_party_b = bridge_state_process_party_b,
626 .process_bridge_leave = bridge_state_process_bridge_leave,
627 .process_parked_channel = base_process_parked_channel,
630 static int parked_state_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
633 * \brief The virtual table for the Parked state
635 * Parking is weird. Unlike typical bridges, it has to be treated somewhat
636 * uniquely - a channel in a parking bridge (which is a subclass of a holding
637 * bridge) has to be handled as if the channel went into an application.
638 * However, when the channel comes out, we need a new CDR - unlike the Single
641 struct cdr_object_fn_table parked_state_fn_table = {
643 .process_party_a = base_process_party_a,
644 .process_bridge_leave = parked_state_process_bridge_leave,
645 .process_parked_channel = base_process_parked_channel,
648 static void finalized_state_init_function(struct cdr_object *cdr);
649 static int finalized_state_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot);
652 * \brief The virtual table for the finalized state.
654 * Once in the finalized state, the CDR is done. No modifications can be made
657 struct cdr_object_fn_table finalized_state_fn_table = {
659 .init_function = finalized_state_init_function,
660 .process_party_a = finalized_state_process_party_a,
661 .process_bridge_enter = base_process_bridge_enter,
664 /*! \brief A wrapper object around a snapshot.
665 * Fields that are mutable by the CDR engine are replicated here.
667 struct cdr_object_snapshot {
668 struct ast_channel_snapshot *snapshot; /*!< The channel snapshot */
669 char userfield[AST_MAX_USER_FIELD]; /*!< Userfield for the channel */
670 unsigned int flags; /*!< Specific flags for this party */
671 struct varshead variables; /*!< CDR variables for the channel */
674 /*! \brief An in-memory representation of an active CDR */
676 struct cdr_object_snapshot party_a; /*!< The Party A information */
677 struct cdr_object_snapshot party_b; /*!< The Party B information */
678 struct cdr_object_fn_table *fn_table; /*!< The current virtual table */
680 enum ast_cdr_disposition disposition; /*!< The disposition of the CDR */
681 struct timeval start; /*!< When this CDR was created */
682 struct timeval answer; /*!< Either when the channel was answered, or when the path between channels was established */
683 struct timeval end; /*!< When this CDR was finalized */
684 unsigned int sequence; /*!< A monotonically increasing number for each CDR */
685 struct ast_flags flags; /*!< Flags on the CDR */
686 AST_DECLARE_STRING_FIELDS(
687 AST_STRING_FIELD(linkedid); /*!< Linked ID. Cached here as it may change out from party A, which must be immutable */
688 AST_STRING_FIELD(uniqueid); /*!< Unique id of party A. Cached here as it is the primary key of this CDR */
689 AST_STRING_FIELD(name); /*!< Channel name of party A. Cached here as the party A address may change */
690 AST_STRING_FIELD(bridge); /*!< The bridge the party A happens to be in. */
691 AST_STRING_FIELD(appl); /*!< The last accepted application party A was in */
692 AST_STRING_FIELD(data); /*!< The data for the last accepted application party A was in */
693 AST_STRING_FIELD(context); /*!< The accepted context for Party A */
694 AST_STRING_FIELD(exten); /*!< The accepted extension for Party A */
696 struct cdr_object *next; /*!< The next CDR object in the chain */
697 struct cdr_object *last; /*!< The last CDR object in the chain */
698 int is_root; /*!< True if this is the first CDR in the chain */
702 * \brief Copy variables from one list to another
703 * \param to_list destination
704 * \param from_list source
705 * \retval The number of copied variables
707 static int copy_variables(struct varshead *to_list, struct varshead *from_list)
709 struct ast_var_t *variables;
710 struct ast_var_t *newvariable;
715 AST_LIST_TRAVERSE(from_list, variables, entries) {
716 var = ast_var_name(variables);
717 if (ast_strlen_zero(var)) {
720 val = ast_var_value(variables);
721 if (ast_strlen_zero(val)) {
724 newvariable = ast_var_assign(var, val);
726 AST_LIST_INSERT_HEAD(to_list, newvariable, entries);
735 * \brief Delete all variables from a variable list
736 * \param headp The head pointer to the variable list to delete
738 static void free_variables(struct varshead *headp)
740 struct ast_var_t *vardata;
742 while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries))) {
743 ast_var_delete(vardata);
748 * \brief Copy a snapshot and its details
749 * \param dst The destination
750 * \param src The source
752 static void cdr_object_snapshot_copy(struct cdr_object_snapshot *dst, struct cdr_object_snapshot *src)
754 ao2_t_replace(dst->snapshot, src->snapshot, "CDR snapshot copy");
755 strcpy(dst->userfield, src->userfield);
756 dst->flags = src->flags;
757 copy_variables(&dst->variables, &src->variables);
761 * \brief Transition a \ref cdr_object to a new state
762 * \param cdr The \ref cdr_object to transition
763 * \param fn_table The \ref cdr_object_fn_table state to go to
765 static void cdr_object_transition_state(struct cdr_object *cdr, struct cdr_object_fn_table *fn_table)
767 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
769 CDR_DEBUG(mod_cfg, "%p - Transitioning CDR for %s from state %s to %s\n",
770 cdr, cdr->party_a.snapshot->name,
771 cdr->fn_table ? cdr->fn_table->name : "NONE", fn_table->name);
772 cdr->fn_table = fn_table;
773 if (cdr->fn_table->init_function) {
774 cdr->fn_table->init_function(cdr);
778 * \brief Hash function for containers of CDRs indexing by Party A uniqueid */
779 static int cdr_object_channel_hash_fn(const void *obj, const int flags)
781 const struct cdr_object *cdr;
784 switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
796 return ast_str_case_hash(key);
800 * \brief Comparison function for containers of CDRs indexing by Party A uniqueid
802 static int cdr_object_channel_cmp_fn(void *obj, void *arg, int flags)
804 struct cdr_object *left = obj;
805 struct cdr_object *right = arg;
806 const char *right_key = arg;
809 switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
811 right_key = right->uniqueid;
814 cmp = strcmp(left->uniqueid, right_key);
816 case OBJ_PARTIAL_KEY:
818 * We could also use a partial key struct containing a length
819 * so strlen() does not get called for every comparison instead.
821 cmp = strncmp(left->uniqueid, right_key, strlen(right_key));
824 /* Sort can only work on something with a full or partial key. */
829 return cmp ? 0 : CMP_MATCH;
833 * \brief \ref cdr_object Destructor
835 static void cdr_object_dtor(void *obj)
837 struct cdr_object *cdr = obj;
838 struct ast_var_t *it_var;
840 ao2_cleanup(cdr->party_a.snapshot);
841 ao2_cleanup(cdr->party_b.snapshot);
842 while ((it_var = AST_LIST_REMOVE_HEAD(&cdr->party_a.variables, entries))) {
843 ast_var_delete(it_var);
845 while ((it_var = AST_LIST_REMOVE_HEAD(&cdr->party_b.variables, entries))) {
846 ast_var_delete(it_var);
848 ast_string_field_free_memory(cdr);
850 /* CDR destruction used to work by calling ao2_cleanup(next) and
851 * allowing the chain to destroy itself neatly. Unfortunately, for
852 * really long chains, this can result in a stack overflow. So now
853 * when the root CDR is destroyed, it is responsible for unreffing
854 * all CDRs in the chain
857 struct cdr_object *curr = cdr->next;
858 struct cdr_object *next;
869 * \brief \ref cdr_object constructor
870 * \param chan The \ref ast_channel_snapshot that is the CDR's Party A
872 * This implicitly sets the state of the newly created CDR to the Single state
873 * (\ref single_state_fn_table)
875 static struct cdr_object *cdr_object_alloc(struct ast_channel_snapshot *chan)
877 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
878 struct cdr_object *cdr;
880 ast_assert(chan != NULL);
882 cdr = ao2_alloc(sizeof(*cdr), cdr_object_dtor);
887 if (ast_string_field_init(cdr, 64)) {
891 ast_string_field_set(cdr, uniqueid, chan->uniqueid);
892 ast_string_field_set(cdr, name, chan->name);
893 ast_string_field_set(cdr, linkedid, chan->linkedid);
894 cdr->disposition = AST_CDR_NULL;
895 cdr->sequence = ast_atomic_fetchadd_int(&global_cdr_sequence, +1);
897 cdr->party_a.snapshot = chan;
898 ao2_t_ref(cdr->party_a.snapshot, +1, "bump snapshot during CDR creation");
900 CDR_DEBUG(mod_cfg, "%p - Created CDR for channel %s\n", cdr, chan->name);
902 cdr_object_transition_state(cdr, &single_state_fn_table);
908 * \brief Create a new \ref cdr_object and append it to an existing chain
909 * \param cdr The \ref cdr_object to append to
911 static struct cdr_object *cdr_object_create_and_append(struct cdr_object *cdr)
913 struct cdr_object *new_cdr;
914 struct cdr_object *it_cdr;
915 struct cdr_object *cdr_last;
917 cdr_last = cdr->last;
918 new_cdr = cdr_object_alloc(cdr_last->party_a.snapshot);
922 new_cdr->disposition = AST_CDR_NULL;
924 /* Copy over the linkedid, as it may have changed */
925 ast_string_field_set(new_cdr, linkedid, cdr_last->linkedid);
926 ast_string_field_set(new_cdr, appl, cdr_last->appl);
927 ast_string_field_set(new_cdr, data, cdr_last->data);
928 ast_string_field_set(new_cdr, context, cdr_last->context);
929 ast_string_field_set(new_cdr, exten, cdr_last->exten);
932 * If the current CDR says to disable all future ones,
933 * keep the disable chain going
935 if (ast_test_flag(&cdr_last->flags, AST_CDR_FLAG_DISABLE_ALL)) {
936 ast_set_flag(&new_cdr->flags, AST_CDR_FLAG_DISABLE_ALL);
939 /* Copy over other Party A information */
940 cdr_object_snapshot_copy(&new_cdr->party_a, &cdr_last->party_a);
942 /* Append the CDR to the end of the list */
943 for (it_cdr = cdr; it_cdr->next; it_cdr = it_cdr->next) {
944 it_cdr->last = new_cdr;
946 it_cdr->last = new_cdr;
947 it_cdr->next = new_cdr;
953 * \brief Return whether or not a channel has changed its state in the dialplan, subject
954 * to endbeforehexten logic
956 * \param old_snapshot The previous state
957 * \param new_snapshot The new state
959 * \retval 0 if the state has not changed
960 * \retval 1 if the state changed
962 static int snapshot_cep_changed(struct ast_channel_snapshot *old_snapshot,
963 struct ast_channel_snapshot *new_snapshot)
965 RAII_VAR(struct module_config *, mod_cfg,
966 ao2_global_obj_ref(module_configs), ao2_cleanup);
968 /* If we ignore hangup logic, don't indicate that we're executing anything new */
969 if (ast_test_flag(&mod_cfg->general->settings, CDR_END_BEFORE_H_EXTEN)
970 && ast_test_flag(&new_snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)) {
974 /* When Party A is originated to an application and the application exits, the stack
975 * will attempt to clear the application and restore the dummy originate application
976 * of "AppDialX". Ignore application changes to AppDialX as a result.
978 if (strcmp(new_snapshot->appl, old_snapshot->appl) && strncasecmp(new_snapshot->appl, "appdial", 7)
979 && (strcmp(new_snapshot->context, old_snapshot->context)
980 || strcmp(new_snapshot->exten, old_snapshot->exten)
981 || new_snapshot->priority != old_snapshot->priority)) {
989 * \brief Return whether or not a \ref ast_channel_snapshot is for a channel
990 * that was created as the result of a dial operation
992 * \retval 0 the channel was not created as the result of a dial
993 * \retval 1 the channel was created as the result of a dial
995 static int snapshot_is_dialed(struct ast_channel_snapshot *snapshot)
997 return (ast_test_flag(&snapshot->flags, AST_FLAG_OUTGOING)
998 && !(ast_test_flag(&snapshot->flags, AST_FLAG_ORIGINATED)));
1002 * \brief Given two CDR snapshots, figure out who should be Party A for the
1004 * \param left One of the snapshots
1005 * \param right The other snapshot
1006 * \retval The snapshot that won
1008 static struct cdr_object_snapshot *cdr_object_pick_party_a(struct cdr_object_snapshot *left, struct cdr_object_snapshot *right)
1010 /* Check whether or not the party is dialed. A dialed party is never the
1011 * Party A with a party that was not dialed.
1013 if (!snapshot_is_dialed(left->snapshot) && snapshot_is_dialed(right->snapshot)) {
1015 } else if (snapshot_is_dialed(left->snapshot) && !snapshot_is_dialed(right->snapshot)) {
1019 /* Try the Party A flag */
1020 if (ast_test_flag(left, AST_CDR_FLAG_PARTY_A) && !ast_test_flag(right, AST_CDR_FLAG_PARTY_A)) {
1022 } else if (!ast_test_flag(right, AST_CDR_FLAG_PARTY_A) && ast_test_flag(right, AST_CDR_FLAG_PARTY_A)) {
1026 /* Neither party is dialed and neither has the Party A flag - defer to
1028 if (left->snapshot->creationtime.tv_sec < right->snapshot->creationtime.tv_sec) {
1030 } else if (left->snapshot->creationtime.tv_sec > right->snapshot->creationtime.tv_sec) {
1032 } else if (left->snapshot->creationtime.tv_usec > right->snapshot->creationtime.tv_usec) {
1035 /* Okay, fine, take the left one */
1041 * Compute the duration for a \ref cdr_object
1043 static long cdr_object_get_duration(struct cdr_object *cdr)
1045 return (long)(ast_tvdiff_ms(ast_tvzero(cdr->end) ? ast_tvnow() : cdr->end, cdr->start) / 1000);
1049 * \brief Compute the billsec for a \ref cdr_object
1051 static long cdr_object_get_billsec(struct cdr_object *cdr)
1053 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
1056 if (ast_tvzero(cdr->answer)) {
1059 ms = ast_tvdiff_ms(ast_tvzero(cdr->end) ? ast_tvnow() : cdr->end, cdr->answer);
1060 if (ast_test_flag(&mod_cfg->general->settings, CDR_INITIATED_SECONDS)
1061 && (ms % 1000 >= 500)) {
1062 ms = (ms / 1000) + 1;
1072 * \brief Set a variable on a CDR object
1074 * \param headp The header pointer to the variable to set
1075 * \param name The name of the variable
1076 * \param value The value of the variable
1078 static void set_variable(struct varshead *headp, const char *name, const char *value)
1080 struct ast_var_t *newvariable;
1082 AST_LIST_TRAVERSE_SAFE_BEGIN(headp, newvariable, entries) {
1083 if (!strcasecmp(ast_var_name(newvariable), name)) {
1084 AST_LIST_REMOVE_CURRENT(entries);
1085 ast_var_delete(newvariable);
1089 AST_LIST_TRAVERSE_SAFE_END;
1091 if (value && (newvariable = ast_var_assign(name, value))) {
1092 AST_LIST_INSERT_HEAD(headp, newvariable, entries);
1097 * \brief Create a chain of \ref ast_cdr objects from a chain of \ref cdr_object
1098 * suitable for consumption by the registered CDR backends
1099 * \param cdr The \ref cdr_object to convert to a public record
1100 * \retval A chain of \ref ast_cdr objects on success
1101 * \retval NULL on failure
1103 static struct ast_cdr *cdr_object_create_public_records(struct cdr_object *cdr)
1105 struct ast_cdr *pub_cdr = NULL, *cdr_prev = NULL;
1106 struct cdr_object *it_cdr;
1107 struct ast_var_t *it_var, *it_copy_var;
1108 struct ast_channel_snapshot *party_a;
1109 struct ast_channel_snapshot *party_b;
1111 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
1112 struct ast_cdr *cdr_copy;
1114 /* Don't create records for CDRs where the party A was a dialed channel */
1115 if (snapshot_is_dialed(it_cdr->party_a.snapshot) && !it_cdr->party_b.snapshot) {
1116 ast_debug(1, "CDR for %s is dialed and has no Party B; discarding\n",
1117 it_cdr->party_a.snapshot->name);
1121 cdr_copy = ast_calloc(1, sizeof(*cdr_copy));
1127 party_a = it_cdr->party_a.snapshot;
1128 party_b = it_cdr->party_b.snapshot;
1131 ast_assert(party_a != NULL);
1132 ast_copy_string(cdr_copy->accountcode, party_a->accountcode, sizeof(cdr_copy->accountcode));
1133 cdr_copy->amaflags = party_a->amaflags;
1134 ast_copy_string(cdr_copy->channel, party_a->name, sizeof(cdr_copy->channel));
1135 ast_callerid_merge(cdr_copy->clid, sizeof(cdr_copy->clid), party_a->caller_name, party_a->caller_number, "");
1136 ast_copy_string(cdr_copy->src, party_a->caller_number, sizeof(cdr_copy->src));
1137 ast_copy_string(cdr_copy->uniqueid, party_a->uniqueid, sizeof(cdr_copy->uniqueid));
1138 ast_copy_string(cdr_copy->lastapp, it_cdr->appl, sizeof(cdr_copy->lastapp));
1139 ast_copy_string(cdr_copy->lastdata, it_cdr->data, sizeof(cdr_copy->lastdata));
1140 ast_copy_string(cdr_copy->dst, it_cdr->exten, sizeof(cdr_copy->dst));
1141 ast_copy_string(cdr_copy->dcontext, it_cdr->context, sizeof(cdr_copy->dcontext));
1145 ast_copy_string(cdr_copy->dstchannel, party_b->name, sizeof(cdr_copy->dstchannel));
1146 ast_copy_string(cdr_copy->peeraccount, party_b->accountcode, sizeof(cdr_copy->peeraccount));
1147 if (!ast_strlen_zero(it_cdr->party_b.userfield)) {
1148 snprintf(cdr_copy->userfield, sizeof(cdr_copy->userfield), "%s;%s", it_cdr->party_a.userfield, it_cdr->party_b.userfield);
1151 if (ast_strlen_zero(cdr_copy->userfield) && !ast_strlen_zero(it_cdr->party_a.userfield)) {
1152 ast_copy_string(cdr_copy->userfield, it_cdr->party_a.userfield, sizeof(cdr_copy->userfield));
1155 /* Timestamps/durations */
1156 cdr_copy->start = it_cdr->start;
1157 cdr_copy->answer = it_cdr->answer;
1158 cdr_copy->end = it_cdr->end;
1159 cdr_copy->billsec = cdr_object_get_billsec(it_cdr);
1160 cdr_copy->duration = cdr_object_get_duration(it_cdr);
1163 ast_copy_flags(cdr_copy, &it_cdr->flags, AST_FLAGS_ALL);
1164 ast_copy_string(cdr_copy->linkedid, it_cdr->linkedid, sizeof(cdr_copy->linkedid));
1165 cdr_copy->disposition = it_cdr->disposition;
1166 cdr_copy->sequence = it_cdr->sequence;
1169 copy_variables(&cdr_copy->varshead, &it_cdr->party_a.variables);
1170 AST_LIST_TRAVERSE(&it_cdr->party_b.variables, it_var, entries) {
1172 struct ast_var_t *newvariable;
1173 AST_LIST_TRAVERSE(&cdr_copy->varshead, it_copy_var, entries) {
1174 if (!strcasecmp(ast_var_name(it_var), ast_var_name(it_copy_var))) {
1179 if (!found && (newvariable = ast_var_assign(ast_var_name(it_var), ast_var_value(it_var)))) {
1180 AST_LIST_INSERT_TAIL(&cdr_copy->varshead, newvariable, entries);
1188 cdr_prev->next = cdr_copy;
1189 cdr_prev = cdr_copy;
1197 * \brief Dispatch a CDR.
1198 * \param cdr The \ref cdr_object to dispatch
1200 * This will create a \ref ast_cdr object and publish it to the various backends
1202 static void cdr_object_dispatch(struct cdr_object *cdr)
1204 RAII_VAR(struct module_config *, mod_cfg,
1205 ao2_global_obj_ref(module_configs), ao2_cleanup);
1206 struct ast_cdr *pub_cdr;
1208 CDR_DEBUG(mod_cfg, "%p - Dispatching CDR for Party A %s, Party B %s\n", cdr,
1209 cdr->party_a.snapshot->name,
1210 cdr->party_b.snapshot ? cdr->party_b.snapshot->name : "<none>");
1211 pub_cdr = cdr_object_create_public_records(cdr);
1212 cdr_detach(pub_cdr);
1216 * \brief Set the disposition on a \ref cdr_object based on a hangupcause code
1217 * \param cdr The \ref cdr_object
1218 * \param hangupcause The Asterisk hangup cause code
1220 static void cdr_object_set_disposition(struct cdr_object *cdr, int hangupcause)
1222 RAII_VAR(struct module_config *, mod_cfg,
1223 ao2_global_obj_ref(module_configs), ao2_cleanup);
1225 /* Change the disposition based on the hang up cause */
1226 switch (hangupcause) {
1227 case AST_CAUSE_BUSY:
1228 cdr->disposition = AST_CDR_BUSY;
1230 case AST_CAUSE_CONGESTION:
1231 if (!ast_test_flag(&mod_cfg->general->settings, CDR_CONGESTION)) {
1232 cdr->disposition = AST_CDR_FAILED;
1234 cdr->disposition = AST_CDR_CONGESTION;
1237 case AST_CAUSE_NO_ROUTE_DESTINATION:
1238 case AST_CAUSE_UNREGISTERED:
1239 cdr->disposition = AST_CDR_FAILED;
1241 case AST_CAUSE_NORMAL_CLEARING:
1242 case AST_CAUSE_NO_ANSWER:
1243 cdr->disposition = AST_CDR_NOANSWER;
1251 * \brief Finalize a CDR.
1253 * This function is safe to call multiple times. Note that you can call this
1254 * explicitly before going to the finalized state if there's a chance the CDR
1255 * will be re-activated, in which case the \ref cdr_object's end time should be
1256 * cleared. This function is implicitly called when a CDR transitions to the
1257 * finalized state and right before it is dispatched
1259 * \param cdr_object The CDR to finalize
1261 static void cdr_object_finalize(struct cdr_object *cdr)
1263 if (!ast_tvzero(cdr->end)) {
1266 cdr->end = ast_tvnow();
1268 if (cdr->disposition == AST_CDR_NULL) {
1269 if (!ast_tvzero(cdr->answer)) {
1270 cdr->disposition = AST_CDR_ANSWERED;
1271 } else if (cdr->party_a.snapshot->hangupcause) {
1272 cdr_object_set_disposition(cdr, cdr->party_a.snapshot->hangupcause);
1273 } else if (cdr->party_b.snapshot && cdr->party_b.snapshot->hangupcause) {
1274 cdr_object_set_disposition(cdr, cdr->party_b.snapshot->hangupcause);
1276 cdr->disposition = AST_CDR_FAILED;
1280 /* tv_usec is suseconds_t, which could be int or long */
1281 ast_debug(1, "Finalized CDR for %s - start %ld.%06ld answer %ld.%06ld end %ld.%06ld dispo %s\n",
1282 cdr->party_a.snapshot->name,
1283 (long)cdr->start.tv_sec,
1284 (long)cdr->start.tv_usec,
1285 (long)cdr->answer.tv_sec,
1286 (long)cdr->answer.tv_usec,
1287 (long)cdr->end.tv_sec,
1288 (long)cdr->end.tv_usec,
1289 ast_cdr_disp2str(cdr->disposition));
1293 * \brief Check to see if a CDR needs to move to the finalized state because
1294 * its Party A hungup.
1296 static void cdr_object_check_party_a_hangup(struct cdr_object *cdr)
1298 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
1300 if (ast_test_flag(&mod_cfg->general->settings, CDR_END_BEFORE_H_EXTEN)
1301 && ast_test_flag(&cdr->party_a.snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)) {
1302 cdr_object_finalize(cdr);
1305 if (ast_test_flag(&cdr->party_a.snapshot->flags, AST_FLAG_DEAD)
1306 && cdr->fn_table != &finalized_state_fn_table) {
1307 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1312 * \brief Check to see if a CDR needs to be answered based on its Party A.
1313 * Note that this is safe to call as much as you want - we won't answer twice
1315 static void cdr_object_check_party_a_answer(struct cdr_object *cdr) {
1316 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
1318 if (cdr->party_a.snapshot->state == AST_STATE_UP && ast_tvzero(cdr->answer)) {
1319 cdr->answer = ast_tvnow();
1320 /* tv_usec is suseconds_t, which could be int or long */
1321 CDR_DEBUG(mod_cfg, "%p - Set answered time to %ld.%06ld\n", cdr,
1322 (long)cdr->answer.tv_sec,
1323 (long)cdr->answer.tv_usec);
1327 /* \brief Set Caller ID information on a CDR */
1328 static void cdr_object_update_cid(struct cdr_object_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot)
1330 if (!old_snapshot->snapshot) {
1331 set_variable(&old_snapshot->variables, "dnid", new_snapshot->caller_dnid);
1332 set_variable(&old_snapshot->variables, "callingsubaddr", new_snapshot->caller_subaddr);
1333 set_variable(&old_snapshot->variables, "calledsubaddr", new_snapshot->dialed_subaddr);
1336 if (!strcmp(old_snapshot->snapshot->caller_dnid, new_snapshot->caller_dnid)) {
1337 set_variable(&old_snapshot->variables, "dnid", new_snapshot->caller_dnid);
1339 if (!strcmp(old_snapshot->snapshot->caller_subaddr, new_snapshot->caller_subaddr)) {
1340 set_variable(&old_snapshot->variables, "callingsubaddr", new_snapshot->caller_subaddr);
1342 if (!strcmp(old_snapshot->snapshot->dialed_subaddr, new_snapshot->dialed_subaddr)) {
1343 set_variable(&old_snapshot->variables, "calledsubaddr", new_snapshot->dialed_subaddr);
1348 * \brief Swap an old \ref cdr_object_snapshot's \ref ast_channel_snapshot for
1349 * a new \ref ast_channel_snapshot
1350 * \param old_snapshot The old \ref cdr_object_snapshot
1351 * \param new_snapshot The new \ref ast_channel_snapshot for old_snapshot
1353 static void cdr_object_swap_snapshot(struct cdr_object_snapshot *old_snapshot,
1354 struct ast_channel_snapshot *new_snapshot)
1356 cdr_object_update_cid(old_snapshot, new_snapshot);
1357 ao2_t_replace(old_snapshot->snapshot, new_snapshot, "Swap CDR shapshot");
1360 /* BASE METHOD IMPLEMENTATIONS */
1362 static int base_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
1364 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
1366 ast_assert(strcasecmp(snapshot->name, cdr->party_a.snapshot->name) == 0);
1368 /* Finalize the CDR if we're in hangup logic and we're set to do so */
1369 if (ast_test_flag(&snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)
1370 && ast_test_flag(&mod_cfg->general->settings, CDR_END_BEFORE_H_EXTEN)) {
1371 cdr_object_finalize(cdr);
1376 * Only record the context and extension if we aren't in a subroutine, or if
1377 * we are executing hangup logic.
1379 if (!ast_test_flag(&snapshot->flags, AST_FLAG_SUBROUTINE_EXEC)
1380 || ast_test_flag(&snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)) {
1381 ast_string_field_set(cdr, context, snapshot->context);
1382 ast_string_field_set(cdr, exten, snapshot->exten);
1385 cdr_object_swap_snapshot(&cdr->party_a, snapshot);
1387 /* When Party A is originated to an application and the application exits, the stack
1388 * will attempt to clear the application and restore the dummy originate application
1389 * of "AppDialX". Prevent that, and any other application changes we might not want
1392 if (!ast_strlen_zero(snapshot->appl)
1393 && (strncasecmp(snapshot->appl, "appdial", 7) || ast_strlen_zero(cdr->appl))
1394 && !ast_test_flag(&cdr->flags, AST_CDR_LOCK_APP)) {
1395 ast_string_field_set(cdr, appl, snapshot->appl);
1396 ast_string_field_set(cdr, data, snapshot->data);
1398 /* Dial (app_dial) is a special case. Because pre-dial handlers, which
1399 * execute before the dial begins, will alter the application/data to
1400 * something people typically don't want to see, if we see a channel enter
1401 * into Dial here, we set the appl/data accordingly and lock it.
1403 if (!strcmp(snapshot->appl, "Dial")) {
1404 ast_set_flag(&cdr->flags, AST_CDR_LOCK_APP);
1408 ast_string_field_set(cdr, linkedid, snapshot->linkedid);
1409 cdr_object_check_party_a_answer(cdr);
1410 cdr_object_check_party_a_hangup(cdr);
1415 static int base_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1420 static int base_process_dial_end(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer, const char *dial_status)
1425 static enum process_bridge_enter_results base_process_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1427 /* Base process bridge enter simply indicates that we can't handle it */
1428 return BRIDGE_ENTER_NEED_CDR;
1431 static int base_process_parked_channel(struct cdr_object *cdr, struct ast_parked_call_payload *parking_info)
1433 char park_info[128];
1435 ast_assert(!strcasecmp(parking_info->parkee->name, cdr->party_a.snapshot->name));
1437 /* Update Party A information regardless */
1438 cdr->fn_table->process_party_a(cdr, parking_info->parkee);
1440 /* Fake out where we're parked */
1441 ast_string_field_set(cdr, appl, "Park");
1442 snprintf(park_info, sizeof(park_info), "%s:%u", parking_info->parkinglot, parking_info->parkingspace);
1443 ast_string_field_set(cdr, data, park_info);
1445 /* Prevent any further changes to the App/Data fields for this record */
1446 ast_set_flag(&cdr->flags, AST_CDR_LOCK_APP);
1453 static void single_state_init_function(struct cdr_object *cdr) {
1454 cdr->start = ast_tvnow();
1455 cdr_object_check_party_a_answer(cdr);
1458 static void single_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
1460 /* This should never happen! */
1461 ast_assert(cdr->party_b.snapshot == NULL);
1466 static int single_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer)
1468 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
1470 if (caller && !strcasecmp(cdr->party_a.snapshot->name, caller->name)) {
1471 base_process_party_a(cdr, caller);
1472 CDR_DEBUG(mod_cfg, "%p - Updated Party A %s snapshot\n", cdr,
1473 cdr->party_a.snapshot->name);
1474 cdr_object_swap_snapshot(&cdr->party_b, peer);
1475 CDR_DEBUG(mod_cfg, "%p - Updated Party B %s snapshot\n", cdr,
1476 cdr->party_b.snapshot->name);
1478 /* If we have two parties, lock the application that caused the
1479 * two parties to be associated. This prevents mid-call event
1480 * macros/gosubs from perturbing the CDR application/data
1482 ast_set_flag(&cdr->flags, AST_CDR_LOCK_APP);
1483 } else if (!strcasecmp(cdr->party_a.snapshot->name, peer->name)) {
1484 /* We're the entity being dialed, i.e., outbound origination */
1485 base_process_party_a(cdr, peer);
1486 CDR_DEBUG(mod_cfg, "%p - Updated Party A %s snapshot\n", cdr,
1487 cdr->party_a.snapshot->name);
1490 cdr_object_transition_state(cdr, &dial_state_fn_table);
1495 * \brief Handle a comparison between our \ref cdr_object and a \ref cdr_object
1496 * already in the bridge while in the Single state. The goal of this is to find
1497 * a Party B for our CDR.
1499 * \param cdr Our \ref cdr_object in the Single state
1500 * \param cand_cdr The \ref cdr_object already in the Bridge state
1502 * \retval 0 The cand_cdr had a Party A or Party B that we could use as our
1504 * \retval 1 No party in the cand_cdr could be used as our Party B
1506 static int single_state_bridge_enter_comparison(struct cdr_object *cdr,
1507 struct cdr_object *cand_cdr)
1509 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
1510 struct cdr_object_snapshot *party_a;
1512 /* Don't match on ourselves */
1513 if (!strcasecmp(cdr->party_a.snapshot->name, cand_cdr->party_a.snapshot->name)) {
1517 /* Try the candidate CDR's Party A first */
1518 party_a = cdr_object_pick_party_a(&cdr->party_a, &cand_cdr->party_a);
1519 if (!strcasecmp(party_a->snapshot->name, cdr->party_a.snapshot->name)) {
1520 CDR_DEBUG(mod_cfg, "%p - Party A %s has new Party B %s\n",
1521 cdr, cdr->party_a.snapshot->name, cand_cdr->party_a.snapshot->name);
1522 cdr_object_snapshot_copy(&cdr->party_b, &cand_cdr->party_a);
1523 if (!cand_cdr->party_b.snapshot) {
1524 /* We just stole them - finalize their CDR. Note that this won't
1525 * transition their state, it just sets the end time and the
1526 * disposition - if we need to re-activate them later, we can.
1528 cdr_object_finalize(cand_cdr);
1533 /* Try their Party B, unless it's us */
1534 if (!cand_cdr->party_b.snapshot
1535 || !strcasecmp(cdr->party_a.snapshot->name, cand_cdr->party_b.snapshot->name)) {
1538 party_a = cdr_object_pick_party_a(&cdr->party_a, &cand_cdr->party_b);
1539 if (!strcasecmp(party_a->snapshot->name, cdr->party_a.snapshot->name)) {
1540 CDR_DEBUG(mod_cfg, "%p - Party A %s has new Party B %s\n",
1541 cdr, cdr->party_a.snapshot->name, cand_cdr->party_b.snapshot->name);
1542 cdr_object_snapshot_copy(&cdr->party_b, &cand_cdr->party_b);
1549 static enum process_bridge_enter_results single_state_process_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1551 struct ao2_iterator it_cdrs;
1555 ast_string_field_set(cdr, bridge, bridge->uniqueid);
1557 if (ao2_container_count(bridge->channels) == 1) {
1558 /* No one in the bridge yet but us! */
1559 cdr_object_transition_state(cdr, &bridge_state_fn_table);
1560 return BRIDGE_ENTER_ONLY_PARTY;
1563 for (it_cdrs = ao2_iterator_init(bridge->channels, 0);
1564 !success && (channel_id = ao2_iterator_next(&it_cdrs));
1565 ao2_ref(channel_id, -1)) {
1566 RAII_VAR(struct cdr_object *, cand_cdr_master,
1567 ao2_find(active_cdrs_by_channel, channel_id, OBJ_KEY),
1569 struct cdr_object *cand_cdr;
1571 if (!cand_cdr_master) {
1575 ao2_lock(cand_cdr_master);
1576 for (cand_cdr = cand_cdr_master; cand_cdr; cand_cdr = cand_cdr->next) {
1577 /* Skip any records that are not in a bridge or in this bridge.
1578 * I'm not sure how that would happen, but it pays to be careful. */
1579 if (cand_cdr->fn_table != &bridge_state_fn_table ||
1580 strcmp(cdr->bridge, cand_cdr->bridge)) {
1584 if (single_state_bridge_enter_comparison(cdr, cand_cdr)) {
1587 /* We successfully got a party B - break out */
1591 ao2_unlock(cand_cdr_master);
1593 ao2_iterator_destroy(&it_cdrs);
1595 /* We always transition state, even if we didn't get a peer */
1596 cdr_object_transition_state(cdr, &bridge_state_fn_table);
1598 /* Success implies that we have a Party B */
1600 return BRIDGE_ENTER_OBTAINED_PARTY_B;
1603 return BRIDGE_ENTER_NO_PARTY_B;
1606 static int single_state_process_parking_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1608 cdr_object_transition_state(cdr, &parked_state_fn_table);
1615 static void dial_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
1617 ast_assert(snapshot != NULL);
1619 if (!cdr->party_b.snapshot
1620 || strcasecmp(cdr->party_b.snapshot->name, snapshot->name)) {
1623 cdr_object_swap_snapshot(&cdr->party_b, snapshot);
1625 /* If party B hangs up, finalize this CDR */
1626 if (ast_test_flag(&cdr->party_b.snapshot->flags, AST_FLAG_DEAD)) {
1627 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1631 static int dial_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer)
1633 /* Don't process a begin dial here. A party A already in the dial state will
1634 * who receives a dial begin for something else will be handled by the
1635 * message router callback and will add a new CDR for the party A */
1641 * \brief Convert a dial status to a CDR disposition
1643 static enum ast_cdr_disposition dial_status_to_disposition(const char *dial_status)
1645 RAII_VAR(struct module_config *, mod_cfg,
1646 ao2_global_obj_ref(module_configs), ao2_cleanup);
1648 if (!strcmp(dial_status, "ANSWER")) {
1649 return AST_CDR_ANSWERED;
1650 } else if (!strcmp(dial_status, "BUSY")) {
1651 return AST_CDR_BUSY;
1652 } else if (!strcmp(dial_status, "CANCEL") || !strcmp(dial_status, "NOANSWER")) {
1653 return AST_CDR_NOANSWER;
1654 } else if (!strcmp(dial_status, "CONGESTION")) {
1655 if (!ast_test_flag(&mod_cfg->general->settings, CDR_CONGESTION)) {
1656 return AST_CDR_FAILED;
1658 return AST_CDR_CONGESTION;
1660 } else if (!strcmp(dial_status, "FAILED")) {
1661 return AST_CDR_FAILED;
1663 return AST_CDR_FAILED;
1666 static int dial_state_process_dial_end(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer, const char *dial_status)
1668 struct ast_channel_snapshot *party_a;
1675 ast_assert(!strcasecmp(cdr->party_a.snapshot->name, party_a->name));
1676 cdr_object_swap_snapshot(&cdr->party_a, party_a);
1678 if (cdr->party_b.snapshot) {
1679 if (strcasecmp(cdr->party_b.snapshot->name, peer->name)) {
1680 /* Not the status for this CDR - defer back to the message router */
1683 cdr_object_swap_snapshot(&cdr->party_b, peer);
1686 /* Set the disposition based on the dial string. */
1687 cdr->disposition = dial_status_to_disposition(dial_status);
1688 if (cdr->disposition == AST_CDR_ANSWERED) {
1689 /* Switch to dial pending to wait and see what the caller does */
1690 cdr_object_transition_state(cdr, &dialed_pending_state_fn_table);
1692 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1698 static enum process_bridge_enter_results dial_state_process_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1700 struct ao2_iterator it_cdrs;
1704 ast_string_field_set(cdr, bridge, bridge->uniqueid);
1706 /* Get parties in the bridge */
1707 if (ao2_container_count(bridge->channels) == 1) {
1708 /* No one in the bridge yet but us! */
1709 cdr_object_transition_state(cdr, &bridge_state_fn_table);
1710 return BRIDGE_ENTER_ONLY_PARTY;
1713 for (it_cdrs = ao2_iterator_init(bridge->channels, 0);
1714 !success && (channel_id = ao2_iterator_next(&it_cdrs));
1715 ao2_ref(channel_id, -1)) {
1716 RAII_VAR(struct cdr_object *, cand_cdr_master,
1717 ao2_find(active_cdrs_by_channel, channel_id, OBJ_KEY),
1719 struct cdr_object *cand_cdr;
1721 if (!cand_cdr_master) {
1725 ao2_lock(cand_cdr_master);
1726 for (cand_cdr = cand_cdr_master; cand_cdr; cand_cdr = cand_cdr->next) {
1727 /* Skip any records that are not in a bridge or in this bridge.
1728 * I'm not sure how that would happen, but it pays to be careful. */
1729 if (cand_cdr->fn_table != &bridge_state_fn_table ||
1730 strcmp(cdr->bridge, cand_cdr->bridge)) {
1734 /* If we don't have a Party B (originated channel), skip it */
1735 if (!cdr->party_b.snapshot) {
1739 /* Skip any records that aren't our Party B */
1740 if (strcasecmp(cdr->party_b.snapshot->name, cand_cdr->party_a.snapshot->name)) {
1743 cdr_object_snapshot_copy(&cdr->party_b, &cand_cdr->party_a);
1744 /* If they have a Party B, they joined up with someone else as their
1745 * Party A. Don't finalize them as they're active. Otherwise, we
1746 * have stolen them so they need to be finalized.
1748 if (!cand_cdr->party_b.snapshot) {
1749 cdr_object_finalize(cand_cdr);
1754 ao2_unlock(cand_cdr_master);
1756 ao2_iterator_destroy(&it_cdrs);
1758 /* We always transition state, even if we didn't get a peer */
1759 cdr_object_transition_state(cdr, &bridge_state_fn_table);
1761 /* Success implies that we have a Party B */
1763 return BRIDGE_ENTER_OBTAINED_PARTY_B;
1765 return BRIDGE_ENTER_NO_PARTY_B;
1768 /* DIALED PENDING STATE */
1770 static int dialed_pending_state_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
1772 /* If we get a CEP change, we're executing dialplan. If we have a Party B
1773 * that means we need a new CDR; otherwise, switch us over to single.
1775 if (snapshot_cep_changed(cdr->party_a.snapshot, snapshot)) {
1776 if (cdr->party_b.snapshot) {
1777 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1778 cdr->fn_table->process_party_a(cdr, snapshot);
1781 cdr_object_transition_state(cdr, &single_state_fn_table);
1782 cdr->fn_table->process_party_a(cdr, snapshot);
1786 base_process_party_a(cdr, snapshot);
1790 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)
1792 cdr_object_transition_state(cdr, &dial_state_fn_table);
1793 return cdr->fn_table->process_bridge_enter(cdr, bridge, channel);
1796 static int dialed_pending_state_process_parking_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1798 if (cdr->party_b.snapshot) {
1799 /* We can't handle this as we have a Party B - ask for a new one */
1802 cdr_object_transition_state(cdr, &parked_state_fn_table);
1806 static int dialed_pending_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer)
1808 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1810 /* Ask for a new CDR */
1816 static void bridge_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
1818 if (!cdr->party_b.snapshot
1819 || strcasecmp(cdr->party_b.snapshot->name, snapshot->name)) {
1822 cdr_object_swap_snapshot(&cdr->party_b, snapshot);
1824 /* If party B hangs up, finalize this CDR */
1825 if (ast_test_flag(&cdr->party_b.snapshot->flags, AST_FLAG_DEAD)) {
1826 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1830 static int bridge_state_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1832 if (strcmp(cdr->bridge, bridge->uniqueid)) {
1835 if (strcasecmp(cdr->party_a.snapshot->name, channel->name)
1836 && cdr->party_b.snapshot
1837 && strcasecmp(cdr->party_b.snapshot->name, channel->name)) {
1840 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1847 static int parked_state_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1849 if (strcasecmp(cdr->party_a.snapshot->name, channel->name)) {
1852 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1857 /* FINALIZED STATE */
1859 static void finalized_state_init_function(struct cdr_object *cdr)
1861 cdr_object_finalize(cdr);
1864 static int finalized_state_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
1866 RAII_VAR(struct module_config *, mod_cfg,
1867 ao2_global_obj_ref(module_configs), ao2_cleanup);
1869 if (ast_test_flag(&snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)
1870 && ast_test_flag(&mod_cfg->general->settings, CDR_END_BEFORE_H_EXTEN)) {
1874 /* Indicate that, if possible, we should get a new CDR */
1880 * \brief Filter channel snapshots by technology
1882 static int filter_channel_snapshot(struct ast_channel_snapshot *snapshot)
1884 return snapshot->tech_properties & AST_CHAN_TP_INTERNAL;
1889 * \brief Filter a channel cache update
1891 static int filter_channel_cache_message(struct ast_channel_snapshot *old_snapshot,
1892 struct ast_channel_snapshot *new_snapshot)
1896 /* Drop cache updates from certain channel technologies */
1898 ret |= filter_channel_snapshot(old_snapshot);
1901 ret |= filter_channel_snapshot(new_snapshot);
1907 static int dial_status_end(const char *dialstatus)
1909 return (strcmp(dialstatus, "RINGING") &&
1910 strcmp(dialstatus, "PROCEEDING") &&
1911 strcmp(dialstatus, "PROGRESS"));
1914 /* TOPIC ROUTER CALLBACKS */
1917 * \brief Handler for Stasis-Core dial messages
1918 * \param data Passed on
1919 * \param sub The stasis subscription for this message callback
1920 * \param topic The topic this message was published for
1921 * \param message The message
1923 static void handle_dial_message(void *data, struct stasis_subscription *sub, struct stasis_message *message)
1925 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
1926 RAII_VAR(struct cdr_object *, cdr, NULL, ao2_cleanup);
1927 struct ast_multi_channel_blob *payload = stasis_message_data(message);
1928 struct ast_channel_snapshot *caller;
1929 struct ast_channel_snapshot *peer;
1930 struct cdr_object *it_cdr;
1931 struct ast_json *dial_status_blob;
1932 const char *dial_status = NULL;
1935 caller = ast_multi_channel_blob_get_channel(payload, "caller");
1936 peer = ast_multi_channel_blob_get_channel(payload, "peer");
1937 if (!peer && !caller) {
1940 dial_status_blob = ast_json_object_get(ast_multi_channel_blob_get_json(payload), "dialstatus");
1941 if (dial_status_blob) {
1942 dial_status = ast_json_string_get(dial_status_blob);
1945 CDR_DEBUG(mod_cfg, "Dial %s message for %s, %s: %u.%08u\n",
1946 ast_strlen_zero(dial_status) ? "Begin" : "End",
1947 caller ? caller->name : "(none)",
1948 peer ? peer->name : "(none)",
1949 (unsigned int)stasis_message_timestamp(message)->tv_sec,
1950 (unsigned int)stasis_message_timestamp(message)->tv_usec);
1952 if (filter_channel_snapshot(peer) || (caller && filter_channel_snapshot(caller))) {
1956 /* Figure out who is running this show */
1958 cdr = ao2_find(active_cdrs_by_channel, caller->uniqueid, OBJ_KEY);
1960 cdr = ao2_find(active_cdrs_by_channel, peer->uniqueid, OBJ_KEY);
1964 ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", caller ? caller->name : peer->name);
1970 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
1971 if (ast_strlen_zero(dial_status)) {
1972 if (!it_cdr->fn_table->process_dial_begin) {
1975 CDR_DEBUG(mod_cfg, "%p - Processing Dial Begin message for channel %s, peer %s\n",
1977 caller ? caller->name : "(none)",
1978 peer ? peer->name : "(none)");
1979 res &= it_cdr->fn_table->process_dial_begin(it_cdr,
1982 } else if (dial_status_end(dial_status)) {
1983 if (!it_cdr->fn_table->process_dial_end) {
1986 CDR_DEBUG(mod_cfg, "%p - Processing Dial End message for channel %s, peer %s\n",
1988 caller ? caller->name : "(none)",
1989 peer ? peer->name : "(none)");
1990 it_cdr->fn_table->process_dial_end(it_cdr,
1997 /* If no CDR handled a dial begin message, make a new one */
1998 if (res && ast_strlen_zero(dial_status)) {
1999 struct cdr_object *new_cdr;
2001 new_cdr = cdr_object_create_and_append(cdr);
2006 new_cdr->fn_table->process_dial_begin(new_cdr,
2013 static int cdr_object_finalize_party_b(void *obj, void *arg, int flags)
2015 struct cdr_object *cdr = obj;
2016 struct ast_channel_snapshot *party_b = arg;
2017 struct cdr_object *it_cdr;
2018 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2019 if (it_cdr->party_b.snapshot
2020 && !strcasecmp(it_cdr->party_b.snapshot->name, party_b->name)) {
2021 /* Don't transition to the finalized state - let the Party A do
2022 * that when its ready
2024 cdr_object_finalize(it_cdr);
2030 static int cdr_object_update_party_b(void *obj, void *arg, int flags)
2032 struct cdr_object *cdr = obj;
2033 struct ast_channel_snapshot *party_b = arg;
2034 struct cdr_object *it_cdr;
2035 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2036 if (!it_cdr->fn_table->process_party_b) {
2039 if (it_cdr->party_b.snapshot
2040 && !strcasecmp(it_cdr->party_b.snapshot->name, party_b->name)) {
2041 it_cdr->fn_table->process_party_b(it_cdr, party_b);
2047 /*! \brief Determine if we need to add a new CDR based on snapshots */
2048 static int check_new_cdr_needed(struct ast_channel_snapshot *old_snapshot,
2049 struct ast_channel_snapshot *new_snapshot)
2051 RAII_VAR(struct module_config *, mod_cfg,
2052 ao2_global_obj_ref(module_configs), ao2_cleanup);
2054 /* If we're dead, we don't need a new CDR */
2056 || (ast_test_flag(&new_snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)
2057 && ast_test_flag(&mod_cfg->general->settings, CDR_END_BEFORE_H_EXTEN))) {
2061 /* Auto-fall through will increment the priority but have no application */
2062 if (ast_strlen_zero(new_snapshot->appl)) {
2066 if (old_snapshot && !snapshot_cep_changed(old_snapshot, new_snapshot)) {
2074 * \brief Handler for Stasis-Core channel cache update messages
2075 * \param data Passed on
2076 * \param sub The stasis subscription for this message callback
2077 * \param topic The topic this message was published for
2078 * \param message The message
2080 static void handle_channel_cache_message(void *data, struct stasis_subscription *sub, struct stasis_message *message)
2082 RAII_VAR(struct cdr_object *, cdr, NULL, ao2_cleanup);
2083 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
2084 struct stasis_cache_update *update = stasis_message_data(message);
2085 struct ast_channel_snapshot *old_snapshot;
2086 struct ast_channel_snapshot *new_snapshot;
2087 const char *uniqueid;
2089 struct cdr_object *it_cdr;
2091 ast_assert(update != NULL);
2092 ast_assert(ast_channel_snapshot_type() == update->type);
2094 old_snapshot = stasis_message_data(update->old_snapshot);
2095 new_snapshot = stasis_message_data(update->new_snapshot);
2096 uniqueid = new_snapshot ? new_snapshot->uniqueid : old_snapshot->uniqueid;
2097 name = new_snapshot ? new_snapshot->name : old_snapshot->name;
2099 if (filter_channel_cache_message(old_snapshot, new_snapshot)) {
2103 if (new_snapshot && !old_snapshot) {
2104 cdr = cdr_object_alloc(new_snapshot);
2109 ao2_link(active_cdrs_by_channel, cdr);
2112 /* Handle Party A */
2114 cdr = ao2_find(active_cdrs_by_channel, uniqueid, OBJ_KEY);
2117 ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", name);
2123 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2124 if (!it_cdr->fn_table->process_party_a) {
2127 all_reject &= it_cdr->fn_table->process_party_a(it_cdr, new_snapshot);
2129 if (all_reject && check_new_cdr_needed(old_snapshot, new_snapshot)) {
2130 /* We're not hung up and we have a new snapshot - we need a new CDR */
2131 struct cdr_object *new_cdr;
2132 new_cdr = cdr_object_create_and_append(cdr);
2134 new_cdr->fn_table->process_party_a(new_cdr, new_snapshot);
2138 CDR_DEBUG(mod_cfg, "%p - Beginning finalize/dispatch for %s\n", cdr, old_snapshot->name);
2139 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2140 cdr_object_finalize(it_cdr);
2142 cdr_object_dispatch(cdr);
2143 ao2_unlink(active_cdrs_by_channel, cdr);
2148 /* Handle Party B */
2150 ao2_callback(active_cdrs_by_channel, OBJ_NODATA, cdr_object_update_party_b,
2153 ao2_callback(active_cdrs_by_channel, OBJ_NODATA, cdr_object_finalize_party_b,
2159 struct bridge_leave_data {
2160 struct ast_bridge_snapshot *bridge;
2161 struct ast_channel_snapshot *channel;
2164 /*! \brief Callback used to notify CDRs of a Party B leaving the bridge */
2165 static int cdr_object_party_b_left_bridge_cb(void *obj, void *arg, int flags)
2167 struct cdr_object *cdr = obj;
2168 struct bridge_leave_data *leave_data = arg;
2169 struct cdr_object *it_cdr;
2171 if (strcmp(cdr->bridge, leave_data->bridge->uniqueid)) {
2174 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2175 if (it_cdr->fn_table != &bridge_state_fn_table) {
2178 if (!it_cdr->party_b.snapshot) {
2181 if (strcasecmp(it_cdr->party_b.snapshot->name, leave_data->channel->name)) {
2184 /* It is our Party B, in our bridge. Set the end time and let the handler
2185 * transition our CDR appropriately when we leave the bridge.
2187 cdr_object_finalize(it_cdr);
2192 /*! \brief Filter bridge messages based on bridge technology */
2193 static int filter_bridge_messages(struct ast_bridge_snapshot *bridge)
2195 /* Ignore holding bridge technology messages. We treat this simply as an application
2196 * that a channel enters into.
2198 if (!strcmp(bridge->technology, "holding_bridge") && strcmp(bridge->subclass, "parking")) {
2205 * \brief Handler for when a channel leaves a bridge
2206 * \param data Passed on
2207 * \param sub The stasis subscription for this message callback
2208 * \param topic The topic this message was published for
2209 * \param message The message - hopefully a bridge one!
2211 static void handle_bridge_leave_message(void *data, struct stasis_subscription *sub,
2212 struct stasis_message *message)
2214 struct ast_bridge_blob *update = stasis_message_data(message);
2215 struct ast_bridge_snapshot *bridge = update->bridge;
2216 struct ast_channel_snapshot *channel = update->channel;
2217 RAII_VAR(struct module_config *, mod_cfg,
2218 ao2_global_obj_ref(module_configs), ao2_cleanup);
2219 RAII_VAR(struct cdr_object *, cdr,
2220 ao2_find(active_cdrs_by_channel, channel->uniqueid, OBJ_KEY),
2222 struct cdr_object *it_cdr;
2223 struct bridge_leave_data leave_data = {
2227 int left_bridge = 0;
2229 if (filter_bridge_messages(bridge)) {
2233 if (filter_channel_snapshot(channel)) {
2237 CDR_DEBUG(mod_cfg, "Bridge Leave message for %s: %u.%08u\n",
2239 (unsigned int)stasis_message_timestamp(message)->tv_sec,
2240 (unsigned int)stasis_message_timestamp(message)->tv_usec);
2243 ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", channel->name);
2250 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2251 if (!it_cdr->fn_table->process_bridge_leave) {
2254 CDR_DEBUG(mod_cfg, "%p - Processing Bridge Leave for %s\n",
2255 it_cdr, channel->name);
2256 if (!it_cdr->fn_table->process_bridge_leave(it_cdr, bridge, channel)) {
2257 ast_string_field_set(it_cdr, bridge, "");
2266 if (strcmp(bridge->subclass, "parking")) {
2268 ao2_callback(active_cdrs_by_channel, OBJ_NODATA,
2269 cdr_object_party_b_left_bridge_cb,
2276 * \brief Create a new CDR, append it to an existing CDR, and update its snapshots
2278 * \note The new CDR will be automatically transitioned to the bridge state
2280 static void bridge_candidate_add_to_cdr(struct cdr_object *cdr,
2281 struct cdr_object_snapshot *party_b)
2283 RAII_VAR(struct module_config *, mod_cfg,
2284 ao2_global_obj_ref(module_configs), ao2_cleanup);
2285 struct cdr_object *new_cdr;
2287 new_cdr = cdr_object_create_and_append(cdr);
2291 cdr_object_snapshot_copy(&new_cdr->party_b, party_b);
2292 cdr_object_check_party_a_answer(new_cdr);
2293 ast_string_field_set(new_cdr, bridge, cdr->bridge);
2294 cdr_object_transition_state(new_cdr, &bridge_state_fn_table);
2295 CDR_DEBUG(mod_cfg, "%p - Party A %s has new Party B %s\n",
2296 new_cdr, new_cdr->party_a.snapshot->name,
2297 party_b->snapshot->name);
2301 * \brief Process a single \ref bridge_candidate
2303 * When a CDR enters a bridge, it needs to make pairings with everyone else
2304 * that it is not currently paired with. This function determines, for the
2305 * CDR for the channel that entered the bridge and the CDR for every other
2306 * channel currently in the bridge, who is Party A and makes new CDRs.
2308 * \param cdr The \ref cdr_obj being processed
2309 * \param cand_cdr The \ref cdr_object that is a candidate
2312 static int bridge_candidate_process(struct cdr_object *cdr, struct cdr_object *base_cand_cdr)
2314 RAII_VAR(struct module_config *, mod_cfg,
2315 ao2_global_obj_ref(module_configs), ao2_cleanup);
2316 struct cdr_object_snapshot *party_a;
2317 struct cdr_object *cand_cdr;
2319 SCOPED_AO2LOCK(lock, base_cand_cdr);
2321 for (cand_cdr = base_cand_cdr; cand_cdr; cand_cdr = cand_cdr->next) {
2322 /* Skip any records that are not in this bridge */
2323 if (strcmp(cand_cdr->bridge, cdr->bridge)) {
2327 /* If the candidate is us or someone we've taken on, pass on by */
2328 if (!strcasecmp(cdr->party_a.snapshot->name, cand_cdr->party_a.snapshot->name)
2329 || (cdr->party_b.snapshot
2330 && !strcasecmp(cdr->party_b.snapshot->name, cand_cdr->party_a.snapshot->name))) {
2334 party_a = cdr_object_pick_party_a(&cdr->party_a, &cand_cdr->party_a);
2335 /* We're party A - make a new CDR, append it to us, and set the candidate as
2337 if (!strcasecmp(party_a->snapshot->name, cdr->party_a.snapshot->name)) {
2338 bridge_candidate_add_to_cdr(cdr, &cand_cdr->party_a);
2342 /* We're Party B. Check if we can add ourselves immediately or if we need
2343 * a new CDR for them (they already have a Party B) */
2344 if (cand_cdr->party_b.snapshot
2345 && strcasecmp(cand_cdr->party_b.snapshot->name, cdr->party_a.snapshot->name)) {
2346 bridge_candidate_add_to_cdr(cand_cdr, &cdr->party_a);
2348 CDR_DEBUG(mod_cfg, "%p - Party A %s has new Party B %s\n",
2349 cand_cdr, cand_cdr->party_a.snapshot->name,
2350 cdr->party_a.snapshot->name);
2351 cdr_object_snapshot_copy(&cand_cdr->party_b, &cdr->party_a);
2352 /* It's possible that this joined at one point and was never chosen
2353 * as party A. Clear their end time, as it would be set in such a
2356 memset(&cand_cdr->end, 0, sizeof(cand_cdr->end));
2364 * \brief Handle creating bridge pairings for the \ref cdr_object that just
2366 * \param cdr The \ref cdr_object that just entered the bridge
2367 * \param bridge The \ref ast_bridge_snapshot representing the bridge it just entered
2369 static void handle_bridge_pairings(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge)
2371 struct ao2_iterator it_channels;
2374 it_channels = ao2_iterator_init(bridge->channels, 0);
2375 while ((channel_id = ao2_iterator_next(&it_channels))) {
2376 RAII_VAR(struct cdr_object *, cand_cdr,
2377 ao2_find(active_cdrs_by_channel, channel_id, OBJ_KEY),
2381 ao2_ref(channel_id, -1);
2385 bridge_candidate_process(cdr, cand_cdr);
2387 ao2_ref(channel_id, -1);
2389 ao2_iterator_destroy(&it_channels);
2392 /*! \brief Handle entering into a parking bridge
2393 * \param cdr The CDR to operate on
2394 * \param bridge The bridge the channel just entered
2395 * \param channel The channel snapshot
2397 static void handle_parking_bridge_enter_message(struct cdr_object *cdr,
2398 struct ast_bridge_snapshot *bridge,
2399 struct ast_channel_snapshot *channel)
2401 RAII_VAR(struct module_config *, mod_cfg,
2402 ao2_global_obj_ref(module_configs), ao2_cleanup);
2404 struct cdr_object *it_cdr;
2405 struct cdr_object *new_cdr;
2409 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2410 if (it_cdr->fn_table->process_parking_bridge_enter) {
2411 res &= it_cdr->fn_table->process_parking_bridge_enter(it_cdr, bridge, channel);
2413 if (it_cdr->fn_table->process_party_a) {
2414 CDR_DEBUG(mod_cfg, "%p - Updating Party A %s snapshot\n", it_cdr,
2416 it_cdr->fn_table->process_party_a(it_cdr, channel);
2421 /* No one handled it - we need a new one! */
2422 new_cdr = cdr_object_create_and_append(cdr);
2424 /* Let the single state transition us to Parked */
2425 cdr_object_transition_state(new_cdr, &single_state_fn_table);
2426 new_cdr->fn_table->process_parking_bridge_enter(new_cdr, bridge, channel);
2432 /*! \brief Handle a bridge enter message for a 'normal' bridge
2433 * \param cdr The CDR to operate on
2434 * \param bridge The bridge the channel just entered
2435 * \param channel The channel snapshot
2437 static void handle_standard_bridge_enter_message(struct cdr_object *cdr,
2438 struct ast_bridge_snapshot *bridge,
2439 struct ast_channel_snapshot *channel)
2441 RAII_VAR(struct module_config *, mod_cfg,
2442 ao2_global_obj_ref(module_configs), ao2_cleanup);
2443 enum process_bridge_enter_results result;
2444 struct cdr_object *it_cdr;
2445 struct cdr_object *new_cdr;
2446 struct cdr_object *handled_cdr = NULL;
2450 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2451 if (it_cdr->fn_table->process_party_a) {
2452 CDR_DEBUG(mod_cfg, "%p - Updating Party A %s snapshot\n", it_cdr,
2454 it_cdr->fn_table->process_party_a(it_cdr, channel);
2457 /* Notify all states that they have entered a bridge */
2458 if (it_cdr->fn_table->process_bridge_enter) {
2459 CDR_DEBUG(mod_cfg, "%p - Processing bridge enter for %s\n", it_cdr,
2461 result = it_cdr->fn_table->process_bridge_enter(it_cdr, bridge, channel);
2463 case BRIDGE_ENTER_ONLY_PARTY:
2465 case BRIDGE_ENTER_OBTAINED_PARTY_B:
2467 handled_cdr = it_cdr;
2470 case BRIDGE_ENTER_NEED_CDR:
2473 case BRIDGE_ENTER_NO_PARTY_B:
2474 /* We didn't win on any - end this CDR. If someone else comes in later
2475 * that is Party B to this CDR, it can re-activate this CDR.
2478 handled_cdr = it_cdr;
2480 cdr_object_finalize(cdr);
2486 /* Create the new matchings, but only for either:
2487 * * The first CDR in the chain that handled it. This avoids issues with
2489 * * If no one handled it, the last CDR in the chain. This would occur if
2490 * a CDR joined a bridge and it wasn't Party A for anyone. We still need
2491 * to make pairings with everyone in the bridge.
2494 handle_bridge_pairings(handled_cdr, bridge);
2496 /* Nothing handled it - we need a new one! */
2497 new_cdr = cdr_object_create_and_append(cdr);
2499 /* This is guaranteed to succeed: the new CDR is created in the single state
2500 * and will be able to handle the bridge enter message
2502 handle_standard_bridge_enter_message(cdr, bridge, channel);
2510 * \brief Handler for Stasis-Core bridge enter messages
2511 * \param data Passed on
2512 * \param sub The stasis subscription for this message callback
2513 * \param topic The topic this message was published for
2514 * \param message The message - hopefully a bridge one!
2516 static void handle_bridge_enter_message(void *data, struct stasis_subscription *sub,
2517 struct stasis_message *message)
2519 struct ast_bridge_blob *update = stasis_message_data(message);
2520 struct ast_bridge_snapshot *bridge = update->bridge;
2521 struct ast_channel_snapshot *channel = update->channel;
2522 RAII_VAR(struct cdr_object *, cdr,
2523 ao2_find(active_cdrs_by_channel, channel->uniqueid, OBJ_KEY),
2525 RAII_VAR(struct module_config *, mod_cfg,
2526 ao2_global_obj_ref(module_configs), ao2_cleanup);
2528 if (filter_bridge_messages(bridge)) {
2532 if (filter_channel_snapshot(channel)) {
2536 CDR_DEBUG(mod_cfg, "Bridge Enter message for channel %s: %u.%08u\n",
2538 (unsigned int)stasis_message_timestamp(message)->tv_sec,
2539 (unsigned int)stasis_message_timestamp(message)->tv_usec);
2542 ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", channel->name);
2547 if (!strcmp(bridge->subclass, "parking")) {
2548 handle_parking_bridge_enter_message(cdr, bridge, channel);
2550 handle_standard_bridge_enter_message(cdr, bridge, channel);
2555 * \brief Handler for when a channel is parked
2556 * \param data Passed on
2557 * \param sub The stasis subscription for this message callback
2558 * \param topic The topic this message was published for
2559 * \param message The message about who got parked
2561 static void handle_parked_call_message(void *data, struct stasis_subscription *sub,
2562 struct stasis_message *message)
2564 struct ast_parked_call_payload *payload = stasis_message_data(message);
2565 struct ast_channel_snapshot *channel = payload->parkee;
2566 RAII_VAR(struct cdr_object *, cdr, NULL, ao2_cleanup);
2567 RAII_VAR(struct module_config *, mod_cfg,
2568 ao2_global_obj_ref(module_configs), ao2_cleanup);
2570 struct cdr_object *it_cdr;
2572 /* Anything other than getting parked will be handled by other updates */
2573 if (payload->event_type != PARKED_CALL) {
2577 /* No one got parked? */
2582 if (filter_channel_snapshot(channel)) {
2586 CDR_DEBUG(mod_cfg, "Parked Call message for channel %s: %u.%08u\n",
2588 (unsigned int)stasis_message_timestamp(message)->tv_sec,
2589 (unsigned int)stasis_message_timestamp(message)->tv_usec);
2591 cdr = ao2_find(active_cdrs_by_channel, channel->uniqueid, OBJ_KEY);
2593 ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", channel->name);
2600 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2601 if (it_cdr->fn_table->process_parked_channel) {
2602 unhandled &= it_cdr->fn_table->process_parked_channel(it_cdr, payload);
2607 /* Nothing handled the messgae - we need a new one! */
2608 struct cdr_object *new_cdr = cdr_object_create_and_append(cdr);
2610 /* As the new CDR is created in the single state, it is guaranteed
2611 * to have a function for the parked call message and will handle
2613 new_cdr->fn_table->process_parked_channel(new_cdr, payload);
2622 * \brief Handler for a synchronization message
2623 * \param data Passed on
2624 * \param sub The stasis subscription for this message callback
2625 * \param topic The topic this message was published for
2626 * \param message A blank ao2 object
2628 static void handle_cdr_sync_message(void *data, struct stasis_subscription *sub,
2629 struct stasis_message *message)
2634 struct ast_cdr_config *ast_cdr_get_config(void)
2636 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
2637 ao2_ref(mod_cfg->general, +1);
2638 return mod_cfg->general;
2641 void ast_cdr_set_config(struct ast_cdr_config *config)
2643 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
2645 ao2_cleanup(mod_cfg->general);
2646 mod_cfg->general = config;
2647 ao2_ref(mod_cfg->general, +1);
2649 cdr_toggle_runtime_options();
2652 int ast_cdr_is_enabled(void)
2654 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
2655 return ast_test_flag(&mod_cfg->general->settings, CDR_ENABLED);
2658 int ast_cdr_backend_suspend(const char *name)
2661 struct cdr_beitem *i = NULL;
2663 AST_RWLIST_WRLOCK(&be_list);
2664 AST_RWLIST_TRAVERSE(&be_list, i, list) {
2665 if (!strcasecmp(name, i->name)) {
2666 ast_debug(3, "Suspending CDR backend %s\n", i->name);
2671 AST_RWLIST_UNLOCK(&be_list);
2676 int ast_cdr_backend_unsuspend(const char *name)
2679 struct cdr_beitem *i = NULL;
2681 AST_RWLIST_WRLOCK(&be_list);
2682 AST_RWLIST_TRAVERSE(&be_list, i, list) {
2683 if (!strcasecmp(name, i->name)) {
2684 ast_debug(3, "Unsuspending CDR backend %s\n", i->name);
2689 AST_RWLIST_UNLOCK(&be_list);
2694 static int cdr_generic_register(struct be_list *generic_list, const char *name, const char *desc, ast_cdrbe be)
2696 struct cdr_beitem *i = NULL;
2702 ast_log(LOG_WARNING, "CDR engine '%s' lacks backend\n", name);
2706 AST_RWLIST_WRLOCK(generic_list);
2707 AST_RWLIST_TRAVERSE(generic_list, i, list) {
2708 if (!strcasecmp(name, i->name)) {
2709 ast_log(LOG_WARNING, "Already have a CDR backend called '%s'\n", name);
2710 AST_RWLIST_UNLOCK(generic_list);
2715 if (!(i = ast_calloc(1, sizeof(*i))))
2719 ast_copy_string(i->name, name, sizeof(i->name));
2720 ast_copy_string(i->desc, desc, sizeof(i->desc));
2722 AST_RWLIST_INSERT_HEAD(generic_list, i, list);
2723 AST_RWLIST_UNLOCK(generic_list);
2728 int ast_cdr_register(const char *name, const char *desc, ast_cdrbe be)
2730 return cdr_generic_register(&be_list, name, desc, be);
2733 int ast_cdr_modifier_register(const char *name, const char *desc, ast_cdrbe be)
2735 return cdr_generic_register((struct be_list *)&mo_list, name, desc, be);
2738 static int ast_cdr_generic_unregister(struct be_list *generic_list, const char *name)
2740 struct cdr_beitem *match = NULL;
2743 AST_RWLIST_WRLOCK(generic_list);
2744 AST_RWLIST_TRAVERSE(generic_list, match, list) {
2745 if (!strcasecmp(name, match->name)) {
2751 AST_RWLIST_UNLOCK(generic_list);
2755 active_count = ao2_container_count(active_cdrs_by_channel);
2757 if (!match->suspended && active_count != 0) {
2758 AST_RWLIST_UNLOCK(generic_list);
2759 ast_log(AST_LOG_WARNING, "Unable to unregister CDR backend %s; %d CDRs are still active\n",
2760 name, active_count);
2764 AST_RWLIST_REMOVE(generic_list, match, list);
2765 AST_RWLIST_UNLOCK(generic_list);
2767 ast_verb(2, "Unregistered '%s' CDR backend\n", name);
2773 int ast_cdr_unregister(const char *name)
2775 return ast_cdr_generic_unregister(&be_list, name);
2778 int ast_cdr_modifier_unregister(const char *name)
2780 return ast_cdr_generic_unregister((struct be_list *)&mo_list, name);
2783 struct ast_cdr *ast_cdr_dup(struct ast_cdr *cdr)
2785 struct ast_cdr *newcdr;
2790 newcdr = ast_cdr_alloc();
2796 AST_LIST_HEAD_INIT_NOLOCK(&newcdr->varshead);
2797 copy_variables(&newcdr->varshead, &cdr->varshead);
2798 newcdr->next = NULL;
2803 static const char *cdr_format_var_internal(struct ast_cdr *cdr, const char *name)
2805 struct ast_var_t *variables;
2807 if (ast_strlen_zero(name)) {
2811 AST_LIST_TRAVERSE(&cdr->varshead, variables, entries) {
2812 if (!strcasecmp(name, ast_var_name(variables))) {
2813 return ast_var_value(variables);
2820 static void cdr_get_tv(struct timeval when, const char *fmt, char *buf, int bufsize)
2822 if (fmt == NULL) { /* raw mode */
2823 snprintf(buf, bufsize, "%ld.%06ld", (long)when.tv_sec, (long)when.tv_usec);
2825 buf[0] = '\0';/* Ensure the buffer is initialized. */
2829 ast_localtime(&when, &tm, NULL);
2830 ast_strftime(buf, bufsize, fmt, &tm);
2835 void ast_cdr_format_var(struct ast_cdr *cdr, const char *name, char **ret, char *workspace, int workspacelen, int raw)
2837 const char *fmt = "%Y-%m-%d %T";
2846 if (!strcasecmp(name, "clid")) {
2847 ast_copy_string(workspace, cdr->clid, workspacelen);
2848 } else if (!strcasecmp(name, "src")) {
2849 ast_copy_string(workspace, cdr->src, workspacelen);
2850 } else if (!strcasecmp(name, "dst")) {
2851 ast_copy_string(workspace, cdr->dst, workspacelen);
2852 } else if (!strcasecmp(name, "dcontext")) {
2853 ast_copy_string(workspace, cdr->dcontext, workspacelen);
2854 } else if (!strcasecmp(name, "channel")) {
2855 ast_copy_string(workspace, cdr->channel, workspacelen);
2856 } else if (!strcasecmp(name, "dstchannel")) {
2857 ast_copy_string(workspace, cdr->dstchannel, workspacelen);
2858 } else if (!strcasecmp(name, "lastapp")) {
2859 ast_copy_string(workspace, cdr->lastapp, workspacelen);
2860 } else if (!strcasecmp(name, "lastdata")) {
2861 ast_copy_string(workspace, cdr->lastdata, workspacelen);
2862 } else if (!strcasecmp(name, "start")) {
2863 cdr_get_tv(cdr->start, raw ? NULL : fmt, workspace, workspacelen);
2864 } else if (!strcasecmp(name, "answer")) {
2865 cdr_get_tv(cdr->answer, raw ? NULL : fmt, workspace, workspacelen);
2866 } else if (!strcasecmp(name, "end")) {
2867 cdr_get_tv(cdr->end, raw ? NULL : fmt, workspace, workspacelen);
2868 } else if (!strcasecmp(name, "duration")) {
2869 snprintf(workspace, workspacelen, "%ld", cdr->end.tv_sec != 0 ? cdr->duration : (long)ast_tvdiff_ms(ast_tvnow(), cdr->start) / 1000);
2870 } else if (!strcasecmp(name, "billsec")) {
2871 snprintf(workspace, workspacelen, "%ld", (cdr->billsec || !ast_tvzero(cdr->end) || ast_tvzero(cdr->answer)) ? cdr->billsec : (long)ast_tvdiff_ms(ast_tvnow(), cdr->answer) / 1000);
2872 } else if (!strcasecmp(name, "disposition")) {
2874 snprintf(workspace, workspacelen, "%ld", cdr->disposition);
2876 ast_copy_string(workspace, ast_cdr_disp2str(cdr->disposition), workspacelen);
2878 } else if (!strcasecmp(name, "amaflags")) {
2880 snprintf(workspace, workspacelen, "%ld", cdr->amaflags);
2882 ast_copy_string(workspace, ast_channel_amaflags2string(cdr->amaflags), workspacelen);
2884 } else if (!strcasecmp(name, "accountcode")) {
2885 ast_copy_string(workspace, cdr->accountcode, workspacelen);
2886 } else if (!strcasecmp(name, "peeraccount")) {
2887 ast_copy_string(workspace, cdr->peeraccount, workspacelen);
2888 } else if (!strcasecmp(name, "uniqueid")) {
2889 ast_copy_string(workspace, cdr->uniqueid, workspacelen);
2890 } else if (!strcasecmp(name, "linkedid")) {
2891 ast_copy_string(workspace, cdr->linkedid, workspacelen);
2892 } else if (!strcasecmp(name, "userfield")) {
2893 ast_copy_string(workspace, cdr->userfield, workspacelen);
2894 } else if (!strcasecmp(name, "sequence")) {
2895 snprintf(workspace, workspacelen, "%d", cdr->sequence);
2896 } else if ((varbuf = cdr_format_var_internal(cdr, name))) {
2897 ast_copy_string(workspace, varbuf, workspacelen);
2899 workspace[0] = '\0';
2902 if (!ast_strlen_zero(workspace)) {
2909 * \brief Callback that finds all CDRs that reference a particular channel by name
2911 static int cdr_object_select_all_by_name_cb(void *obj, void *arg, int flags)
2913 struct cdr_object *cdr = obj;
2914 const char *name = arg;
2916 if (!strcasecmp(cdr->party_a.snapshot->name, name) ||
2917 (cdr->party_b.snapshot && !strcasecmp(cdr->party_b.snapshot->name, name))) {
2925 * \brief Callback that finds a CDR by channel name
2927 static int cdr_object_get_by_name_cb(void *obj, void *arg, int flags)
2929 struct cdr_object *cdr = obj;
2930 const char *name = arg;
2932 if (!strcasecmp(cdr->party_a.snapshot->name, name)) {
2938 /* Read Only CDR variables */
2939 static const char * const cdr_readonly_vars[] = {
2963 int ast_cdr_setvar(const char *channel_name, const char *name, const char *value)
2965 struct cdr_object *cdr;
2966 struct cdr_object *it_cdr;
2967 struct ao2_iterator *it_cdrs;
2968 char *arg = ast_strdupa(channel_name);
2971 for (x = 0; cdr_readonly_vars[x]; x++) {
2972 if (!strcasecmp(name, cdr_readonly_vars[x])) {
2973 ast_log(LOG_ERROR, "Attempt to set the '%s' read-only variable!\n", name);
2978 it_cdrs = ao2_callback(active_cdrs_by_channel, OBJ_MULTIPLE, cdr_object_select_all_by_name_cb, arg);
2980 ast_log(AST_LOG_ERROR, "Unable to find CDR for channel %s\n", channel_name);
2984 for (; (cdr = ao2_iterator_next(it_cdrs)); ao2_unlock(cdr), ao2_cleanup(cdr)) {
2986 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2987 struct varshead *headp = NULL;
2989 if (it_cdr->fn_table == &finalized_state_fn_table && it_cdr->next != NULL) {
2992 if (!strcasecmp(channel_name, it_cdr->party_a.snapshot->name)) {
2993 headp = &it_cdr->party_a.variables;
2994 } else if (it_cdr->party_b.snapshot
2995 && !strcasecmp(channel_name, it_cdr->party_b.snapshot->name)) {
2996 headp = &it_cdr->party_b.variables;
2999 set_variable(headp, name, value);
3003 ao2_iterator_destroy(it_cdrs);
3009 * \brief Format a variable on a \ref cdr_object
3011 static void cdr_object_format_var_internal(struct cdr_object *cdr, const char *name, char *value, size_t length)
3013 struct ast_var_t *variable;
3015 AST_LIST_TRAVERSE(&cdr->party_a.variables, variable, entries) {
3016 if (!strcasecmp(name, ast_var_name(variable))) {
3017 ast_copy_string(value, ast_var_value(variable), length);
3026 * \brief Format one of the standard properties on a \ref cdr_object
3028 static int cdr_object_format_property(struct cdr_object *cdr_obj, const char *name, char *value, size_t length)
3030 struct ast_channel_snapshot *party_a = cdr_obj->party_a.snapshot;
3031 struct ast_channel_snapshot *party_b = cdr_obj->party_b.snapshot;
3033 if (!strcasecmp(name, "clid")) {
3034 ast_callerid_merge(value, length, party_a->caller_name, party_a->caller_number, "");
3035 } else if (!strcasecmp(name, "src")) {
3036 ast_copy_string(value, party_a->caller_number, length);
3037 } else if (!strcasecmp(name, "dst")) {
3038 ast_copy_string(value, party_a->exten, length);
3039 } else if (!strcasecmp(name, "dcontext")) {
3040 ast_copy_string(value, party_a->context, length);
3041 } else if (!strcasecmp(name, "channel")) {
3042 ast_copy_string(value, party_a->name, length);
3043 } else if (!strcasecmp(name, "dstchannel")) {
3045 ast_copy_string(value, party_b->name, length);
3047 ast_copy_string(value, "", length);
3049 } else if (!strcasecmp(name, "lastapp")) {
3050 ast_copy_string(value, party_a->appl, length);
3051 } else if (!strcasecmp(name, "lastdata")) {
3052 ast_copy_string(value, party_a->data, length);
3053 } else if (!strcasecmp(name, "start")) {
3054 cdr_get_tv(cdr_obj->start, NULL, value, length);
3055 } else if (!strcasecmp(name, "answer")) {
3056 cdr_get_tv(cdr_obj->answer, NULL, value, length);
3057 } else if (!strcasecmp(name, "end")) {
3058 cdr_get_tv(cdr_obj->end, NULL, value, length);
3059 } else if (!strcasecmp(name, "duration")) {
3060 snprintf(value, length, "%ld", cdr_object_get_duration(cdr_obj));
3061 } else if (!strcasecmp(name, "billsec")) {
3062 snprintf(value, length, "%ld", cdr_object_get_billsec(cdr_obj));
3063 } else if (!strcasecmp(name, "disposition")) {
3064 snprintf(value, length, "%u", cdr_obj->disposition);
3065 } else if (!strcasecmp(name, "amaflags")) {
3066 snprintf(value, length, "%d", party_a->amaflags);
3067 } else if (!strcasecmp(name, "accountcode")) {
3068 ast_copy_string(value, party_a->accountcode, length);
3069 } else if (!strcasecmp(name, "peeraccount")) {
3071 ast_copy_string(value, party_b->accountcode, length);
3073 ast_copy_string(value, "", length);
3075 } else if (!strcasecmp(name, "uniqueid")) {
3076 ast_copy_string(value, party_a->uniqueid, length);
3077 } else if (!strcasecmp(name, "linkedid")) {
3078 ast_copy_string(value, cdr_obj->linkedid, length);
3079 } else if (!strcasecmp(name, "userfield")) {
3080 ast_copy_string(value, cdr_obj->party_a.userfield, length);
3081 } else if (!strcasecmp(name, "sequence")) {
3082 snprintf(value, length, "%u", cdr_obj->sequence);
3091 * \brief Look up and retrieve a CDR object by channel name
3092 * \param name The name of the channel
3093 * \retval NULL on error
3094 * \retval The \ref cdr_object for the channel on success, with the reference
3095 * count bumped by one.
3097 static struct cdr_object *cdr_object_get_by_name(const char *name)
3101 if (ast_strlen_zero(name)) {
3105 param = ast_strdupa(name);
3106 return ao2_callback(active_cdrs_by_channel, 0, cdr_object_get_by_name_cb, param);
3109 int ast_cdr_getvar(const char *channel_name, const char *name, char *value, size_t length)
3111 RAII_VAR(struct cdr_object *, cdr, cdr_object_get_by_name(channel_name), ao2_cleanup);
3112 struct cdr_object *cdr_obj;
3115 ast_log(AST_LOG_ERROR, "Unable to find CDR for channel %s\n", channel_name);
3119 if (ast_strlen_zero(name)) {
3125 cdr_obj = cdr->last;
3126 if (cdr_object_format_property(cdr_obj, name, value, length)) {
3127 /* Property failed; attempt variable */
3128 cdr_object_format_var_internal(cdr_obj, name, value, length);
3136 int ast_cdr_serialize_variables(const char *channel_name, struct ast_str **buf, char delim, char sep)
3138 RAII_VAR(struct cdr_object *, cdr, cdr_object_get_by_name(channel_name), ao2_cleanup);
3139 struct cdr_object *it_cdr;
3140 struct ast_var_t *variable;
3142 char workspace[256];
3143 int total = 0, x = 0, i;
3146 RAII_VAR(struct module_config *, mod_cfg,
3147 ao2_global_obj_ref(module_configs), ao2_cleanup);
3149 if (ast_test_flag(&mod_cfg->general->settings, CDR_ENABLED)) {
3150 ast_log(AST_LOG_ERROR, "Unable to find CDR for channel %s\n", channel_name);
3156 ast_str_reset(*buf);
3159 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3161 ast_str_append(buf, 0, "\n");
3163 AST_LIST_TRAVERSE(&it_cdr->party_a.variables, variable, entries) {
3164 if (!(var = ast_var_name(variable))) {
3168 if (ast_str_append(buf, 0, "level %d: %s%c%s%c", x, var, delim, S_OR(ast_var_value(variable), ""), sep) < 0) {
3169 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
3176 for (i = 0; cdr_readonly_vars[i]; i++) {
3177 if (cdr_object_format_property(it_cdr, cdr_readonly_vars[i], workspace, sizeof(workspace))) {
3178 /* Unhandled read-only CDR variable. */
3183 if (!ast_strlen_zero(workspace)
3184 && ast_str_append(buf, 0, "level %d: %s%c%s%c", x, cdr_readonly_vars[i], delim, workspace, sep) < 0) {
3185 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
3195 void ast_cdr_free(struct ast_cdr *cdr)
3198 struct ast_cdr *next = cdr->next;
3200 free_variables(&cdr->varshead);
3206 struct ast_cdr *ast_cdr_alloc(void)
3210 x = ast_calloc(1, sizeof(*x));
3214 const char *ast_cdr_disp2str(int disposition)
3216 switch (disposition) {
3218 return "NO ANSWER"; /* by default, for backward compatibility */
3219 case AST_CDR_NOANSWER:
3221 case AST_CDR_FAILED:
3225 case AST_CDR_ANSWERED:
3227 case AST_CDR_CONGESTION:
3228 return "CONGESTION";
3233 struct party_b_userfield_update {
3234 const char *channel_name;
3235 const char *userfield;
3238 /*! \brief Callback used to update the userfield on Party B on all CDRs */
3239 static int cdr_object_update_party_b_userfield_cb(void *obj, void *arg, int flags)
3241 struct cdr_object *cdr = obj;
3242 struct party_b_userfield_update *info = arg;
3243 struct cdr_object *it_cdr;
3244 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3245 if (it_cdr->fn_table == &finalized_state_fn_table && it_cdr->next != NULL) {
3248 if (it_cdr->party_b.snapshot
3249 && !strcasecmp(it_cdr->party_b.snapshot->name, info->channel_name)) {
3250 strcpy(it_cdr->party_b.userfield, info->userfield);
3256 void ast_cdr_setuserfield(const char *channel_name, const char *userfield)
3258 RAII_VAR(struct cdr_object *, cdr, cdr_object_get_by_name(channel_name), ao2_cleanup);
3259 struct party_b_userfield_update party_b_info = {
3260 .channel_name = channel_name,
3261 .userfield = userfield,
3263 struct cdr_object *it_cdr;
3265 /* Handle Party A */
3268 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3269 if (it_cdr->fn_table == &finalized_state_fn_table && it_cdr->next != NULL) {
3272 ast_copy_string(it_cdr->party_a.userfield, userfield, AST_MAX_USER_FIELD);
3277 /* Handle Party B */
3278 ao2_callback(active_cdrs_by_channel, OBJ_NODATA,
3279 cdr_object_update_party_b_userfield_cb,
3284 static void post_cdr(struct ast_cdr *cdr)
3286 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
3287 struct cdr_beitem *i;
3289 for (; cdr ; cdr = cdr->next) {
3290 /* For people, who don't want to see unanswered single-channel events */
3291 if (!ast_test_flag(&mod_cfg->general->settings, CDR_UNANSWERED) &&
3292 cdr->disposition < AST_CDR_ANSWERED &&
3293 (ast_strlen_zero(cdr->channel) || ast_strlen_zero(cdr->dstchannel))) {
3294 ast_debug(1, "Skipping CDR for %s since we weren't answered\n", cdr->channel);
3299 AST_RWLIST_RDLOCK(&mo_list);
3300 AST_RWLIST_TRAVERSE(&mo_list, i, list) {
3303 AST_RWLIST_UNLOCK(&mo_list);
3305 if (ast_test_flag(cdr, AST_CDR_FLAG_DISABLE)) {
3308 AST_RWLIST_RDLOCK(&be_list);
3309 AST_RWLIST_TRAVERSE(&be_list, i, list) {
3310 if (!i->suspended) {
3314 AST_RWLIST_UNLOCK(&be_list);
3318 int ast_cdr_set_property(const char *channel_name, enum ast_cdr_options option)
3320 RAII_VAR(struct cdr_object *, cdr, cdr_object_get_by_name(channel_name), ao2_cleanup);
3321 struct cdr_object *it_cdr;
3328 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3329 if (it_cdr->fn_table == &finalized_state_fn_table) {
3332 /* Note: in general, set the flags on both the CDR record as well as the
3333 * Party A. Sometimes all we have is the Party A to look at.
3335 ast_set_flag(&it_cdr->flags, option);
3336 ast_set_flag(&it_cdr->party_a, option);
3343 int ast_cdr_clear_property(const char *channel_name, enum ast_cdr_options option)
3345 RAII_VAR(struct cdr_object *, cdr, cdr_object_get_by_name(channel_name), ao2_cleanup);
3346 struct cdr_object *it_cdr;
3353 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3354 if (it_cdr->fn_table == &finalized_state_fn_table) {
3357 ast_clear_flag(&it_cdr->flags, option);
3364 int ast_cdr_reset(const char *channel_name, int keep_variables)
3366 RAII_VAR(struct cdr_object *, cdr, cdr_object_get_by_name(channel_name), ao2_cleanup);
3367 struct ast_var_t *vardata;
3368 struct cdr_object *it_cdr;
3375 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3376 /* clear variables */
3377 if (!keep_variables) {
3378 while ((vardata = AST_LIST_REMOVE_HEAD(&it_cdr->party_a.variables, entries))) {
3379 ast_var_delete(vardata);
3381 if (cdr->party_b.snapshot) {
3382 while ((vardata = AST_LIST_REMOVE_HEAD(&it_cdr->party_b.variables, entries))) {
3383 ast_var_delete(vardata);
3388 /* Reset to initial state */
3389 memset(&it_cdr->start, 0, sizeof(it_cdr->start));
3390 memset(&it_cdr->end, 0, sizeof(it_cdr->end));
3391 memset(&it_cdr->answer, 0, sizeof(it_cdr->answer));
3392 it_cdr->start = ast_tvnow();
3393 cdr_object_check_party_a_answer(it_cdr);
3400 int ast_cdr_fork(const char *channel_name, struct ast_flags *options)
3402 RAII_VAR(struct cdr_object *, cdr, cdr_object_get_by_name(channel_name), ao2_cleanup);
3403 struct cdr_object *new_cdr;
3404 struct cdr_object *it_cdr;
3405 struct cdr_object *cdr_obj;
3412 SCOPED_AO2LOCK(lock, cdr);
3414 cdr_obj = cdr->last;
3415 if (cdr_obj->fn_table == &finalized_state_fn_table) {
3416 /* If the last CDR in the chain is finalized, don't allow a fork -
3417 * things are already dying at this point
3422 /* Copy over the basic CDR information. The Party A information is
3423 * copied over automatically as part of the append
3425 ast_debug(1, "Forking CDR for channel %s\n", cdr->party_a.snapshot->name);
3426 new_cdr = cdr_object_create_and_append(cdr);
3430 new_cdr->fn_table = cdr_obj->fn_table;
3431 ast_string_field_set(new_cdr, bridge, cdr->bridge);
3432 ast_string_field_set(new_cdr, appl, cdr->appl);
3433 ast_string_field_set(new_cdr, data, cdr->data);
3434 ast_string_field_set(new_cdr, context, cdr->context);
3435 ast_string_field_set(new_cdr, exten, cdr->exten);
3436 new_cdr->flags = cdr->flags;
3437 /* Explicitly clear the AST_CDR_LOCK_APP flag - we want
3438 * the application to be changed on the new CDR if the
3439 * dialplan demands it
3441 ast_clear_flag(&new_cdr->flags, AST_CDR_LOCK_APP);
3443 /* If there's a Party B, copy it over as well */
3444 if (cdr_obj->party_b.snapshot) {
3445 new_cdr->party_b.snapshot = cdr_obj->party_b.snapshot;
3446 ao2_ref(new_cdr->party_b.snapshot, +1);
3447 strcpy(new_cdr->party_b.userfield, cdr_obj->party_b.userfield);
3448 new_cdr->party_b.flags = cdr_obj->party_b.flags;
3449 if (ast_test_flag(options, AST_CDR_FLAG_KEEP_VARS)) {
3450 copy_variables(&new_cdr->party_b.variables, &cdr_obj->party_b.variables);
3453 new_cdr->start = cdr_obj->start;
3454 new_cdr->answer = cdr_obj->answer;
3456 /* Modify the times based on the flags passed in */
3457 if (ast_test_flag(options, AST_CDR_FLAG_SET_ANSWER)
3458 && new_cdr->party_a.snapshot->state == AST_STATE_UP) {
3459 new_cdr->answer = ast_tvnow();
3461 if (ast_test_flag(options, AST_CDR_FLAG_RESET)) {
3462 new_cdr->answer = ast_tvnow();
3463 new_cdr->start = ast_tvnow();
3466 /* Create and append, by default, copies over the variables */
3467 if (!ast_test_flag(options, AST_CDR_FLAG_KEEP_VARS)) {
3468 free_variables(&new_cdr->party_a.variables);
3471 /* Finalize any current CDRs */
3472 if (ast_test_flag(options, AST_CDR_FLAG_FINALIZE)) {
3473 for (it_cdr = cdr; it_cdr != new_cdr; it_cdr = it_cdr->next) {
3474 if (it_cdr->fn_table == &finalized_state_fn_table) {
3477 /* Force finalization on the CDR. This will bypass any checks for
3478 * end before 'h' extension.
3480 cdr_object_finalize(it_cdr);
3481 cdr_object_transition_state(it_cdr, &finalized_state_fn_table);
3489 /*! \note Don't call without cdr_batch_lock */
3490 static void reset_batch(void)
3497 /*! \note Don't call without cdr_batch_lock */
3498 static int init_batch(void)
3500 /* This is the single meta-batch used to keep track of all CDRs during the entire life of the program */
3501 if (!(batch = ast_malloc(sizeof(*batch))))
3509 static void *do_batch_backend_process(void *data)
3511 struct cdr_batch_item *processeditem;
3512 struct cdr_batch_item *batchitem = data;
3514 /* Push each CDR into storage mechanism(s) and free all the memory */
3516 post_cdr(batchitem->cdr);
3517 ast_cdr_free(batchitem->cdr);
3518 processeditem = batchitem;
3519 batchitem = batchitem->next;
3520 ast_free(processeditem);
3526 static void cdr_submit_batch(int do_shutdown)
3528 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
3529 struct cdr_batch_item *oldbatchitems = NULL;
3530 pthread_t batch_post_thread = AST_PTHREADT_NULL;
3532 /* if there's no batch, or no CDRs in the batch, then there's nothing to do */
3533 if (!batch || !batch->head) {
3537 /* move the old CDRs aside, and prepare a new CDR batch */
3538 ast_mutex_lock(&cdr_batch_lock);
3539 oldbatchitems = batch->head;
3541 ast_mutex_unlock(&cdr_batch_lock);
3543 /* if configured, spawn a new thread to post these CDRs,
3544 also try to save as much as possible if we are shutting down safely */
3545 if (ast_test_flag(&mod_cfg->general->batch_settings.settings, BATCH_MODE_SCHEDULER_ONLY) || do_shutdown) {
3546 ast_debug(1, "CDR single-threaded batch processing begins now\n");
3547 do_batch_backend_process(oldbatchitems);
3549 if (ast_pthread_create_detached_background(&batch_post_thread, NULL, do_batch_backend_process, oldbatchitems)) {
3550 ast_log(LOG_WARNING, "CDR processing thread could not detach, now trying in this thread\n");
3551 do_batch_backend_process(oldbatchitems);
3553 ast_debug(1, "CDR multi-threaded batch processing begins now\n");
3558 static int submit_scheduled_batch(const void *data)
3560 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
3561 cdr_submit_batch(0);
3562 /* manually reschedule from this point in time */
3564 ast_mutex_lock(&cdr_sched_lock);
3565 cdr_sched = ast_sched_add(sched, mod_cfg->general->batch_settings.time * 1000, submit_scheduled_batch, NULL);
3566 ast_mutex_unlock(&cdr_sched_lock);
3567 /* returning zero so the scheduler does not automatically reschedule */
3571 /*! Do not hold the batch lock while calling this function */
3572 static void submit_unscheduled_batch(void)
3574 /* Prevent two deletes from happening at the same time */
3575 ast_mutex_lock(&cdr_sched_lock);
3576 /* this is okay since we are not being called from within the scheduler */
3577 AST_SCHED_DEL(sched, cdr_sched);
3578 /* schedule the submission to occur ASAP (1 ms) */
3579 cdr_sched = ast_sched_add(sched, 1, submit_scheduled_batch, NULL);
3580 ast_mutex_unlock(&cdr_sched_lock);
3582 /* signal the do_cdr thread to wakeup early and do some work (that lazy thread ;) */
3583 ast_mutex_lock(&cdr_pending_lock);
3584 ast_cond_signal(&cdr_pending_cond);
3585 ast_mutex_unlock(&cdr_pending_lock);
3588 static void cdr_detach(struct ast_cdr *cdr)
3590 struct cdr_batch_item *newtail;
3592 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
3593 int submit_batch = 0;
3599 /* maybe they disabled CDR stuff completely, so just drop it */
3600 if (!ast_test_flag(&mod_cfg->general->settings, CDR_ENABLED)) {
3601 ast_debug(1, "Dropping CDR !\n");
3606 /* post stuff immediately if we are not in batch mode, this is legacy behaviour */
3607 if (!ast_test_flag(&mod_cfg->general->settings, CDR_BATCHMODE)) {
3613 /* otherwise, each CDR gets put into a batch list (at the end) */
3614 ast_debug(1, "CDR detaching from this thread\n");
3616 /* we'll need a new tail for every CDR */
3617 if (!(newtail = ast_calloc(1, sizeof(*newtail)))) {
3623 /* don't traverse a whole list (just keep track of the tail) */
3624 ast_mutex_lock(&cdr_batch_lock);
3628 /* new batch is empty, so point the head at the new tail */
3629 batch->head = newtail;
3631 /* already got a batch with something in it, so just append a new tail */
3632 batch->tail->next = newtail;
3635 batch->tail = newtail;
3636 curr = batch->size++;
3638 /* if we have enough stuff to post, then do it */
3639 if (curr >= (mod_cfg->general->batch_settings.size - 1)) {
3642 ast_mutex_unlock(&cdr_batch_lock);
3644 /* Don't call submit_unscheduled_batch with the cdr_batch_lock held */
3646 submit_unscheduled_batch();
3650 static void *do_cdr(void *data)
3652 struct timespec timeout;
3658 schedms = ast_sched_wait(sched);
3659 /* this shouldn't happen, but provide a 1 second default just in case */
3662 now = ast_tvadd(ast_tvnow(), ast_samp2tv(schedms, 1000));
3663 timeout.tv_sec = now.tv_sec;
3664 timeout.tv_nsec = now.tv_usec * 1000;
3665 /* prevent stuff from clobbering cdr_pending_cond, then wait on signals sent to it until the timeout expires */
3666 ast_mutex_lock(&cdr_pending_lock);
3667 ast_cond_timedwait(&cdr_pending_cond, &cdr_pending_lock, &timeout);
3668 numevents = ast_sched_runq(sched);
3669 ast_mutex_unlock(&cdr_pending_lock);
3670 ast_debug(2, "Processed %d scheduled CDR batches from the run queue\n", numevents);
3676 static char *handle_cli_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
3678 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
3682 e->command = "cdr set debug [on|off]";
3683 e->usage = "Enable or disable extra debugging in the CDR Engine. Note\n"
3684 "that this will dump debug information to the VERBOSE setting\n"
3685 "and should only be used when debugging information from the\n"
3686 "CDR engine is needed.\n";
3693 return CLI_SHOWUSAGE;
3696 if (!strcasecmp(a->argv[3], "on")
3697 && !ast_test_flag(&mod_cfg->general->settings, CDR_DEBUG)) {
3698 ast_set_flag(&mod_cfg->general->settings, CDR_DEBUG);
3699 ast_cli(a->fd, "CDR debugging enabled\n");
3700 } else if (!strcasecmp(a->argv[3], "off")
3701 && ast_test_flag(&mod_cfg->general->settings, CDR_DEBUG)) {
3702 ast_clear_flag(&mod_cfg->general->settings, CDR_DEBUG);
3703 ast_cli(a->fd, "CDR debugging disabled\n");
3709 /*! \brief Complete user input for 'cdr show' */
3710 static char *cli_complete_show(struct ast_cli_args *a)
3712 char *result = NULL;
3713 int wordlen = strlen(a->word);
3715 struct ao2_iterator it_cdrs;
3716 struct cdr_object *cdr;
3718 it_cdrs = ao2_iterator_init(active_cdrs_by_channel, 0);
3719 while ((cdr = ao2_iterator_next(&it_cdrs))) {
3720 if (!strncasecmp(a->word, cdr->party_a.snapshot->name, wordlen) &&
3722 result = ast_strdup(cdr->party_a.snapshot->name);
3730 ao2_iterator_destroy(&it_cdrs);
3734 static void cli_show_channels(struct ast_cli_args *a)
3736 struct ao2_iterator it_cdrs;
3737 struct cdr_object *cdr;
3738 char start_time_buffer[64];
3739 char answer_time_buffer[64];
3740 char end_time_buffer[64];
3742 #define TITLE_STRING "%-25.25s %-25.25s %-15.15s %-8.8s %-8.8s %-8.8s %-8.8s %-8.8s\n"
3743 #define FORMAT_STRING "%-25.25s %-25.25s %-15.15s %-8.8s %-8.8s %-8.8s %-8.8ld %-8.8ld\n"
3745 ast_cli(a->fd, "\n");
3746 ast_cli(a->fd, "Channels with Call Detail Record (CDR) Information\n");
3747 ast_cli(a->fd, "--------------------------------------------------\n");
3748 ast_cli(a->fd, TITLE_STRING, "Channel", "Dst. Channel", "LastApp", "Start", "Answer", "End", "Billsec", "Duration");
3750 it_cdrs = ao2_iterator_init(active_cdrs_by_channel, 0);
3751 for (; (cdr = ao2_iterator_next(&it_cdrs)); ao2_cleanup(cdr)) {
3752 struct cdr_object *it_cdr;
3753 struct timeval start_time = { 0, };
3754 struct timeval answer_time = { 0, };
3755 struct timeval end_time = { 0, };
3757 SCOPED_AO2LOCK(lock, cdr);
3759 /* Calculate the start, end, answer, billsec, and duration over the
3760 * life of all of the CDR entries
3762 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3763 if (snapshot_is_dialed(it_cdr->party_a.snapshot)) {
3766 if (ast_tvzero(start_time)) {
3767 start_time = it_cdr->start;
3769 if (!ast_tvzero(it_cdr->answer) && ast_tvzero(answer_time)) {
3770 answer_time = it_cdr->answer;
3774 /* If there was no start time, then all CDRs were for a dialed channel; skip */
3775 if (ast_tvzero(start_time)) {
3780 end_time = ast_tvzero(it_cdr->end) ? ast_tvnow() : it_cdr->end;
3781 cdr_get_tv(start_time, "%T", start_time_buffer, sizeof(start_time_buffer));
3782 cdr_get_tv(answer_time, "%T", answer_time_buffer, sizeof(answer_time_buffer));
3783 cdr_get_tv(end_time, "%T", end_time_buffer, sizeof(end_time_buffer));
3784 ast_cli(a->fd, FORMAT_STRING, it_cdr->party_a.snapshot->name,
3785 it_cdr->party_b.snapshot ? it_cdr->party_b.snapshot->name : "<none>",