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_bridges.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>Don't produce CDRs while executing hangup logic</synopsis>
125 <para>As each CDR for a channel is finished, its end time is updated
126 and the CDR is finalized. When a channel is hung up and hangup
127 logic is present (in the form of a hangup handler or the
128 <literal>h</literal> extension), a new CDR is generated for the
129 channel. Any statistics are gathered from this new CDR. By enabling
130 this option, no new CDR is created for the dialplan logic that is
131 executed in <literal>h</literal> extensions or attached hangup handler
132 subroutines. The default value is <literal>no</literal>, indicating
133 that a CDR will be generated during hangup logic.</para>
136 <configOption name="initiatedseconds">
137 <synopsis>Count microseconds for billsec purposes</synopsis>
138 <description><para>Normally, the <literal>billsec</literal> field logged to the CDR backends
139 is simply the end time (hangup time) minus the answer time in seconds. Internally,
140 asterisk stores the time in terms of microseconds and seconds. By setting
141 initiatedseconds to <literal>yes</literal>, you can force asterisk to report any seconds
142 that were initiated (a sort of round up method). Technically, this is
143 when the microsecond part of the end time is greater than the microsecond
144 part of the answer time, then the billsec time is incremented one second.</para>
147 <configOption name="batch">
148 <synopsis>Submit CDRs to the backends for processing in batches</synopsis>
149 <description><para>Define the CDR batch mode, where instead of posting the CDR at the end of
150 every call, the data will be stored in a buffer to help alleviate load on the
151 asterisk server.</para>
152 <warning><para>Use of batch mode may result in data loss after unsafe asterisk termination,
153 i.e., software crash, power failure, kill -9, etc.</para>
157 <configOption name="size">
158 <synopsis>The maximum number of CDRs to accumulate before triggering a batch</synopsis>
159 <description><para>Define the maximum number of CDRs to accumulate in the buffer before posting
160 them to the backend engines. batch must be set to <literal>yes</literal>.</para>
163 <configOption name="time">
164 <synopsis>The maximum time to accumulate CDRs before triggering a batch</synopsis>
165 <description><para>Define the maximum time to accumulate CDRs before posting them in a batch to the
166 backend engines. If this time limit is reached, then it will post the records, regardless of the value
167 defined for size. batch must be set to <literal>yes</literal>.</para>
168 <note><para>Time is expressed in seconds.</para></note>
171 <configOption name="scheduleronly">
172 <synopsis>Post batched CDRs on their own thread instead of the scheduler</synopsis>
173 <description><para>The CDR engine uses the internal asterisk scheduler to determine when to post
174 records. Posting can either occur inside the scheduler thread, or a new
175 thread can be spawned for the submission of every batch. For small batches,
176 it might be acceptable to just use the scheduler thread, so set this to <literal>yes</literal>.
177 For large batches, say anything over size=10, a new thread is recommended, so
178 set this to <literal>no</literal>.</para>
181 <configOption name="safeshutdown">
182 <synopsis>Block shutdown of Asterisk until CDRs are submitted</synopsis>
183 <description><para>When shutting down asterisk, you can block until the CDRs are submitted. If
184 you don't, then data will likely be lost. You can always check the size of
185 the CDR batch buffer with the CLI <astcli>cdr status</astcli> command. To enable blocking on
186 submission of CDR data during asterisk shutdown, set this to <literal>yes</literal>.</para>
195 #define DEFAULT_ENABLED "1"
196 #define DEFAULT_BATCHMODE "0"
197 #define DEFAULT_UNANSWERED "0"
198 #define DEFAULT_CONGESTION "0"
199 #define DEFAULT_END_BEFORE_H_EXTEN "0"
200 #define DEFAULT_INITIATED_SECONDS "0"
202 #define DEFAULT_BATCH_SIZE "100"
203 #define MAX_BATCH_SIZE 1000
204 #define DEFAULT_BATCH_TIME "300"
205 #define MAX_BATCH_TIME 86400
206 #define DEFAULT_BATCH_SCHEDULER_ONLY "0"
207 #define DEFAULT_BATCH_SAFE_SHUTDOWN "1"
209 #define CDR_DEBUG(mod_cfg, fmt, ...) \
211 if (ast_test_flag(&(mod_cfg)->general->settings, CDR_DEBUG)) { \
212 ast_verb(1, (fmt), ##__VA_ARGS__); \
215 static void cdr_detach(struct ast_cdr *cdr);
216 static void cdr_submit_batch(int shutdown);
218 /*! \brief The configuration settings for this module */
219 struct module_config {
220 struct ast_cdr_config *general; /*< CDR global settings */
223 /*! \brief The container for the module configuration */
224 static AO2_GLOBAL_OBJ_STATIC(module_configs);
226 /*! \brief The type definition for general options */
227 static struct aco_type general_option = {
230 .item_offset = offsetof(struct module_config, general),
231 .category = "^general$",
232 .category_match = ACO_WHITELIST,
235 static void *module_config_alloc(void);
236 static void module_config_destructor(void *obj);
238 /*! \brief The file definition */
239 static struct aco_file module_file_conf = {
240 .filename = "cdr.conf",
241 .skip_category = "(^csv$|^custom$|^manager$|^odbc$|^pgsql$|^radius$|^sqlite$|^tds$|^mysql$)",
242 .types = ACO_TYPES(&general_option),
245 CONFIG_INFO_CORE("cdr", cfg_info, module_configs, module_config_alloc,
246 .files = ACO_FILES(&module_file_conf),
249 static struct aco_type *general_options[] = ACO_TYPES(&general_option);
251 /*! \brief Dispose of a module config object */
252 static void module_config_destructor(void *obj)
254 struct module_config *cfg = obj;
259 ao2_ref(cfg->general, -1);
262 /*! \brief Create a new module config object */
263 static void *module_config_alloc(void)
265 struct module_config *mod_cfg;
266 struct ast_cdr_config *cdr_config;
268 mod_cfg = ao2_alloc(sizeof(*mod_cfg), module_config_destructor);
273 cdr_config = ao2_alloc(sizeof(*cdr_config), NULL);
275 ao2_ref(cdr_config, -1);
278 mod_cfg->general = cdr_config;
283 /*! \brief Registration object for CDR backends */
288 AST_RWLIST_ENTRY(cdr_beitem) list;
291 /*! \brief List of registered backends */
292 static AST_RWLIST_HEAD_STATIC(be_list, cdr_beitem);
294 /*! \brief Queued CDR waiting to be batched */
295 struct cdr_batch_item {
297 struct cdr_batch_item *next;
300 /*! \brief The actual batch queue */
301 static struct cdr_batch {
303 struct cdr_batch_item *head;
304 struct cdr_batch_item *tail;
307 /*! \brief The global sequence counter used for CDRs */
308 static int global_cdr_sequence = 0;
310 /*! \brief Scheduler items */
311 static struct ast_sched_context *sched;
312 static int cdr_sched = -1;
313 AST_MUTEX_DEFINE_STATIC(cdr_sched_lock);
314 static pthread_t cdr_thread = AST_PTHREADT_NULL;
316 /*! \brief Lock protecting modifications to the batch queue */
317 AST_MUTEX_DEFINE_STATIC(cdr_batch_lock);
319 /*! \brief These are used to wake up the CDR thread when there's work to do */
320 AST_MUTEX_DEFINE_STATIC(cdr_pending_lock);
321 static ast_cond_t cdr_pending_cond;
323 /*! \brief A container of the active CDRs indexed by Party A channel name */
324 static struct ao2_container *active_cdrs_by_channel;
326 /*! \brief Message router for stasis messages regarding channel state */
327 static struct stasis_message_router *stasis_router;
329 /*! \brief Our subscription for bridges */
330 static struct stasis_subscription *bridge_subscription;
332 /*! \brief Our subscription for channels */
333 static struct stasis_subscription *channel_subscription;
335 /*! \brief Our subscription for parking */
336 static struct stasis_subscription *parking_subscription;
338 /*! \brief The parent topic for all topics we want to aggregate for CDRs */
339 static struct stasis_topic *cdr_topic;
343 /*! \brief Return types for \ref process_bridge_enter functions */
344 enum process_bridge_enter_results {
346 * The CDR was the only party in the bridge.
348 BRIDGE_ENTER_ONLY_PARTY,
350 * The CDR was able to obtain a Party B from some other party already in the bridge
352 BRIDGE_ENTER_OBTAINED_PARTY_B,
354 * The CDR was not able to obtain a Party B
356 BRIDGE_ENTER_NO_PARTY_B,
358 * This CDR can't handle a bridge enter message and a new CDR needs to be created
360 BRIDGE_ENTER_NEED_CDR,
364 * \brief A virtual table used for \ref cdr_object.
366 * Note that all functions are optional - if a subclass does not need an
367 * implementation, it is safe to leave it NULL.
369 struct cdr_object_fn_table {
370 /*! \brief Name of the subclass */
374 * \brief An initialization function. This will be called automatically
375 * when a \ref cdr_object is switched to this type in
376 * \ref cdr_object_transition_state
378 * \param cdr The \ref cdr_object that was just transitioned
380 void (* const init_function)(struct cdr_object *cdr);
383 * \brief Process a Party A update for the \ref cdr_object
385 * \param cdr The \ref cdr_object to process the update
386 * \param snapshot The snapshot for the CDR's Party A
387 * \retval 0 the CDR handled the update or ignored it
388 * \retval 1 the CDR is finalized and a new one should be made to handle it
390 int (* const process_party_a)(struct cdr_object *cdr,
391 struct ast_channel_snapshot *snapshot);
394 * \brief Process a Party B update for the \ref cdr_object
396 * \param cdr The \ref cdr_object to process the update
397 * \param snapshot The snapshot for the CDR's Party B
399 void (* const process_party_b)(struct cdr_object *cdr,
400 struct ast_channel_snapshot *snapshot);
403 * \brief Process the beginning of a dial. A dial message implies one of two
405 * The \ref cdr_object's Party A has been originated
406 * The \ref cdr_object's Party A is dialing its Party B
408 * \param cdr The \ref cdr_object
409 * \param caller The originator of the dial attempt
410 * \param peer The destination of the dial attempt
412 * \retval 0 if the parties in the dial were handled by this CDR
413 * \retval 1 if the parties could not be handled by this CDR
415 int (* const process_dial_begin)(struct cdr_object *cdr,
416 struct ast_channel_snapshot *caller,
417 struct ast_channel_snapshot *peer);
420 * \brief Process the end of a dial. At the end of a dial, a CDR can be
421 * transitioned into one of two states - DialedPending
422 * (\ref dialed_pending_state_fn_table) or Finalized
423 * (\ref finalized_state_fn_table).
425 * \param cdr The \ref cdr_object
426 * \param caller The originator of the dial attempt
427 * \param peer the Destination of the dial attempt
428 * \param dial_status What happened
430 * \retval 0 if the parties in the dial were handled by this CDR
431 * \retval 1 if the parties could not be handled by this CDR
433 int (* const process_dial_end)(struct cdr_object *cdr,
434 struct ast_channel_snapshot *caller,
435 struct ast_channel_snapshot *peer,
436 const char *dial_status);
439 * \brief Process the entering of a bridge by this CDR. The purpose of this
440 * callback is to have the CDR prepare itself for the bridge and attempt to
441 * find a valid Party B. The act of creating new CDRs based on the entering
442 * of this channel into the bridge is handled by the higher level message
445 * Note that this handler is for when a channel enters into a "normal"
446 * bridge, where people actually talk to each other. Parking is its own
449 * \param cdr The \ref cdr_object
450 * \param bridge The bridge that the Party A just entered into
451 * \param channel The \ref ast_channel_snapshot for this CDR's Party A
453 * \retval process_bridge_enter_results Defines whether or not this CDR was able
454 * to fully handle the bridge enter message.
456 enum process_bridge_enter_results (* const process_bridge_enter)(
457 struct cdr_object *cdr,
458 struct ast_bridge_snapshot *bridge,
459 struct ast_channel_snapshot *channel);
462 * \brief Process entering into a parking bridge.
464 * \param cdr The \ref cdr_object
465 * \param bridge The parking bridge that Party A just entered into
466 * \param channel The \ref ast_channel_snapshot for this CDR's Party A
468 * \retval 0 This CDR successfully transitioned itself into the parked state
469 * \retval 1 This CDR couldn't handle the parking transition and we need a
472 int (* const process_parking_bridge_enter)(struct cdr_object *cdr,
473 struct ast_bridge_snapshot *bridge,
474 struct ast_channel_snapshot *channel);
477 * \brief Process the leaving of a bridge by this CDR.
479 * \param cdr The \ref cdr_object
480 * \param bridge The bridge that the Party A just left
481 * \param channel The \ref ast_channel_snapshot for this CDR's Party A
483 * \retval 0 This CDR left successfully
486 int (* const process_bridge_leave)(struct cdr_object *cdr,
487 struct ast_bridge_snapshot *bridge,
488 struct ast_channel_snapshot *channel);
491 * \brief Process an update informing us that the channel got itself parked
493 * \param cdr The \ref cdr_object
494 * \param channel The parking information for this CDR's party A
496 * \retval 0 This CDR successfully parked itself
497 * \retval 1 This CDR couldn't handle the park
499 int (* const process_parked_channel)(struct cdr_object *cdr,
500 struct ast_parked_call_payload *parking_info);
503 static int base_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot);
504 static enum process_bridge_enter_results base_process_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
505 static int base_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
506 static int base_process_dial_end(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer, const char *dial_status);
507 static int base_process_parked_channel(struct cdr_object *cdr, struct ast_parked_call_payload *parking_info);
509 static void single_state_init_function(struct cdr_object *cdr);
510 static void single_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot);
511 static int single_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer);
512 static enum process_bridge_enter_results single_state_process_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
513 static int single_state_process_parking_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
516 * \brief The virtual table for the Single state.
518 * A \ref cdr_object starts off in this state. This represents a channel that
519 * has no Party B information itself.
521 * A \ref cdr_object from this state can go into any of the following states:
522 * * \ref dial_state_fn_table
523 * * \ref bridge_state_fn_table
524 * * \ref finalized_state_fn_table
526 struct cdr_object_fn_table single_state_fn_table = {
528 .init_function = single_state_init_function,
529 .process_party_a = base_process_party_a,
530 .process_party_b = single_state_process_party_b,
531 .process_dial_begin = single_state_process_dial_begin,
532 .process_dial_end = base_process_dial_end,
533 .process_bridge_enter = single_state_process_bridge_enter,
534 .process_parking_bridge_enter = single_state_process_parking_bridge_enter,
535 .process_bridge_leave = base_process_bridge_leave,
536 .process_parked_channel = base_process_parked_channel,
539 static void dial_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot);
540 static int dial_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer);
541 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);
542 static enum process_bridge_enter_results dial_state_process_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
545 * \brief The virtual table for the Dial state.
547 * A \ref cdr_object that has begun a dial operation. This state is entered when
548 * the Party A for a CDR is determined to be dialing out to a Party B or when
549 * a CDR is for an originated channel (in which case the Party A information is
550 * the originated channel, and there is no Party B).
552 * A \ref cdr_object from this state can go in any of the following states:
553 * * \ref dialed_pending_state_fn_table
554 * * \ref bridge_state_fn_table
555 * * \ref finalized_state_fn_table
557 struct cdr_object_fn_table dial_state_fn_table = {
559 .process_party_a = base_process_party_a,
560 .process_party_b = dial_state_process_party_b,
561 .process_dial_begin = dial_state_process_dial_begin,
562 .process_dial_end = dial_state_process_dial_end,
563 .process_bridge_enter = dial_state_process_bridge_enter,
564 .process_bridge_leave = base_process_bridge_leave,
567 static int dialed_pending_state_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot);
568 static int dialed_pending_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer);
569 static enum process_bridge_enter_results dialed_pending_state_process_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
570 static int dialed_pending_state_process_parking_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
573 * \brief The virtual table for the Dialed Pending state.
575 * A \ref cdr_object that has successfully finished a dial operation, but we
576 * don't know what they're going to do yet. It's theoretically possible to dial
577 * a party and then have that party not be bridged with the caller; likewise,
578 * an origination can complete and the channel go off and execute dialplan. The
579 * pending state acts as a bridge between either:
580 * * Entering a bridge
581 * * Getting a new CDR for new dialplan execution
582 * * Switching from being originated to executing dialplan
584 * A \ref cdr_object from this state can go in any of the following states:
585 * * \ref single_state_fn_table
586 * * \ref dialed_pending_state_fn_table
587 * * \ref bridge_state_fn_table
588 * * \ref finalized_state_fn_table
590 struct cdr_object_fn_table dialed_pending_state_fn_table = {
591 .name = "DialedPending",
592 .process_party_a = dialed_pending_state_process_party_a,
593 .process_dial_begin = dialed_pending_state_process_dial_begin,
594 .process_bridge_enter = dialed_pending_state_process_bridge_enter,
595 .process_parking_bridge_enter = dialed_pending_state_process_parking_bridge_enter,
596 .process_bridge_leave = base_process_bridge_leave,
597 .process_parked_channel = base_process_parked_channel,
600 static void bridge_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot);
601 static int bridge_state_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
604 * \brief The virtual table for the Bridged state
606 * A \ref cdr_object enters this state when it receives notification that the
607 * channel has entered a bridge.
609 * A \ref cdr_object from this state can go to:
610 * * \ref finalized_state_fn_table
612 struct cdr_object_fn_table bridge_state_fn_table = {
614 .process_party_a = base_process_party_a,
615 .process_party_b = bridge_state_process_party_b,
616 .process_bridge_leave = bridge_state_process_bridge_leave,
617 .process_parked_channel = base_process_parked_channel,
620 static int parked_state_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
623 * \brief The virtual table for the Parked state
625 * Parking is weird. Unlike typical bridges, it has to be treated somewhat
626 * uniquely - a channel in a parking bridge (which is a subclass of a holding
627 * bridge) has to be handled as if the channel went into an application.
628 * However, when the channel comes out, we need a new CDR - unlike the Single
631 struct cdr_object_fn_table parked_state_fn_table = {
633 .process_party_a = base_process_party_a,
634 .process_bridge_leave = parked_state_process_bridge_leave,
635 .process_parked_channel = base_process_parked_channel,
638 static void finalized_state_init_function(struct cdr_object *cdr);
639 static int finalized_state_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot);
642 * \brief The virtual table for the finalized state.
644 * Once in the finalized state, the CDR is done. No modifications can be made
647 struct cdr_object_fn_table finalized_state_fn_table = {
649 .init_function = finalized_state_init_function,
650 .process_party_a = finalized_state_process_party_a,
651 .process_bridge_enter = base_process_bridge_enter,
654 /*! \brief A wrapper object around a snapshot.
655 * Fields that are mutable by the CDR engine are replicated here.
657 struct cdr_object_snapshot {
658 struct ast_channel_snapshot *snapshot; /*!< The channel snapshot */
659 char userfield[AST_MAX_USER_FIELD]; /*!< Userfield for the channel */
660 unsigned int flags; /*!< Specific flags for this party */
661 struct varshead variables; /*!< CDR variables for the channel */
664 /*! \brief An in-memory representation of an active CDR */
666 struct cdr_object_snapshot party_a; /*!< The Party A information */
667 struct cdr_object_snapshot party_b; /*!< The Party B information */
668 struct cdr_object_fn_table *fn_table; /*!< The current virtual table */
670 enum ast_cdr_disposition disposition; /*!< The disposition of the CDR */
671 struct timeval start; /*!< When this CDR was created */
672 struct timeval answer; /*!< Either when the channel was answered, or when the path between channels was established */
673 struct timeval end; /*!< When this CDR was finalized */
674 unsigned int sequence; /*!< A monotonically increasing number for each CDR */
675 struct ast_flags flags; /*!< Flags on the CDR */
676 AST_DECLARE_STRING_FIELDS(
677 AST_STRING_FIELD(linkedid); /*!< Linked ID. Cached here as it may change out from party A, which must be immutable */
678 AST_STRING_FIELD(name); /*!< Channel name of party A. Cached here as the party A address may change */
679 AST_STRING_FIELD(bridge); /*!< The bridge the party A happens to be in. */
680 AST_STRING_FIELD(appl); /*!< The last accepted application party A was in */
681 AST_STRING_FIELD(data); /*!< The data for the last accepted application party A was in */
683 struct cdr_object *next; /*!< The next CDR object in the chain */
684 struct cdr_object *last; /*!< The last CDR object in the chain */
688 * \brief Copy variables from one list to another
689 * \param to_list destination
690 * \param from_list source
691 * \retval The number of copied variables
693 static int copy_variables(struct varshead *to_list, struct varshead *from_list)
695 struct ast_var_t *variables, *newvariable = NULL;
696 const char *var, *val;
699 AST_LIST_TRAVERSE(from_list, variables, entries) {
701 (var = ast_var_name(variables)) && (val = ast_var_value(variables)) &&
702 !ast_strlen_zero(var) && !ast_strlen_zero(val) &&
703 (newvariable = ast_var_assign(var, val))) {
704 AST_LIST_INSERT_HEAD(to_list, newvariable, entries);
713 * \brief Delete all variables from a variable list
714 * \param headp The head pointer to the variable list to delete
716 static void free_variables(struct varshead *headp)
718 struct ast_var_t *vardata;
720 while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries))) {
721 ast_var_delete(vardata);
726 * \brief Copy a snapshot and its details
727 * \param dst The destination
728 * \param src The source
730 static void cdr_object_snapshot_copy(struct cdr_object_snapshot *dst, struct cdr_object_snapshot *src)
733 ao2_t_ref(dst->snapshot, -1, "release old snapshot during copy");
735 dst->snapshot = src->snapshot;
736 ao2_t_ref(dst->snapshot, +1, "bump new snapshot during copy");
737 strcpy(dst->userfield, src->userfield);
738 dst->flags = src->flags;
739 copy_variables(&dst->variables, &src->variables);
743 * \brief Transition a \ref cdr_object to a new state
744 * \param cdr The \ref cdr_object to transition
745 * \param fn_table The \ref cdr_object_fn_table state to go to
747 static void cdr_object_transition_state(struct cdr_object *cdr, struct cdr_object_fn_table *fn_table)
749 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
751 CDR_DEBUG(mod_cfg, "%p - Transitioning CDR for %s from state %s to %s\n",
752 cdr, cdr->party_a.snapshot->name,
753 cdr->fn_table ? cdr->fn_table->name : "NONE", fn_table->name);
754 cdr->fn_table = fn_table;
755 if (cdr->fn_table->init_function) {
756 cdr->fn_table->init_function(cdr);
760 * \brief Hash function for containers of CDRs indexing by Party A name */
761 static int cdr_object_channel_hash_fn(const void *obj, const int flags)
763 const struct cdr_object *cdr = obj;
764 const char *name = (flags & OBJ_KEY) ? obj : cdr->name;
765 return ast_str_case_hash(name);
769 * \brief Comparison function for containers of CDRs indexing by Party A name
771 static int cdr_object_channel_cmp_fn(void *obj, void *arg, int flags)
773 struct cdr_object *left = obj;
774 struct cdr_object *right = arg;
775 const char *match = (flags & OBJ_KEY) ? arg : right->name;
776 return strcasecmp(left->name, match) ? 0 : (CMP_MATCH | CMP_STOP);
780 * \brief Comparison function for containers of CDRs indexing by bridge. Note
781 * that we expect there to be collisions, as a single bridge may have multiple
782 * CDRs active at one point in time
784 static int cdr_object_bridge_cmp_fn(void *obj, void *arg, int flags)
786 struct cdr_object *left = obj;
787 struct cdr_object *it_cdr;
788 const char *match = arg;
790 for (it_cdr = left; it_cdr; it_cdr = it_cdr->next) {
791 if (!strcasecmp(it_cdr->bridge, match)) {
799 * \brief \ref cdr_object Destructor
801 static void cdr_object_dtor(void *obj)
803 struct cdr_object *cdr = obj;
804 struct ast_var_t *it_var;
810 ao2_cleanup(cdr->party_a.snapshot);
811 ao2_cleanup(cdr->party_b.snapshot);
812 while ((it_var = AST_LIST_REMOVE_HEAD(&cdr->party_a.variables, entries))) {
813 ast_var_delete(it_var);
815 while ((it_var = AST_LIST_REMOVE_HEAD(&cdr->party_b.variables, entries))) {
816 ast_var_delete(it_var);
818 ast_string_field_free_memory(cdr);
821 ao2_cleanup(cdr->next);
826 * \brief \ref cdr_object constructor
827 * \param chan The \ref ast_channel_snapshot that is the CDR's Party A
829 * This implicitly sets the state of the newly created CDR to the Single state
830 * (\ref single_state_fn_table)
832 static struct cdr_object *cdr_object_alloc(struct ast_channel_snapshot *chan)
834 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
835 struct cdr_object *cdr;
837 ast_assert(chan != NULL);
839 cdr = ao2_alloc(sizeof(*cdr), cdr_object_dtor);
844 if (ast_string_field_init(cdr, 64)) {
847 ast_string_field_set(cdr, name, chan->name);
848 ast_string_field_set(cdr, linkedid, chan->linkedid);
849 cdr->disposition = AST_CDR_NULL;
850 cdr->sequence = ast_atomic_fetchadd_int(&global_cdr_sequence, +1);
852 cdr->party_a.snapshot = chan;
853 ao2_t_ref(cdr->party_a.snapshot, +1, "bump snapshot during CDR creation");
855 CDR_DEBUG(mod_cfg, "%p - Created CDR for channel %s\n", cdr, chan->name);
857 cdr_object_transition_state(cdr, &single_state_fn_table);
863 * \brief Create a new \ref cdr_object and append it to an existing chain
864 * \param cdr The \ref cdr_object to append to
866 static struct cdr_object *cdr_object_create_and_append(struct cdr_object *cdr)
868 struct cdr_object *new_cdr;
869 struct cdr_object *it_cdr;
870 struct cdr_object *cdr_last;
872 cdr_last = cdr->last;
873 new_cdr = cdr_object_alloc(cdr_last->party_a.snapshot);
877 new_cdr->disposition = AST_CDR_NULL;
879 /* Copy over the linkedid, as it may have changed */
880 ast_string_field_set(new_cdr, linkedid, cdr_last->linkedid);
881 ast_string_field_set(new_cdr, appl, cdr_last->appl);
882 ast_string_field_set(new_cdr, data, cdr_last->data);
884 /* Copy over other Party A information */
885 cdr_object_snapshot_copy(&new_cdr->party_a, &cdr_last->party_a);
887 /* Append the CDR to the end of the list */
888 for (it_cdr = cdr; it_cdr->next; it_cdr = it_cdr->next) {
889 it_cdr->last = new_cdr;
891 it_cdr->last = new_cdr;
892 it_cdr->next = new_cdr;
898 * \brief Return whether or not a channel has changed its state in the dialplan, subject
899 * to endbeforehexten logic
901 * \param old_snapshot The previous state
902 * \param new_snapshot The new state
904 * \retval 0 if the state has not changed
905 * \retval 1 if the state changed
907 static int snapshot_cep_changed(struct ast_channel_snapshot *old_snapshot,
908 struct ast_channel_snapshot *new_snapshot)
910 RAII_VAR(struct module_config *, mod_cfg,
911 ao2_global_obj_ref(module_configs), ao2_cleanup);
913 /* If we ignore hangup logic, don't indicate that we're executing anything new */
914 if (ast_test_flag(&mod_cfg->general->settings, CDR_END_BEFORE_H_EXTEN)
915 && ast_test_flag(&new_snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)) {
919 /* When Party A is originated to an application and the application exits, the stack
920 * will attempt to clear the application and restore the dummy originate application
921 * of "AppDialX". Ignore application changes to AppDialX as a result.
923 if (strcmp(new_snapshot->appl, old_snapshot->appl) && strncasecmp(new_snapshot->appl, "appdial", 7)
924 && (strcmp(new_snapshot->context, old_snapshot->context)
925 || strcmp(new_snapshot->exten, old_snapshot->exten)
926 || new_snapshot->priority != old_snapshot->priority)) {
934 * \brief Return whether or not a \ref ast_channel_snapshot is for a channel
935 * that was created as the result of a dial operation
937 * \retval 0 the channel was not created as the result of a dial
938 * \retval 1 the channel was created as the result of a dial
940 static int snapshot_is_dialed(struct ast_channel_snapshot *snapshot)
942 return (ast_test_flag(&snapshot->flags, AST_FLAG_OUTGOING)
943 && !(ast_test_flag(&snapshot->flags, AST_FLAG_ORIGINATED)));
947 * \brief Given two CDR snapshots, figure out who should be Party A for the
949 * \param left One of the snapshots
950 * \param right The other snapshot
951 * \retval The snapshot that won
953 static struct cdr_object_snapshot *cdr_object_pick_party_a(struct cdr_object_snapshot *left, struct cdr_object_snapshot *right)
955 /* Check whether or not the party is dialed. A dialed party is never the
956 * Party A with a party that was not dialed.
958 if (!snapshot_is_dialed(left->snapshot) && snapshot_is_dialed(right->snapshot)) {
960 } else if (snapshot_is_dialed(left->snapshot) && !snapshot_is_dialed(right->snapshot)) {
964 /* Try the Party A flag */
965 if (ast_test_flag(left, AST_CDR_FLAG_PARTY_A) && !ast_test_flag(right, AST_CDR_FLAG_PARTY_A)) {
967 } else if (!ast_test_flag(right, AST_CDR_FLAG_PARTY_A) && ast_test_flag(right, AST_CDR_FLAG_PARTY_A)) {
971 /* Neither party is dialed and neither has the Party A flag - defer to
973 if (left->snapshot->creationtime.tv_sec < right->snapshot->creationtime.tv_sec) {
975 } else if (left->snapshot->creationtime.tv_sec > right->snapshot->creationtime.tv_sec) {
977 } else if (left->snapshot->creationtime.tv_usec > right->snapshot->creationtime.tv_usec) {
980 /* Okay, fine, take the left one */
986 * Compute the duration for a \ref cdr_object
988 static long cdr_object_get_duration(struct cdr_object *cdr)
990 return (long)(ast_tvdiff_ms(ast_tvzero(cdr->end) ? ast_tvnow() : cdr->end, cdr->start) / 1000);
994 * \brief Compute the billsec for a \ref cdr_object
996 static long cdr_object_get_billsec(struct cdr_object *cdr)
998 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
1001 if (ast_tvzero(cdr->answer)) {
1004 ms = ast_tvdiff_ms(ast_tvzero(cdr->end) ? ast_tvnow() : cdr->end, cdr->answer);
1005 if (ast_test_flag(&mod_cfg->general->settings, CDR_INITIATED_SECONDS)
1006 && (ms % 1000 >= 500)) {
1007 ms = (ms / 1000) + 1;
1017 * \brief Set a variable on a CDR object
1019 * \param headp The header pointer to the variable to set
1020 * \param name The name of the variable
1021 * \param value The value of the variable
1023 static void set_variable(struct varshead *headp, const char *name, const char *value)
1025 struct ast_var_t *newvariable;
1027 AST_LIST_TRAVERSE_SAFE_BEGIN(headp, newvariable, entries) {
1028 if (!strcasecmp(ast_var_name(newvariable), name)) {
1029 AST_LIST_REMOVE_CURRENT(entries);
1030 ast_var_delete(newvariable);
1034 AST_LIST_TRAVERSE_SAFE_END;
1036 if (value && (newvariable = ast_var_assign(name, value))) {
1037 AST_LIST_INSERT_HEAD(headp, newvariable, entries);
1042 * \brief Create a chain of \ref ast_cdr objects from a chain of \ref cdr_object
1043 * suitable for consumption by the registered CDR backends
1044 * \param cdr The \ref cdr_object to convert to a public record
1045 * \retval A chain of \ref ast_cdr objects on success
1046 * \retval NULL on failure
1048 static struct ast_cdr *cdr_object_create_public_records(struct cdr_object *cdr)
1050 struct ast_cdr *pub_cdr = NULL, *cdr_prev = NULL;
1051 struct cdr_object *it_cdr;
1052 struct ast_var_t *it_var, *it_copy_var;
1053 struct ast_channel_snapshot *party_a;
1054 struct ast_channel_snapshot *party_b;
1056 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
1057 struct ast_cdr *cdr_copy;
1059 /* Don't create records for CDRs where the party A was a dialed channel */
1060 if (snapshot_is_dialed(it_cdr->party_a.snapshot)) {
1064 cdr_copy = ast_calloc(1, sizeof(*cdr_copy));
1070 party_a = it_cdr->party_a.snapshot;
1071 party_b = it_cdr->party_b.snapshot;
1074 ast_assert(party_a != NULL);
1075 ast_copy_string(cdr_copy->accountcode, party_a->accountcode, sizeof(cdr_copy->accountcode));
1076 cdr_copy->amaflags = party_a->amaflags;
1077 ast_copy_string(cdr_copy->channel, party_a->name, sizeof(cdr_copy->channel));
1078 ast_callerid_merge(cdr_copy->clid, sizeof(cdr_copy->clid), party_a->caller_name, party_a->caller_number, "");
1079 ast_copy_string(cdr_copy->src, party_a->caller_number, sizeof(cdr_copy->src));
1080 ast_copy_string(cdr_copy->uniqueid, party_a->uniqueid, sizeof(cdr_copy->uniqueid));
1081 ast_copy_string(cdr_copy->lastapp, it_cdr->appl, sizeof(cdr_copy->lastapp));
1082 ast_copy_string(cdr_copy->lastdata, it_cdr->data, sizeof(cdr_copy->lastdata));
1083 ast_copy_string(cdr_copy->dst, party_a->exten, sizeof(cdr_copy->dst));
1084 ast_copy_string(cdr_copy->dcontext, party_a->context, sizeof(cdr_copy->dcontext));
1088 ast_copy_string(cdr_copy->dstchannel, party_b->name, sizeof(cdr_copy->dstchannel));
1089 ast_copy_string(cdr_copy->peeraccount, party_b->accountcode, sizeof(cdr_copy->peeraccount));
1090 if (!ast_strlen_zero(it_cdr->party_b.userfield)) {
1091 snprintf(cdr_copy->userfield, sizeof(cdr_copy->userfield), "%s;%s", it_cdr->party_a.userfield, it_cdr->party_b.userfield);
1094 if (ast_strlen_zero(cdr_copy->userfield) && !ast_strlen_zero(it_cdr->party_a.userfield)) {
1095 ast_copy_string(cdr_copy->userfield, it_cdr->party_a.userfield, sizeof(cdr_copy->userfield));
1098 /* Timestamps/durations */
1099 cdr_copy->start = it_cdr->start;
1100 cdr_copy->answer = it_cdr->answer;
1101 cdr_copy->end = it_cdr->end;
1102 cdr_copy->billsec = cdr_object_get_billsec(it_cdr);
1103 cdr_copy->duration = cdr_object_get_duration(it_cdr);
1106 ast_copy_flags(cdr_copy, &it_cdr->flags, AST_FLAGS_ALL);
1107 ast_copy_string(cdr_copy->linkedid, it_cdr->linkedid, sizeof(cdr_copy->linkedid));
1108 cdr_copy->disposition = it_cdr->disposition;
1109 cdr_copy->sequence = it_cdr->sequence;
1112 copy_variables(&cdr_copy->varshead, &it_cdr->party_a.variables);
1113 AST_LIST_TRAVERSE(&it_cdr->party_b.variables, it_var, entries) {
1115 struct ast_var_t *newvariable;
1116 AST_LIST_TRAVERSE(&cdr_copy->varshead, it_copy_var, entries) {
1117 if (!strcmp(ast_var_name(it_var), ast_var_name(it_copy_var))) {
1122 if (!found && (newvariable = ast_var_assign(ast_var_name(it_var), ast_var_value(it_var)))) {
1123 AST_LIST_INSERT_TAIL(&cdr_copy->varshead, newvariable, entries);
1131 cdr_prev->next = cdr_copy;
1132 cdr_prev = cdr_copy;
1140 * \brief Dispatch a CDR.
1141 * \param cdr The \ref cdr_object to dispatch
1143 * This will create a \ref ast_cdr object and publish it to the various backends
1145 static void cdr_object_dispatch(struct cdr_object *cdr)
1147 RAII_VAR(struct module_config *, mod_cfg,
1148 ao2_global_obj_ref(module_configs), ao2_cleanup);
1149 struct ast_cdr *pub_cdr;
1151 CDR_DEBUG(mod_cfg, "%p - Dispatching CDR for Party A %s, Party B %s\n", cdr,
1152 cdr->party_a.snapshot->name,
1153 cdr->party_b.snapshot ? cdr->party_b.snapshot->name : "<none>");
1154 pub_cdr = cdr_object_create_public_records(cdr);
1155 cdr_detach(pub_cdr);
1159 * \brief Set the disposition on a \ref cdr_object based on a hangupcause code
1160 * \param cdr The \ref cdr_object
1161 * \param hangupcause The Asterisk hangup cause code
1163 static void cdr_object_set_disposition(struct cdr_object *cdr, int hangupcause)
1165 RAII_VAR(struct module_config *, mod_cfg,
1166 ao2_global_obj_ref(module_configs), ao2_cleanup);
1168 /* Change the disposition based on the hang up cause */
1169 switch (hangupcause) {
1170 case AST_CAUSE_BUSY:
1171 cdr->disposition = AST_CDR_BUSY;
1173 case AST_CAUSE_CONGESTION:
1174 if (!ast_test_flag(&mod_cfg->general->settings, CDR_CONGESTION)) {
1175 cdr->disposition = AST_CDR_FAILED;
1177 cdr->disposition = AST_CDR_CONGESTION;
1180 case AST_CAUSE_NO_ROUTE_DESTINATION:
1181 case AST_CAUSE_UNREGISTERED:
1182 cdr->disposition = AST_CDR_FAILED;
1184 case AST_CAUSE_NORMAL_CLEARING:
1185 case AST_CAUSE_NO_ANSWER:
1186 cdr->disposition = AST_CDR_NOANSWER;
1194 * \brief Finalize a CDR.
1196 * This function is safe to call multiple times. Note that you can call this
1197 * explicitly before going to the finalized state if there's a chance the CDR
1198 * will be re-activated, in which case the \ref cdr_object's end time should be
1199 * cleared. This function is implicitly called when a CDR transitions to the
1200 * finalized state and right before it is dispatched
1202 * \param cdr_object The CDR to finalize
1204 static void cdr_object_finalize(struct cdr_object *cdr)
1206 RAII_VAR(struct module_config *, mod_cfg,
1207 ao2_global_obj_ref(module_configs), ao2_cleanup);
1209 if (!ast_tvzero(cdr->end)) {
1212 cdr->end = ast_tvnow();
1214 if (cdr->disposition == AST_CDR_NULL) {
1215 if (!ast_tvzero(cdr->answer)) {
1216 cdr->disposition = AST_CDR_ANSWERED;
1217 } else if (cdr->party_a.snapshot->hangupcause) {
1218 cdr_object_set_disposition(cdr, cdr->party_a.snapshot->hangupcause);
1219 } else if (cdr->party_b.snapshot && cdr->party_b.snapshot->hangupcause) {
1220 cdr_object_set_disposition(cdr, cdr->party_b.snapshot->hangupcause);
1222 cdr->disposition = AST_CDR_FAILED;
1226 /* tv_usec is suseconds_t, which could be int or long */
1227 ast_debug(1, "Finalized CDR for %s - start %ld.%06ld answer %ld.%06ld end %ld.%06ld dispo %s\n",
1228 cdr->party_a.snapshot->name,
1230 (long)cdr->start.tv_usec,
1232 (long)cdr->answer.tv_usec,
1234 (long)cdr->end.tv_usec,
1235 ast_cdr_disp2str(cdr->disposition));
1239 * \brief Check to see if a CDR needs to move to the finalized state because
1240 * its Party A hungup.
1242 static void cdr_object_check_party_a_hangup(struct cdr_object *cdr)
1244 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
1246 if (ast_test_flag(&mod_cfg->general->settings, CDR_END_BEFORE_H_EXTEN)
1247 && ast_test_flag(&cdr->party_a.snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)) {
1248 cdr_object_finalize(cdr);
1251 if (ast_test_flag(&cdr->party_a.snapshot->flags, AST_FLAG_DEAD)
1252 && cdr->fn_table != &finalized_state_fn_table) {
1253 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1258 * \brief Check to see if a CDR needs to be answered based on its Party A.
1259 * Note that this is safe to call as much as you want - we won't answer twice
1261 static void cdr_object_check_party_a_answer(struct cdr_object *cdr) {
1262 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
1264 if (cdr->party_a.snapshot->state == AST_STATE_UP && ast_tvzero(cdr->answer)) {
1265 cdr->answer = ast_tvnow();
1266 /* tv_usec is suseconds_t, which could be int or long */
1267 CDR_DEBUG(mod_cfg, "%p - Set answered time to %ld.%06ld\n", cdr,
1269 (long)cdr->answer.tv_usec);
1273 /* \brief Set Caller ID information on a CDR */
1274 static void cdr_object_update_cid(struct cdr_object_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot)
1276 if (!old_snapshot->snapshot) {
1277 set_variable(&old_snapshot->variables, "dnid", new_snapshot->caller_dnid);
1278 set_variable(&old_snapshot->variables, "callingsubaddr", new_snapshot->caller_subaddr);
1279 set_variable(&old_snapshot->variables, "calledsubaddr", new_snapshot->dialed_subaddr);
1282 if (!strcmp(old_snapshot->snapshot->caller_dnid, new_snapshot->caller_dnid)) {
1283 set_variable(&old_snapshot->variables, "dnid", new_snapshot->caller_dnid);
1285 if (!strcmp(old_snapshot->snapshot->caller_subaddr, new_snapshot->caller_subaddr)) {
1286 set_variable(&old_snapshot->variables, "callingsubaddr", new_snapshot->caller_subaddr);
1288 if (!strcmp(old_snapshot->snapshot->dialed_subaddr, new_snapshot->dialed_subaddr)) {
1289 set_variable(&old_snapshot->variables, "calledsubaddr", new_snapshot->dialed_subaddr);
1294 * \brief Swap an old \ref cdr_object_snapshot's \ref ast_channel_snapshot for
1295 * a new \ref ast_channel_snapshot
1296 * \param old_snapshot The old \ref cdr_object_snapshot
1297 * \param new_snapshot The new \ref ast_channel_snapshot for old_snapshot
1299 static void cdr_object_swap_snapshot(struct cdr_object_snapshot *old_snapshot,
1300 struct ast_channel_snapshot *new_snapshot)
1302 cdr_object_update_cid(old_snapshot, new_snapshot);
1303 if (old_snapshot->snapshot) {
1304 ao2_t_ref(old_snapshot->snapshot, -1, "Drop ref for swap");
1306 ao2_t_ref(new_snapshot, +1, "Bump ref for swap");
1307 old_snapshot->snapshot = new_snapshot;
1310 /* BASE METHOD IMPLEMENTATIONS */
1312 static int base_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
1314 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
1316 ast_assert(strcmp(snapshot->name, cdr->party_a.snapshot->name) == 0);
1317 cdr_object_swap_snapshot(&cdr->party_a, snapshot);
1319 /* When Party A is originated to an application and the application exits, the stack
1320 * will attempt to clear the application and restore the dummy originate application
1321 * of "AppDialX". Prevent that, and any other application changes we might not want
1324 if (!ast_strlen_zero(snapshot->appl)
1325 && (strncasecmp(snapshot->appl, "appdial", 7) || ast_strlen_zero(cdr->appl))
1326 && !ast_test_flag(&cdr->flags, AST_CDR_LOCK_APP)) {
1327 ast_string_field_set(cdr, appl, snapshot->appl);
1328 ast_string_field_set(cdr, data, snapshot->data);
1331 ast_string_field_set(cdr, linkedid, snapshot->linkedid);
1332 cdr_object_check_party_a_answer(cdr);
1333 cdr_object_check_party_a_hangup(cdr);
1338 static int base_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1340 /* In general, most things shouldn't get a bridge leave */
1345 static int base_process_dial_end(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer, const char *dial_status)
1347 /* In general, most things shouldn't get a dial end. */
1352 static enum process_bridge_enter_results base_process_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1354 /* Base process bridge enter simply indicates that we can't handle it */
1355 return BRIDGE_ENTER_NEED_CDR;
1358 static int base_process_parked_channel(struct cdr_object *cdr, struct ast_parked_call_payload *parking_info)
1360 char park_info[128];
1362 ast_assert(!strcmp(parking_info->parkee->name, cdr->party_a.snapshot->name));
1364 /* Update Party A information regardless */
1365 cdr->fn_table->process_party_a(cdr, parking_info->parkee);
1367 /* Fake out where we're parked */
1368 ast_string_field_set(cdr, appl, "Park");
1369 snprintf(park_info, sizeof(park_info), "%s:%u", parking_info->parkinglot, parking_info->parkingspace);
1370 ast_string_field_set(cdr, data, park_info);
1372 /* Prevent any further changes to the App/Data fields for this record */
1373 ast_set_flag(&cdr->flags, AST_CDR_LOCK_APP);
1380 static void single_state_init_function(struct cdr_object *cdr) {
1381 cdr->start = ast_tvnow();
1382 cdr_object_check_party_a_answer(cdr);
1385 static void single_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
1387 /* This should never happen! */
1388 ast_assert(cdr->party_b.snapshot == NULL);
1393 static int single_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer)
1395 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
1397 if (caller && !strcmp(cdr->party_a.snapshot->name, caller->name)) {
1398 cdr_object_swap_snapshot(&cdr->party_a, caller);
1399 CDR_DEBUG(mod_cfg, "%p - Updated Party A %s snapshot\n", cdr,
1400 cdr->party_a.snapshot->name);
1401 cdr_object_swap_snapshot(&cdr->party_b, peer);
1402 CDR_DEBUG(mod_cfg, "%p - Updated Party B %s snapshot\n", cdr,
1403 cdr->party_b.snapshot->name);
1404 } else if (!strcmp(cdr->party_a.snapshot->name, peer->name)) {
1405 /* We're the entity being dialed, i.e., outbound origination */
1406 cdr_object_swap_snapshot(&cdr->party_a, peer);
1407 CDR_DEBUG(mod_cfg, "%p - Updated Party A %s snapshot\n", cdr,
1408 cdr->party_a.snapshot->name);
1411 cdr_object_transition_state(cdr, &dial_state_fn_table);
1416 * \brief Handle a comparison between our \ref cdr_object and a \ref cdr_object
1417 * already in the bridge while in the Single state. The goal of this is to find
1418 * a Party B for our CDR.
1420 * \param cdr Our \ref cdr_object in the Single state
1421 * \param cand_cdr The \ref cdr_object already in the Bridge state
1423 * \retval 0 The cand_cdr had a Party A or Party B that we could use as our
1425 * \retval 1 No party in the cand_cdr could be used as our Party B
1427 static int single_state_bridge_enter_comparison(struct cdr_object *cdr,
1428 struct cdr_object *cand_cdr)
1430 struct cdr_object_snapshot *party_a;
1432 /* Don't match on ourselves */
1433 if (!strcmp(cdr->party_a.snapshot->name, cand_cdr->party_a.snapshot->name)) {
1437 /* Try the candidate CDR's Party A first */
1438 party_a = cdr_object_pick_party_a(&cdr->party_a, &cand_cdr->party_a);
1439 if (!strcmp(party_a->snapshot->name, cdr->party_a.snapshot->name)) {
1440 cdr_object_snapshot_copy(&cdr->party_b, &cand_cdr->party_a);
1441 if (!cand_cdr->party_b.snapshot) {
1442 /* We just stole them - finalize their CDR. Note that this won't
1443 * transition their state, it just sets the end time and the
1444 * disposition - if we need to re-activate them later, we can.
1446 cdr_object_finalize(cand_cdr);
1451 /* Try their Party B, unless it's us */
1452 if (!cand_cdr->party_b.snapshot || !strcmp(cdr->party_a.snapshot->name, cand_cdr->party_b.snapshot->name)) {
1455 party_a = cdr_object_pick_party_a(&cdr->party_a, &cand_cdr->party_b);
1456 if (!strcmp(party_a->snapshot->name, cdr->party_a.snapshot->name)) {
1457 cdr_object_snapshot_copy(&cdr->party_b, &cand_cdr->party_b);
1464 static enum process_bridge_enter_results single_state_process_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1466 struct ao2_iterator *it_cdrs;
1467 struct cdr_object *cand_cdr_master;
1468 char *bridge_id = ast_strdupa(bridge->uniqueid);
1471 ast_string_field_set(cdr, bridge, bridge->uniqueid);
1473 /* Get parties in the bridge */
1474 it_cdrs = ao2_callback(active_cdrs_by_channel, OBJ_MULTIPLE,
1475 cdr_object_bridge_cmp_fn, bridge_id);
1477 /* No one in the bridge yet! */
1478 cdr_object_transition_state(cdr, &bridge_state_fn_table);
1479 return BRIDGE_ENTER_ONLY_PARTY;
1482 while ((cand_cdr_master = ao2_iterator_next(it_cdrs))) {
1483 struct cdr_object *cand_cdr;
1484 RAII_VAR(struct cdr_object *, cdr_cleanup, cand_cdr_master, ao2_cleanup);
1485 SCOPED_AO2LOCK(lock, cand_cdr_master);
1487 for (cand_cdr = cand_cdr_master; cand_cdr; cand_cdr = cand_cdr->next) {
1488 /* Skip any records that are not in a bridge or in this bridge.
1489 * I'm not sure how that would happen, but it pays to be careful. */
1490 if (cand_cdr->fn_table != &bridge_state_fn_table ||
1491 strcmp(cdr->bridge, cand_cdr->bridge)) {
1495 if (single_state_bridge_enter_comparison(cdr, cand_cdr)) {
1498 /* We successfully got a party B - break out */
1503 ao2_iterator_destroy(it_cdrs);
1505 /* We always transition state, even if we didn't get a peer */
1506 cdr_object_transition_state(cdr, &bridge_state_fn_table);
1508 /* Success implies that we have a Party B */
1510 return BRIDGE_ENTER_OBTAINED_PARTY_B;
1513 return BRIDGE_ENTER_NO_PARTY_B;
1516 static int single_state_process_parking_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1518 cdr_object_transition_state(cdr, &parked_state_fn_table);
1525 static void dial_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
1527 ast_assert(snapshot != NULL);
1529 if (!cdr->party_b.snapshot || strcmp(cdr->party_b.snapshot->name, snapshot->name)) {
1532 cdr_object_swap_snapshot(&cdr->party_b, snapshot);
1534 /* If party B hangs up, finalize this CDR */
1535 if (ast_test_flag(&cdr->party_b.snapshot->flags, AST_FLAG_DEAD)) {
1536 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1540 static int dial_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer)
1542 /* Don't process a begin dial here. A party A already in the dial state will
1543 * who receives a dial begin for something else will be handled by the
1544 * message router callback and will add a new CDR for the party A */
1548 /*! \internal \brief Convert a dial status to a CDR disposition */
1549 static enum ast_cdr_disposition dial_status_to_disposition(const char *dial_status)
1551 RAII_VAR(struct module_config *, mod_cfg,
1552 ao2_global_obj_ref(module_configs), ao2_cleanup);
1554 if (!strcmp(dial_status, "ANSWER")) {
1555 return AST_CDR_ANSWERED;
1556 } else if (!strcmp(dial_status, "BUSY")) {
1557 return AST_CDR_BUSY;
1558 } else if (!strcmp(dial_status, "CANCEL") || !strcmp(dial_status, "NOANSWER")) {
1559 return AST_CDR_NOANSWER;
1560 } else if (!strcmp(dial_status, "CONGESTION")) {
1561 if (!ast_test_flag(&mod_cfg->general->settings, CDR_CONGESTION)) {
1562 return AST_CDR_FAILED;
1564 return AST_CDR_CONGESTION;
1566 } else if (!strcmp(dial_status, "FAILED")) {
1567 return AST_CDR_FAILED;
1569 return AST_CDR_FAILED;
1572 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)
1574 RAII_VAR(struct module_config *, mod_cfg,
1575 ao2_global_obj_ref(module_configs), ao2_cleanup);
1576 struct ast_channel_snapshot *party_a;
1583 ast_assert(!strcmp(cdr->party_a.snapshot->name, party_a->name));
1584 cdr_object_swap_snapshot(&cdr->party_a, party_a);
1586 if (cdr->party_b.snapshot) {
1587 if (strcmp(cdr->party_b.snapshot->name, peer->name)) {
1588 /* Not the status for this CDR - defer back to the message router */
1591 cdr_object_swap_snapshot(&cdr->party_b, peer);
1594 /* Set the disposition based on the dial string. */
1595 cdr->disposition = dial_status_to_disposition(dial_status);
1596 if (cdr->disposition == AST_CDR_ANSWERED) {
1597 /* Switch to dial pending to wait and see what the caller does */
1598 cdr_object_transition_state(cdr, &dialed_pending_state_fn_table);
1600 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1606 static enum process_bridge_enter_results dial_state_process_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1608 struct ao2_iterator *it_cdrs;
1609 char *bridge_id = ast_strdupa(bridge->uniqueid);
1610 struct cdr_object *cand_cdr_master;
1613 ast_string_field_set(cdr, bridge, bridge->uniqueid);
1615 /* Get parties in the bridge */
1616 it_cdrs = ao2_callback(active_cdrs_by_channel, OBJ_MULTIPLE,
1617 cdr_object_bridge_cmp_fn, bridge_id);
1619 /* No one in the bridge yet! */
1620 cdr_object_transition_state(cdr, &bridge_state_fn_table);
1621 return BRIDGE_ENTER_ONLY_PARTY;
1624 while ((cand_cdr_master = ao2_iterator_next(it_cdrs))) {
1625 struct cdr_object *cand_cdr;
1626 RAII_VAR(struct cdr_object *, cdr_cleanup, cand_cdr_master, ao2_cleanup);
1627 SCOPED_AO2LOCK(lock, cand_cdr_master);
1629 for (cand_cdr = cand_cdr_master; cand_cdr; cand_cdr = cand_cdr->next) {
1630 /* Skip any records that are not in a bridge or in this bridge.
1631 * I'm not sure how that would happen, but it pays to be careful. */
1632 if (cand_cdr->fn_table != &bridge_state_fn_table ||
1633 strcmp(cdr->bridge, cand_cdr->bridge)) {
1637 /* If we don't have a Party B (originated channel), skip it */
1638 if (!cdr->party_b.snapshot) {
1642 /* Skip any records that aren't our Party B */
1643 if (strcmp(cdr->party_b.snapshot->name, cand_cdr->party_a.snapshot->name)) {
1646 cdr_object_snapshot_copy(&cdr->party_b, &cand_cdr->party_a);
1647 /* If they have a Party B, they joined up with someone else as their
1648 * Party A. Don't finalize them as they're active. Otherwise, we
1649 * have stolen them so they need to be finalized.
1651 if (!cand_cdr->party_b.snapshot) {
1652 cdr_object_finalize(cand_cdr);
1658 ao2_iterator_destroy(it_cdrs);
1660 /* We always transition state, even if we didn't get a peer */
1661 cdr_object_transition_state(cdr, &bridge_state_fn_table);
1663 /* Success implies that we have a Party B */
1665 return BRIDGE_ENTER_OBTAINED_PARTY_B;
1667 return BRIDGE_ENTER_NO_PARTY_B;
1670 /* DIALED PENDING STATE */
1672 static int dialed_pending_state_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
1674 /* If we get a CEP change, we're executing dialplan. If we have a Party B
1675 * that means we need a new CDR; otherwise, switch us over to single.
1677 if (snapshot_cep_changed(cdr->party_a.snapshot, snapshot)) {
1678 if (cdr->party_b.snapshot) {
1679 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1680 cdr->fn_table->process_party_a(cdr, snapshot);
1683 cdr_object_transition_state(cdr, &single_state_fn_table);
1684 cdr->fn_table->process_party_a(cdr, snapshot);
1688 base_process_party_a(cdr, snapshot);
1692 static enum process_bridge_enter_results dialed_pending_state_process_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1694 cdr_object_transition_state(cdr, &dial_state_fn_table);
1695 return cdr->fn_table->process_bridge_enter(cdr, bridge, channel);
1698 static int dialed_pending_state_process_parking_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1700 /* We can't handle this as we have a Party B - ask for a new one */
1704 static int dialed_pending_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer)
1706 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1708 /* Ask for a new CDR */
1714 static void bridge_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
1716 if (!cdr->party_b.snapshot || strcmp(cdr->party_b.snapshot->name, snapshot->name)) {
1719 cdr_object_swap_snapshot(&cdr->party_b, snapshot);
1721 /* If party B hangs up, finalize this CDR */
1722 if (ast_test_flag(&cdr->party_b.snapshot->flags, AST_FLAG_DEAD)) {
1723 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1727 static int bridge_state_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1729 if (strcmp(cdr->bridge, bridge->uniqueid)) {
1732 if (strcmp(cdr->party_a.snapshot->name, channel->name)
1733 && cdr->party_b.snapshot
1734 && strcmp(cdr->party_b.snapshot->name, channel->name)) {
1737 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1744 static int parked_state_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1746 if (strcmp(cdr->party_a.snapshot->name, channel->name)) {
1749 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1754 /* FINALIZED STATE */
1756 static void finalized_state_init_function(struct cdr_object *cdr)
1758 cdr_object_finalize(cdr);
1761 static int finalized_state_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
1763 RAII_VAR(struct module_config *, mod_cfg,
1764 ao2_global_obj_ref(module_configs), ao2_cleanup);
1766 /* If we ignore hangup logic, indicate that we don't need a new CDR */
1767 if (ast_test_flag(&mod_cfg->general->settings, CDR_END_BEFORE_H_EXTEN)
1768 && ast_test_flag(&snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)) {
1772 /* Indicate that, if possible, we should get a new CDR */
1776 /* TOPIC ROUTER CALLBACKS */
1779 * \brief Handler for Stasis-Core dial messages
1780 * \param data Passed on
1781 * \param sub The stasis subscription for this message callback
1782 * \param topic The topic this message was published for
1783 * \param message The message
1785 static void handle_dial_message(void *data, struct stasis_subscription *sub, struct stasis_topic *topic, struct stasis_message *message)
1787 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
1788 struct cdr_object *cdr;
1789 struct ast_multi_channel_blob *payload = stasis_message_data(message);
1790 struct ast_channel_snapshot *caller;
1791 struct ast_channel_snapshot *peer;
1792 struct cdr_object *it_cdr;
1793 struct ast_json *dial_status_blob;
1794 const char *dial_status = NULL;
1797 caller = ast_multi_channel_blob_get_channel(payload, "caller");
1798 peer = ast_multi_channel_blob_get_channel(payload, "peer");
1799 if (!peer && !caller) {
1802 dial_status_blob = ast_json_object_get(ast_multi_channel_blob_get_json(payload), "dialstatus");
1803 if (dial_status_blob) {
1804 dial_status = ast_json_string_get(dial_status_blob);
1807 CDR_DEBUG(mod_cfg, "Dial %s message for %s, %s: %u.%08u\n",
1808 ast_strlen_zero(dial_status) ? "Begin" : "End",
1809 caller ? caller->name : "(none)",
1810 peer ? peer->name : "(none)",
1811 (unsigned int)stasis_message_timestamp(message)->tv_sec,
1812 (unsigned int)stasis_message_timestamp(message)->tv_usec);
1814 /* Figure out who is running this show */
1816 cdr = ao2_find(active_cdrs_by_channel, caller->name, OBJ_KEY);
1818 cdr = ao2_find(active_cdrs_by_channel, peer->name, OBJ_KEY);
1822 ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", caller ? caller->name : peer->name);
1827 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
1828 if (ast_strlen_zero(dial_status)) {
1829 if (!it_cdr->fn_table->process_dial_begin) {
1832 CDR_DEBUG(mod_cfg, "%p - Processing Dial Begin message for channel %s, peer %s\n",
1834 caller ? caller->name : "(none)",
1835 peer ? peer->name : "(none)");
1836 res &= it_cdr->fn_table->process_dial_begin(it_cdr,
1840 if (!it_cdr->fn_table->process_dial_end) {
1843 CDR_DEBUG(mod_cfg, "%p - Processing Dial End message for channel %s, peer %s\n",
1845 caller ? caller->name : "(none)",
1846 peer ? peer->name : "(none)");
1847 it_cdr->fn_table->process_dial_end(it_cdr,
1854 /* If no CDR handled a dial begin message, make a new one */
1855 if (res && ast_strlen_zero(dial_status)) {
1856 struct cdr_object *new_cdr;
1858 new_cdr = cdr_object_create_and_append(cdr);
1862 new_cdr->fn_table->process_dial_begin(new_cdr,
1869 static int cdr_object_finalize_party_b(void *obj, void *arg, int flags)
1871 struct cdr_object *cdr = obj;
1872 struct ast_channel_snapshot *party_b = arg;
1873 struct cdr_object *it_cdr;
1874 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
1875 if (it_cdr->party_b.snapshot && !strcmp(it_cdr->party_b.snapshot->name, party_b->name)) {
1876 /* Don't transition to the finalized state - let the Party A do
1877 * that when its ready
1879 cdr_object_finalize(it_cdr);
1885 static int cdr_object_update_party_b(void *obj, void *arg, int flags)
1887 struct cdr_object *cdr = obj;
1888 struct ast_channel_snapshot *party_b = arg;
1889 struct cdr_object *it_cdr;
1890 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
1891 if (!it_cdr->fn_table->process_party_b) {
1894 if (it_cdr->party_b.snapshot && !strcmp(it_cdr->party_b.snapshot->name, party_b->name)) {
1895 it_cdr->fn_table->process_party_b(it_cdr, party_b);
1901 /*! \internal \brief Filter channel snapshots by technology */
1902 static int filter_channel_snapshot(struct ast_channel_snapshot *snapshot)
1904 return snapshot->tech_properties & AST_CHAN_TP_INTERNAL;
1907 /*! \internal \brief Filter a channel cache update */
1908 static int filter_channel_cache_message(struct ast_channel_snapshot *old_snapshot,
1909 struct ast_channel_snapshot *new_snapshot)
1913 /* Drop cache updates from certain channel technologies */
1915 ret |= filter_channel_snapshot(old_snapshot);
1918 ret |= filter_channel_snapshot(new_snapshot);
1924 /*! \brief Determine if we need to add a new CDR based on snapshots */
1925 static int check_new_cdr_needed(struct ast_channel_snapshot *old_snapshot,
1926 struct ast_channel_snapshot *new_snapshot)
1928 RAII_VAR(struct module_config *, mod_cfg,
1929 ao2_global_obj_ref(module_configs), ao2_cleanup);
1931 if (!new_snapshot) {
1935 if (ast_test_flag(&new_snapshot->flags, AST_FLAG_DEAD)) {
1939 /* Auto-fall through will increment the priority but have no application */
1940 if (ast_strlen_zero(new_snapshot->appl)) {
1944 if (old_snapshot && !snapshot_cep_changed(old_snapshot, new_snapshot)) {
1952 * \brief Handler for Stasis-Core channel cache update messages
1953 * \param data Passed on
1954 * \param sub The stasis subscription for this message callback
1955 * \param topic The topic this message was published for
1956 * \param message The message
1958 static void handle_channel_cache_message(void *data, struct stasis_subscription *sub, struct stasis_topic *topic, struct stasis_message *message)
1960 RAII_VAR(struct cdr_object *, cdr, NULL, ao2_cleanup);
1961 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
1962 struct stasis_cache_update *update = stasis_message_data(message);
1963 struct ast_channel_snapshot *old_snapshot;
1964 struct ast_channel_snapshot *new_snapshot;
1966 struct cdr_object *it_cdr;
1968 ast_assert(update != NULL);
1969 ast_assert(ast_channel_snapshot_type() == update->type);
1971 old_snapshot = stasis_message_data(update->old_snapshot);
1972 new_snapshot = stasis_message_data(update->new_snapshot);
1973 name = new_snapshot ? new_snapshot->name : old_snapshot->name;
1975 if (filter_channel_cache_message(old_snapshot, new_snapshot)) {
1979 CDR_DEBUG(mod_cfg, "Channel Update message for %s: %u.%08u\n",
1981 (unsigned int)stasis_message_timestamp(message)->tv_sec,
1982 (unsigned int)stasis_message_timestamp(message)->tv_usec);
1984 if (new_snapshot && !old_snapshot) {
1985 cdr = cdr_object_alloc(new_snapshot);
1989 ao2_link(active_cdrs_by_channel, cdr);
1992 /* Handle Party A */
1994 cdr = ao2_find(active_cdrs_by_channel, name, OBJ_KEY);
1997 ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", name);
2002 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2003 if (!it_cdr->fn_table->process_party_a) {
2006 CDR_DEBUG(mod_cfg, "%p - Processing new channel snapshot %s\n", it_cdr, new_snapshot->name);
2007 all_reject &= it_cdr->fn_table->process_party_a(it_cdr, new_snapshot);
2009 if (all_reject && check_new_cdr_needed(old_snapshot, new_snapshot)) {
2010 /* We're not hung up and we have a new snapshot - we need a new CDR */
2011 struct cdr_object *new_cdr;
2012 new_cdr = cdr_object_create_and_append(cdr);
2014 new_cdr->fn_table->process_party_a(new_cdr, new_snapshot);
2018 CDR_DEBUG(mod_cfg, "%p - Beginning finalize/dispatch for %s\n", cdr, old_snapshot->name);
2019 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2020 cdr_object_finalize(it_cdr);
2022 cdr_object_dispatch(cdr);
2023 ao2_unlink(active_cdrs_by_channel, cdr);
2028 /* Handle Party B */
2030 ao2_callback(active_cdrs_by_channel, OBJ_NODATA, cdr_object_update_party_b,
2033 ao2_callback(active_cdrs_by_channel, OBJ_NODATA, cdr_object_finalize_party_b,
2039 struct bridge_leave_data {
2040 struct ast_bridge_snapshot *bridge;
2041 struct ast_channel_snapshot *channel;
2044 /*! \brief Callback used to notify CDRs of a Party B leaving the bridge */
2045 static int cdr_object_party_b_left_bridge_cb(void *obj, void *arg, int flags)
2047 struct cdr_object *cdr = obj;
2048 struct bridge_leave_data *leave_data = arg;
2049 struct cdr_object *it_cdr;
2051 if (strcmp(cdr->bridge, leave_data->bridge->uniqueid)) {
2054 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2055 if (it_cdr->fn_table != &bridge_state_fn_table) {
2058 if (!it_cdr->party_b.snapshot) {
2061 if (strcmp(it_cdr->party_b.snapshot->name, leave_data->channel->name)) {
2064 /* It is our Party B, in our bridge. Set the end time and let the handler
2065 * transition our CDR appropriately when we leave the bridge.
2067 cdr_object_finalize(it_cdr);
2072 /*! \brief Filter bridge messages based on bridge technology */
2073 static int filter_bridge_messages(struct ast_bridge_snapshot *bridge)
2075 /* Ignore holding bridge technology messages. We treat this simply as an application
2076 * that a channel enters into.
2078 if (!strcmp(bridge->technology, "holding_bridge") && strcmp(bridge->subclass, "parking")) {
2085 * \brief Handler for when a channel leaves a bridge
2086 * \param data Passed on
2087 * \param sub The stasis subscription for this message callback
2088 * \param topic The topic this message was published for
2089 * \param message The message - hopefully a bridge one!
2091 static void handle_bridge_leave_message(void *data, struct stasis_subscription *sub,
2092 struct stasis_topic *topic, struct stasis_message *message)
2094 struct ast_bridge_blob *update = stasis_message_data(message);
2095 struct ast_bridge_snapshot *bridge = update->bridge;
2096 struct ast_channel_snapshot *channel = update->channel;
2097 RAII_VAR(struct module_config *, mod_cfg,
2098 ao2_global_obj_ref(module_configs), ao2_cleanup);
2099 RAII_VAR(struct cdr_object *, cdr,
2100 ao2_find(active_cdrs_by_channel, channel->name, OBJ_KEY),
2102 struct cdr_object *it_cdr;
2103 struct bridge_leave_data leave_data = {
2107 int left_bridge = 0;
2109 if (filter_bridge_messages(bridge)) {
2113 CDR_DEBUG(mod_cfg, "Bridge Leave message for %s: %u.%08u\n",
2115 (unsigned int)stasis_message_timestamp(message)->tv_sec,
2116 (unsigned int)stasis_message_timestamp(message)->tv_usec);
2119 ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", channel->name);
2125 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2126 if (!it_cdr->fn_table->process_bridge_leave) {
2129 CDR_DEBUG(mod_cfg, "%p - Processing Bridge Leave for %s\n",
2130 it_cdr, channel->name);
2131 if (!it_cdr->fn_table->process_bridge_leave(it_cdr, bridge, channel)) {
2132 ast_string_field_set(it_cdr, bridge, "");
2142 if (strcmp(bridge->subclass, "parking")) {
2144 ao2_callback(active_cdrs_by_channel, OBJ_NODATA,
2145 cdr_object_party_b_left_bridge_cb,
2150 struct bridge_candidate {
2151 struct cdr_object *cdr; /*!< The actual CDR this candidate belongs to, either as A or B */
2152 struct cdr_object_snapshot candidate; /*!< The candidate for a new pairing */
2156 * \brief Comparison function for \ref bridge_candidate objects
2158 static int bridge_candidate_cmp_fn(void *obj, void *arg, int flags)
2160 struct bridge_candidate *left = obj;
2161 struct bridge_candidate *right = arg;
2162 const char *match = (flags & OBJ_KEY) ? arg : right->candidate.snapshot->name;
2163 return strcasecmp(left->candidate.snapshot->name, match) ? 0 : (CMP_MATCH | CMP_STOP);
2167 * \brief Hash function for \ref bridge_candidate objects
2169 static int bridge_candidate_hash_fn(const void *obj, const int flags)
2171 const struct bridge_candidate *bc = obj;
2172 const char *id = (flags & OBJ_KEY) ? obj : bc->candidate.snapshot->name;
2173 return ast_str_case_hash(id);
2176 /*! \brief \ref bridge_candidate Destructor */
2177 static void bridge_candidate_dtor(void *obj)
2179 struct bridge_candidate *bcand = obj;
2180 ao2_cleanup(bcand->cdr);
2181 ao2_cleanup(bcand->candidate.snapshot);
2182 free_variables(&bcand->candidate.variables);
2186 * \brief \ref bridge_candidate Constructor
2187 * \param cdr The \ref cdr_object that is a candidate for being compared to in
2188 * a bridge operation
2189 * \param candidate The \ref cdr_object_snapshot candidate snapshot in the CDR
2190 * that should be used during the operaton
2192 static struct bridge_candidate *bridge_candidate_alloc(struct cdr_object *cdr, struct cdr_object_snapshot *candidate)
2194 struct bridge_candidate *bcand;
2196 bcand = ao2_alloc(sizeof(*bcand), bridge_candidate_dtor);
2201 ao2_ref(bcand->cdr, +1);
2202 bcand->candidate.flags = candidate->flags;
2203 strcpy(bcand->candidate.userfield, candidate->userfield);
2204 bcand->candidate.snapshot = candidate->snapshot;
2205 ao2_ref(bcand->candidate.snapshot, +1);
2206 copy_variables(&bcand->candidate.variables, &candidate->variables);
2212 * \internal \brief Build and add bridge candidates based on a CDR
2213 * \param bridge_id The ID of the bridge we need candidates for
2214 * \param candidates The container of \ref bridge_candidate objects
2215 * \param cdr The \ref cdr_object that is our candidate
2216 * \param party_a Non-zero if we should look at the Party A channel; 0 if Party B
2218 static void add_candidate_for_bridge(const char *bridge_id,
2219 struct ao2_container *candidates,
2220 struct cdr_object *cdr,
2223 struct cdr_object *it_cdr;
2225 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2226 struct cdr_object_snapshot *party_snapshot;
2227 RAII_VAR(struct bridge_candidate *, bcand, NULL, ao2_cleanup);
2229 party_snapshot = party_a ? &it_cdr->party_a : &it_cdr->party_b;
2231 if (it_cdr->fn_table != &bridge_state_fn_table || strcmp(bridge_id, it_cdr->bridge)) {
2235 if (!party_snapshot->snapshot) {
2239 /* Don't add a party twice */
2240 bcand = ao2_find(candidates, party_snapshot->snapshot->name, OBJ_KEY);
2245 bcand = bridge_candidate_alloc(it_cdr, party_snapshot);
2247 ao2_link(candidates, bcand);
2253 * \brief Create new \ref bridge_candidate objects for each party currently
2255 * \param bridge The \param ast_bridge_snapshot for the bridge we're processing
2257 * Note that we use two passes here instead of one so that we only create a
2258 * candidate for a party B if they are never a party A in the bridge. Otherwise,
2259 * we don't care about them.
2261 static struct ao2_container *create_candidates_for_bridge(struct ast_bridge_snapshot *bridge)
2263 struct ao2_container *candidates = ao2_container_alloc(51, bridge_candidate_hash_fn, bridge_candidate_cmp_fn);
2264 char *bridge_id = ast_strdupa(bridge->uniqueid);
2265 struct ao2_iterator *it_cdrs;
2266 struct cdr_object *cand_cdr_master;
2272 /* For each CDR that has a record in the bridge, get their Party A and
2273 * make them a candidate. Note that we do this in two passes as opposed to one so
2274 * that we give preference CDRs where the channel is Party A */
2275 it_cdrs = ao2_callback(active_cdrs_by_channel, OBJ_MULTIPLE,
2276 cdr_object_bridge_cmp_fn, bridge_id);
2278 /* No one in the bridge yet! */
2279 ao2_cleanup(candidates);
2282 for (; (cand_cdr_master = ao2_iterator_next(it_cdrs)); ao2_cleanup(cand_cdr_master)) {
2283 SCOPED_AO2LOCK(lock, cand_cdr_master);
2284 add_candidate_for_bridge(bridge->uniqueid, candidates, cand_cdr_master, 1);
2286 ao2_iterator_destroy(it_cdrs);
2287 /* For each CDR that has a record in the bridge, get their Party B and
2288 * make them a candidate. */
2289 it_cdrs = ao2_callback(active_cdrs_by_channel, OBJ_MULTIPLE,
2290 cdr_object_bridge_cmp_fn, bridge_id);
2292 /* Now it's just an error. */
2293 ao2_cleanup(candidates);
2296 for (; (cand_cdr_master = ao2_iterator_next(it_cdrs)); ao2_cleanup(cand_cdr_master)) {
2297 SCOPED_AO2LOCK(lock, cand_cdr_master);
2298 add_candidate_for_bridge(bridge->uniqueid, candidates, cand_cdr_master, 0);
2300 ao2_iterator_destroy(it_cdrs);
2306 * \internal \brief Create a new CDR, append it to an existing CDR, and update its snapshots
2307 * \note The new CDR will be automatically transitioned to the bridge state
2309 static void bridge_candidate_add_to_cdr(struct cdr_object *cdr,
2310 const char *bridge_id,
2311 struct cdr_object_snapshot *party_b)
2313 struct cdr_object *new_cdr;
2315 new_cdr = cdr_object_create_and_append(cdr);
2319 cdr_object_snapshot_copy(&new_cdr->party_b, party_b);
2320 cdr_object_check_party_a_answer(new_cdr);
2321 ast_string_field_set(new_cdr, bridge, cdr->bridge);
2322 cdr_object_transition_state(new_cdr, &bridge_state_fn_table);
2326 * \brief Process a single \ref bridge_candidate. Note that this is called as
2327 * part of an \ref ao2_callback on an \ref ao2_container of \ref bridge_candidate
2328 * objects previously created by \ref create_candidates_for_bridge.
2330 * \param obj The \ref bridge_candidate being processed
2331 * \param arg The \ref cdr_object that is being compared against the candidates
2333 * The purpose of this function is to create the necessary CDR entries as a
2334 * result of \ref cdr_object having entered the same bridge as the CDR
2335 * represented by \ref bridge_candidate.
2337 static int bridge_candidate_process(void *obj, void *arg, int flags)
2339 struct bridge_candidate *bcand = obj;
2340 struct cdr_object *cdr = arg;
2341 struct cdr_object_snapshot *party_a;
2343 /* If the candidate is us or someone we've taken on, pass on by */
2344 if (!strcmp(cdr->party_a.snapshot->name, bcand->candidate.snapshot->name)
2345 || (cdr->party_b.snapshot && !(strcmp(cdr->party_b.snapshot->name, bcand->candidate.snapshot->name)))) {
2348 party_a = cdr_object_pick_party_a(&cdr->party_a, &bcand->candidate);
2349 /* We're party A - make a new CDR, append it to us, and set the candidate as
2351 if (!strcmp(party_a->snapshot->name, cdr->party_a.snapshot->name)) {
2352 bridge_candidate_add_to_cdr(cdr, cdr->bridge, &bcand->candidate);
2356 /* We're Party B. Check if the candidate is the CDR's Party A. If so, find out if we
2357 * can add ourselves directly as the Party B, or if we need a new CDR. */
2358 if (!strcmp(bcand->cdr->party_a.snapshot->name, bcand->candidate.snapshot->name)) {
2359 if (bcand->cdr->party_b.snapshot
2360 && strcmp(bcand->cdr->party_b.snapshot->name, cdr->party_a.snapshot->name)) {
2361 bridge_candidate_add_to_cdr(bcand->cdr, cdr->bridge, &cdr->party_a);
2363 cdr_object_snapshot_copy(&bcand->cdr->party_b, &cdr->party_a);
2364 /* It's possible that this joined at one point and was never chosen
2365 * as party A. Clear their end time, as it would be set in such a
2368 memset(&bcand->cdr->end, 0, sizeof(bcand->cdr->end));
2371 /* We are Party B to a candidate CDR's Party B. Since a candidate
2372 * CDR will only have a Party B represented here if that channel
2373 * was never a Party A in the bridge, we have to go looking for
2374 * that channel's primary CDR record.
2376 struct cdr_object *b_party = ao2_find(active_cdrs_by_channel, bcand->candidate.snapshot->name, OBJ_KEY);
2378 /* Holy cow - no CDR? */
2379 b_party = cdr_object_alloc(bcand->candidate.snapshot);
2380 cdr_object_snapshot_copy(&b_party->party_a, &bcand->candidate);
2381 cdr_object_snapshot_copy(&b_party->party_b, &cdr->party_a);
2382 cdr_object_check_party_a_answer(b_party);
2383 ast_string_field_set(b_party, bridge, cdr->bridge);
2384 cdr_object_transition_state(b_party, &bridge_state_fn_table);
2385 ao2_link(active_cdrs_by_channel, b_party);
2387 bridge_candidate_add_to_cdr(b_party, cdr->bridge, &cdr->party_a);
2389 ao2_ref(b_party, -1);
2396 * \brief Handle creating bridge pairings for the \ref cdr_object that just
2398 * \param cdr The \ref cdr_object that just entered the bridge
2399 * \param bridge The \ref ast_bridge_snapshot representing the bridge it just entered
2401 static void handle_bridge_pairings(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge)
2403 RAII_VAR(struct ao2_container *, candidates,
2404 create_candidates_for_bridge(bridge),
2410 ao2_callback(candidates, OBJ_NODATA,
2411 bridge_candidate_process,
2417 /*! \brief Handle entering into a parking bridge
2418 * \param cdr The CDR to operate on
2419 * \param bridge The bridge the channel just entered
2420 * \param channel The channel snapshot
2422 static void handle_parking_bridge_enter_message(struct cdr_object *cdr,
2423 struct ast_bridge_snapshot *bridge,
2424 struct ast_channel_snapshot *channel)
2426 RAII_VAR(struct module_config *, mod_cfg,
2427 ao2_global_obj_ref(module_configs), ao2_cleanup);
2429 struct cdr_object *it_cdr;
2430 struct cdr_object *new_cdr;
2434 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2435 if (it_cdr->fn_table->process_parking_bridge_enter) {
2436 res &= it_cdr->fn_table->process_parking_bridge_enter(it_cdr, bridge, channel);
2438 if (it_cdr->fn_table->process_party_a) {
2439 CDR_DEBUG(mod_cfg, "%p - Updating Party A %s snapshot\n", it_cdr,
2441 it_cdr->fn_table->process_party_a(it_cdr, channel);
2446 /* No one handled it - we need a new one! */
2447 new_cdr = cdr_object_create_and_append(cdr);
2449 /* Let the single state transition us to Parked */
2450 cdr_object_transition_state(new_cdr, &single_state_fn_table);
2451 new_cdr->fn_table->process_parking_bridge_enter(new_cdr, bridge, channel);
2457 /*! \brief Handle a bridge enter message for a 'normal' bridge
2458 * \param cdr The CDR to operate on
2459 * \param bridge The bridge the channel just entered
2460 * \param channel The channel snapshot
2462 static void handle_standard_bridge_enter_message(struct cdr_object *cdr,
2463 struct ast_bridge_snapshot *bridge,
2464 struct ast_channel_snapshot *channel)
2466 RAII_VAR(struct module_config *, mod_cfg,
2467 ao2_global_obj_ref(module_configs), ao2_cleanup);
2468 enum process_bridge_enter_results result;
2469 struct cdr_object *it_cdr;
2470 struct cdr_object *new_cdr;
2471 struct cdr_object *handled_cdr = NULL;
2475 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2476 if (it_cdr->fn_table->process_party_a) {
2477 CDR_DEBUG(mod_cfg, "%p - Updating Party A %s snapshot\n", it_cdr,
2479 it_cdr->fn_table->process_party_a(it_cdr, channel);
2482 /* Notify all states that they have entered a bridge */
2483 if (it_cdr->fn_table->process_bridge_enter) {
2484 CDR_DEBUG(mod_cfg, "%p - Processing bridge enter for %s\n", it_cdr,
2486 result = it_cdr->fn_table->process_bridge_enter(it_cdr, bridge, channel);
2488 case BRIDGE_ENTER_ONLY_PARTY:
2490 case BRIDGE_ENTER_OBTAINED_PARTY_B:
2492 handled_cdr = it_cdr;
2495 case BRIDGE_ENTER_NEED_CDR:
2498 case BRIDGE_ENTER_NO_PARTY_B:
2499 /* We didn't win on any - end this CDR. If someone else comes in later
2500 * that is Party B to this CDR, it can re-activate this CDR.
2503 handled_cdr = it_cdr;
2505 cdr_object_finalize(cdr);
2511 /* Create the new matchings, but only for either:
2512 * * The first CDR in the chain that handled it. This avoids issues with
2514 * * If no one handled it, the last CDR in the chain. This would occur if
2515 * a CDR joined a bridge and it wasn't Party A for anyone. We still need
2516 * to make pairings with everyone in the bridge.
2519 handle_bridge_pairings(handled_cdr, bridge);
2521 /* Nothing handled it - we need a new one! */
2522 new_cdr = cdr_object_create_and_append(cdr);
2524 /* This is guaranteed to succeed: the new CDR is created in the single state
2525 * and will be able to handle the bridge enter message
2527 handle_standard_bridge_enter_message(cdr, bridge, channel);
2534 * \brief Handler for Stasis-Core bridge enter messages
2535 * \param data Passed on
2536 * \param sub The stasis subscription for this message callback
2537 * \param topic The topic this message was published for
2538 * \param message The message - hopefully a bridge one!
2540 static void handle_bridge_enter_message(void *data, struct stasis_subscription *sub,
2541 struct stasis_topic *topic, struct stasis_message *message)
2543 struct ast_bridge_blob *update = stasis_message_data(message);
2544 struct ast_bridge_snapshot *bridge = update->bridge;
2545 struct ast_channel_snapshot *channel = update->channel;
2546 RAII_VAR(struct cdr_object *, cdr,
2547 ao2_find(active_cdrs_by_channel, channel->name, OBJ_KEY),
2549 RAII_VAR(struct module_config *, mod_cfg,
2550 ao2_global_obj_ref(module_configs), ao2_cleanup);
2552 if (filter_bridge_messages(bridge)) {
2556 CDR_DEBUG(mod_cfg, "Bridge Enter message for channel %s: %u.%08u\n",
2558 (unsigned int)stasis_message_timestamp(message)->tv_sec,
2559 (unsigned int)stasis_message_timestamp(message)->tv_usec);
2562 ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", channel->name);
2566 if (!strcmp(bridge->subclass, "parking")) {
2567 handle_parking_bridge_enter_message(cdr, bridge, channel);
2569 handle_standard_bridge_enter_message(cdr, bridge, channel);
2574 * \brief Handler for when a channel is parked
2575 * \param data Passed on
2576 * \param sub The stasis subscription for this message callback
2577 * \param topic The topic this message was published for
2578 * \param message The message about who got parked
2580 static void handle_parked_call_message(void *data, struct stasis_subscription *sub,
2581 struct stasis_topic *topic, struct stasis_message *message)
2583 struct ast_parked_call_payload *payload = stasis_message_data(message);
2584 struct ast_channel_snapshot *channel = payload->parkee;
2585 RAII_VAR(struct cdr_object *, cdr, NULL, ao2_cleanup);
2586 RAII_VAR(struct module_config *, mod_cfg,
2587 ao2_global_obj_ref(module_configs), ao2_cleanup);
2588 struct cdr_object *it_cdr;
2590 /* Anything other than getting parked will be handled by other updates */
2591 if (payload->event_type != PARKED_CALL) {
2595 /* No one got parked? */
2600 CDR_DEBUG(mod_cfg, "Parked Call message for channel %s: %u.%08u\n",
2602 (unsigned int)stasis_message_timestamp(message)->tv_sec,
2603 (unsigned int)stasis_message_timestamp(message)->tv_usec);
2605 cdr = ao2_find(active_cdrs_by_channel, channel->name, OBJ_KEY);
2607 ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", channel->name);
2613 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2614 if (it_cdr->fn_table->process_parked_channel) {
2615 it_cdr->fn_table->process_parked_channel(it_cdr, payload);
2623 struct ast_cdr_config *ast_cdr_get_config(void)
2625 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
2626 ao2_ref(mod_cfg->general, +1);
2627 return mod_cfg->general;
2630 void ast_cdr_set_config(struct ast_cdr_config *config)
2632 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
2633 ao2_cleanup(mod_cfg->general);
2634 mod_cfg->general = config;
2635 ao2_ref(mod_cfg->general, +1);
2638 int ast_cdr_is_enabled(void)
2640 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
2641 return ast_test_flag(&mod_cfg->general->settings, CDR_ENABLED);
2644 int ast_cdr_register(const char *name, const char *desc, ast_cdrbe be)
2646 struct cdr_beitem *i = NULL;
2652 ast_log(LOG_WARNING, "CDR engine '%s' lacks backend\n", name);
2656 AST_RWLIST_WRLOCK(&be_list);
2657 AST_RWLIST_TRAVERSE(&be_list, i, list) {
2658 if (!strcasecmp(name, i->name)) {
2659 ast_log(LOG_WARNING, "Already have a CDR backend called '%s'\n", name);
2660 AST_RWLIST_UNLOCK(&be_list);
2665 if (!(i = ast_calloc(1, sizeof(*i))))
2669 ast_copy_string(i->name, name, sizeof(i->name));
2670 ast_copy_string(i->desc, desc, sizeof(i->desc));
2672 AST_RWLIST_INSERT_HEAD(&be_list, i, list);
2673 AST_RWLIST_UNLOCK(&be_list);
2678 void ast_cdr_unregister(const char *name)
2680 struct cdr_beitem *i = NULL;
2682 AST_RWLIST_WRLOCK(&be_list);
2683 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&be_list, i, list) {
2684 if (!strcasecmp(name, i->name)) {
2685 AST_RWLIST_REMOVE_CURRENT(list);
2689 AST_RWLIST_TRAVERSE_SAFE_END;
2690 AST_RWLIST_UNLOCK(&be_list);
2693 ast_verb(2, "Unregistered '%s' CDR backend\n", name);
2698 struct ast_cdr *ast_cdr_dup(struct ast_cdr *cdr)
2700 struct ast_cdr *newcdr;
2705 newcdr = ast_cdr_alloc();
2710 memcpy(newcdr, cdr, sizeof(*newcdr));
2711 memset(&newcdr->varshead, 0, sizeof(newcdr->varshead));
2712 copy_variables(&newcdr->varshead, &cdr->varshead);
2713 newcdr->next = NULL;
2718 static const char *cdr_format_var_internal(struct ast_cdr *cdr, const char *name)
2720 struct ast_var_t *variables;
2721 struct varshead *headp = &cdr->varshead;
2723 if (ast_strlen_zero(name)) {
2727 AST_LIST_TRAVERSE(headp, variables, entries) {
2728 if (!strcasecmp(name, ast_var_name(variables))) {
2729 return ast_var_value(variables);
2736 static void cdr_get_tv(struct timeval when, const char *fmt, char *buf, int bufsize)
2738 if (fmt == NULL) { /* raw mode */
2739 snprintf(buf, bufsize, "%ld.%06ld", (long)when.tv_sec, (long)when.tv_usec);
2744 ast_localtime(&when, &tm, NULL);
2745 ast_strftime(buf, bufsize, fmt, &tm);
2750 void ast_cdr_format_var(struct ast_cdr *cdr, const char *name, char **ret, char *workspace, int workspacelen, int raw)
2752 const char *fmt = "%Y-%m-%d %T";
2761 if (!strcasecmp(name, "clid")) {
2762 ast_copy_string(workspace, cdr->clid, workspacelen);
2763 } else if (!strcasecmp(name, "src")) {
2764 ast_copy_string(workspace, cdr->src, workspacelen);
2765 } else if (!strcasecmp(name, "dst")) {
2766 ast_copy_string(workspace, cdr->dst, workspacelen);
2767 } else if (!strcasecmp(name, "dcontext")) {
2768 ast_copy_string(workspace, cdr->dcontext, workspacelen);
2769 } else if (!strcasecmp(name, "channel")) {
2770 ast_copy_string(workspace, cdr->channel, workspacelen);
2771 } else if (!strcasecmp(name, "dstchannel")) {
2772 ast_copy_string(workspace, cdr->dstchannel, workspacelen);
2773 } else if (!strcasecmp(name, "lastapp")) {
2774 ast_copy_string(workspace, cdr->lastapp, workspacelen);
2775 } else if (!strcasecmp(name, "lastdata")) {
2776 ast_copy_string(workspace, cdr->lastdata, workspacelen);
2777 } else if (!strcasecmp(name, "start")) {
2778 cdr_get_tv(cdr->start, raw ? NULL : fmt, workspace, workspacelen);
2779 } else if (!strcasecmp(name, "answer")) {
2780 cdr_get_tv(cdr->answer, raw ? NULL : fmt, workspace, workspacelen);
2781 } else if (!strcasecmp(name, "end")) {
2782 cdr_get_tv(cdr->end, raw ? NULL : fmt, workspace, workspacelen);
2783 } else if (!strcasecmp(name, "duration")) {
2784 snprintf(workspace, workspacelen, "%ld", cdr->end.tv_sec != 0 ? cdr->duration : (long)ast_tvdiff_ms(ast_tvnow(), cdr->start) / 1000);
2785 } else if (!strcasecmp(name, "billsec")) {
2786 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);
2787 } else if (!strcasecmp(name, "disposition")) {
2789 snprintf(workspace, workspacelen, "%ld", cdr->disposition);
2791 ast_copy_string(workspace, ast_cdr_disp2str(cdr->disposition), workspacelen);
2793 } else if (!strcasecmp(name, "amaflags")) {
2795 snprintf(workspace, workspacelen, "%ld", cdr->amaflags);
2797 ast_copy_string(workspace, ast_channel_amaflags2string(cdr->amaflags), workspacelen);
2799 } else if (!strcasecmp(name, "accountcode")) {
2800 ast_copy_string(workspace, cdr->accountcode, workspacelen);
2801 } else if (!strcasecmp(name, "peeraccount")) {
2802 ast_copy_string(workspace, cdr->peeraccount, workspacelen);
2803 } else if (!strcasecmp(name, "uniqueid")) {
2804 ast_copy_string(workspace, cdr->uniqueid, workspacelen);
2805 } else if (!strcasecmp(name, "linkedid")) {
2806 ast_copy_string(workspace, cdr->linkedid, workspacelen);
2807 } else if (!strcasecmp(name, "userfield")) {
2808 ast_copy_string(workspace, cdr->userfield, workspacelen);
2809 } else if (!strcasecmp(name, "sequence")) {
2810 snprintf(workspace, workspacelen, "%d", cdr->sequence);
2811 } else if ((varbuf = cdr_format_var_internal(cdr, name))) {
2812 ast_copy_string(workspace, varbuf, workspacelen);
2814 workspace[0] = '\0';
2817 if (!ast_strlen_zero(workspace)) {
2824 * \brief Callback that finds all CDRs that reference a particular channel
2826 static int cdr_object_select_all_by_channel_cb(void *obj, void *arg, int flags)
2828 struct cdr_object *cdr = obj;
2829 const char *name = arg;
2831 if (!strcasecmp(cdr->party_a.snapshot->name, name) ||
2832 (cdr->party_b.snapshot && !strcasecmp(cdr->party_b.snapshot->name, name))) {
2838 /* Read Only CDR variables */
2839 static const char * const cdr_readonly_vars[] = { "clid", "src", "dst", "dcontext",
2840 "channel", "dstchannel", "lastapp", "lastdata", "start", "answer", "end", "duration",
2841 "billsec", "disposition", "amaflags", "accountcode", "uniqueid", "linkedid",
2842 "userfield", "sequence", "total_duration", "total_billsec", "first_start",
2843 "first_answer", NULL };
2845 int ast_cdr_setvar(const char *channel_name, const char *name, const char *value)
2847 struct cdr_object *cdr;
2848 struct cdr_object *it_cdr;
2849 struct ao2_iterator *it_cdrs;
2850 char *arg = ast_strdupa(channel_name);
2853 for (x = 0; cdr_readonly_vars[x]; x++) {
2854 if (!strcasecmp(name, cdr_readonly_vars[x])) {
2855 ast_log(LOG_ERROR, "Attempt to set the '%s' read-only variable!\n", name);
2860 it_cdrs = ao2_callback(active_cdrs_by_channel, OBJ_MULTIPLE, cdr_object_select_all_by_channel_cb, arg);
2862 ast_log(AST_LOG_ERROR, "Unable to find CDR for channel %s\n", channel_name);
2866 for (; (cdr = ao2_iterator_next(it_cdrs)); ao2_unlock(cdr), ao2_cleanup(cdr)) {
2868 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2869 struct varshead *headp = NULL;
2870 if (it_cdr->fn_table == &finalized_state_fn_table) {
2873 if (!strcmp(channel_name, it_cdr->party_a.snapshot->name)) {
2874 headp = &it_cdr->party_a.variables;
2875 } else if (it_cdr->party_b.snapshot && !strcmp(channel_name, it_cdr->party_b.snapshot->name)) {
2876 headp = &it_cdr->party_b.variables;
2879 set_variable(headp, name, value);
2883 ao2_iterator_destroy(it_cdrs);
2889 * \brief Format a variable on a \ref cdr_object
2891 static void cdr_object_format_var_internal(struct cdr_object *cdr, const char *name, char *value, size_t length)
2893 struct ast_var_t *variable;
2895 AST_LIST_TRAVERSE(&cdr->party_a.variables, variable, entries) {
2896 if (!strcasecmp(name, ast_var_name(variable))) {
2897 ast_copy_string(value, ast_var_value(variable), length);
2906 * \brief Format one of the standard properties on a \ref cdr_object
2908 static int cdr_object_format_property(struct cdr_object *cdr_obj, const char *name, char *value, size_t length)
2910 struct ast_channel_snapshot *party_a = cdr_obj->party_a.snapshot;
2911 struct ast_channel_snapshot *party_b = cdr_obj->party_b.snapshot;
2913 if (!strcasecmp(name, "clid")) {
2914 ast_callerid_merge(value, length, party_a->caller_name, party_a->caller_number, "");
2915 } else if (!strcasecmp(name, "src")) {
2916 ast_copy_string(value, party_a->caller_number, length);
2917 } else if (!strcasecmp(name, "dst")) {
2918 ast_copy_string(value, party_a->exten, length);
2919 } else if (!strcasecmp(name, "dcontext")) {
2920 ast_copy_string(value, party_a->context, length);
2921 } else if (!strcasecmp(name, "channel")) {
2922 ast_copy_string(value, party_a->name, length);
2923 } else if (!strcasecmp(name, "dstchannel")) {
2925 ast_copy_string(value, party_b->name, length);
2927 ast_copy_string(value, "", length);
2929 } else if (!strcasecmp(name, "lastapp")) {
2930 ast_copy_string(value, party_a->appl, length);
2931 } else if (!strcasecmp(name, "lastdata")) {
2932 ast_copy_string(value, party_a->data, length);
2933 } else if (!strcasecmp(name, "start")) {
2934 cdr_get_tv(cdr_obj->start, NULL, value, length);
2935 } else if (!strcasecmp(name, "answer")) {
2936 cdr_get_tv(cdr_obj->answer, NULL, value, length);
2937 } else if (!strcasecmp(name, "end")) {
2938 cdr_get_tv(cdr_obj->end, NULL, value, length);
2939 } else if (!strcasecmp(name, "duration")) {
2940 snprintf(value, length, "%ld", cdr_object_get_duration(cdr_obj));
2941 } else if (!strcasecmp(name, "billsec")) {
2942 snprintf(value, length, "%ld", cdr_object_get_billsec(cdr_obj));
2943 } else if (!strcasecmp(name, "disposition")) {
2944 snprintf(value, length, "%d", cdr_obj->disposition);
2945 } else if (!strcasecmp(name, "amaflags")) {
2946 snprintf(value, length, "%d", party_a->amaflags);
2947 } else if (!strcasecmp(name, "accountcode")) {
2948 ast_copy_string(value, party_a->accountcode, length);
2949 } else if (!strcasecmp(name, "peeraccount")) {
2951 ast_copy_string(value, party_b->accountcode, length);
2953 ast_copy_string(value, "", length);
2955 } else if (!strcasecmp(name, "uniqueid")) {
2956 ast_copy_string(value, party_a->uniqueid, length);
2957 } else if (!strcasecmp(name, "linkedid")) {
2958 ast_copy_string(value, cdr_obj->linkedid, length);
2959 } else if (!strcasecmp(name, "userfield")) {
2960 ast_copy_string(value, cdr_obj->party_a.userfield, length);
2961 } else if (!strcasecmp(name, "sequence")) {
2962 snprintf(value, length, "%d", cdr_obj->sequence);
2970 int ast_cdr_getvar(const char *channel_name, const char *name, char *value, size_t length)
2972 RAII_VAR(struct cdr_object *, cdr,
2973 ao2_find(active_cdrs_by_channel, channel_name, OBJ_KEY),
2975 struct cdr_object *cdr_obj;
2978 ast_log(AST_LOG_ERROR, "Unable to find CDR for channel %s\n", channel_name);
2982 if (ast_strlen_zero(name)) {
2988 cdr_obj = cdr->last;
2989 if (cdr_object_format_property(cdr_obj, name, value, length)) {
2990 /* Property failed; attempt variable */
2991 cdr_object_format_var_internal(cdr_obj, name, value, length);
2999 int ast_cdr_serialize_variables(const char *channel_name, struct ast_str **buf, char delim, char sep)
3001 RAII_VAR(struct cdr_object *, cdr,
3002 ao2_find(active_cdrs_by_channel, channel_name, OBJ_KEY),
3004 struct cdr_object *it_cdr;
3005 struct ast_var_t *variable;
3007 RAII_VAR(char *, workspace, ast_malloc(256), ast_free);
3008 int total = 0, x = 0, i;
3015 ast_log(AST_LOG_ERROR, "Unable to find CDR for channel %s\n", channel_name);
3019 ast_str_reset(*buf);
3022 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3024 ast_str_append(buf, 0, "\n");
3026 AST_LIST_TRAVERSE(&it_cdr->party_a.variables, variable, entries) {
3027 if (!(var = ast_var_name(variable))) {
3031 if (ast_str_append(buf, 0, "level %d: %s%c%s%c", x, var, delim, S_OR(ast_var_value(variable), ""), sep) < 0) {
3032 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
3039 for (i = 0; cdr_readonly_vars[i]; i++) {
3040 /* null out the workspace, because the cdr_get_tv() won't write anything if time is NULL, so you get old vals */
3042 cdr_object_format_property(it_cdr, cdr_readonly_vars[i], workspace, sizeof(workspace));
3044 if (!ast_strlen_zero(workspace)
3045 && ast_str_append(buf, 0, "level %d: %s%c%s%c", x, cdr_readonly_vars[i], delim, workspace, sep) < 0) {
3046 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
3056 void ast_cdr_free(struct ast_cdr *cdr)
3059 struct ast_cdr *next = cdr->next;
3061 free_variables(&cdr->varshead);
3067 struct ast_cdr *ast_cdr_alloc(void)
3071 x = ast_calloc(1, sizeof(*x));
3075 const char *ast_cdr_disp2str(int disposition)
3077 switch (disposition) {
3079 return "NO ANSWER"; /* by default, for backward compatibility */
3080 case AST_CDR_NOANSWER:
3082 case AST_CDR_FAILED:
3086 case AST_CDR_ANSWERED:
3088 case AST_CDR_CONGESTION:
3089 return "CONGESTION";
3094 struct party_b_userfield_update {
3095 const char *channel_name;
3096 const char *userfield;
3099 /*! \brief Callback used to update the userfield on Party B on all CDRs */
3100 static int cdr_object_update_party_b_userfield_cb(void *obj, void *arg, int flags)
3102 struct cdr_object *cdr = obj;
3103 struct party_b_userfield_update *info = arg;
3104 struct cdr_object *it_cdr;
3105 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3106 if (it_cdr->fn_table == &finalized_state_fn_table) {
3109 if (it_cdr->party_b.snapshot
3110 && !strcmp(it_cdr->party_b.snapshot->name, info->channel_name)) {
3111 strcpy(it_cdr->party_b.userfield, info->userfield);
3117 void ast_cdr_setuserfield(const char *channel_name, const char *userfield)
3119 RAII_VAR(struct cdr_object *, cdr,
3120 ao2_find(active_cdrs_by_channel, channel_name, OBJ_KEY),
3122 struct party_b_userfield_update party_b_info = {
3123 .channel_name = channel_name,
3124 .userfield = userfield,
3126 struct cdr_object *it_cdr;
3128 /* Handle Party A */
3131 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3132 if (it_cdr->fn_table == &finalized_state_fn_table) {
3135 strcpy(it_cdr->party_a.userfield, userfield);
3140 /* Handle Party B */
3141 ao2_callback(active_cdrs_by_channel, OBJ_NODATA,
3142 cdr_object_update_party_b_userfield_cb,
3147 static void post_cdr(struct ast_cdr *cdr)
3149 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
3150 struct cdr_beitem *i;
3152 for (; cdr ; cdr = cdr->next) {
3153 /* For people, who don't want to see unanswered single-channel events */
3154 if (!ast_test_flag(&mod_cfg->general->settings, CDR_UNANSWERED) &&
3155 cdr->disposition < AST_CDR_ANSWERED &&
3156 (ast_strlen_zero(cdr->channel) || ast_strlen_zero(cdr->dstchannel))) {
3157 ast_debug(1, "Skipping CDR for %s since we weren't answered\n", cdr->channel);
3161 if (ast_test_flag(cdr, AST_CDR_FLAG_DISABLE)) {
3164 AST_RWLIST_RDLOCK(&be_list);
3165 AST_RWLIST_TRAVERSE(&be_list, i, list) {
3168 AST_RWLIST_UNLOCK(&be_list);
3172 int ast_cdr_set_property(const char *channel_name, enum ast_cdr_options option)
3174 RAII_VAR(struct cdr_object *, cdr,
3175 ao2_find(active_cdrs_by_channel, channel_name, OBJ_KEY),
3177 struct cdr_object *it_cdr;
3184 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3185 if (it_cdr->fn_table == &finalized_state_fn_table) {
3188 /* Note: in general, set the flags on both the CDR record as well as the
3189 * Party A. Sometimes all we have is the Party A to look at.
3191 ast_set_flag(&it_cdr->flags, option);
3192 ast_set_flag(&it_cdr->party_a, option);
3199 int ast_cdr_clear_property(const char *channel_name, enum ast_cdr_options option)
3201 RAII_VAR(struct cdr_object *, cdr,
3202 ao2_find(active_cdrs_by_channel, channel_name, OBJ_KEY),
3204 struct cdr_object *it_cdr;
3211 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3212 if (it_cdr->fn_table == &finalized_state_fn_table) {
3215 ast_clear_flag(&it_cdr->flags, option);
3222 int ast_cdr_reset(const char *channel_name, struct ast_flags *options)
3224 RAII_VAR(struct cdr_object *, cdr,
3225 ao2_find(active_cdrs_by_channel, channel_name, OBJ_KEY),
3227 struct ast_var_t *vardata;
3228 struct cdr_object *it_cdr;
3235 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3236 /* clear variables */
3237 if (!ast_test_flag(options, AST_CDR_FLAG_KEEP_VARS)) {
3238 while ((vardata = AST_LIST_REMOVE_HEAD(&it_cdr->party_a.variables, entries))) {
3239 ast_var_delete(vardata);
3241 if (cdr->party_b.snapshot) {
3242 while ((vardata = AST_LIST_REMOVE_HEAD(&it_cdr->party_b.variables, entries))) {
3243 ast_var_delete(vardata);
3248 /* Reset to initial state */
3249 memset(&it_cdr->start, 0, sizeof(it_cdr->start));
3250 memset(&it_cdr->end, 0, sizeof(it_cdr->end));
3251 memset(&it_cdr->answer, 0, sizeof(it_cdr->answer));
3252 it_cdr->start = ast_tvnow();
3253 cdr_object_check_party_a_answer(it_cdr);
3260 int ast_cdr_fork(const char *channel_name, struct ast_flags *options)
3262 RAII_VAR(struct cdr_object *, cdr,
3263 ao2_find(active_cdrs_by_channel, channel_name, OBJ_KEY),
3265 struct cdr_object *new_cdr;
3266 struct cdr_object *it_cdr;
3267 struct cdr_object *cdr_obj;