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>
48 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
53 #include "asterisk/lock.h"
54 #include "asterisk/channel.h"
55 #include "asterisk/cdr.h"
56 #include "asterisk/callerid.h"
57 #include "asterisk/manager.h"
58 #include "asterisk/causes.h"
59 #include "asterisk/linkedlists.h"
60 #include "asterisk/utils.h"
61 #include "asterisk/sched.h"
62 #include "asterisk/config.h"
63 #include "asterisk/cli.h"
64 #include "asterisk/stringfields.h"
65 #include "asterisk/data.h"
66 #include "asterisk/config_options.h"
67 #include "asterisk/json.h"
68 #include "asterisk/parking.h"
69 #include "asterisk/stasis.h"
70 #include "asterisk/stasis_channels.h"
71 #include "asterisk/stasis_bridging.h"
72 #include "asterisk/stasis_message_router.h"
73 #include "asterisk/astobj2.h"
76 <configInfo name="cdr" language="en_US">
77 <synopsis>Call Detail Record configuration</synopsis>
79 <para>CDR is Call Detail Record, which provides logging services via a variety of
80 pluggable backend modules. Detailed call information can be recorded to
81 databases, files, etc. Useful for billing, fraud prevention, compliance with
82 Sarbanes-Oxley aka The Enron Act, QOS evaluations, and more.</para>
84 <configFile name="cdr.conf">
85 <configObject name="general">
86 <synopsis>Global settings applied to the CDR engine.</synopsis>
87 <configOption name="debug">
88 <synopsis>Enable/disable verbose CDR debugging.</synopsis>
89 <description><para>When set to <literal>True</literal>, verbose updates
90 of changes in CDR information will be logged. Note that this is only
91 of use when debugging CDR behavior.</para>
94 <configOption name="enable">
95 <synopsis>Enable/disable CDR logging.</synopsis>
96 <description><para>Define whether or not to use CDR logging. Setting this to "no" will override
97 any loading of backend CDR modules. Default is "yes".</para>
100 <configOption name="unanswered">
101 <synopsis>Log calls that are never answered.</synopsis>
102 <description><para>Define whether or not to log unanswered calls. Setting this to "yes" will
103 report every attempt to ring a phone in dialing attempts, when it was not
104 answered. For example, if you try to dial 3 extensions, and this option is "yes",
105 you will get 3 CDR's, one for each phone that was rung. Some find this information horribly
106 useless. Others find it very valuable. Note, in "yes" mode, you will see one CDR, with one of
107 the call targets on one side, and the originating channel on the other, and then one CDR for
108 each channel attempted. This may seem redundant, but cannot be helped.</para>
109 <para>In brief, this option controls the reporting of unanswered calls which only have an A
110 party. Calls which get offered to an outgoing line, but are unanswered, are still
111 logged, and that is the intended behavior. (It also results in some B side CDRs being
112 output, as they have the B side channel as their source channel, and no destination
116 <configOption name="congestion">
117 <synopsis>Log congested calls.</synopsis>
118 <description><para>Define whether or not to log congested calls. Setting this to "yes" will
119 report each call that fails to complete due to congestion conditions.</para>
122 <configOption name="endbeforehexten">
123 <synopsis>End the CDR before executing the "h" extension</synopsis>
124 <description><para>Normally, CDR's are not closed out until after all extensions are finished
125 executing. By enabling this option, the CDR will be ended before executing
126 the <literal>h</literal> extension and hangup handlers so that CDR values such as <literal>end</literal> and
127 <literal>"billsec"</literal> may be retrieved inside of this extension.
128 The default value is "no".</para>
131 <configOption name="initiatedseconds">
132 <synopsis>Count microseconds for billsec purposes</synopsis>
133 <description><para>Normally, the <literal>billsec</literal> field logged to the CDR backends
134 is simply the end time (hangup time) minus the answer time in seconds. Internally,
135 asterisk stores the time in terms of microseconds and seconds. By setting
136 initiatedseconds to <literal>yes</literal>, you can force asterisk to report any seconds
137 that were initiated (a sort of round up method). Technically, this is
138 when the microsecond part of the end time is greater than the microsecond
139 part of the answer time, then the billsec time is incremented one second.</para>
142 <configOption name="batch">
143 <synopsis>Submit CDRs to the backends for processing in batches</synopsis>
144 <description><para>Define the CDR batch mode, where instead of posting the CDR at the end of
145 every call, the data will be stored in a buffer to help alleviate load on the
146 asterisk server.</para>
147 <warning><para>Use of batch mode may result in data loss after unsafe asterisk termination,
148 i.e., software crash, power failure, kill -9, etc.</para>
152 <configOption name="size">
153 <synopsis>The maximum number of CDRs to accumulate before triggering a batch</synopsis>
154 <description><para>Define the maximum number of CDRs to accumulate in the buffer before posting
155 them to the backend engines. batch must be set to <literal>yes</literal>.</para>
158 <configOption name="time">
159 <synopsis>The maximum time to accumulate CDRs before triggering a batch</synopsis>
160 <description><para>Define the maximum time to accumulate CDRs before posting them in a batch to the
161 backend engines. If this time limit is reached, then it will post the records, regardless of the value
162 defined for size. batch must be set to <literal>yes</literal>.</para>
163 <note><para>Time is expressed in seconds.</para></note>
166 <configOption name="scheduleronly">
167 <synopsis>Post batched CDRs on their own thread instead of the scheduler</synopsis>
168 <description><para>The CDR engine uses the internal asterisk scheduler to determine when to post
169 records. Posting can either occur inside the scheduler thread, or a new
170 thread can be spawned for the submission of every batch. For small batches,
171 it might be acceptable to just use the scheduler thread, so set this to <literal>yes</literal>.
172 For large batches, say anything over size=10, a new thread is recommended, so
173 set this to <literal>no</literal>.</para>
176 <configOption name="safeshutdown">
177 <synopsis>Block shutdown of Asterisk until CDRs are submitted</synopsis>
178 <description><para>When shutting down asterisk, you can block until the CDRs are submitted. If
179 you don't, then data will likely be lost. You can always check the size of
180 the CDR batch buffer with the CLI <astcli>cdr status</astcli> command. To enable blocking on
181 submission of CDR data during asterisk shutdown, set this to <literal>yes</literal>.</para>
190 #define DEFAULT_ENABLED "1"
191 #define DEFAULT_BATCHMODE "0"
192 #define DEFAULT_UNANSWERED "0"
193 #define DEFAULT_CONGESTION "0"
194 #define DEFAULT_END_BEFORE_H_EXTEN "0"
195 #define DEFAULT_INITIATED_SECONDS "0"
197 #define DEFAULT_BATCH_SIZE "100"
198 #define MAX_BATCH_SIZE 1000
199 #define DEFAULT_BATCH_TIME "300"
200 #define MAX_BATCH_TIME 86400
201 #define DEFAULT_BATCH_SCHEDULER_ONLY "0"
202 #define DEFAULT_BATCH_SAFE_SHUTDOWN "1"
204 #define CDR_DEBUG(mod_cfg, fmt, ...) \
206 if (ast_test_flag(&(mod_cfg)->general->settings, CDR_DEBUG)) { \
207 ast_verb(1, (fmt), ##__VA_ARGS__); \
210 static void cdr_detach(struct ast_cdr *cdr);
211 static void cdr_submit_batch(int shutdown);
213 /*! \brief The configuration settings for this module */
214 struct module_config {
215 struct ast_cdr_config *general; /*< CDR global settings */
218 /*! \brief The container for the module configuration */
219 static AO2_GLOBAL_OBJ_STATIC(module_configs);
221 /*! \brief The type definition for general options */
222 static struct aco_type general_option = {
225 .item_offset = offsetof(struct module_config, general),
226 .category = "^general$",
227 .category_match = ACO_WHITELIST,
230 static void *module_config_alloc(void);
231 static void module_config_destructor(void *obj);
233 /*! \brief The file definition */
234 static struct aco_file module_file_conf = {
235 .filename = "cdr.conf",
236 .skip_category = "(^csv$|^custom$|^manager$|^odbc$|^pgsql$|^radius$|^sqlite$|^tds$|^mysql$)",
237 .types = ACO_TYPES(&general_option),
240 CONFIG_INFO_CORE("cdr", cfg_info, module_configs, module_config_alloc,
241 .files = ACO_FILES(&module_file_conf),
244 static struct aco_type *general_options[] = ACO_TYPES(&general_option);
246 /*! \brief Dispose of a module config object */
247 static void module_config_destructor(void *obj)
249 struct module_config *cfg = obj;
254 ao2_ref(cfg->general, -1);
257 /*! \brief Create a new module config object */
258 static void *module_config_alloc(void)
260 struct module_config *mod_cfg;
261 struct ast_cdr_config *cdr_config;
263 mod_cfg = ao2_alloc(sizeof(*mod_cfg), module_config_destructor);
268 cdr_config = ao2_alloc(sizeof(*cdr_config), NULL);
270 ao2_ref(cdr_config, -1);
273 mod_cfg->general = cdr_config;
278 /*! \brief Registration object for CDR backends */
283 AST_RWLIST_ENTRY(cdr_beitem) list;
286 /*! \brief List of registered backends */
287 static AST_RWLIST_HEAD_STATIC(be_list, cdr_beitem);
289 /*! \brief Queued CDR waiting to be batched */
290 struct cdr_batch_item {
292 struct cdr_batch_item *next;
295 /*! \brief The actual batch queue */
296 static struct cdr_batch {
298 struct cdr_batch_item *head;
299 struct cdr_batch_item *tail;
302 /*! \brief The global sequence counter used for CDRs */
303 static int global_cdr_sequence = 0;
305 /*! \brief Scheduler items */
306 static struct ast_sched_context *sched;
307 static int cdr_sched = -1;
308 AST_MUTEX_DEFINE_STATIC(cdr_sched_lock);
309 static pthread_t cdr_thread = AST_PTHREADT_NULL;
311 /*! \brief Lock protecting modifications to the batch queue */
312 AST_MUTEX_DEFINE_STATIC(cdr_batch_lock);
314 /*! \brief These are used to wake up the CDR thread when there's work to do */
315 AST_MUTEX_DEFINE_STATIC(cdr_pending_lock);
316 static ast_cond_t cdr_pending_cond;
318 /*! \brief A container of the active CDRs indexed by Party A channel name */
319 static struct ao2_container *active_cdrs_by_channel;
321 /*! \brief A container of the active CDRs indexed by the bridge ID */
322 static struct ao2_container *active_cdrs_by_bridge;
324 /*! \brief Message router for stasis messages regarding channel state */
325 static struct stasis_message_router *stasis_router;
327 /*! \brief Our subscription for bridges */
328 static struct stasis_subscription *bridge_subscription;
330 /*! \brief Our subscription for channels */
331 static struct stasis_subscription *channel_subscription;
333 /*! \brief Our subscription for parking */
334 static struct stasis_subscription *parking_subscription;
336 /*! \brief The parent topic for all topics we want to aggregate for CDRs */
337 static struct stasis_topic *cdr_topic;
342 * \brief A virtual table used for \ref cdr_object.
344 * Note that all functions are optional - if a subclass does not need an
345 * implementation, it is safe to leave it NULL.
347 struct cdr_object_fn_table {
348 /*! \brief Name of the subclass */
352 * \brief An initialization function. This will be called automatically
353 * when a \ref cdr_object is switched to this type in
354 * \ref cdr_object_transition_state
356 * \param cdr The \ref cdr_object that was just transitioned
358 void (* const init_function)(struct cdr_object *cdr);
361 * \brief Process a Party A update for the \ref cdr_object
363 * \param cdr The \ref cdr_object to process the update
364 * \param snapshot The snapshot for the CDR's Party A
365 * \retval 0 the CDR handled the update or ignored it
366 * \retval 1 the CDR is finalized and a new one should be made to handle it
368 int (* const process_party_a)(struct cdr_object *cdr,
369 struct ast_channel_snapshot *snapshot);
372 * \brief Process a Party B update for the \ref cdr_object
374 * \param cdr The \ref cdr_object to process the update
375 * \param snapshot The snapshot for the CDR's Party B
377 void (* const process_party_b)(struct cdr_object *cdr,
378 struct ast_channel_snapshot *snapshot);
381 * \brief Process the beginning of a dial. A dial message implies one of two
383 * The \ref cdr_object's Party A has been originated
384 * The \ref cdr_object's Party A is dialing its Party B
386 * \param cdr The \ref cdr_object
387 * \param caller The originator of the dial attempt
388 * \param peer The destination of the dial attempt
390 * \retval 0 if the parties in the dial were handled by this CDR
391 * \retval 1 if the parties could not be handled by this CDR
393 int (* const process_dial_begin)(struct cdr_object *cdr,
394 struct ast_channel_snapshot *caller,
395 struct ast_channel_snapshot *peer);
398 * \brief Process the end of a dial. At the end of a dial, a CDR can be
399 * transitioned into one of two states - DialedPending
400 * (\ref dialed_pending_state_fn_table) or Finalized
401 * (\ref finalized_state_fn_table).
403 * \param cdr The \ref cdr_object
404 * \param caller The originator of the dial attempt
405 * \param peer the Destination of the dial attempt
406 * \param dial_status What happened
408 * \retval 0 if the parties in the dial were handled by this CDR
409 * \retval 1 if the parties could not be handled by this CDR
411 int (* const process_dial_end)(struct cdr_object *cdr,
412 struct ast_channel_snapshot *caller,
413 struct ast_channel_snapshot *peer,
414 const char *dial_status);
417 * \brief Process the entering of a bridge by this CDR. The purpose of this
418 * callback is to have the CDR prepare itself for the bridge and attempt to
419 * find a valid Party B. The act of creating new CDRs based on the entering
420 * of this channel into the bridge is handled by the higher level message
423 * Note that this handler is for when a channel enters into a "normal"
424 * bridge, where people actually talk to each other. Parking is its own
427 * \param cdr The \ref cdr_object
428 * \param bridge The bridge that the Party A just entered into
429 * \param channel The \ref ast_channel_snapshot for this CDR's Party A
431 * \retval 0 This CDR found a Party B for itself and updated it, or there
432 * was no Party B to find (we're all alone)
433 * \retval 1 This CDR couldn't find a Party B and channels were in the bridge
435 int (* const process_bridge_enter)(struct cdr_object *cdr,
436 struct ast_bridge_snapshot *bridge,
437 struct ast_channel_snapshot *channel);
440 * \brief Process entering into a parking bridge.
442 * \param cdr The \ref cdr_object
443 * \param bridge The parking bridge that Party A just entered into
444 * \param channel The \ref ast_channel_snapshot for this CDR's Party A
446 * \retval 0 This CDR successfully transitioned itself into the parked state
447 * \retval 1 This CDR couldn't handle the parking transition and we need a
450 int (* const process_parking_bridge_enter)(struct cdr_object *cdr,
451 struct ast_bridge_snapshot *bridge,
452 struct ast_channel_snapshot *channel);
455 * \brief Process the leaving of a bridge by this CDR.
457 * \param cdr The \ref cdr_object
458 * \param bridge The bridge that the Party A just left
459 * \param channel The \ref ast_channel_snapshot for this CDR's Party A
461 * \retval 0 This CDR left successfully
464 int (* const process_bridge_leave)(struct cdr_object *cdr,
465 struct ast_bridge_snapshot *bridge,
466 struct ast_channel_snapshot *channel);
469 * \brief Process an update informing us that the channel got itself parked
471 * \param cdr The \ref cdr_object
472 * \param channel The parking information for this CDR's party A
474 * \retval 0 This CDR successfully parked itself
475 * \retval 1 This CDR couldn't handle the park
477 int (* const process_parked_channel)(struct cdr_object *cdr,
478 struct ast_parked_call_payload *parking_info);
481 static int base_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot);
482 static int base_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
483 static int base_process_dial_end(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer, const char *dial_status);
484 static int base_process_parked_channel(struct cdr_object *cdr, struct ast_parked_call_payload *parking_info);
486 static void single_state_init_function(struct cdr_object *cdr);
487 static void single_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot);
488 static int single_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer);
489 static int single_state_process_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
490 static int single_state_process_parking_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
493 * \brief The virtual table for the Single state.
495 * A \ref cdr_object starts off in this state. This represents a channel that
496 * has no Party B information itself.
498 * A \ref cdr_object from this state can go into any of the following states:
499 * * \ref dial_state_fn_table
500 * * \ref bridge_state_fn_table
501 * * \ref finalized_state_fn_table
503 struct cdr_object_fn_table single_state_fn_table = {
505 .init_function = single_state_init_function,
506 .process_party_a = base_process_party_a,
507 .process_party_b = single_state_process_party_b,
508 .process_dial_begin = single_state_process_dial_begin,
509 .process_dial_end = base_process_dial_end,
510 .process_bridge_enter = single_state_process_bridge_enter,
511 .process_parking_bridge_enter = single_state_process_parking_bridge_enter,
512 .process_bridge_leave = base_process_bridge_leave,
513 .process_parked_channel = base_process_parked_channel,
516 static void dial_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot);
517 static int dial_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer);
518 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);
519 static int dial_state_process_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
522 * \brief The virtual table for the Dial state.
524 * A \ref cdr_object that has begun a dial operation. This state is entered when
525 * the Party A for a CDR is determined to be dialing out to a Party B or when
526 * a CDR is for an originated channel (in which case the Party A information is
527 * the originated channel, and there is no Party B).
529 * A \ref cdr_object from this state can go in any of the following states:
530 * * \ref dialed_pending_state_fn_table
531 * * \ref bridge_state_fn_table
532 * * \ref finalized_state_fn_table
534 struct cdr_object_fn_table dial_state_fn_table = {
536 .process_party_a = base_process_party_a,
537 .process_party_b = dial_state_process_party_b,
538 .process_dial_begin = dial_state_process_dial_begin,
539 .process_dial_end = dial_state_process_dial_end,
540 .process_bridge_enter = dial_state_process_bridge_enter,
541 .process_bridge_leave = base_process_bridge_leave,
544 static int dialed_pending_state_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot);
545 static int dialed_pending_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer);
546 static int dialed_pending_state_process_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
547 static int dialed_pending_state_process_parking_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
550 * \brief The virtual table for the Dialed Pending state.
552 * A \ref cdr_object that has successfully finished a dial operation, but we
553 * don't know what they're going to do yet. It's theoretically possible to dial
554 * a party and then have that party not be bridged with the caller; likewise,
555 * an origination can complete and the channel go off and execute dialplan. The
556 * pending state acts as a bridge between either:
557 * * Entering a bridge
558 * * Getting a new CDR for new dialplan execution
559 * * Switching from being originated to executing dialplan
561 * A \ref cdr_object from this state can go in any of the following states:
562 * * \ref single_state_fn_table
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 dialed_pending_state_fn_table = {
568 .name = "DialedPending",
569 .process_party_a = dialed_pending_state_process_party_a,
570 .process_dial_begin = dialed_pending_state_process_dial_begin,
571 .process_bridge_enter = dialed_pending_state_process_bridge_enter,
572 .process_parking_bridge_enter = dialed_pending_state_process_parking_bridge_enter,
573 .process_bridge_leave = base_process_bridge_leave,
574 .process_parked_channel = base_process_parked_channel,
577 static void bridge_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot);
578 static int bridge_state_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
581 * \brief The virtual table for the Bridged state
583 * A \ref cdr_object enters this state when it receives notification that the
584 * channel has entered a bridge.
586 * A \ref cdr_object from this state can go to:
587 * * \ref finalized_state_fn_table
588 * * \ref pending_state_fn_table
590 struct cdr_object_fn_table bridge_state_fn_table = {
592 .process_party_a = base_process_party_a,
593 .process_party_b = bridge_state_process_party_b,
594 .process_bridge_leave = bridge_state_process_bridge_leave,
595 .process_parked_channel = base_process_parked_channel,
598 static void pending_state_init_function(struct cdr_object *cdr);
599 static int pending_state_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot);
600 static int pending_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer);
601 static int pending_state_process_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
602 static int pending_state_process_parking_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
605 * \brief The virtual table for the Pending state
607 * At certain times, we don't know where to go with the CDR. A good example is
608 * when a channel leaves a bridge - we don't know if the channel is about to
609 * be hung up; if it is about to go execute dialplan; dial someone; go into
610 * another bridge, etc. At these times, the CDR goes into pending and observes
611 * the messages that come in next to infer where the next logical place to go
614 * In this state, a CDR can go anywhere!
616 struct cdr_object_fn_table bridged_pending_state_fn_table = {
618 .init_function = pending_state_init_function,
619 .process_party_a = pending_state_process_party_a,
620 .process_dial_begin = pending_state_process_dial_begin,
621 .process_dial_end = base_process_dial_end,
622 .process_bridge_enter = pending_state_process_bridge_enter,
623 .process_parking_bridge_enter = pending_state_process_parking_bridge_enter,
624 .process_bridge_leave = base_process_bridge_leave,
625 .process_parked_channel = base_process_parked_channel,
628 static int parked_state_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
631 * \brief The virtual table for the Parked state
633 * Parking is weird. Unlike typical bridges, it has to be treated somewhat
634 * uniquely - a channel in a parking bridge (which is a subclass of a holding
635 * bridge) has to be handled as if the channel went into an application.
636 * However, when the channel comes out, we need a new CDR - unlike the Single
639 struct cdr_object_fn_table parked_state_fn_table = {
641 .process_party_a = base_process_party_a,
642 .process_bridge_leave = parked_state_process_bridge_leave,
643 .process_parked_channel = base_process_parked_channel,
646 static void finalized_state_init_function(struct cdr_object *cdr);
647 static int finalized_state_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot);
650 * \brief The virtual table for the finalized state.
652 * Once in the finalized state, the CDR is done. No modifications can be made
655 struct cdr_object_fn_table finalized_state_fn_table = {
657 .init_function = finalized_state_init_function,
658 .process_party_a = finalized_state_process_party_a,
661 /*! \brief A wrapper object around a snapshot.
662 * Fields that are mutable by the CDR engine are replicated here.
664 struct cdr_object_snapshot {
665 struct ast_channel_snapshot *snapshot; /*!< The channel snapshot */
666 char userfield[AST_MAX_USER_FIELD]; /*!< Userfield for the channel */
667 unsigned int flags; /*!< Specific flags for this party */
668 struct varshead variables; /*!< CDR variables for the channel */
671 /*! \brief An in-memory representation of an active CDR */
673 struct cdr_object_snapshot party_a; /*!< The Party A information */
674 struct cdr_object_snapshot party_b; /*!< The Party B information */
675 struct cdr_object_fn_table *fn_table; /*!< The current virtual table */
677 enum ast_cdr_disposition disposition; /*!< The disposition of the CDR */
678 struct timeval start; /*!< When this CDR was created */
679 struct timeval answer; /*!< Either when the channel was answered, or when the path between channels was established */
680 struct timeval end; /*!< When this CDR was finalized */
681 unsigned int sequence; /*!< A monotonically increasing number for each CDR */
682 struct ast_flags flags; /*!< Flags on the CDR */
683 AST_DECLARE_STRING_FIELDS(
684 AST_STRING_FIELD(linkedid); /*!< Linked ID. Cached here as it may change out from party A, which must be immutable */
685 AST_STRING_FIELD(name); /*!< Channel name of party A. Cached here as the party A address may change */
686 AST_STRING_FIELD(bridge); /*!< The bridge the party A happens to be in. */
687 AST_STRING_FIELD(appl); /*!< The last accepted application party A was in */
688 AST_STRING_FIELD(data); /*!< The data for the last accepted application party A was in */
690 struct cdr_object *next; /*!< The next CDR object in the chain */
691 struct cdr_object *last; /*!< The last CDR object in the chain */
695 * \brief Copy variables from one list to another
696 * \param to_list destination
697 * \param from_list source
698 * \retval The number of copied variables
700 static int copy_variables(struct varshead *to_list, struct varshead *from_list)
702 struct ast_var_t *variables, *newvariable = NULL;
703 const char *var, *val;
706 AST_LIST_TRAVERSE(from_list, variables, entries) {
708 (var = ast_var_name(variables)) && (val = ast_var_value(variables)) &&
709 !ast_strlen_zero(var) && !ast_strlen_zero(val)) {
710 newvariable = ast_var_assign(var, val);
711 AST_LIST_INSERT_HEAD(to_list, newvariable, entries);
720 * \brief Delete all variables from a variable list
721 * \param headp The head pointer to the variable list to delete
723 static void free_variables(struct varshead *headp)
725 struct ast_var_t *vardata;
727 while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries))) {
728 ast_var_delete(vardata);
733 * \brief Copy a snapshot and its details
734 * \param dst The destination
735 * \param src The source
737 static void cdr_object_snapshot_copy(struct cdr_object_snapshot *dst, struct cdr_object_snapshot *src)
740 ao2_t_ref(dst->snapshot, -1, "release old snapshot during copy");
742 dst->snapshot = src->snapshot;
743 ao2_t_ref(dst->snapshot, +1, "bump new snapshot during copy");
744 strcpy(dst->userfield, src->userfield);
745 dst->flags = src->flags;
746 copy_variables(&dst->variables, &src->variables);
750 * \brief Transition a \ref cdr_object to a new state
751 * \param cdr The \ref cdr_object to transition
752 * \param fn_table The \ref cdr_object_fn_table state to go to
754 static void cdr_object_transition_state(struct cdr_object *cdr, struct cdr_object_fn_table *fn_table)
756 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
758 CDR_DEBUG(mod_cfg, "%p - Transitioning CDR for %s from state %s to %s\n",
759 cdr, cdr->party_a.snapshot->name,
760 cdr->fn_table ? cdr->fn_table->name : "NONE", fn_table->name);
761 cdr->fn_table = fn_table;
762 if (cdr->fn_table->init_function) {
763 cdr->fn_table->init_function(cdr);
767 * \brief Hash function for containers of CDRs indexing by Party A name */
768 static int cdr_object_channel_hash_fn(const void *obj, const int flags)
770 const struct cdr_object *cdr = obj;
771 const char *name = (flags & OBJ_KEY) ? obj : cdr->name;
772 return ast_str_case_hash(name);
776 * \brief Comparison function for containers of CDRs indexing by Party A name
778 static int cdr_object_channel_cmp_fn(void *obj, void *arg, int flags)
780 struct cdr_object *left = obj;
781 struct cdr_object *right = arg;
782 const char *match = (flags & OBJ_KEY) ? arg : right->name;
783 return strcasecmp(left->name, match) ? 0 : (CMP_MATCH | CMP_STOP);
787 * \brief Hash function for containers of CDRs indexing by bridge ID
789 static int cdr_object_bridge_hash_fn(const void *obj, const int flags)
791 const struct cdr_object *cdr = obj;
792 const char *id = (flags & OBJ_KEY) ? obj : cdr->bridge;
793 return ast_str_case_hash(id);
797 * \brief Comparison function for containers of CDRs indexing by bridge. Note
798 * that we expect there to be collisions, as a single bridge may have multiple
799 * CDRs active at one point in time
801 static int cdr_object_bridge_cmp_fn(void *obj, void *arg, int flags)
803 struct cdr_object *left = obj;
804 struct cdr_object *right = arg;
805 struct cdr_object *it_cdr;
806 const char *match = (flags & OBJ_KEY) ? arg : right->bridge;
807 for (it_cdr = left; it_cdr; it_cdr = it_cdr->next) {
808 if (!strcasecmp(it_cdr->bridge, match)) {
816 * \brief \ref cdr_object Destructor
818 static void cdr_object_dtor(void *obj)
820 struct cdr_object *cdr = obj;
821 struct ast_var_t *it_var;
827 ao2_cleanup(cdr->party_a.snapshot);
828 ao2_cleanup(cdr->party_b.snapshot);
829 while ((it_var = AST_LIST_REMOVE_HEAD(&cdr->party_a.variables, entries))) {
830 ast_var_delete(it_var);
832 while ((it_var = AST_LIST_REMOVE_HEAD(&cdr->party_b.variables, entries))) {
833 ast_var_delete(it_var);
835 ast_string_field_free_memory(cdr);
838 ao2_cleanup(cdr->next);
843 * \brief \ref cdr_object constructor
844 * \param chan The \ref ast_channel_snapshot that is the CDR's Party A
846 * This implicitly sets the state of the newly created CDR to the Single state
847 * (\ref single_state_fn_table)
849 static struct cdr_object *cdr_object_alloc(struct ast_channel_snapshot *chan)
851 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
852 struct cdr_object *cdr;
854 ast_assert(chan != NULL);
856 cdr = ao2_alloc(sizeof(*cdr), cdr_object_dtor);
861 if (ast_string_field_init(cdr, 64)) {
864 ast_string_field_set(cdr, name, chan->name);
865 ast_string_field_set(cdr, linkedid, chan->linkedid);
866 cdr->disposition = AST_CDR_NULL;
867 cdr->sequence = ast_atomic_fetchadd_int(&global_cdr_sequence, +1);
869 cdr->party_a.snapshot = chan;
870 ao2_t_ref(cdr->party_a.snapshot, +1, "bump snapshot during CDR creation");
872 CDR_DEBUG(mod_cfg, "%p - Created CDR for channel %s\n", cdr, chan->name);
874 cdr_object_transition_state(cdr, &single_state_fn_table);
880 * \brief Create a new \ref cdr_object and append it to an existing chain
881 * \param cdr The \ref cdr_object to append to
883 static struct cdr_object *cdr_object_create_and_append(struct cdr_object *cdr)
885 struct cdr_object *new_cdr;
886 struct cdr_object *it_cdr;
887 struct cdr_object *cdr_last;
889 cdr_last = cdr->last;
890 new_cdr = cdr_object_alloc(cdr_last->party_a.snapshot);
894 new_cdr->disposition = AST_CDR_NULL;
896 /* Copy over the linkedid, as it may have changed */
897 ast_string_field_set(new_cdr, linkedid, cdr_last->linkedid);
898 ast_string_field_set(new_cdr, appl, cdr_last->appl);
899 ast_string_field_set(new_cdr, data, cdr_last->data);
901 /* Copy over other Party A information */
902 cdr_object_snapshot_copy(&new_cdr->party_a, &cdr_last->party_a);
904 /* Append the CDR to the end of the list */
905 for (it_cdr = cdr; it_cdr->next; it_cdr = it_cdr->next) {
906 it_cdr->last = new_cdr;
908 it_cdr->last = new_cdr;
909 it_cdr->next = new_cdr;
915 * \brief Return whether or not a \ref ast_channel_snapshot is for a channel
916 * that was created as the result of a dial operation
918 * \retval 0 the channel was not created as the result of a dial
919 * \retval 1 the channel was created as the result of a dial
921 static int snapshot_is_dialed(struct ast_channel_snapshot *snapshot)
923 return (ast_test_flag(&snapshot->flags, AST_FLAG_OUTGOING)
924 && !(ast_test_flag(&snapshot->flags, AST_FLAG_ORIGINATED)));
928 * \brief Given two CDR snapshots, figure out who should be Party A for the
930 * \param left One of the snapshots
931 * \param right The other snapshot
932 * \retval The snapshot that won
934 static struct cdr_object_snapshot *cdr_object_pick_party_a(struct cdr_object_snapshot *left, struct cdr_object_snapshot *right)
936 /* Check whether or not the party is dialed. A dialed party is never the
937 * Party A with a party that was not dialed.
939 if (!snapshot_is_dialed(left->snapshot) && snapshot_is_dialed(right->snapshot)) {
941 } else if (snapshot_is_dialed(left->snapshot) && !snapshot_is_dialed(right->snapshot)) {
945 /* Try the Party A flag */
946 if (ast_test_flag(left, AST_CDR_FLAG_PARTY_A) && !ast_test_flag(right, AST_CDR_FLAG_PARTY_A)) {
948 } else if (!ast_test_flag(right, AST_CDR_FLAG_PARTY_A) && ast_test_flag(right, AST_CDR_FLAG_PARTY_A)) {
952 /* Neither party is dialed and neither has the Party A flag - defer to
954 if (left->snapshot->creationtime.tv_sec < right->snapshot->creationtime.tv_sec) {
956 } else if (left->snapshot->creationtime.tv_sec > right->snapshot->creationtime.tv_sec) {
958 } else if (left->snapshot->creationtime.tv_usec > right->snapshot->creationtime.tv_usec) {
961 /* Okay, fine, take the left one */
967 * Compute the duration for a \ref cdr_object
969 static long cdr_object_get_duration(struct cdr_object *cdr)
971 if (ast_tvzero(cdr->end)) {
972 return (long)(ast_tvdiff_ms(ast_tvnow(), cdr->start) / 1000);
974 return (long)(ast_tvdiff_ms(cdr->end, cdr->start) / 1000);
979 * \brief Compute the billsec for a \ref cdr_object
981 static long cdr_object_get_billsec(struct cdr_object *cdr)
983 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
986 if (ast_tvzero(cdr->answer)) {
989 ms = ast_tvdiff_ms(cdr->end, cdr->answer);
990 if (ast_test_flag(&mod_cfg->general->settings, CDR_INITIATED_SECONDS)
991 && (ms % 1000 >= 500)) {
992 ms = (ms / 1000) + 1;
1001 * \brief Create a chain of \ref ast_cdr objects from a chain of \ref cdr_object
1002 * suitable for consumption by the registered CDR backends
1003 * \param cdr The \ref cdr_object to convert to a public record
1004 * \retval A chain of \ref ast_cdr objects on success
1005 * \retval NULL on failure
1007 static struct ast_cdr *cdr_object_create_public_records(struct cdr_object *cdr)
1009 struct ast_cdr *pub_cdr = NULL, *cdr_prev = NULL;
1010 struct ast_var_t *it_var, *it_copy_var;
1011 struct ast_channel_snapshot *party_a;
1012 struct ast_channel_snapshot *party_b;
1015 struct ast_cdr *cdr_copy;
1017 /* Don't create records for CDRs where the party A was a dialed channel */
1018 if (snapshot_is_dialed(cdr->party_a.snapshot)) {
1023 cdr_copy = ast_calloc(1, sizeof(*cdr_copy));
1029 party_a = cdr->party_a.snapshot;
1030 party_b = cdr->party_b.snapshot;
1033 ast_assert(party_a != NULL);
1034 ast_copy_string(cdr_copy->accountcode, party_a->accountcode, sizeof(cdr_copy->accountcode));
1035 cdr_copy->amaflags = party_a->amaflags;
1036 ast_copy_string(cdr_copy->channel, party_a->name, sizeof(cdr_copy->channel));
1037 ast_callerid_merge(cdr_copy->clid, sizeof(cdr_copy->clid), party_a->caller_name, party_a->caller_number, "");
1038 ast_copy_string(cdr_copy->src, party_a->caller_number, sizeof(cdr_copy->src));
1039 ast_copy_string(cdr_copy->uniqueid, party_a->uniqueid, sizeof(cdr_copy->uniqueid));
1040 ast_copy_string(cdr_copy->lastapp, cdr->appl, sizeof(cdr_copy->lastapp));
1041 ast_copy_string(cdr_copy->lastdata, cdr->data, sizeof(cdr_copy->lastdata));
1042 ast_copy_string(cdr_copy->dst, party_a->exten, sizeof(cdr_copy->dst));
1043 ast_copy_string(cdr_copy->dcontext, party_a->context, sizeof(cdr_copy->dcontext));
1047 ast_copy_string(cdr_copy->dstchannel, party_b->name, sizeof(cdr_copy->dstchannel));
1048 ast_copy_string(cdr_copy->peeraccount, party_b->accountcode, sizeof(cdr_copy->peeraccount));
1049 if (!ast_strlen_zero(cdr->party_b.userfield)) {
1050 snprintf(cdr_copy->userfield, sizeof(cdr_copy->userfield), "%s;%s", cdr->party_a.userfield, cdr->party_b.userfield);
1053 if (ast_strlen_zero(cdr_copy->userfield) && !ast_strlen_zero(cdr->party_a.userfield)) {
1054 ast_copy_string(cdr_copy->userfield, cdr->party_a.userfield, sizeof(cdr_copy->userfield));
1057 /* Timestamps/durations */
1058 cdr_copy->start = cdr->start;
1059 cdr_copy->answer = cdr->answer;
1060 cdr_copy->end = cdr->end;
1061 cdr_copy->billsec = cdr_object_get_billsec(cdr);
1062 cdr_copy->duration = cdr_object_get_duration(cdr);
1065 ast_copy_flags(cdr_copy, &cdr->flags, AST_FLAGS_ALL);
1066 ast_copy_string(cdr_copy->linkedid, cdr->linkedid, sizeof(cdr_copy->linkedid));
1067 cdr_copy->disposition = cdr->disposition;
1068 cdr_copy->sequence = cdr->sequence;
1071 copy_variables(&cdr_copy->varshead, &cdr->party_a.variables);
1072 AST_LIST_TRAVERSE(&cdr->party_b.variables, it_var, entries) {
1074 AST_LIST_TRAVERSE(&cdr_copy->varshead, it_copy_var, entries) {
1075 if (!strcmp(ast_var_name(it_var), ast_var_name(it_copy_var))) {
1081 AST_LIST_INSERT_TAIL(&cdr_copy->varshead, ast_var_assign(ast_var_name(it_var),
1082 ast_var_value(it_var)), entries);
1090 cdr_prev->next = cdr_copy;
1091 cdr_prev = cdr_copy;
1100 * \brief Dispatch a CDR.
1101 * \param cdr The \ref cdr_object to dispatch
1103 * This will create a \ref ast_cdr object and publish it to the various backends
1105 static void cdr_object_dispatch(struct cdr_object *cdr)
1107 RAII_VAR(struct module_config *, mod_cfg,
1108 ao2_global_obj_ref(module_configs), ao2_cleanup);
1109 struct ast_cdr *pub_cdr;
1111 CDR_DEBUG(mod_cfg, "%p - Dispatching CDR for Party A %s, Party B %s\n", cdr,
1112 cdr->party_a.snapshot->name,
1113 cdr->party_b.snapshot ? cdr->party_b.snapshot->name : "<none>");
1114 pub_cdr = cdr_object_create_public_records(cdr);
1115 cdr_detach(pub_cdr);
1119 * \brief Set the disposition on a \ref cdr_object based on a hangupcause code
1120 * \param cdr The \ref cdr_object
1121 * \param hangupcause The Asterisk hangup cause code
1123 static void cdr_object_set_disposition(struct cdr_object *cdr, int hangupcause)
1125 RAII_VAR(struct module_config *, mod_cfg,
1126 ao2_global_obj_ref(module_configs), ao2_cleanup);
1128 /* Change the disposition based on the hang up cause */
1129 switch (hangupcause) {
1130 case AST_CAUSE_BUSY:
1131 cdr->disposition = AST_CDR_BUSY;
1133 case AST_CAUSE_CONGESTION:
1134 if (!ast_test_flag(&mod_cfg->general->settings, CDR_CONGESTION)) {
1135 cdr->disposition = AST_CDR_FAILED;
1137 cdr->disposition = AST_CDR_CONGESTION;
1140 case AST_CAUSE_NO_ROUTE_DESTINATION:
1141 case AST_CAUSE_UNREGISTERED:
1142 cdr->disposition = AST_CDR_FAILED;
1144 case AST_CAUSE_NORMAL_CLEARING:
1145 case AST_CAUSE_NO_ANSWER:
1146 cdr->disposition = AST_CDR_NOANSWER;
1154 * \brief Finalize a CDR.
1156 * This function is safe to call multiple times. Note that you can call this
1157 * explicitly before going to the finalized state if there's a chance the CDR
1158 * will be re-activated, in which case the \ref cdr_object's end time should be
1159 * cleared. This function is implicitly called when a CDR transitions to the
1160 * finalized state and right before it is dispatched
1162 * \param cdr_object The CDR to finalize
1164 static void cdr_object_finalize(struct cdr_object *cdr)
1166 RAII_VAR(struct module_config *, mod_cfg,
1167 ao2_global_obj_ref(module_configs), ao2_cleanup);
1169 if (!ast_tvzero(cdr->end)) {
1172 cdr->end = ast_tvnow();
1174 if (cdr->disposition == AST_CDR_NULL) {
1175 if (!ast_tvzero(cdr->answer)) {
1176 cdr->disposition = AST_CDR_ANSWERED;
1177 } else if (cdr->party_a.snapshot->hangupcause) {
1178 cdr_object_set_disposition(cdr, cdr->party_a.snapshot->hangupcause);
1179 } else if (cdr->party_b.snapshot && cdr->party_b.snapshot->hangupcause) {
1180 cdr_object_set_disposition(cdr, cdr->party_b.snapshot->hangupcause);
1182 cdr->disposition = AST_CDR_FAILED;
1186 /* tv_usec is suseconds_t, which could be int or long */
1187 ast_debug(1, "Finalized CDR for %s - start %ld.%06ld answer %ld.%06ld end %ld.%06ld dispo %s\n",
1188 cdr->party_a.snapshot->name,
1190 (long)cdr->start.tv_usec,
1192 (long)cdr->answer.tv_usec,
1194 (long)cdr->end.tv_usec,
1195 ast_cdr_disp2str(cdr->disposition));
1199 * \brief Check to see if a CDR needs to move to the finalized state because
1200 * its Party A hungup.
1202 static void cdr_object_check_party_a_hangup(struct cdr_object *cdr)
1204 if (ast_test_flag(&cdr->party_a.snapshot->flags, AST_FLAG_ZOMBIE)
1205 && cdr->fn_table != &finalized_state_fn_table) {
1206 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1211 * \brief Check to see if a CDR needs to be answered based on its Party A.
1212 * Note that this is safe to call as much as you want - we won't answer twice
1214 static void cdr_object_check_party_a_answer(struct cdr_object *cdr) {
1215 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
1217 if (cdr->party_a.snapshot->state == AST_STATE_UP && ast_tvzero(cdr->answer)) {
1218 cdr->answer = ast_tvnow();
1219 /* tv_usec is suseconds_t, which could be int or long */
1220 CDR_DEBUG(mod_cfg, "%p - Set answered time to %ld.%06ld\n", cdr,
1222 (long)cdr->answer.tv_usec);
1228 * \brief Set a variable on a CDR object
1230 * \param headp The header pointer to the variable to set
1231 * \param name The name of the variable
1232 * \param value The value of the variable
1234 * CDRs that are in a hungup state cannot have their variables set.
1236 static void set_variable(struct varshead *headp, const char *name, const char *value)
1238 struct ast_var_t *newvariable;
1240 AST_LIST_TRAVERSE_SAFE_BEGIN(headp, newvariable, entries) {
1241 if (!strcasecmp(ast_var_name(newvariable), name)) {
1242 AST_LIST_REMOVE_CURRENT(entries);
1243 ast_var_delete(newvariable);
1247 AST_LIST_TRAVERSE_SAFE_END;
1250 newvariable = ast_var_assign(name, value);
1251 AST_LIST_INSERT_HEAD(headp, newvariable, entries);
1255 /* \brief Set Caller ID information on a CDR */
1256 static void cdr_object_update_cid(struct cdr_object_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot)
1258 if (!old_snapshot->snapshot) {
1259 set_variable(&old_snapshot->variables, "dnid", new_snapshot->caller_dnid);
1260 set_variable(&old_snapshot->variables, "callingsubaddr", new_snapshot->caller_subaddr);
1261 set_variable(&old_snapshot->variables, "calledsubaddr", new_snapshot->dialed_subaddr);
1264 if (!strcmp(old_snapshot->snapshot->caller_dnid, new_snapshot->caller_dnid)) {
1265 set_variable(&old_snapshot->variables, "dnid", new_snapshot->caller_dnid);
1267 if (!strcmp(old_snapshot->snapshot->caller_subaddr, new_snapshot->caller_subaddr)) {
1268 set_variable(&old_snapshot->variables, "callingsubaddr", new_snapshot->caller_subaddr);
1270 if (!strcmp(old_snapshot->snapshot->dialed_subaddr, new_snapshot->dialed_subaddr)) {
1271 set_variable(&old_snapshot->variables, "calledsubaddr", new_snapshot->dialed_subaddr);
1276 * \brief Swap an old \ref cdr_object_snapshot's \ref ast_channel_snapshot for
1277 * a new \ref ast_channel_snapshot
1278 * \param old_snapshot The old \ref cdr_object_snapshot
1279 * \param new_snapshot The new \ref ast_channel_snapshot for old_snapshot
1281 static void cdr_object_swap_snapshot(struct cdr_object_snapshot *old_snapshot,
1282 struct ast_channel_snapshot *new_snapshot)
1284 cdr_object_update_cid(old_snapshot, new_snapshot);
1285 if (old_snapshot->snapshot) {
1286 ao2_t_ref(old_snapshot->snapshot, -1, "Drop ref for swap");
1288 ao2_t_ref(new_snapshot, +1, "Bump ref for swap");
1289 old_snapshot->snapshot = new_snapshot;
1292 /* BASE METHOD IMPLEMENTATIONS */
1294 static int base_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
1296 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
1298 ast_assert(strcmp(snapshot->name, cdr->party_a.snapshot->name) == 0);
1299 cdr_object_swap_snapshot(&cdr->party_a, snapshot);
1301 /* When Party A is originated to an application and the application exits, the stack
1302 * will attempt to clear the application and restore the dummy originate application
1303 * of "AppDialX". Prevent that, and any other application changes we might not want
1306 if (!ast_strlen_zero(snapshot->appl)
1307 && (strncasecmp(snapshot->appl, "appdial", 7) || ast_strlen_zero(cdr->appl))
1308 && !ast_test_flag(&cdr->flags, AST_CDR_LOCK_APP)) {
1309 ast_string_field_set(cdr, appl, snapshot->appl);
1310 ast_string_field_set(cdr, data, snapshot->data);
1313 ast_string_field_set(cdr, linkedid, snapshot->linkedid);
1314 cdr_object_check_party_a_answer(cdr);
1315 cdr_object_check_party_a_hangup(cdr);
1320 static int base_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1322 /* In general, most things shouldn't get a bridge leave */
1327 static int base_process_dial_end(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer, const char *dial_status)
1329 /* In general, most things shouldn't get a dial end. */
1334 static int base_process_parked_channel(struct cdr_object *cdr, struct ast_parked_call_payload *parking_info)
1336 char park_info[128];
1338 ast_assert(!strcmp(parking_info->parkee->name, cdr->party_a.snapshot->name));
1340 /* Update Party A information regardless */
1341 cdr->fn_table->process_party_a(cdr, parking_info->parkee);
1343 /* Fake out where we're parked */
1344 ast_string_field_set(cdr, appl, "Park");
1345 snprintf(park_info, sizeof(park_info), "%s:%u", parking_info->parkinglot, parking_info->parkingspace);
1346 ast_string_field_set(cdr, data, park_info);
1348 /* Prevent any further changes to the App/Data fields for this record */
1349 ast_set_flag(&cdr->flags, AST_CDR_LOCK_APP);
1356 static void single_state_init_function(struct cdr_object *cdr) {
1357 cdr->start = ast_tvnow();
1358 cdr_object_check_party_a_answer(cdr);
1361 static void single_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
1363 /* This should never happen! */
1364 ast_assert(cdr->party_b.snapshot == NULL);
1369 static int single_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer)
1371 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
1373 if (caller && !strcmp(cdr->party_a.snapshot->name, caller->name)) {
1374 cdr_object_swap_snapshot(&cdr->party_a, caller);
1375 CDR_DEBUG(mod_cfg, "%p - Updated Party A %s snapshot\n", cdr,
1376 cdr->party_a.snapshot->name);
1377 cdr_object_swap_snapshot(&cdr->party_b, peer);
1378 CDR_DEBUG(mod_cfg, "%p - Updated Party B %s snapshot\n", cdr,
1379 cdr->party_b.snapshot->name);
1380 } else if (!strcmp(cdr->party_a.snapshot->name, peer->name)) {
1381 /* We're the entity being dialed, i.e., outbound origination */
1382 cdr_object_swap_snapshot(&cdr->party_a, peer);
1383 CDR_DEBUG(mod_cfg, "%p - Updated Party A %s snapshot\n", cdr,
1384 cdr->party_a.snapshot->name);
1387 cdr_object_transition_state(cdr, &dial_state_fn_table);
1392 * \brief Handle a comparison between our \ref cdr_object and a \ref cdr_object
1393 * already in the bridge while in the Single state. The goal of this is to find
1394 * a Party B for our CDR.
1396 * \param cdr Our \ref cdr_object in the Single state
1397 * \param cand_cdr The \ref cdr_object already in the Bridge state
1399 * \retval 0 The cand_cdr had a Party A or Party B that we could use as our
1401 * \retval 1 No party in the cand_cdr could be used as our Party B
1403 static int single_state_bridge_enter_comparison(struct cdr_object *cdr,
1404 struct cdr_object *cand_cdr)
1406 struct cdr_object_snapshot *party_a;
1408 /* Try the candidate CDR's Party A first */
1409 party_a = cdr_object_pick_party_a(&cdr->party_a, &cand_cdr->party_a);
1410 if (!strcmp(party_a->snapshot->name, cdr->party_a.snapshot->name)) {
1411 cdr_object_snapshot_copy(&cdr->party_b, &cand_cdr->party_a);
1412 if (!cand_cdr->party_b.snapshot) {
1413 /* We just stole them - finalize their CDR. Note that this won't
1414 * transition their state, it just sets the end time and the
1415 * disposition - if we need to re-activate them later, we can.
1417 cdr_object_finalize(cand_cdr);
1422 /* Try their Party B */
1423 if (!cand_cdr->party_b.snapshot) {
1426 party_a = cdr_object_pick_party_a(&cdr->party_a, &cand_cdr->party_b);
1427 if (!strcmp(party_a->snapshot->name, cdr->party_a.snapshot->name)) {
1428 cdr_object_snapshot_copy(&cdr->party_b, &cand_cdr->party_b);
1435 static int single_state_process_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1437 struct ao2_iterator *it_cdrs;
1438 struct cdr_object *cand_cdr_master;
1439 char *bridge_id = ast_strdupa(bridge->uniqueid);
1442 ast_string_field_set(cdr, bridge, bridge->uniqueid);
1444 /* Get parties in the bridge */
1445 it_cdrs = ao2_callback(active_cdrs_by_bridge, OBJ_MULTIPLE | OBJ_KEY,
1446 cdr_object_bridge_cmp_fn, bridge_id);
1448 /* No one in the bridge yet! */
1449 cdr_object_transition_state(cdr, &bridge_state_fn_table);
1453 while ((cand_cdr_master = ao2_iterator_next(it_cdrs))) {
1454 struct cdr_object *cand_cdr;
1456 ao2_lock(cand_cdr_master);
1457 for (cand_cdr = cand_cdr_master; cand_cdr; cand_cdr = cand_cdr->next) {
1458 /* Skip any records that are not in a bridge or in this bridge.
1459 * I'm not sure how that would happen, but it pays to be careful. */
1460 if (cand_cdr->fn_table != &bridge_state_fn_table ||
1461 strcmp(cdr->bridge, cand_cdr->bridge)) {
1465 if (single_state_bridge_enter_comparison(cdr, cand_cdr)) {
1468 /* We successfully got a party B - break out */
1472 ao2_unlock(cand_cdr_master);
1473 ao2_t_ref(cand_cdr_master, -1, "Drop iterator reference");
1475 ao2_iterator_destroy(it_cdrs);
1477 /* We always transition state, even if we didn't get a peer */
1478 cdr_object_transition_state(cdr, &bridge_state_fn_table);
1480 /* Success implies that we have a Party B */
1484 static int single_state_process_parking_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1486 cdr_object_transition_state(cdr, &parked_state_fn_table);
1493 static void dial_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
1495 ast_assert(snapshot != NULL);
1497 if (!cdr->party_b.snapshot || strcmp(cdr->party_b.snapshot->name, snapshot->name)) {
1500 cdr_object_swap_snapshot(&cdr->party_b, snapshot);
1502 /* If party B hangs up, finalize this CDR */
1503 if (ast_test_flag(&cdr->party_b.snapshot->flags, AST_FLAG_ZOMBIE)) {
1504 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1508 static int dial_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer)
1510 /* Don't process a begin dial here. A party A already in the dial state will
1511 * who receives a dial begin for something else will be handled by the
1512 * message router callback and will add a new CDR for the party A */
1516 /*! \internal \brief Convert a dial status to a CDR disposition */
1517 static enum ast_cdr_disposition dial_status_to_disposition(const char *dial_status)
1519 RAII_VAR(struct module_config *, mod_cfg,
1520 ao2_global_obj_ref(module_configs), ao2_cleanup);
1522 if (!strcmp(dial_status, "ANSWER")) {
1523 return AST_CDR_ANSWERED;
1524 } else if (!strcmp(dial_status, "BUSY")) {
1525 return AST_CDR_BUSY;
1526 } else if (!strcmp(dial_status, "CANCEL") || !strcmp(dial_status, "NOANSWER")) {
1527 return AST_CDR_NOANSWER;
1528 } else if (!strcmp(dial_status, "CONGESTION")) {
1529 if (!ast_test_flag(&mod_cfg->general->settings, CDR_CONGESTION)) {
1530 return AST_CDR_FAILED;
1532 return AST_CDR_CONGESTION;
1534 } else if (!strcmp(dial_status, "FAILED")) {
1535 return AST_CDR_FAILED;
1537 return AST_CDR_FAILED;
1540 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)
1542 RAII_VAR(struct module_config *, mod_cfg,
1543 ao2_global_obj_ref(module_configs), ao2_cleanup);
1544 struct ast_channel_snapshot *party_a;
1551 ast_assert(!strcmp(cdr->party_a.snapshot->name, party_a->name));
1552 cdr_object_swap_snapshot(&cdr->party_a, party_a);
1554 if (cdr->party_b.snapshot) {
1555 if (strcmp(cdr->party_b.snapshot->name, peer->name)) {
1556 /* Not the status for this CDR - defer back to the message router */
1559 cdr_object_swap_snapshot(&cdr->party_b, peer);
1562 /* Set the disposition based on the dial string. */
1563 cdr->disposition = dial_status_to_disposition(dial_status);
1564 if (cdr->disposition == AST_CDR_ANSWERED) {
1565 /* Switch to dial pending to wait and see what the caller does */
1566 cdr_object_transition_state(cdr, &dialed_pending_state_fn_table);
1568 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1574 static int dial_state_process_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1576 struct ao2_iterator *it_cdrs;
1577 char *bridge_id = ast_strdupa(bridge->uniqueid);
1578 struct cdr_object *cand_cdr_master;
1581 ast_string_field_set(cdr, bridge, bridge->uniqueid);
1583 /* Get parties in the bridge */
1584 it_cdrs = ao2_callback(active_cdrs_by_bridge, OBJ_MULTIPLE | OBJ_KEY,
1585 cdr_object_bridge_cmp_fn, bridge_id);
1587 /* No one in the bridge yet! */
1588 cdr_object_transition_state(cdr, &bridge_state_fn_table);
1592 while ((cand_cdr_master = ao2_iterator_next(it_cdrs))) {
1593 struct cdr_object *cand_cdr;
1595 ao2_lock(cand_cdr_master);
1596 for (cand_cdr = cand_cdr_master; cand_cdr; cand_cdr = cand_cdr->next) {
1597 /* Skip any records that are not in a bridge or in this bridge.
1598 * I'm not sure how that would happen, but it pays to be careful. */
1599 if (cand_cdr->fn_table != &bridge_state_fn_table ||
1600 strcmp(cdr->bridge, cand_cdr->bridge)) {
1604 /* Skip any records that aren't our Party B */
1605 if (strcmp(cdr->party_b.snapshot->name, cand_cdr->party_a.snapshot->name)) {
1609 cdr_object_snapshot_copy(&cdr->party_b, &cand_cdr->party_a);
1610 /* If they have a Party B, they joined up with someone else as their
1611 * Party A. Don't finalize them as they're active. Otherwise, we
1612 * have stolen them so they need to be finalized.
1614 if (!cand_cdr->party_b.snapshot) {
1615 cdr_object_finalize(cand_cdr);
1620 ao2_unlock(cand_cdr_master);
1621 ao2_t_ref(cand_cdr_master, -1, "Drop iterator reference");
1623 ao2_iterator_destroy(it_cdrs);
1625 /* We always transition state, even if we didn't get a peer */
1626 cdr_object_transition_state(cdr, &bridge_state_fn_table);
1628 /* Success implies that we have a Party B */
1632 /* DIALED PENDING STATE */
1634 static int dialed_pending_state_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
1636 /* If we get a CEP change, we're executing dialplan. If we have a Party B
1637 * that means we need a new CDR; otherwise, switch us over to single.
1639 if (strcmp(snapshot->context, cdr->party_a.snapshot->context)
1640 || strcmp(snapshot->exten, cdr->party_a.snapshot->exten)
1641 || snapshot->priority != cdr->party_a.snapshot->priority
1642 || strcmp(snapshot->appl, cdr->party_a.snapshot->appl)) {
1643 if (cdr->party_b.snapshot) {
1644 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1645 cdr->fn_table->process_party_a(cdr, snapshot);
1648 cdr_object_transition_state(cdr, &single_state_fn_table);
1649 cdr->fn_table->process_party_a(cdr, snapshot);
1653 base_process_party_a(cdr, snapshot);
1657 static int dialed_pending_state_process_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1659 cdr_object_transition_state(cdr, &dial_state_fn_table);
1660 return cdr->fn_table->process_bridge_enter(cdr, bridge, channel);
1663 static int dialed_pending_state_process_parking_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1665 /* We can't handle this as we have a Party B - ask for a new one */
1669 static int dialed_pending_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer)
1671 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1673 /* Ask for a new CDR */
1679 static void bridge_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
1681 if (!cdr->party_b.snapshot || strcmp(cdr->party_b.snapshot->name, snapshot->name)) {
1684 cdr_object_swap_snapshot(&cdr->party_b, snapshot);
1686 /* If party B hangs up, finalize this CDR */
1687 if (ast_test_flag(&cdr->party_b.snapshot->flags, AST_FLAG_ZOMBIE)) {
1688 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1692 static int bridge_state_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1694 if (strcmp(cdr->bridge, bridge->uniqueid)) {
1697 if (strcmp(cdr->party_a.snapshot->name, channel->name)
1698 && cdr->party_b.snapshot
1699 && strcmp(cdr->party_b.snapshot->name, channel->name)) {
1702 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1709 static void pending_state_init_function(struct cdr_object *cdr)
1711 ast_cdr_set_property(cdr->name, AST_CDR_FLAG_DISABLE);
1714 static int pending_state_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
1716 if (ast_test_flag(&snapshot->flags, AST_FLAG_ZOMBIE)) {
1720 /* Ignore if we don't get a CEP change */
1721 if (!strcmp(snapshot->context, cdr->party_a.snapshot->context)
1722 && !strcmp(snapshot->exten, cdr->party_a.snapshot->exten)
1723 && snapshot->priority == cdr->party_a.snapshot->priority) {
1727 cdr_object_transition_state(cdr, &single_state_fn_table);
1728 ast_cdr_clear_property(cdr->name, AST_CDR_FLAG_DISABLE);
1729 cdr->fn_table->process_party_a(cdr, snapshot);
1733 static int pending_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer)
1735 cdr_object_transition_state(cdr, &single_state_fn_table);
1736 ast_cdr_clear_property(cdr->name, AST_CDR_FLAG_DISABLE);
1737 return cdr->fn_table->process_dial_begin(cdr, caller, peer);
1740 static int pending_state_process_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1742 cdr_object_transition_state(cdr, &single_state_fn_table);
1743 ast_cdr_clear_property(cdr->name, AST_CDR_FLAG_DISABLE);
1744 return cdr->fn_table->process_bridge_enter(cdr, bridge, channel);
1747 static int pending_state_process_parking_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1749 cdr_object_transition_state(cdr, &single_state_fn_table);
1750 ast_cdr_clear_property(cdr->name, AST_CDR_FLAG_DISABLE);
1751 return cdr->fn_table->process_parking_bridge_enter(cdr, bridge, channel);
1756 static int parked_state_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1758 if (strcmp(cdr->party_a.snapshot->name, channel->name)) {
1761 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1766 /* FINALIZED STATE */
1768 static void finalized_state_init_function(struct cdr_object *cdr)
1770 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
1772 if (!ast_test_flag(&mod_cfg->general->settings, CDR_END_BEFORE_H_EXTEN)) {
1776 cdr_object_finalize(cdr);
1779 static int finalized_state_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
1781 if (ast_test_flag(&cdr->party_a.snapshot->flags, AST_FLAG_ZOMBIE)) {
1782 cdr_object_finalize(cdr);
1785 /* Indicate that, if possible, we should get a new CDR */
1789 /* TOPIC ROUTER CALLBACKS */
1792 * \brief Handler for Stasis-Core dial messages
1793 * \param data Passed on
1794 * \param sub The stasis subscription for this message callback
1795 * \param topic The topic this message was published for
1796 * \param message The message
1798 static void handle_dial_message(void *data, struct stasis_subscription *sub, struct stasis_topic *topic, struct stasis_message *message)
1800 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
1801 RAII_VAR(struct cdr_object *, cdr_caller, NULL, ao2_cleanup);
1802 RAII_VAR(struct cdr_object *, cdr_peer, NULL, ao2_cleanup);
1803 struct cdr_object *cdr;
1804 struct ast_multi_channel_blob *payload = stasis_message_data(message);
1805 struct ast_channel_snapshot *caller;
1806 struct ast_channel_snapshot *peer;
1807 struct ast_channel_snapshot *party_a_snapshot;
1808 struct ast_channel_snapshot *party_b_snapshot;
1809 struct cdr_object_snapshot *party_a;
1810 struct cdr_object *it_cdr;
1811 struct ast_json *dial_status_blob;
1812 const char *dial_status = NULL;
1815 caller = ast_multi_channel_blob_get_channel(payload, "caller");
1816 peer = ast_multi_channel_blob_get_channel(payload, "peer");
1817 if (!peer && !caller) {
1820 dial_status_blob = ast_json_object_get(ast_multi_channel_blob_get_json(payload), "dialstatus");
1821 if (dial_status_blob) {
1822 dial_status = ast_json_string_get(dial_status_blob);
1825 CDR_DEBUG(mod_cfg, "Dial %s message for %s, %s: %u.%08u\n",
1826 ast_strlen_zero(dial_status) ? "Begin" : "End",
1827 caller ? caller->name : "(none)",
1828 peer ? peer->name : "(none)",
1829 (unsigned int)stasis_message_timestamp(message)->tv_sec,
1830 (unsigned int)stasis_message_timestamp(message)->tv_usec);
1832 /* Figure out who is running this show */
1834 cdr_caller = ao2_find(active_cdrs_by_channel, caller->name, OBJ_KEY);
1837 cdr_peer = ao2_find(active_cdrs_by_channel, peer->name, OBJ_KEY);
1839 if (cdr_caller && cdr_peer) {
1840 party_a = cdr_object_pick_party_a(&cdr_caller->last->party_a, &cdr_peer->last->party_a);
1841 if (!strcmp(party_a->snapshot->name, cdr_caller->last->party_a.snapshot->name)) {
1843 party_a_snapshot = caller;
1844 party_b_snapshot = peer;
1847 party_a_snapshot = peer;
1848 party_b_snapshot = caller;
1850 } else if (cdr_caller) {
1852 party_a_snapshot = caller;
1853 party_b_snapshot = NULL;
1854 } else if (cdr_peer) {
1856 party_a_snapshot = NULL;
1857 party_b_snapshot = peer;
1863 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
1864 if (ast_strlen_zero(dial_status)) {
1865 if (!it_cdr->fn_table->process_dial_begin) {
1868 CDR_DEBUG(mod_cfg, "%p - Processing Dial Begin message for channel %s, peer %s\n",
1870 party_a_snapshot ? party_a_snapshot->name : "(none)",
1871 party_b_snapshot ? party_b_snapshot->name : "(none)");
1872 res &= it_cdr->fn_table->process_dial_begin(it_cdr,
1876 if (!it_cdr->fn_table->process_dial_end) {
1879 CDR_DEBUG(mod_cfg, "%p - Processing Dial End message for channel %s, peer %s\n",
1881 party_a_snapshot ? party_a_snapshot->name : "(none)",
1882 party_b_snapshot ? party_b_snapshot->name : "(none)");
1883 it_cdr->fn_table->process_dial_end(it_cdr,
1890 /* If no CDR handled a dial begin message, make a new one */
1891 if (res && ast_strlen_zero(dial_status)) {
1892 struct cdr_object *new_cdr;
1894 new_cdr = cdr_object_create_and_append(cdr);
1898 new_cdr->fn_table->process_dial_begin(new_cdr,
1905 static int cdr_object_finalize_party_b(void *obj, void *arg, int flags)
1907 struct cdr_object *cdr = obj;
1908 struct ast_channel_snapshot *party_b = arg;
1909 struct cdr_object *it_cdr;
1910 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
1911 if (it_cdr->party_b.snapshot && !strcmp(it_cdr->party_b.snapshot->name, party_b->name)) {
1912 /* Don't transition to the finalized state - let the Party A do
1913 * that when its ready
1915 cdr_object_finalize(it_cdr);
1921 static int cdr_object_update_party_b(void *obj, void *arg, int flags)
1923 struct cdr_object *cdr = obj;
1924 struct ast_channel_snapshot *party_b = arg;
1925 struct cdr_object *it_cdr;
1926 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
1927 if (!it_cdr->fn_table->process_party_b) {
1930 if (it_cdr->party_b.snapshot && !strcmp(it_cdr->party_b.snapshot->name, party_b->name)) {
1931 it_cdr->fn_table->process_party_b(it_cdr, party_b);
1937 /*! \internal \brief Filter channel snapshots by technology */
1938 static int filter_channel_snapshot(struct ast_channel_snapshot *snapshot)
1940 if (!strncmp(snapshot->name, "CBAnn", 5) ||
1941 !strncmp(snapshot->name, "CBRec", 5)) {
1947 /*! \internal \brief Filter a channel cache update */
1948 static int filter_channel_cache_message(struct ast_channel_snapshot *old_snapshot,
1949 struct ast_channel_snapshot *new_snapshot)
1953 /* Drop cache updates from certain channel technologies */
1955 ret |= filter_channel_snapshot(old_snapshot);
1958 ret |= filter_channel_snapshot(new_snapshot);
1964 /*! \brief Determine if we need to add a new CDR based on snapshots */
1965 static int check_new_cdr_needed(struct ast_channel_snapshot *old_snapshot,
1966 struct ast_channel_snapshot *new_snapshot)
1968 RAII_VAR(struct module_config *, mod_cfg,
1969 ao2_global_obj_ref(module_configs), ao2_cleanup);
1971 if (!new_snapshot) {
1975 if (ast_test_flag(&new_snapshot->flags, AST_FLAG_ZOMBIE)) {
1979 /* Auto-fall through will increment the priority but have no application */
1980 if (ast_strlen_zero(new_snapshot->appl)) {
1984 if (old_snapshot && !strcmp(old_snapshot->context, new_snapshot->context)
1985 && !strcmp(old_snapshot->exten, new_snapshot->exten)
1986 && old_snapshot->priority == new_snapshot->priority
1987 && !(strcmp(old_snapshot->appl, new_snapshot->appl))) {
1995 * \brief Handler for Stasis-Core channel cache update messages
1996 * \param data Passed on
1997 * \param sub The stasis subscription for this message callback
1998 * \param topic The topic this message was published for
1999 * \param message The message
2001 static void handle_channel_cache_message(void *data, struct stasis_subscription *sub, struct stasis_topic *topic, struct stasis_message *message)
2003 RAII_VAR(struct cdr_object *, cdr, NULL, ao2_cleanup);
2004 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
2005 struct stasis_cache_update *update = stasis_message_data(message);
2006 struct ast_channel_snapshot *old_snapshot;
2007 struct ast_channel_snapshot *new_snapshot;
2009 struct cdr_object *it_cdr;
2011 ast_assert(update != NULL);
2012 if (ast_channel_snapshot_type() != update->type) {
2016 old_snapshot = stasis_message_data(update->old_snapshot);
2017 new_snapshot = stasis_message_data(update->new_snapshot);
2018 name = new_snapshot ? new_snapshot->name : old_snapshot->name;
2020 if (filter_channel_cache_message(old_snapshot, new_snapshot)) {
2024 CDR_DEBUG(mod_cfg, "Channel Update message for %s: %u.%08u\n",
2026 (unsigned int)stasis_message_timestamp(message)->tv_sec,
2027 (unsigned int)stasis_message_timestamp(message)->tv_usec);
2029 if (new_snapshot && !old_snapshot) {
2030 cdr = cdr_object_alloc(new_snapshot);
2034 ao2_link(active_cdrs_by_channel, cdr);
2037 /* Handle Party A */
2039 cdr = ao2_find(active_cdrs_by_channel, name, OBJ_KEY);
2042 ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", name);
2047 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2048 if (!it_cdr->fn_table->process_party_a) {
2051 CDR_DEBUG(mod_cfg, "%p - Processing new channel snapshot %s\n", it_cdr, new_snapshot->name);
2052 all_reject &= it_cdr->fn_table->process_party_a(it_cdr, new_snapshot);
2054 if (all_reject && check_new_cdr_needed(old_snapshot, new_snapshot)) {
2055 /* We're not hung up and we have a new snapshot - we need a new CDR */
2056 struct cdr_object *new_cdr;
2057 new_cdr = cdr_object_create_and_append(cdr);
2059 new_cdr->fn_table->process_party_a(new_cdr, new_snapshot);
2063 CDR_DEBUG(mod_cfg, "%p - Beginning finalize/dispatch for %s\n", cdr, old_snapshot->name);
2064 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2065 cdr_object_finalize(it_cdr);
2067 cdr_object_dispatch(cdr);
2068 ao2_unlink(active_cdrs_by_channel, cdr);
2073 /* Handle Party B */
2075 ao2_callback(active_cdrs_by_channel, OBJ_NODATA, cdr_object_update_party_b,
2078 ao2_callback(active_cdrs_by_channel, OBJ_NODATA, cdr_object_finalize_party_b,
2084 struct bridge_leave_data {
2085 struct ast_bridge_snapshot *bridge;
2086 struct ast_channel_snapshot *channel;
2089 /*! \brief Callback used to notify CDRs of a Party B leaving the bridge */
2090 static int cdr_object_party_b_left_bridge_cb(void *obj, void *arg, int flags)
2092 struct cdr_object *cdr = obj;
2093 struct bridge_leave_data *leave_data = arg;
2094 struct cdr_object *it_cdr;
2096 if (strcmp(cdr->bridge, leave_data->bridge->uniqueid)) {
2099 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2100 if (it_cdr->fn_table != &bridge_state_fn_table) {
2103 if (!it_cdr->party_b.snapshot) {
2106 if (strcmp(it_cdr->party_b.snapshot->name, leave_data->channel->name)) {
2109 if (!it_cdr->fn_table->process_bridge_leave(it_cdr, leave_data->bridge, leave_data->channel)) {
2110 /* Update the end times for this CDR. We don't want to actually
2111 * finalize it, as the Party A will eventually need to leave, which
2112 * will switch the records to pending bridged.
2114 cdr_object_finalize(it_cdr);
2120 /*! \brief Filter bridge messages based on bridge technology */
2121 static int filter_bridge_messages(struct ast_bridge_snapshot *bridge)
2123 /* Ignore holding bridge technology messages. We treat this simply as an application
2124 * that a channel enters into.
2126 if (!strcmp(bridge->technology, "holding_bridge") && strcmp(bridge->subclass, "parking")) {
2133 * \brief Handler for when a channel leaves a bridge
2134 * \param data Passed on
2135 * \param sub The stasis subscription for this message callback
2136 * \param topic The topic this message was published for
2137 * \param message The message - hopefully a bridge one!
2139 static void handle_bridge_leave_message(void *data, struct stasis_subscription *sub,
2140 struct stasis_topic *topic, struct stasis_message *message)
2142 struct ast_bridge_blob *update = stasis_message_data(message);
2143 struct ast_bridge_snapshot *bridge = update->bridge;
2144 struct ast_channel_snapshot *channel = update->channel;
2145 RAII_VAR(struct module_config *, mod_cfg,
2146 ao2_global_obj_ref(module_configs), ao2_cleanup);
2147 RAII_VAR(struct cdr_object *, cdr,
2148 ao2_find(active_cdrs_by_channel, channel->name, OBJ_KEY),
2150 struct cdr_object *it_cdr;
2151 struct cdr_object *pending_cdr;
2152 struct bridge_leave_data leave_data = {
2156 int left_bridge = 0;
2158 if (filter_bridge_messages(bridge)) {
2162 CDR_DEBUG(mod_cfg, "Bridge Leave message for %s: %u.%08u\n",
2164 (unsigned int)stasis_message_timestamp(message)->tv_sec,
2165 (unsigned int)stasis_message_timestamp(message)->tv_usec);
2168 ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", channel->name);
2174 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2175 if (!it_cdr->fn_table->process_bridge_leave) {
2178 CDR_DEBUG(mod_cfg, "%p - Processing Bridge Leave for %s\n",
2179 it_cdr, channel->name);
2180 if (!it_cdr->fn_table->process_bridge_leave(it_cdr, bridge, channel)) {
2181 ast_string_field_set(it_cdr, bridge, "");
2190 if (strcmp(bridge->subclass, "parking")) {
2191 ao2_unlink(active_cdrs_by_bridge, cdr);
2194 /* Create a new pending record. If the channel decides to do something else,
2195 * the pending record will handle it - otherwise, if gets dropped.
2197 pending_cdr = cdr_object_create_and_append(cdr);
2199 cdr_object_transition_state(pending_cdr, &bridged_pending_state_fn_table);
2203 if (strcmp(bridge->subclass, "parking")) {
2205 ao2_callback(active_cdrs_by_bridge, OBJ_NODATA,
2206 cdr_object_party_b_left_bridge_cb,
2211 struct bridge_candidate {
2212 struct cdr_object *cdr; /*!< The actual CDR this candidate belongs to, either as A or B */
2213 struct cdr_object_snapshot candidate; /*!< The candidate for a new pairing */
2217 * \brief Comparison function for \ref bridge_candidate objects
2219 static int bridge_candidate_cmp_fn(void *obj, void *arg, int flags)
2221 struct bridge_candidate *left = obj;
2222 struct bridge_candidate *right = arg;
2223 const char *match = (flags & OBJ_KEY) ? arg : right->candidate.snapshot->name;
2224 return strcasecmp(left->candidate.snapshot->name, match) ? 0 : (CMP_MATCH | CMP_STOP);
2228 * \brief Hash function for \ref bridge_candidate objects
2230 static int bridge_candidate_hash_fn(const void *obj, const int flags)
2232 const struct bridge_candidate *bc = obj;
2233 const char *id = (flags & OBJ_KEY) ? obj : bc->candidate.snapshot->name;
2234 return ast_str_case_hash(id);
2237 /*! \brief \ref bridge_candidate Destructor */
2238 static void bridge_candidate_dtor(void *obj)
2240 struct bridge_candidate *bcand = obj;
2241 ao2_cleanup(bcand->cdr);
2242 ao2_cleanup(bcand->candidate.snapshot);
2243 free_variables(&bcand->candidate.variables);
2247 * \brief \ref bridge_candidate Constructor
2248 * \param cdr The \ref cdr_object that is a candidate for being compared to in
2249 * a bridge operation
2250 * \param candidate The \ref cdr_object_snapshot candidate snapshot in the CDR
2251 * that should be used during the operaton
2253 static struct bridge_candidate *bridge_candidate_alloc(struct cdr_object *cdr, struct cdr_object_snapshot *candidate)
2255 struct bridge_candidate *bcand;
2257 bcand = ao2_alloc(sizeof(*bcand), bridge_candidate_dtor);
2262 ao2_ref(bcand->cdr, +1);
2263 bcand->candidate.flags = candidate->flags;
2264 strcpy(bcand->candidate.userfield, candidate->userfield);
2265 bcand->candidate.snapshot = candidate->snapshot;
2266 ao2_ref(bcand->candidate.snapshot, +1);
2267 copy_variables(&bcand->candidate.variables, &candidate->variables);
2273 * \internal \brief Build and add bridge candidates based on a CDR
2274 * \param bridge_id The ID of the bridge we need candidates for
2275 * \param candidates The container of \ref bridge_candidate objects
2276 * \param cdr The \ref cdr_object that is our candidate
2277 * \param party_a Non-zero if we should look at the Party A channel; 0 if Party B
2279 static void add_candidate_for_bridge(const char *bridge_id,
2280 struct ao2_container *candidates,
2281 struct cdr_object *cdr,
2284 struct cdr_object *it_cdr;
2286 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2287 struct cdr_object_snapshot *party_snapshot;
2288 RAII_VAR(struct bridge_candidate *, bcand, NULL, ao2_cleanup);
2290 party_snapshot = party_a ? &it_cdr->party_a : &it_cdr->party_b;
2292 if (it_cdr->fn_table != &bridge_state_fn_table || strcmp(bridge_id, it_cdr->bridge)) {
2296 if (!party_snapshot->snapshot) {
2300 /* Don't add a party twice */
2301 bcand = ao2_find(candidates, party_snapshot->snapshot->name, OBJ_KEY);
2306 bcand = bridge_candidate_alloc(it_cdr, party_snapshot);
2308 ao2_link(candidates, bcand);
2314 * \brief Create new \ref bridge_candidate objects for each party currently
2316 * \param bridge The \param ast_bridge_snapshot for the bridge we're processing
2318 * Note that we use two passes here instead of one so that we only create a
2319 * candidate for a party B if they are never a party A in the bridge. Otherwise,
2320 * we don't care about them.
2322 static struct ao2_container *create_candidates_for_bridge(struct ast_bridge_snapshot *bridge)
2324 struct ao2_container *candidates = ao2_container_alloc(51, bridge_candidate_hash_fn, bridge_candidate_cmp_fn);
2325 char *bridge_id = ast_strdupa(bridge->uniqueid);
2326 struct ao2_iterator *it_cdrs;
2327 struct cdr_object *cand_cdr_master;
2333 /* For each CDR that has a record in the bridge, get their Party A and
2334 * make them a candidate. Note that we do this in two passes as opposed to one so
2335 * that we give preference CDRs where the channel is Party A */
2336 it_cdrs = ao2_callback(active_cdrs_by_bridge, OBJ_MULTIPLE | OBJ_KEY,
2337 cdr_object_bridge_cmp_fn, bridge_id);
2339 /* No one in the bridge yet! */
2340 ao2_cleanup(candidates);
2343 while ((cand_cdr_master = ao2_iterator_next(it_cdrs))) {
2344 SCOPED_AO2LOCK(lock, cand_cdr_master);
2345 add_candidate_for_bridge(bridge->uniqueid, candidates, cand_cdr_master, 1);
2347 ao2_iterator_destroy(it_cdrs);
2349 /* For each CDR that has a record in the bridge, get their Party B and
2350 * make them a candidate. */
2351 it_cdrs = ao2_callback(active_cdrs_by_bridge, OBJ_MULTIPLE | OBJ_KEY,
2352 cdr_object_bridge_cmp_fn, bridge_id);
2354 /* Now it's just an error. */
2355 ao2_cleanup(candidates);
2358 while ((cand_cdr_master = ao2_iterator_next(it_cdrs))) {
2359 SCOPED_AO2LOCK(lock, cand_cdr_master);
2360 add_candidate_for_bridge(bridge->uniqueid, candidates, cand_cdr_master, 0);
2362 ao2_iterator_destroy(it_cdrs);
2368 * \internal \brief Create a new CDR, append it to an existing CDR, and update its snapshots
2369 * \note The new CDR will be automatically transitioned to the bridge state
2371 static void bridge_candidate_add_to_cdr(struct cdr_object *cdr,
2372 const char *bridge_id,
2373 struct cdr_object_snapshot *party_b)
2375 struct cdr_object *new_cdr;
2377 new_cdr = cdr_object_create_and_append(cdr);
2381 cdr_object_snapshot_copy(&new_cdr->party_b, party_b);
2382 cdr_object_check_party_a_answer(new_cdr);
2383 ast_string_field_set(new_cdr, bridge, cdr->bridge);
2384 cdr_object_transition_state(new_cdr, &bridge_state_fn_table);
2388 * \brief Process a single \ref bridge_candidate. Note that this is called as
2389 * part of an \ref ao2_callback on an \ref ao2_container of \ref bridge_candidate
2390 * objects previously created by \ref create_candidates_for_bridge.
2392 * \param obj The \ref bridge_candidate being processed
2393 * \param arg The \ref cdr_object that is being compared against the candidates
2395 * The purpose of this function is to create the necessary CDR entries as a
2396 * result of \ref cdr_object having entered the same bridge as the CDR
2397 * represented by \ref bridge_candidate.
2399 static int bridge_candidate_process(void *obj, void *arg, int flags)
2401 struct bridge_candidate *bcand = obj;
2402 struct cdr_object *cdr = arg;
2403 struct cdr_object_snapshot *party_a;
2405 /* If the candidate is us or someone we've taken on, pass on by */
2406 if (!strcmp(cdr->party_a.snapshot->name, bcand->candidate.snapshot->name)
2407 || (cdr->party_b.snapshot && !(strcmp(cdr->party_b.snapshot->name, bcand->candidate.snapshot->name)))) {
2411 party_a = cdr_object_pick_party_a(&cdr->party_a, &bcand->candidate);
2412 /* We're party A - make a new CDR, append it to us, and set the candidate as
2414 if (!strcmp(party_a->snapshot->name, cdr->party_a.snapshot->name)) {
2415 bridge_candidate_add_to_cdr(cdr, cdr->bridge, &bcand->candidate);
2419 /* We're Party B. Check if the candidate is the CDR's Party A. If so, find out if we
2420 * can add ourselves directly as the Party B, or if we need a new CDR. */
2421 if (!strcmp(bcand->cdr->party_a.snapshot->name, bcand->candidate.snapshot->name)) {
2422 if (bcand->cdr->party_b.snapshot
2423 && strcmp(bcand->cdr->party_b.snapshot->name, cdr->party_a.snapshot->name)) {
2424 bridge_candidate_add_to_cdr(bcand->cdr, cdr->bridge, &cdr->party_a);
2426 cdr_object_snapshot_copy(&bcand->cdr->party_b, &cdr->party_a);
2427 /* It's possible that this joined at one point and was never chosen
2428 * as party A. Clear their end time, as it would be set in such a
2431 memset(&bcand->cdr->end, 0, sizeof(bcand->cdr->end));
2434 /* We are Party B to a candidate CDR's Party B. Since a candidate
2435 * CDR will only have a Party B represented here if that channel
2436 * was never a Party A in the bridge, we have to go looking for
2437 * that channel's primary CDR record.
2439 struct cdr_object *b_party = ao2_find(active_cdrs_by_channel, bcand->candidate.snapshot->name, OBJ_KEY);
2441 /* Holy cow - no CDR? */
2442 b_party = cdr_object_alloc(bcand->candidate.snapshot);
2443 cdr_object_snapshot_copy(&b_party->party_a, &bcand->candidate);
2444 cdr_object_snapshot_copy(&b_party->party_b, &cdr->party_a);
2445 cdr_object_check_party_a_answer(b_party);
2446 ast_string_field_set(b_party, bridge, cdr->bridge);
2447 cdr_object_transition_state(b_party, &bridge_state_fn_table);
2448 ao2_link(active_cdrs_by_channel, b_party);
2450 bridge_candidate_add_to_cdr(b_party, cdr->bridge, &cdr->party_a);
2452 ao2_link(active_cdrs_by_bridge, b_party);
2453 ao2_ref(b_party, -1);
2460 * \brief Handle creating bridge pairings for the \ref cdr_object that just
2462 * \param cdr The \ref cdr_object that just entered the bridge
2463 * \param bridge The \ref ast_bridge_snapshot representing the bridge it just entered
2465 static void handle_bridge_pairings(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge)
2467 RAII_VAR(struct ao2_container *, candidates,
2468 create_candidates_for_bridge(bridge),
2475 ao2_callback(candidates, OBJ_NODATA,
2476 bridge_candidate_process,
2482 /*! \brief Handle entering into a parking bridge
2483 * \param cdr The CDR to operate on
2484 * \param bridge The bridge the channel just entered
2485 * \param channel The channel snapshot
2487 static void handle_parking_bridge_enter_message(struct cdr_object *cdr,
2488 struct ast_bridge_snapshot *bridge,
2489 struct ast_channel_snapshot *channel)
2491 RAII_VAR(struct module_config *, mod_cfg,
2492 ao2_global_obj_ref(module_configs), ao2_cleanup);
2494 struct cdr_object *it_cdr;
2495 struct cdr_object *new_cdr;
2499 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2500 if (it_cdr->fn_table->process_parking_bridge_enter) {
2501 res &= it_cdr->fn_table->process_parking_bridge_enter(it_cdr, bridge, channel);
2503 if (it_cdr->fn_table->process_party_a) {
2504 CDR_DEBUG(mod_cfg, "%p - Updating Party A %s snapshot\n", it_cdr,
2506 it_cdr->fn_table->process_party_a(it_cdr, channel);
2511 /* No one handled it - we need a new one! */
2512 new_cdr = cdr_object_create_and_append(cdr);
2514 /* Let the single state transition us to Parked */
2515 cdr_object_transition_state(new_cdr, &single_state_fn_table);
2516 new_cdr->fn_table->process_parking_bridge_enter(new_cdr, bridge, channel);
2522 /*! \brief Handle a bridge enter message for a 'normal' bridge
2523 * \param cdr The CDR to operate on
2524 * \param bridge The bridge the channel just entered
2525 * \param channel The channel snapshot
2527 static void handle_standard_bridge_enter_message(struct cdr_object *cdr,
2528 struct ast_bridge_snapshot *bridge,
2529 struct ast_channel_snapshot *channel)
2531 RAII_VAR(struct module_config *, mod_cfg,
2532 ao2_global_obj_ref(module_configs), ao2_cleanup);
2534 struct cdr_object *it_cdr;
2535 struct cdr_object *handled_cdr = NULL;
2539 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2540 if (it_cdr->fn_table->process_party_a) {
2541 CDR_DEBUG(mod_cfg, "%p - Updating Party A %s snapshot\n", it_cdr,
2543 it_cdr->fn_table->process_party_a(it_cdr, channel);
2546 /* Notify all states that they have entered a bridge */
2547 if (it_cdr->fn_table->process_bridge_enter) {
2548 CDR_DEBUG(mod_cfg, "%p - Processing bridge enter for %s\n", it_cdr,
2550 res &= it_cdr->fn_table->process_bridge_enter(it_cdr, bridge, channel);
2551 if (!res && !handled_cdr) {
2552 handled_cdr = it_cdr;
2558 /* We didn't win on any - end this CDR. If someone else comes in later
2559 * that is Party B to this CDR, it can re-activate this CDR.
2561 cdr_object_finalize(cdr);
2564 /* Create the new matchings, but only for either:
2565 * * The first CDR in the chain that handled it. This avoids issues with
2567 * * If no one handled it, the last CDR in the chain. This would occur if
2568 * a CDR joined a bridge and it wasn't Party A for anyone. We still need
2569 * to make pairings with everyone in the bridge.
2572 handled_cdr = cdr->last;
2574 handle_bridge_pairings(handled_cdr, bridge);
2576 ao2_link(active_cdrs_by_bridge, cdr);
2581 * \brief Handler for Stasis-Core bridge enter messages
2582 * \param data Passed on
2583 * \param sub The stasis subscription for this message callback
2584 * \param topic The topic this message was published for
2585 * \param message The message - hopefully a bridge one!
2587 static void handle_bridge_enter_message(void *data, struct stasis_subscription *sub,
2588 struct stasis_topic *topic, struct stasis_message *message)
2590 struct ast_bridge_blob *update = stasis_message_data(message);
2591 struct ast_bridge_snapshot *bridge = update->bridge;
2592 struct ast_channel_snapshot *channel = update->channel;
2593 RAII_VAR(struct cdr_object *, cdr,
2594 ao2_find(active_cdrs_by_channel, channel->name, OBJ_KEY),
2596 RAII_VAR(struct module_config *, mod_cfg,
2597 ao2_global_obj_ref(module_configs), ao2_cleanup);
2599 if (filter_bridge_messages(bridge)) {
2603 CDR_DEBUG(mod_cfg, "Bridge Enter message for channel %s: %u.%08u\n",
2605 (unsigned int)stasis_message_timestamp(message)->tv_sec,
2606 (unsigned int)stasis_message_timestamp(message)->tv_usec);
2609 ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", channel->name);
2613 if (!strcmp(bridge->subclass, "parking")) {
2614 handle_parking_bridge_enter_message(cdr, bridge, channel);
2616 handle_standard_bridge_enter_message(cdr, bridge, channel);
2621 * \brief Handler for when a channel is parked
2622 * \param data Passed on
2623 * \param sub The stasis subscription for this message callback
2624 * \param topic The topic this message was published for
2625 * \param message The message about who got parked
2627 static void handle_parked_call_message(void *data, struct stasis_subscription *sub,
2628 struct stasis_topic *topic, struct stasis_message *message)
2630 struct ast_parked_call_payload *payload = stasis_message_data(message);
2631 struct ast_channel_snapshot *channel = payload->parkee;
2632 RAII_VAR(struct cdr_object *, cdr, NULL, ao2_cleanup);
2633 RAII_VAR(struct module_config *, mod_cfg,
2634 ao2_global_obj_ref(module_configs), ao2_cleanup);
2635 struct cdr_object *it_cdr;
2637 /* Anything other than getting parked will be handled by other updates */
2638 if (payload->event_type != PARKED_CALL) {
2642 /* No one got parked? */
2647 CDR_DEBUG(mod_cfg, "Parked Call message for channel %s: %u.%08u\n",
2649 (unsigned int)stasis_message_timestamp(message)->tv_sec,
2650 (unsigned int)stasis_message_timestamp(message)->tv_usec);
2652 cdr = ao2_find(active_cdrs_by_channel, channel->name, OBJ_KEY);
2654 ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", channel->name);
2660 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2661 if (it_cdr->fn_table->process_parked_channel) {
2662 it_cdr->fn_table->process_parked_channel(it_cdr, payload);
2670 struct ast_cdr_config *ast_cdr_get_config(void)
2672 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
2673 ao2_ref(mod_cfg->general, +1);
2674 return mod_cfg->general;
2677 void ast_cdr_set_config(struct ast_cdr_config *config)
2679 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
2680 ao2_cleanup(mod_cfg->general);
2681 mod_cfg->general = config;
2682 ao2_ref(mod_cfg->general, +1);
2685 int ast_cdr_is_enabled(void)
2687 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
2688 return ast_test_flag(&mod_cfg->general->settings, CDR_ENABLED);
2691 int ast_cdr_register(const char *name, const char *desc, ast_cdrbe be)
2693 struct cdr_beitem *i = NULL;
2699 ast_log(LOG_WARNING, "CDR engine '%s' lacks backend\n", name);
2703 AST_RWLIST_WRLOCK(&be_list);
2704 AST_RWLIST_TRAVERSE(&be_list, i, list) {
2705 if (!strcasecmp(name, i->name)) {
2706 ast_log(LOG_WARNING, "Already have a CDR backend called '%s'\n", name);
2707 AST_RWLIST_UNLOCK(&be_list);
2712 if (!(i = ast_calloc(1, sizeof(*i))))
2716 ast_copy_string(i->name, name, sizeof(i->name));
2717 ast_copy_string(i->desc, desc, sizeof(i->desc));
2719 AST_RWLIST_INSERT_HEAD(&be_list, i, list);
2720 AST_RWLIST_UNLOCK(&be_list);
2725 void ast_cdr_unregister(const char *name)
2727 struct cdr_beitem *i = NULL;
2729 AST_RWLIST_WRLOCK(&be_list);
2730 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&be_list, i, list) {
2731 if (!strcasecmp(name, i->name)) {
2732 AST_RWLIST_REMOVE_CURRENT(list);
2736 AST_RWLIST_TRAVERSE_SAFE_END;
2737 AST_RWLIST_UNLOCK(&be_list);
2740 ast_verb(2, "Unregistered '%s' CDR backend\n", name);
2745 struct ast_cdr *ast_cdr_dup(struct ast_cdr *cdr)
2747 struct ast_cdr *newcdr;
2752 newcdr = ast_cdr_alloc();
2757 memcpy(newcdr, cdr, sizeof(*newcdr));
2758 memset(&newcdr->varshead, 0, sizeof(newcdr->varshead));
2759 copy_variables(&newcdr->varshead, &cdr->varshead);
2760 newcdr->next = NULL;
2765 static const char *cdr_format_var_internal(struct ast_cdr *cdr, const char *name)
2767 struct ast_var_t *variables;
2768 struct varshead *headp = &cdr->varshead;
2770 if (ast_strlen_zero(name)) {
2774 AST_LIST_TRAVERSE(headp, variables, entries) {
2775 if (!strcasecmp(name, ast_var_name(variables))) {
2776 return ast_var_value(variables);
2783 static void cdr_get_tv(struct timeval when, const char *fmt, char *buf, int bufsize)
2785 if (fmt == NULL) { /* raw mode */
2786 snprintf(buf, bufsize, "%ld.%06ld", (long)when.tv_sec, (long)when.tv_usec);
2791 ast_localtime(&when, &tm, NULL);
2792 ast_strftime(buf, bufsize, fmt, &tm);
2797 void ast_cdr_format_var(struct ast_cdr *cdr, const char *name, char **ret, char *workspace, int workspacelen, int raw)
2799 const char *fmt = "%Y-%m-%d %T";
2808 if (!strcasecmp(name, "clid")) {
2809 ast_copy_string(workspace, cdr->clid, workspacelen);
2810 } else if (!strcasecmp(name, "src")) {
2811 ast_copy_string(workspace, cdr->src, workspacelen);
2812 } else if (!strcasecmp(name, "dst")) {
2813 ast_copy_string(workspace, cdr->dst, workspacelen);
2814 } else if (!strcasecmp(name, "dcontext")) {
2815 ast_copy_string(workspace, cdr->dcontext, workspacelen);
2816 } else if (!strcasecmp(name, "channel")) {
2817 ast_copy_string(workspace, cdr->channel, workspacelen);
2818 } else if (!strcasecmp(name, "dstchannel")) {
2819 ast_copy_string(workspace, cdr->dstchannel, workspacelen);
2820 } else if (!strcasecmp(name, "lastapp")) {
2821 ast_copy_string(workspace, cdr->lastapp, workspacelen);
2822 } else if (!strcasecmp(name, "lastdata")) {
2823 ast_copy_string(workspace, cdr->lastdata, workspacelen);
2824 } else if (!strcasecmp(name, "start")) {
2825 cdr_get_tv(cdr->start, raw ? NULL : fmt, workspace, workspacelen);
2826 } else if (!strcasecmp(name, "answer")) {
2827 cdr_get_tv(cdr->answer, raw ? NULL : fmt, workspace, workspacelen);
2828 } else if (!strcasecmp(name, "end")) {
2829 cdr_get_tv(cdr->end, raw ? NULL : fmt, workspace, workspacelen);
2830 } else if (!strcasecmp(name, "duration")) {
2831 snprintf(workspace, workspacelen, "%ld", cdr->end.tv_sec != 0 ? cdr->duration : (long)ast_tvdiff_ms(ast_tvnow(), cdr->start) / 1000);
2832 } else if (!strcasecmp(name, "billsec")) {
2833 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);
2834 } else if (!strcasecmp(name, "disposition")) {
2836 snprintf(workspace, workspacelen, "%ld", cdr->disposition);
2838 ast_copy_string(workspace, ast_cdr_disp2str(cdr->disposition), workspacelen);
2840 } else if (!strcasecmp(name, "amaflags")) {
2842 snprintf(workspace, workspacelen, "%ld", cdr->amaflags);
2844 ast_copy_string(workspace, ast_channel_amaflags2string(cdr->amaflags), workspacelen);
2846 } else if (!strcasecmp(name, "accountcode")) {
2847 ast_copy_string(workspace, cdr->accountcode, workspacelen);
2848 } else if (!strcasecmp(name, "peeraccount")) {
2849 ast_copy_string(workspace, cdr->peeraccount, workspacelen);
2850 } else if (!strcasecmp(name, "uniqueid")) {
2851 ast_copy_string(workspace, cdr->uniqueid, workspacelen);
2852 } else if (!strcasecmp(name, "linkedid")) {
2853 ast_copy_string(workspace, cdr->linkedid, workspacelen);
2854 } else if (!strcasecmp(name, "userfield")) {
2855 ast_copy_string(workspace, cdr->userfield, workspacelen);
2856 } else if (!strcasecmp(name, "sequence")) {
2857 snprintf(workspace, workspacelen, "%d", cdr->sequence);
2858 } else if ((varbuf = cdr_format_var_internal(cdr, name))) {
2859 ast_copy_string(workspace, varbuf, workspacelen);
2861 workspace[0] = '\0';
2864 if (!ast_strlen_zero(workspace)) {
2871 * \brief Callback that finds all CDRs that reference a particular channel
2873 static int cdr_object_select_all_by_channel_cb(void *obj, void *arg, int flags)
2875 struct cdr_object *cdr = obj;
2876 const char *name = arg;
2877 if (!(flags & OBJ_KEY)) {
2880 if (!strcasecmp(cdr->party_a.snapshot->name, name) ||
2881 (cdr->party_b.snapshot && !strcasecmp(cdr->party_b.snapshot->name, name))) {
2887 /* Read Only CDR variables */
2888 static const char * const cdr_readonly_vars[] = { "clid", "src", "dst", "dcontext", "channel", "dstchannel",
2889 "lastapp", "lastdata", "start", "answer", "end", "duration",
2890 "billsec", "disposition", "amaflags", "accountcode", "uniqueid", "linkedid",
2891 "userfield", "sequence", NULL };
2893 int ast_cdr_setvar(const char *channel_name, const char *name, const char *value)
2895 struct cdr_object *cdr;
2896 struct cdr_object *it_cdr;
2897 struct ao2_iterator *it_cdrs;
2898 char *arg = ast_strdupa(channel_name);
2901 for (x = 0; cdr_readonly_vars[x]; x++) {
2902 if (!strcasecmp(name, cdr_readonly_vars[x])) {
2903 ast_log(LOG_ERROR, "Attempt to set the '%s' read-only variable!\n", name);
2908 it_cdrs = ao2_callback(active_cdrs_by_channel, OBJ_MULTIPLE | OBJ_KEY, cdr_object_select_all_by_channel_cb, arg);
2910 ast_log(AST_LOG_ERROR, "Unable to find CDR for channel %s\n", channel_name);
2914 while ((cdr = ao2_iterator_next(it_cdrs))) {
2916 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2917 struct varshead *headp = NULL;
2918 if (it_cdr->fn_table == &finalized_state_fn_table) {
2921 if (!strcmp(channel_name, it_cdr->party_a.snapshot->name)) {
2922 headp = &it_cdr->party_a.variables;
2923 } else if (it_cdr->party_b.snapshot && !strcmp(channel_name, it_cdr->party_b.snapshot->name)) {
2924 headp = &it_cdr->party_b.variables;
2927 set_variable(headp, name, value);
2933 ao2_iterator_destroy(it_cdrs);
2939 * \brief Format a variable on a \ref cdr_object
2941 static void cdr_object_format_var_internal(struct cdr_object *cdr, const char *name, char *value, size_t length)
2943 struct ast_var_t *variable;
2945 AST_LIST_TRAVERSE(&cdr->party_a.variables, variable, entries) {
2946 if (!strcasecmp(name, ast_var_name(variable))) {
2947 ast_copy_string(value, ast_var_value(variable), length);
2956 * \brief Format one of the standard properties on a \ref cdr_object
2958 static int cdr_object_format_property(struct cdr_object *cdr_obj, const char *name, char *value, size_t length)
2960 struct ast_channel_snapshot *party_a = cdr_obj->party_a.snapshot;
2961 struct ast_channel_snapshot *party_b = cdr_obj->party_b.snapshot;
2963 if (!strcasecmp(name, "clid")) {
2964 ast_callerid_merge(value, length, party_a->caller_name, party_a->caller_number, "");
2965 } else if (!strcasecmp(name, "src")) {
2966 ast_copy_string(value, party_a->caller_number, length);
2967 } else if (!strcasecmp(name, "dst")) {
2968 ast_copy_string(value, party_a->exten, length);
2969 } else if (!strcasecmp(name, "dcontext")) {
2970 ast_copy_string(value, party_a->context, length);
2971 } else if (!strcasecmp(name, "channel")) {
2972 ast_copy_string(value, party_a->name, length);
2973 } else if (!strcasecmp(name, "dstchannel")) {
2975 ast_copy_string(value, party_b->name, length);
2977 ast_copy_string(value, "", length);
2979 } else if (!strcasecmp(name, "lastapp")) {
2980 ast_copy_string(value, party_a->appl, length);
2981 } else if (!strcasecmp(name, "lastdata")) {
2982 ast_copy_string(value, party_a->data, length);
2983 } else if (!strcasecmp(name, "start")) {
2984 cdr_get_tv(cdr_obj->start, NULL, value, length);
2985 } else if (!strcasecmp(name, "answer")) {
2986 cdr_get_tv(cdr_obj->answer, NULL, value, length);
2987 } else if (!strcasecmp(name, "end")) {
2988 cdr_get_tv(cdr_obj->end, NULL, value, length);
2989 } else if (!strcasecmp(name, "duration")) {
2990 snprintf(value, length, "%ld", cdr_object_get_duration(cdr_obj));
2991 } else if (!strcasecmp(name, "billsec")) {
2992 snprintf(value, length, "%ld", cdr_object_get_billsec(cdr_obj));
2993 } else if (!strcasecmp(name, "disposition")) {
2994 snprintf(value, length, "%d", cdr_obj->disposition);
2995 } else if (!strcasecmp(name, "amaflags")) {
2996 snprintf(value, length, "%d", party_a->amaflags);
2997 } else if (!strcasecmp(name, "accountcode")) {
2998 ast_copy_string(value, party_a->accountcode, length);
2999 } else if (!strcasecmp(name, "peeraccount")) {
3001 ast_copy_string(value, party_b->accountcode, length);
3003 ast_copy_string(value, "", length);
3005 } else if (!strcasecmp(name, "uniqueid")) {
3006 ast_copy_string(value, party_a->uniqueid, length);
3007 } else if (!strcasecmp(name, "linkedid")) {
3008 ast_copy_string(value, cdr_obj->linkedid, length);
3009 } else if (!strcasecmp(name, "userfield")) {
3010 ast_copy_string(value, cdr_obj->party_a.userfield, length);
3011 } else if (!strcasecmp(name, "sequence")) {
3012 snprintf(value, length, "%d", cdr_obj->sequence);
3020 int ast_cdr_getvar(const char *channel_name, const char *name, char *value, size_t length)
3022 RAII_VAR(struct cdr_object *, cdr,
3023 ao2_find(active_cdrs_by_channel, channel_name, OBJ_KEY),
3025 struct cdr_object *cdr_obj;
3028 ast_log(AST_LOG_ERROR, "Unable to find CDR for channel %s\n", channel_name);
3032 if (ast_strlen_zero(name)) {
3038 cdr_obj = cdr->last;
3040 if (cdr_object_format_property(cdr_obj, name, value, length)) {
3041 /* Property failed; attempt variable */
3042 cdr_object_format_var_internal(cdr_obj, name, value, length);
3049 int ast_cdr_serialize_variables(const char *channel_name, struct ast_str **buf, char delim, char sep)
3051 RAII_VAR(struct cdr_object *, cdr,
3052 ao2_find(active_cdrs_by_channel, channel_name, OBJ_KEY),
3054 struct cdr_object *it_cdr;
3055 struct ast_var_t *variable;
3057 RAII_VAR(char *, workspace, ast_malloc(256), ast_free);
3058 int total = 0, x = 0, i;
3065 ast_log(AST_LOG_ERROR, "Unable to find CDR for channel %s\n", channel_name);
3069 ast_str_reset(*buf);
3072 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3074 ast_str_append(buf, 0, "\n");
3076 AST_LIST_TRAVERSE(&it_cdr->party_a.variables, variable, entries) {
3077 if (!(var = ast_var_name(variable))) {
3081 if (ast_str_append(buf, 0, "level %d: %s%c%s%c", x, var, delim, S_OR(ast_var_value(variable), ""), sep) < 0) {
3082 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
3089 for (i = 0; cdr_readonly_vars[i]; i++) {
3090 /* null out the workspace, because the cdr_get_tv() won't write anything if time is NULL, so you get old vals */
3092 cdr_object_format_property(it_cdr, cdr_readonly_vars[i], workspace, sizeof(workspace));
3094 if (!ast_strlen_zero(workspace)
3095 && ast_str_append(buf, 0, "level %d: %s%c%s%c", x, cdr_readonly_vars[i], delim, workspace, sep) < 0) {
3096 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
3106 void ast_cdr_free(struct ast_cdr *cdr)
3109 struct ast_cdr *next = cdr->next;
3111 free_variables(&cdr->varshead);
3117 struct ast_cdr *ast_cdr_alloc(void)
3121 x = ast_calloc(1, sizeof(*x));
3125 const char *ast_cdr_disp2str(int disposition)
3127 switch (disposition) {
3129 return "NO ANSWER"; /* by default, for backward compatibility */
3130 case AST_CDR_NOANSWER:
3132 case AST_CDR_FAILED:
3136 case AST_CDR_ANSWERED:
3138 case AST_CDR_CONGESTION:
3139 return "CONGESTION";
3144 struct party_b_userfield_update {
3145 const char *channel_name;
3146 const char *userfield;
3149 /*! \brief Callback used to update the userfield on Party B on all CDRs */
3150 static int cdr_object_update_party_b_userfield_cb(void *obj, void *arg, int flags)
3152 struct cdr_object *cdr = obj;
3153 struct party_b_userfield_update *info = arg;
3154 struct cdr_object *it_cdr;
3155 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3156 if (it_cdr->fn_table == &finalized_state_fn_table) {
3159 if (it_cdr->party_b.snapshot
3160 && !strcmp(it_cdr->party_b.snapshot->name, info->channel_name)) {
3161 strcpy(it_cdr->party_b.userfield, info->userfield);
3167 void ast_cdr_setuserfield(const char *channel_name, const char *userfield)
3169 RAII_VAR(struct cdr_object *, cdr,
3170 ao2_find(active_cdrs_by_channel, channel_name, OBJ_KEY),
3172 struct party_b_userfield_update party_b_info = {
3173 .channel_name = channel_name,
3174 .userfield = userfield,
3176 struct cdr_object *it_cdr;
3178 /* Handle Party A */
3181 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3182 if (it_cdr->fn_table == &finalized_state_fn_table) {
3185 strcpy(it_cdr->party_a.userfield, userfield);
3190 /* Handle Party B */
3191 ao2_callback(active_cdrs_by_channel, OBJ_NODATA,
3192 cdr_object_update_party_b_userfield_cb,
3197 static void post_cdr(struct ast_cdr *cdr)
3199 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
3200 struct cdr_beitem *i;
3202 for (; cdr ; cdr = cdr->next) {
3203 /* For people, who don't want to see unanswered single-channel events */
3204 if (!ast_test_flag(&mod_cfg->general->settings, CDR_UNANSWERED) &&
3205 cdr->disposition < AST_CDR_ANSWERED &&
3206 (ast_strlen_zero(cdr->channel) || ast_strlen_zero(cdr->dstchannel))) {
3207 ast_log(AST_LOG_WARNING, "Skipping CDR since we weren't answered\n");
3211 if (ast_test_flag(cdr, AST_CDR_FLAG_DISABLE)) {
3214 AST_RWLIST_RDLOCK(&be_list);
3215 AST_RWLIST_TRAVERSE(&be_list, i, list) {
3218 AST_RWLIST_UNLOCK(&be_list);
3222 int ast_cdr_set_property(const char *channel_name, enum ast_cdr_options option)
3224 RAII_VAR(struct cdr_object *, cdr,
3225 ao2_find(active_cdrs_by_channel, channel_name, OBJ_KEY),
3227 struct cdr_object *it_cdr;
3234 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3235 if (it_cdr->fn_table == &finalized_state_fn_table) {
3238 ast_set_flag(&it_cdr->flags, option);
3245 int ast_cdr_clear_property(const char *channel_name, enum ast_cdr_options option)
3247 RAII_VAR(struct cdr_object *, cdr,
3248 ao2_find(active_cdrs_by_channel, channel_name, OBJ_KEY),
3250 struct cdr_object *it_cdr;
3257 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3258 if (it_cdr->fn_table == &finalized_state_fn_table) {
3261 ast_clear_flag(&it_cdr->flags, option);
3268 int ast_cdr_reset(const char *channel_name, struct ast_flags *options)
3270 RAII_VAR(struct cdr_object *, cdr,
3271 ao2_find(active_cdrs_by_channel, channel_name, OBJ_KEY),
3273 struct ast_var_t *vardata;
3274 struct cdr_object *it_cdr;
3281 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3282 /* clear variables */
3283 if (!ast_test_flag(options, AST_CDR_FLAG_KEEP_VARS)) {
3284 while ((vardata = AST_LIST_REMOVE_HEAD(&it_cdr->party_a.variables, entries))) {
3285 ast_var_delete(vardata);
3287 if (cdr->party_b.snapshot) {
3288 while ((vardata = AST_LIST_REMOVE_HEAD(&it_cdr->party_b.variables, entries))) {
3289 ast_var_delete(vardata);
3294 /* Reset to initial state */
3295 memset(&it_cdr->start, 0, sizeof(it_cdr->start));
3296 memset(&it_cdr->end, 0, sizeof(it_cdr->end));
3297 memset(&it_cdr->answer, 0, sizeof(it_cdr->answer));
3298 it_cdr->start = ast_tvnow();
3299 cdr_object_check_party_a_answer(it_cdr);
3306 int ast_cdr_fork(const char *channel_name, struct ast_flags *options)
3308 RAII_VAR(struct cdr_object *, cdr,
3309 ao2_find(active_cdrs_by_channel, channel_name, OBJ_KEY),
3311 struct cdr_object *new_cdr;
3312 struct cdr_object *it_cdr;
3313 struct cdr_object *cdr_obj;
3320 SCOPED_AO2LOCK(lock, cdr);
3321 cdr_obj = cdr->last;
3322 if (cdr_obj->fn_table == &finalized_state_fn_table) {
3323 /* If the last CDR in the chain is finalized, don't allow a fork -
3324 * things are already dying at this point
3326 ast_log(AST_LOG_ERROR, "FARK\n");
3330 /* Copy over the basic CDR information. The Party A information is
3331 * copied over automatically as part of the append
3333 ast_debug(1, "Forking CDR for channel %s\n", cdr->party_a.snapshot->name);
3334 new_cdr = cdr_object_create_and_append(cdr);
3338 new_cdr->fn_table = cdr_obj->fn_table;
3339 ast_string_field_set(new_cdr, bridge, cdr->bridge);
3340 new_cdr->flags = cdr->flags;
3342 /* If there's a Party B, copy it over as well */
3343 if (cdr_obj->party_b.snapshot) {
3344 new_cdr->party_b.snapshot = cdr_obj->party_b.snapshot;
3345 ao2_ref(new_cdr->party_b.snapshot, +1);
3346 strcpy(new_cdr->party_b.userfield, cdr_obj->party_b.userfield);
3347 new_cdr->party_b.flags = cdr_obj->party_b.flags;
3348 if (ast_test_flag(options, AST_CDR_FLAG_KEEP_VARS)) {
3349 copy_variables(&new_cdr->party_b.variables, &cdr_obj->party_b.variables);
3352 new_cdr->start = cdr_obj->start;
3353 new_cdr->answer = cdr_obj->answer;
3355 /* Modify the times based on the flags passed in */
3356 if (ast_test_flag(options, AST_CDR_FLAG_SET_ANSWER)
3357 && new_cdr->party_a.snapshot->state == AST_STATE_UP) {
3358 new_cdr->answer = ast_tvnow();
3360 if (ast_test_flag(options, AST_CDR_FLAG_RESET)) {
3361 new_cdr->answer = ast_tvnow();
3362 new_cdr->start = ast_tvnow();
3365 /* Create and append, by default, copies over the variables */
3366 if (!ast_test_flag(options, AST_CDR_FLAG_KEEP_VARS)) {
3367 free_variables(&new_cdr->party_a.variables);
3370 /* Finalize any current CDRs */
3371 if (ast_test_flag(options, AST_CDR_FLAG_FINALIZE)) {
3372 for (it_cdr = cdr; it_cdr != new_cdr; it_cdr = it_cdr->next) {
3373 if (it_cdr->fn_table == &finalized_state_fn_table) {
3376 /* Force finalization on the CDR. This will bypass any checks for
3377 * end before 'h' extension.
3379 cdr_object_finalize(it_cdr);
3380 cdr_object_transition_state(it_cdr, &finalized_state_fn_table);
3388 /*! \note Don't call without cdr_batch_lock */
3389 static void reset_batch(void)
3396 /*! \note Don't call without cdr_batch_lock */
3397 static int init_batch(void)
3399 /* This is the single meta-batch used to keep track of all CDRs during the entire life of the program */
3400 if (!(batch = ast_malloc(sizeof(*batch))))
3408 static void *do_batch_backend_process(void *data)
3410 struct cdr_batch_item *processeditem;
3411 struct cdr_batch_item *batchitem = data;
3413 /* Push each CDR into storage mechanism(s) and free all the memory */
3415 post_cdr(batchitem->cdr);
3416 ast_cdr_free(batchitem->cdr);
3417 processeditem = batchitem;
3418 batchitem = batchitem->next;
3419 ast_free(processeditem);
3425 static void cdr_submit_batch(int do_shutdown)
3427 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
3428 struct cdr_batch_item *oldbatchitems = NULL;
3429 pthread_t batch_post_thread = AST_PTHREADT_NULL;
3431 /* if there's no batch, or no CDRs in the batch, then there's nothing to do */
3432 if (!batch || !batch->head) {
3436 /* move the old CDRs aside, and prepare a new CDR batch */
3437 ast_mutex_lock(&cdr_batch_lock);
3438 oldbatchitems = batch->head;
3440 ast_mutex_unlock(&cdr_batch_lock);
3442 /* if configured, spawn a new thread to post these CDRs,
3443 also try to save as much as possible if we are shutting down safely */
3444 if (ast_test_flag(&mod_cfg->general->batch_settings.settings, BATCH_MODE_SCHEDULER_ONLY) || do_shutdown) {
3445 ast_debug(1, "CDR single-threaded batch processing begins now\n");
3446 do_batch_backend_process(oldbatchitems);
3448 if (ast_pthread_create_detached_background(&batch_post_thread, NULL, do_batch_backend_process, oldbatchitems)) {
3449 ast_log(LOG_WARNING, "CDR processing thread could not detach, now trying in this thread\n");
3450 do_batch_backend_process(oldbatchitems);
3452 ast_debug(1, "CDR multi-threaded batch processing begins now\n");
3457 static int submit_scheduled_batch(const void *data)
3459 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
3460 cdr_submit_batch(0);
3461 /* manually reschedule from this point in time */
3463 ast_mutex_lock(&cdr_sched_lock);
3464 cdr_sched = ast_sched_add(sched, mod_cfg->general->batch_settings.size * 1000, submit_scheduled_batch, NULL);
3465 ast_mutex_unlock(&cdr_sched_lock);
3466 /* returning zero so the scheduler does not automatically reschedule */
3470 /*! Do not hold the batch lock while calling this function */
3471 static void submit_unscheduled_batch(void)
3473 /* Prevent two deletes from happening at the same time */
3474 ast_mutex_lock(&cdr_sched_lock);
3475 /* this is okay since we are not being called from within the scheduler */
3476 AST_SCHED_DEL(sched, cdr_sched);
3477 /* schedule the submission to occur ASAP (1 ms) */
3478 cdr_sched = ast_sched_add(sched, 1, submit_scheduled_batch, NULL);
3479 ast_mutex_unlock(&cdr_sched_lock);
3481 /* signal the do_cdr thread to wakeup early and do some work (that lazy thread ;) */
3482 ast_mutex_lock(&cdr_pending_lock);
3483 ast_cond_signal(&cdr_pending_cond);
3484 ast_mutex_unlock(&cdr_pending_lock);
3487 static void cdr_detach(struct ast_cdr *cdr)
3489 struct cdr_batch_item *newtail;
3491 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
3492 int submit_batch = 0;
3498 /* maybe they disabled CDR stuff completely, so just drop it */
3499 if (!ast_test_flag(&mod_cfg->general->settings, CDR_ENABLED)) {
3500 ast_debug(1, "Dropping CDR !\n");
3505 /* post stuff immediately if we are not in batch mode, this is legacy behaviour */
3506 if (!ast_test_flag(&mod_cfg->general->settings, CDR_BATCHMODE)) {
3512 /* otherwise, each CDR gets put into a batch list (at the end) */
3513 ast_debug(1, "CDR detaching from this thread\n");
3515 /* we'll need a new tail for every CDR */
3516 if (!(newtail = ast_calloc(1, sizeof(*newtail)))) {
3522 /* don't traverse a whole list (just keep track of the tail) */
3523 ast_mutex_lock(&cdr_batch_lock);
3527 /* new batch is empty, so point the head at the new tail */
3528 batch->head = newtail;
3530 /* already got a batch with something in it, so just append a new tail */
3531 batch->tail->next = newtail;
3534 batch->tail = newtail;
3535 curr = batch->size++;
3537 /* if we have enough stuff to post, then do it */
3538 if (curr >= (mod_cfg->general->batch_settings.size - 1)) {
3541 ast_mutex_unlock(&cdr_batch_lock);
3543 /* Don't call submit_unscheduled_batch with the cdr_batch_lock held */
3545 submit_unscheduled_batch();
3549 static void *do_cdr(void *data)
3551 struct timespec timeout;
3557 schedms = ast_sched_wait(sched);
3558 /* this shouldn't happen, but provide a 1 second default just in case */
3561 now = ast_tvadd(ast_tvnow(), ast_samp2tv(schedms, 1000));
3562 timeout.tv_sec = now.tv_sec;
3563 timeout.tv_nsec = now.tv_usec * 1000;
3564 /* prevent stuff from clobbering cdr_pending_cond, then wait on signals sent to it until the timeout expires */
3565 ast_mutex_lock(&cdr_pending_lock);
3566 ast_cond_timedwait(&cdr_pending_cond, &cdr_pending_lock, &timeout);
3567 numevents = ast_sched_runq(sched);
3568 ast_mutex_unlock(&cdr_pending_lock);
3569 ast_debug(2, "Processed %d scheduled CDR batches from the run queue\n", numevents);
3575 static char *handle_cli_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
3577 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
3581 e->command = "cdr set debug [on|off]";
3582 e->usage = "Enable or disable extra debugging in the CDR Engine";
3589 return CLI_SHOWUSAGE;
3592 if (!strcmp(a->argv[3], "on") && !ast_test_flag(&mod_cfg->general->settings, CDR_DEBUG)) {
3593 ast_set_flag(&mod_cfg->general->settings, CDR_DEBUG);
3594 ast_cli(a->fd, "CDR debugging enabled\n");
3595 } else if (!strcmp(a->argv[3], "off") && ast_test_flag(&mod_cfg->general->settings, CDR_DEBUG)) {
3596 ast_clear_flag(&mod_cfg->general->settings, CDR_DEBUG);
3597 ast_cli(a->fd, "CDR debugging disabled\n");
3603 static char *handle_cli_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
3605 struct cdr_beitem *beitem = NULL;
3606 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
3608 long nextbatchtime = 0;
3612 e->command = "cdr show status";
3614 "Usage: cdr show status\n"
3615 " Displays the Call Detail Record engine system status.\n";
3622 return CLI_SHOWUSAGE;
3624 ast_cli(a->fd, "\n");
3625 ast_cli(a->fd, "Call Detail Record (CDR) settings\n");
3626 ast_cli(a->fd, "----------------------------------\n");
3627 ast_cli(a->fd, " Logging: %s\n", ast_test_flag(&mod_cfg->general->settings, CDR_ENABLED) ? "Enabled" : "Disabled");
3628 ast_cli(a->fd, " Mode: %s\n", ast_test_flag(&mod_cfg->general->settings, CDR_BATCHMODE) ? "Batch" : "Simple");
3629 if (ast_test_flag(&mod_cfg->general->settings, CDR_ENABLED)) {
3630 ast_cli(a->fd, " Log unanswered calls: %s\n", ast_test_flag(&mod_cfg->general->settings, CDR_UNANSWERED) ? "Yes" : "No");
3631 ast_cli(a->fd, " Log congestion: %s\n\n", ast_test_flag(&mod_cfg->general->settings, CDR_CONGESTION) ? "Yes" : "No");
3632 if (ast_test_flag(&mod_cfg->general->settings, CDR_BATCHMODE)) {
3633 ast_cli(a->fd, "* Batch Mode Settings\n");
3634 ast_cli(a->fd, " -------------------\n");
3638 nextbatchtime = ast_sched_when(sched, cdr_sched);
3639 ast_cli(a->fd, " Safe shutdown: %s\n", ast_test_flag(&mod_cfg->general->batch_settings.settings, BATCH_MODE_SAFE_SHUTDOWN) ? "Enabled" : "Disabled");
3640 ast_cli(a->fd, " Threading model: %s\n", ast_test_flag(&mod_cfg->general->batch_settings.settings, BATCH_MODE_SCHEDULER_ONLY) ? "Scheduler only" : "Scheduler plus separate threads");
3641 ast_cli(a->fd, " Current batch size: %d record%s\n", cnt, ESS(cnt));
3642 ast_cli(a->fd, " Maximum batch size: %d record%s\n", mod_cfg->general->batch_settings.size, ESS(mod_cfg->general->batch_settings.size));
3643 ast_cli(a->fd, " Maximum batch time: %d second%s\n", mod_cfg->general->batch_settings.time, ESS(mod_cfg->general->batch_settings.time));
3644 ast_cli(a->fd, " Next batch processing time: %ld second%s\n\n", nextbatchtime, ESS(nextbatchtime));
3646 ast_cli(a->fd, "* Registered Backends\n");
3647 ast_cli(a->fd, " -------------------\n");
3648 AST_RWLIST_RDLOCK(&be_list);
3649 if (AST_RWLIST_EMPTY(&be_list)) {
3650 ast_cli(a->fd, " (none)\n");
3652 AST_RWLIST_TRAVERSE(&be_list, beitem, list) {
3653 ast_cli(a->fd, " %s\n", beitem->name);
3656 AST_RWLIST_UNLOCK(&be_list);
3657 ast_cli(a->fd, "\n");
3663 static char *handle_cli_submit(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
3667 e->command = "cdr submit";
3669 "Usage: cdr submit\n"
3670 " Posts all pending batched CDR data to the configured CDR backend engine modules.\n";
3676 return CLI_SHOWUSAGE;
3678 submit_unscheduled_batch();
3679 ast_cli(a->fd, "Submitted CDRs to backend engines for processing. This may take a while.\n");
3684 static struct ast_cli_entry cli_submit = AST_CLI_DEFINE(handle_cli_submit, "Posts all pending batched CDR data");
3685 static struct ast_cli_entry cli_status = AST_CLI_DEFINE(handle_cli_status, "Display the CDR status");
3686 static struct ast_cli_entry cli_debug = AST_CLI_DEFINE(handle_cli_debug, "Enable debugging");
3690 * \brief This dispatches *all* \ref cdr_objects. It should only be used during
3691 * shutdown, so that we get billing records for everything that we can.
3693 static int cdr_object_dispatch_all_cb(void *obj, void *arg, int flags)
3695 struct cdr_object *cdr = obj;
3696 struct cdr_object *it_cdr;
3698 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3699 cdr_object_transition_state(it_cdr, &finalized_state_fn_table);
3701 cdr_object_dispatch(cdr);
3706 static void finalize_batch_mode(void)
3708 if (cdr_thread == AST_PTHREADT_NULL) {
3711 /* wake up the thread so it will exit */
3712 pthread_cancel(cdr_thread);
3713 pthread_kill(cdr_thread, SIGURG);
3714 pthread_join(cdr_thread, NULL);
3715 cdr_thread = AST_PTHREADT_NULL;
3716 ast_cond_destroy(&cdr_pending_cond);
3717 ast_cli_unregister(&cli_submit);
3718 ast_cdr_engine_term();
3721 static int process_config(int reload)
3723 RAII_VAR(struct module_config *, mod_cfg, module_config_alloc(), ao2_cleanup);
3726 if (aco_info_init(&cfg_info)) {
3730 aco_option_register(&cfg_info, "enable", ACO_EXACT, general_options, DEFAULT_ENABLED, OPT_BOOLFLAG_T, 1, FLDSET(struct ast_cdr_config, settings), CDR_ENABLED);
3731 aco_option_register(&cfg_info, "debug", ACO_EXACT, general_options, 0, OPT_BOOLFLAG_T, 1, FLDSET(struct ast_cdr_config, settings), CDR_DEBUG);
3732 aco_option_register(&cfg_info, "unanswered", ACO_EXACT, general_options, DEFAULT_UNANSWERED, OPT_BOOLFLAG_T, 1, FLDSET(struct ast_cdr_config, settings), CDR_UNANSWERED);
3733 aco_option_register(&cfg_info, "congestion", ACO_EXACT, general_options, 0, OPT_BOOLFLAG_T, 1, FLDSET(struct ast_cdr_config, settings), CDR_CONGESTION);
3734 aco_option_register(&cfg_info, "batch", ACO_EXACT, general_options, DEFAULT_BATCHMODE, OPT_BOOLFLAG_T, 1, FLDSET(struct ast_cdr_config, settings), CDR_BATCHMODE);
3735 aco_option_register(&cfg_info, "endbeforehexten", ACO_EXACT, general_options, DEFAULT_END_BEFORE_H_EXTEN, OPT_BOOLFLAG_T, 1, FLDSET(struct ast_cdr_config, settings), CDR_END_BEFORE_H_EXTEN);
3736 aco_option_register(&cfg_info, "initiatedseconds", ACO_EXACT, general_options, DEFAULT_INITIATED_SECONDS, OPT_BOOLFLAG_T, 1, FLDSET(struct ast_cdr_config, settings), CDR_INITIATED_SECONDS);
3737 aco_option_register(&cfg_info, "scheduleronly", ACO_EXACT, general_options, DEFAULT_BATCH_SCHEDULER_ONLY, OPT_BOOLFLAG_T, 1, FLDSET(struct ast_cdr_config, batch_settings.settings), BATCH_MODE_SCHEDULER_ONLY);
3738 aco_option_register(&cfg_info, "safeshutdown", ACO_EXACT, general_options, DEFAULT_BATCH_SAFE_SHUTDOWN, OPT_BOOLFLAG_T, 1, FLDSET(struct ast_cdr_config, batch_settings.settings), BATCH_MODE_SAFE_SHUTDOWN);
3739 aco_option_register(&cfg_info, "size", ACO_EXACT, general_options, DEFAULT_BATCH_SIZE, OPT_UINT_T, PARSE_IN_RANGE, FLDSET(struct ast_cdr_config, batch_settings.size), 0, MAX_BATCH_SIZE);
3740 aco_option_register(&cfg_info, "time", ACO_EXACT, general_options, DEFAULT_BATCH_TIME, OPT_UINT_T, PARSE_IN_RANGE, FLDSET(struct ast_cdr_config, batch_settings.time), 0, MAX_BATCH_TIME);
3743 if (aco_process_config(&cfg_info, reload)) {
3747 /* If we couldn't process the configuration and this wasn't a reload,
3748 * create a default config
3750 if (!reload && !(aco_set_defaults(&general_option, "general", mod_cfg->general))) {
3751 ast_log(LOG_NOTICE, "Failed to process CDR configuration; using defaults\n");
3752 ao2_global_obj_replace(module_configs, mod_cfg);
3759 manager_event(EVENT_FLAG_SYSTEM, "Reload", "Module: CDR\r\nMessage: CDR subsystem reload requested\r\n");
3764 static void cdr_engine_shutdown(void)
3766 ao2_callback(active_cdrs_by_channel, OBJ_NODATA, cdr_object_dispatch_all_cb,
3768 finalize_batch_mode();
3769 ast_cli_unregister(&cli_status);
3770 ast_cli_unregister(&cli_debug);
3771 ast_sched_context_destroy(sched);
3776 channel_subscription = stasis_unsubscribe_and_join(channel_subscription);
3777 bridge_subscription = stasis_unsubscribe_and_join(bridge_subscription);
3778 stasis_message_router_unsubscribe_and_join(stasis_router);
3779 aco_info_destroy(&cfg_info);
3780 ao2_global_obj_release(module_configs);
3782 ao2_ref(active_cdrs_by_channel, -1);
3783 ao2_ref(active_cdrs_by_bridge, -1);
3786 static void cdr_enable_batch_mode(struct ast_cdr_config *config)
3788 SCOPED_LOCK(batch, &cdr_batch_lock, ast_mutex_lock, ast_mutex_unlock);
3790 /* Only create the thread level portions once */
3791 if (cdr_thread == AST_PTHREADT_NULL) {
3792 ast_cond_init(&cdr_pending_cond, NULL);
3793 if (ast_pthread_create_background(&cdr_thread, NULL, do_cdr, NULL) < 0) {
3794 ast_log(LOG_ERROR, "Unable to start CDR thread.\n");