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 /* The prime here should be similar in size to the channel container. */
197 #define NUM_CDR_BUCKETS 61
199 #define NUM_CDR_BUCKETS 769
202 #define DEFAULT_ENABLED "1"
203 #define DEFAULT_BATCHMODE "0"
204 #define DEFAULT_UNANSWERED "0"
205 #define DEFAULT_CONGESTION "0"
206 #define DEFAULT_END_BEFORE_H_EXTEN "0"
207 #define DEFAULT_INITIATED_SECONDS "0"
209 #define DEFAULT_BATCH_SIZE "100"
210 #define MAX_BATCH_SIZE 1000
211 #define DEFAULT_BATCH_TIME "300"
212 #define MAX_BATCH_TIME 86400
213 #define DEFAULT_BATCH_SCHEDULER_ONLY "0"
214 #define DEFAULT_BATCH_SAFE_SHUTDOWN "1"
216 #define CDR_DEBUG(mod_cfg, fmt, ...) \
218 if (ast_test_flag(&(mod_cfg)->general->settings, CDR_DEBUG)) { \
219 ast_verb(1, (fmt), ##__VA_ARGS__); \
222 static void cdr_detach(struct ast_cdr *cdr);
223 static void cdr_submit_batch(int shutdown);
225 /*! \brief The configuration settings for this module */
226 struct module_config {
227 struct ast_cdr_config *general; /*< CDR global settings */
230 /*! \brief The container for the module configuration */
231 static AO2_GLOBAL_OBJ_STATIC(module_configs);
233 /*! \brief The type definition for general options */
234 static struct aco_type general_option = {
237 .item_offset = offsetof(struct module_config, general),
238 .category = "^general$",
239 .category_match = ACO_WHITELIST,
242 static void *module_config_alloc(void);
243 static void module_config_destructor(void *obj);
245 /*! \brief The file definition */
246 static struct aco_file module_file_conf = {
247 .filename = "cdr.conf",
248 .skip_category = "(^csv$|^custom$|^manager$|^odbc$|^pgsql$|^radius$|^sqlite$|^tds$|^mysql$)",
249 .types = ACO_TYPES(&general_option),
252 CONFIG_INFO_CORE("cdr", cfg_info, module_configs, module_config_alloc,
253 .files = ACO_FILES(&module_file_conf),
256 static struct aco_type *general_options[] = ACO_TYPES(&general_option);
258 /*! \brief Dispose of a module config object */
259 static void module_config_destructor(void *obj)
261 struct module_config *cfg = obj;
266 ao2_ref(cfg->general, -1);
269 /*! \brief Create a new module config object */
270 static void *module_config_alloc(void)
272 struct module_config *mod_cfg;
273 struct ast_cdr_config *cdr_config;
275 mod_cfg = ao2_alloc(sizeof(*mod_cfg), module_config_destructor);
280 cdr_config = ao2_alloc(sizeof(*cdr_config), NULL);
282 ao2_ref(cdr_config, -1);
285 mod_cfg->general = cdr_config;
290 /*! \brief Registration object for CDR backends */
295 AST_RWLIST_ENTRY(cdr_beitem) list;
298 /*! \brief List of registered backends */
299 static AST_RWLIST_HEAD_STATIC(be_list, cdr_beitem);
301 /*! \brief Queued CDR waiting to be batched */
302 struct cdr_batch_item {
304 struct cdr_batch_item *next;
307 /*! \brief The actual batch queue */
308 static struct cdr_batch {
310 struct cdr_batch_item *head;
311 struct cdr_batch_item *tail;
314 /*! \brief The global sequence counter used for CDRs */
315 static int global_cdr_sequence = 0;
317 /*! \brief Scheduler items */
318 static struct ast_sched_context *sched;
319 static int cdr_sched = -1;
320 AST_MUTEX_DEFINE_STATIC(cdr_sched_lock);
321 static pthread_t cdr_thread = AST_PTHREADT_NULL;
323 /*! \brief Lock protecting modifications to the batch queue */
324 AST_MUTEX_DEFINE_STATIC(cdr_batch_lock);
326 /*! \brief These are used to wake up the CDR thread when there's work to do */
327 AST_MUTEX_DEFINE_STATIC(cdr_pending_lock);
328 static ast_cond_t cdr_pending_cond;
330 /*! \brief A container of the active CDRs indexed by Party A channel name */
331 static struct ao2_container *active_cdrs_by_channel;
333 /*! \brief Message router for stasis messages regarding channel state */
334 static struct stasis_message_router *stasis_router;
336 /*! \brief Our subscription for bridges */
337 static struct stasis_subscription *bridge_subscription;
339 /*! \brief Our subscription for channels */
340 static struct stasis_subscription *channel_subscription;
342 /*! \brief Our subscription for parking */
343 static struct stasis_subscription *parking_subscription;
345 /*! \brief The parent topic for all topics we want to aggregate for CDRs */
346 static struct stasis_topic *cdr_topic;
350 /*! \brief Return types for \ref process_bridge_enter functions */
351 enum process_bridge_enter_results {
353 * The CDR was the only party in the bridge.
355 BRIDGE_ENTER_ONLY_PARTY,
357 * The CDR was able to obtain a Party B from some other party already in the bridge
359 BRIDGE_ENTER_OBTAINED_PARTY_B,
361 * The CDR was not able to obtain a Party B
363 BRIDGE_ENTER_NO_PARTY_B,
365 * This CDR can't handle a bridge enter message and a new CDR needs to be created
367 BRIDGE_ENTER_NEED_CDR,
371 * \brief A virtual table used for \ref cdr_object.
373 * Note that all functions are optional - if a subclass does not need an
374 * implementation, it is safe to leave it NULL.
376 struct cdr_object_fn_table {
377 /*! \brief Name of the subclass */
381 * \brief An initialization function. This will be called automatically
382 * when a \ref cdr_object is switched to this type in
383 * \ref cdr_object_transition_state
385 * \param cdr The \ref cdr_object that was just transitioned
387 void (* const init_function)(struct cdr_object *cdr);
390 * \brief Process a Party A update for the \ref cdr_object
392 * \param cdr The \ref cdr_object to process the update
393 * \param snapshot The snapshot for the CDR's Party A
394 * \retval 0 the CDR handled the update or ignored it
395 * \retval 1 the CDR is finalized and a new one should be made to handle it
397 int (* const process_party_a)(struct cdr_object *cdr,
398 struct ast_channel_snapshot *snapshot);
401 * \brief Process a Party B update for the \ref cdr_object
403 * \param cdr The \ref cdr_object to process the update
404 * \param snapshot The snapshot for the CDR's Party B
406 void (* const process_party_b)(struct cdr_object *cdr,
407 struct ast_channel_snapshot *snapshot);
410 * \brief Process the beginning of a dial. A dial message implies one of two
412 * The \ref cdr_object's Party A has been originated
413 * The \ref cdr_object's Party A is dialing its Party B
415 * \param cdr The \ref cdr_object
416 * \param caller The originator of the dial attempt
417 * \param peer The destination of the dial attempt
419 * \retval 0 if the parties in the dial were handled by this CDR
420 * \retval 1 if the parties could not be handled by this CDR
422 int (* const process_dial_begin)(struct cdr_object *cdr,
423 struct ast_channel_snapshot *caller,
424 struct ast_channel_snapshot *peer);
427 * \brief Process the end of a dial. At the end of a dial, a CDR can be
428 * transitioned into one of two states - DialedPending
429 * (\ref dialed_pending_state_fn_table) or Finalized
430 * (\ref finalized_state_fn_table).
432 * \param cdr The \ref cdr_object
433 * \param caller The originator of the dial attempt
434 * \param peer the Destination of the dial attempt
435 * \param dial_status What happened
437 * \retval 0 if the parties in the dial were handled by this CDR
438 * \retval 1 if the parties could not be handled by this CDR
440 int (* const process_dial_end)(struct cdr_object *cdr,
441 struct ast_channel_snapshot *caller,
442 struct ast_channel_snapshot *peer,
443 const char *dial_status);
446 * \brief Process the entering of a bridge by this CDR. The purpose of this
447 * callback is to have the CDR prepare itself for the bridge and attempt to
448 * find a valid Party B. The act of creating new CDRs based on the entering
449 * of this channel into the bridge is handled by the higher level message
452 * Note that this handler is for when a channel enters into a "normal"
453 * bridge, where people actually talk to each other. Parking is its own
456 * \param cdr The \ref cdr_object
457 * \param bridge The bridge that the Party A just entered into
458 * \param channel The \ref ast_channel_snapshot for this CDR's Party A
460 * \retval process_bridge_enter_results Defines whether or not this CDR was able
461 * to fully handle the bridge enter message.
463 enum process_bridge_enter_results (* const process_bridge_enter)(
464 struct cdr_object *cdr,
465 struct ast_bridge_snapshot *bridge,
466 struct ast_channel_snapshot *channel);
469 * \brief Process entering into a parking bridge.
471 * \param cdr The \ref cdr_object
472 * \param bridge The parking bridge that Party A just entered into
473 * \param channel The \ref ast_channel_snapshot for this CDR's Party A
475 * \retval 0 This CDR successfully transitioned itself into the parked state
476 * \retval 1 This CDR couldn't handle the parking transition and we need a
479 int (* const process_parking_bridge_enter)(struct cdr_object *cdr,
480 struct ast_bridge_snapshot *bridge,
481 struct ast_channel_snapshot *channel);
484 * \brief Process the leaving of a bridge by this CDR.
486 * \param cdr The \ref cdr_object
487 * \param bridge The bridge that the Party A just left
488 * \param channel The \ref ast_channel_snapshot for this CDR's Party A
490 * \retval 0 This CDR left successfully
493 int (* const process_bridge_leave)(struct cdr_object *cdr,
494 struct ast_bridge_snapshot *bridge,
495 struct ast_channel_snapshot *channel);
498 * \brief Process an update informing us that the channel got itself parked
500 * \param cdr The \ref cdr_object
501 * \param channel The parking information for this CDR's party A
503 * \retval 0 This CDR successfully parked itself
504 * \retval 1 This CDR couldn't handle the park
506 int (* const process_parked_channel)(struct cdr_object *cdr,
507 struct ast_parked_call_payload *parking_info);
510 static int base_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot);
511 static enum process_bridge_enter_results base_process_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
512 static int base_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
513 static int base_process_dial_end(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer, const char *dial_status);
514 static int base_process_parked_channel(struct cdr_object *cdr, struct ast_parked_call_payload *parking_info);
516 static void single_state_init_function(struct cdr_object *cdr);
517 static void single_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot);
518 static int single_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer);
519 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);
520 static int single_state_process_parking_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
523 * \brief The virtual table for the Single state.
525 * A \ref cdr_object starts off in this state. This represents a channel that
526 * has no Party B information itself.
528 * A \ref cdr_object from this state can go into any of the following states:
529 * * \ref dial_state_fn_table
530 * * \ref bridge_state_fn_table
531 * * \ref finalized_state_fn_table
533 struct cdr_object_fn_table single_state_fn_table = {
535 .init_function = single_state_init_function,
536 .process_party_a = base_process_party_a,
537 .process_party_b = single_state_process_party_b,
538 .process_dial_begin = single_state_process_dial_begin,
539 .process_dial_end = base_process_dial_end,
540 .process_bridge_enter = single_state_process_bridge_enter,
541 .process_parking_bridge_enter = single_state_process_parking_bridge_enter,
542 .process_bridge_leave = base_process_bridge_leave,
543 .process_parked_channel = base_process_parked_channel,
546 static void dial_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot);
547 static int dial_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer);
548 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);
549 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);
552 * \brief The virtual table for the Dial state.
554 * A \ref cdr_object that has begun a dial operation. This state is entered when
555 * the Party A for a CDR is determined to be dialing out to a Party B or when
556 * a CDR is for an originated channel (in which case the Party A information is
557 * the originated channel, and there is no Party B).
559 * A \ref cdr_object from this state can go in any of the following states:
560 * * \ref dialed_pending_state_fn_table
561 * * \ref bridge_state_fn_table
562 * * \ref finalized_state_fn_table
564 struct cdr_object_fn_table dial_state_fn_table = {
566 .process_party_a = base_process_party_a,
567 .process_party_b = dial_state_process_party_b,
568 .process_dial_begin = dial_state_process_dial_begin,
569 .process_dial_end = dial_state_process_dial_end,
570 .process_bridge_enter = dial_state_process_bridge_enter,
571 .process_bridge_leave = base_process_bridge_leave,
574 static int dialed_pending_state_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot);
575 static int dialed_pending_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer);
576 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);
577 static int dialed_pending_state_process_parking_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
580 * \brief The virtual table for the Dialed Pending state.
582 * A \ref cdr_object that has successfully finished a dial operation, but we
583 * don't know what they're going to do yet. It's theoretically possible to dial
584 * a party and then have that party not be bridged with the caller; likewise,
585 * an origination can complete and the channel go off and execute dialplan. The
586 * pending state acts as a bridge between either:
587 * * Entering a bridge
588 * * Getting a new CDR for new dialplan execution
589 * * Switching from being originated to executing dialplan
591 * A \ref cdr_object from this state can go in any of the following states:
592 * * \ref single_state_fn_table
593 * * \ref dialed_pending_state_fn_table
594 * * \ref bridge_state_fn_table
595 * * \ref finalized_state_fn_table
597 struct cdr_object_fn_table dialed_pending_state_fn_table = {
598 .name = "DialedPending",
599 .process_party_a = dialed_pending_state_process_party_a,
600 .process_dial_begin = dialed_pending_state_process_dial_begin,
601 .process_bridge_enter = dialed_pending_state_process_bridge_enter,
602 .process_parking_bridge_enter = dialed_pending_state_process_parking_bridge_enter,
603 .process_bridge_leave = base_process_bridge_leave,
604 .process_parked_channel = base_process_parked_channel,
607 static void bridge_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot);
608 static int bridge_state_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
611 * \brief The virtual table for the Bridged state
613 * A \ref cdr_object enters this state when it receives notification that the
614 * channel has entered a bridge.
616 * A \ref cdr_object from this state can go to:
617 * * \ref finalized_state_fn_table
619 struct cdr_object_fn_table bridge_state_fn_table = {
621 .process_party_a = base_process_party_a,
622 .process_party_b = bridge_state_process_party_b,
623 .process_bridge_leave = bridge_state_process_bridge_leave,
624 .process_parked_channel = base_process_parked_channel,
627 static int parked_state_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
630 * \brief The virtual table for the Parked state
632 * Parking is weird. Unlike typical bridges, it has to be treated somewhat
633 * uniquely - a channel in a parking bridge (which is a subclass of a holding
634 * bridge) has to be handled as if the channel went into an application.
635 * However, when the channel comes out, we need a new CDR - unlike the Single
638 struct cdr_object_fn_table parked_state_fn_table = {
640 .process_party_a = base_process_party_a,
641 .process_bridge_leave = parked_state_process_bridge_leave,
642 .process_parked_channel = base_process_parked_channel,
645 static void finalized_state_init_function(struct cdr_object *cdr);
646 static int finalized_state_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot);
649 * \brief The virtual table for the finalized state.
651 * Once in the finalized state, the CDR is done. No modifications can be made
654 struct cdr_object_fn_table finalized_state_fn_table = {
656 .init_function = finalized_state_init_function,
657 .process_party_a = finalized_state_process_party_a,
658 .process_bridge_enter = base_process_bridge_enter,
661 /*! \brief A wrapper object around a snapshot.
662 * Fields that are mutable by the CDR engine are replicated here.
664 struct cdr_object_snapshot {
665 struct ast_channel_snapshot *snapshot; /*!< The channel snapshot */
666 char userfield[AST_MAX_USER_FIELD]; /*!< Userfield for the channel */
667 unsigned int flags; /*!< Specific flags for this party */
668 struct varshead variables; /*!< CDR variables for the channel */
671 /*! \brief An in-memory representation of an active CDR */
673 struct cdr_object_snapshot party_a; /*!< The Party A information */
674 struct cdr_object_snapshot party_b; /*!< The Party B information */
675 struct cdr_object_fn_table *fn_table; /*!< The current virtual table */
677 enum ast_cdr_disposition disposition; /*!< The disposition of the CDR */
678 struct timeval start; /*!< When this CDR was created */
679 struct timeval answer; /*!< Either when the channel was answered, or when the path between channels was established */
680 struct timeval end; /*!< When this CDR was finalized */
681 unsigned int sequence; /*!< A monotonically increasing number for each CDR */
682 struct ast_flags flags; /*!< Flags on the CDR */
683 AST_DECLARE_STRING_FIELDS(
684 AST_STRING_FIELD(linkedid); /*!< Linked ID. Cached here as it may change out from party A, which must be immutable */
685 AST_STRING_FIELD(name); /*!< Channel name of party A. Cached here as the party A address may change */
686 AST_STRING_FIELD(bridge); /*!< The bridge the party A happens to be in. */
687 AST_STRING_FIELD(appl); /*!< The last accepted application party A was in */
688 AST_STRING_FIELD(data); /*!< The data for the last accepted application party A was in */
690 struct cdr_object *next; /*!< The next CDR object in the chain */
691 struct cdr_object *last; /*!< The last CDR object in the chain */
695 * \brief Copy variables from one list to another
696 * \param to_list destination
697 * \param from_list source
698 * \retval The number of copied variables
700 static int copy_variables(struct varshead *to_list, struct varshead *from_list)
702 struct ast_var_t *variables;
703 struct ast_var_t *newvariable;
708 AST_LIST_TRAVERSE(from_list, variables, entries) {
709 var = ast_var_name(variables);
710 if (ast_strlen_zero(var)) {
713 val = ast_var_value(variables);
714 if (ast_strlen_zero(val)) {
717 newvariable = ast_var_assign(var, val);
719 AST_LIST_INSERT_HEAD(to_list, newvariable, entries);
728 * \brief Delete all variables from a variable list
729 * \param headp The head pointer to the variable list to delete
731 static void free_variables(struct varshead *headp)
733 struct ast_var_t *vardata;
735 while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries))) {
736 ast_var_delete(vardata);
741 * \brief Copy a snapshot and its details
742 * \param dst The destination
743 * \param src The source
745 static void cdr_object_snapshot_copy(struct cdr_object_snapshot *dst, struct cdr_object_snapshot *src)
748 ao2_t_ref(dst->snapshot, -1, "release old snapshot during copy");
750 dst->snapshot = src->snapshot;
751 ao2_t_ref(dst->snapshot, +1, "bump new snapshot during copy");
752 strcpy(dst->userfield, src->userfield);
753 dst->flags = src->flags;
754 copy_variables(&dst->variables, &src->variables);
758 * \brief Transition a \ref cdr_object to a new state
759 * \param cdr The \ref cdr_object to transition
760 * \param fn_table The \ref cdr_object_fn_table state to go to
762 static void cdr_object_transition_state(struct cdr_object *cdr, struct cdr_object_fn_table *fn_table)
764 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
766 CDR_DEBUG(mod_cfg, "%p - Transitioning CDR for %s from state %s to %s\n",
767 cdr, cdr->party_a.snapshot->name,
768 cdr->fn_table ? cdr->fn_table->name : "NONE", fn_table->name);
769 cdr->fn_table = fn_table;
770 if (cdr->fn_table->init_function) {
771 cdr->fn_table->init_function(cdr);
775 * \brief Hash function for containers of CDRs indexing by Party A name */
776 static int cdr_object_channel_hash_fn(const void *obj, const int flags)
778 const struct cdr_object *cdr = obj;
779 const char *name = (flags & OBJ_KEY) ? obj : cdr->name;
780 return ast_str_case_hash(name);
784 * \brief Comparison function for containers of CDRs indexing by Party A name
786 static int cdr_object_channel_cmp_fn(void *obj, void *arg, int flags)
788 struct cdr_object *left = obj;
789 struct cdr_object *right = arg;
790 const char *match = (flags & OBJ_KEY) ? arg : right->name;
791 return strcasecmp(left->name, match) ? 0 : (CMP_MATCH | CMP_STOP);
795 * \brief Comparison function for containers of CDRs indexing by bridge. Note
796 * that we expect there to be collisions, as a single bridge may have multiple
797 * CDRs active at one point in time
799 static int cdr_object_bridge_cmp_fn(void *obj, void *arg, int flags)
801 struct cdr_object *left = obj;
802 struct cdr_object *it_cdr;
803 const char *match = arg;
805 for (it_cdr = left; it_cdr; it_cdr = it_cdr->next) {
806 if (!strcasecmp(it_cdr->bridge, match)) {
814 * \brief \ref cdr_object Destructor
816 static void cdr_object_dtor(void *obj)
818 struct cdr_object *cdr = obj;
819 struct ast_var_t *it_var;
821 ao2_cleanup(cdr->party_a.snapshot);
822 ao2_cleanup(cdr->party_b.snapshot);
823 while ((it_var = AST_LIST_REMOVE_HEAD(&cdr->party_a.variables, entries))) {
824 ast_var_delete(it_var);
826 while ((it_var = AST_LIST_REMOVE_HEAD(&cdr->party_b.variables, entries))) {
827 ast_var_delete(it_var);
829 ast_string_field_free_memory(cdr);
831 ao2_cleanup(cdr->next);
835 * \brief \ref cdr_object constructor
836 * \param chan The \ref ast_channel_snapshot that is the CDR's Party A
838 * This implicitly sets the state of the newly created CDR to the Single state
839 * (\ref single_state_fn_table)
841 static struct cdr_object *cdr_object_alloc(struct ast_channel_snapshot *chan)
843 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
844 struct cdr_object *cdr;
846 ast_assert(chan != NULL);
848 cdr = ao2_alloc(sizeof(*cdr), cdr_object_dtor);
853 if (ast_string_field_init(cdr, 64)) {
857 ast_string_field_set(cdr, name, chan->name);
858 ast_string_field_set(cdr, linkedid, chan->linkedid);
859 cdr->disposition = AST_CDR_NULL;
860 cdr->sequence = ast_atomic_fetchadd_int(&global_cdr_sequence, +1);
862 cdr->party_a.snapshot = chan;
863 ao2_t_ref(cdr->party_a.snapshot, +1, "bump snapshot during CDR creation");
865 CDR_DEBUG(mod_cfg, "%p - Created CDR for channel %s\n", cdr, chan->name);
867 cdr_object_transition_state(cdr, &single_state_fn_table);
873 * \brief Create a new \ref cdr_object and append it to an existing chain
874 * \param cdr The \ref cdr_object to append to
876 static struct cdr_object *cdr_object_create_and_append(struct cdr_object *cdr)
878 struct cdr_object *new_cdr;
879 struct cdr_object *it_cdr;
880 struct cdr_object *cdr_last;
882 cdr_last = cdr->last;
883 new_cdr = cdr_object_alloc(cdr_last->party_a.snapshot);
887 new_cdr->disposition = AST_CDR_NULL;
889 /* Copy over the linkedid, as it may have changed */
890 ast_string_field_set(new_cdr, linkedid, cdr_last->linkedid);
891 ast_string_field_set(new_cdr, appl, cdr_last->appl);
892 ast_string_field_set(new_cdr, data, cdr_last->data);
894 /* Copy over other Party A information */
895 cdr_object_snapshot_copy(&new_cdr->party_a, &cdr_last->party_a);
897 /* Append the CDR to the end of the list */
898 for (it_cdr = cdr; it_cdr->next; it_cdr = it_cdr->next) {
899 it_cdr->last = new_cdr;
901 it_cdr->last = new_cdr;
902 it_cdr->next = new_cdr;
908 * \brief Return whether or not a channel has changed its state in the dialplan, subject
909 * to endbeforehexten logic
911 * \param old_snapshot The previous state
912 * \param new_snapshot The new state
914 * \retval 0 if the state has not changed
915 * \retval 1 if the state changed
917 static int snapshot_cep_changed(struct ast_channel_snapshot *old_snapshot,
918 struct ast_channel_snapshot *new_snapshot)
920 RAII_VAR(struct module_config *, mod_cfg,
921 ao2_global_obj_ref(module_configs), ao2_cleanup);
923 /* If we ignore hangup logic, don't indicate that we're executing anything new */
924 if (ast_test_flag(&mod_cfg->general->settings, CDR_END_BEFORE_H_EXTEN)
925 && ast_test_flag(&new_snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)) {
929 /* When Party A is originated to an application and the application exits, the stack
930 * will attempt to clear the application and restore the dummy originate application
931 * of "AppDialX". Ignore application changes to AppDialX as a result.
933 if (strcmp(new_snapshot->appl, old_snapshot->appl) && strncasecmp(new_snapshot->appl, "appdial", 7)
934 && (strcmp(new_snapshot->context, old_snapshot->context)
935 || strcmp(new_snapshot->exten, old_snapshot->exten)
936 || new_snapshot->priority != old_snapshot->priority)) {
944 * \brief Return whether or not a \ref ast_channel_snapshot is for a channel
945 * that was created as the result of a dial operation
947 * \retval 0 the channel was not created as the result of a dial
948 * \retval 1 the channel was created as the result of a dial
950 static int snapshot_is_dialed(struct ast_channel_snapshot *snapshot)
952 return (ast_test_flag(&snapshot->flags, AST_FLAG_OUTGOING)
953 && !(ast_test_flag(&snapshot->flags, AST_FLAG_ORIGINATED)));
957 * \brief Given two CDR snapshots, figure out who should be Party A for the
959 * \param left One of the snapshots
960 * \param right The other snapshot
961 * \retval The snapshot that won
963 static struct cdr_object_snapshot *cdr_object_pick_party_a(struct cdr_object_snapshot *left, struct cdr_object_snapshot *right)
965 /* Check whether or not the party is dialed. A dialed party is never the
966 * Party A with a party that was not dialed.
968 if (!snapshot_is_dialed(left->snapshot) && snapshot_is_dialed(right->snapshot)) {
970 } else if (snapshot_is_dialed(left->snapshot) && !snapshot_is_dialed(right->snapshot)) {
974 /* Try the Party A flag */
975 if (ast_test_flag(left, AST_CDR_FLAG_PARTY_A) && !ast_test_flag(right, AST_CDR_FLAG_PARTY_A)) {
977 } else if (!ast_test_flag(right, AST_CDR_FLAG_PARTY_A) && ast_test_flag(right, AST_CDR_FLAG_PARTY_A)) {
981 /* Neither party is dialed and neither has the Party A flag - defer to
983 if (left->snapshot->creationtime.tv_sec < right->snapshot->creationtime.tv_sec) {
985 } else if (left->snapshot->creationtime.tv_sec > right->snapshot->creationtime.tv_sec) {
987 } else if (left->snapshot->creationtime.tv_usec > right->snapshot->creationtime.tv_usec) {
990 /* Okay, fine, take the left one */
996 * Compute the duration for a \ref cdr_object
998 static long cdr_object_get_duration(struct cdr_object *cdr)
1000 return (long)(ast_tvdiff_ms(ast_tvzero(cdr->end) ? ast_tvnow() : cdr->end, cdr->start) / 1000);
1004 * \brief Compute the billsec for a \ref cdr_object
1006 static long cdr_object_get_billsec(struct cdr_object *cdr)
1008 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
1011 if (ast_tvzero(cdr->answer)) {
1014 ms = ast_tvdiff_ms(ast_tvzero(cdr->end) ? ast_tvnow() : cdr->end, cdr->answer);
1015 if (ast_test_flag(&mod_cfg->general->settings, CDR_INITIATED_SECONDS)
1016 && (ms % 1000 >= 500)) {
1017 ms = (ms / 1000) + 1;
1027 * \brief Set a variable on a CDR object
1029 * \param headp The header pointer to the variable to set
1030 * \param name The name of the variable
1031 * \param value The value of the variable
1033 static void set_variable(struct varshead *headp, const char *name, const char *value)
1035 struct ast_var_t *newvariable;
1037 AST_LIST_TRAVERSE_SAFE_BEGIN(headp, newvariable, entries) {
1038 if (!strcasecmp(ast_var_name(newvariable), name)) {
1039 AST_LIST_REMOVE_CURRENT(entries);
1040 ast_var_delete(newvariable);
1044 AST_LIST_TRAVERSE_SAFE_END;
1046 if (value && (newvariable = ast_var_assign(name, value))) {
1047 AST_LIST_INSERT_HEAD(headp, newvariable, entries);
1052 * \brief Create a chain of \ref ast_cdr objects from a chain of \ref cdr_object
1053 * suitable for consumption by the registered CDR backends
1054 * \param cdr The \ref cdr_object to convert to a public record
1055 * \retval A chain of \ref ast_cdr objects on success
1056 * \retval NULL on failure
1058 static struct ast_cdr *cdr_object_create_public_records(struct cdr_object *cdr)
1060 struct ast_cdr *pub_cdr = NULL, *cdr_prev = NULL;
1061 struct cdr_object *it_cdr;
1062 struct ast_var_t *it_var, *it_copy_var;
1063 struct ast_channel_snapshot *party_a;
1064 struct ast_channel_snapshot *party_b;
1066 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
1067 struct ast_cdr *cdr_copy;
1069 /* Don't create records for CDRs where the party A was a dialed channel */
1070 if (snapshot_is_dialed(it_cdr->party_a.snapshot)) {
1074 cdr_copy = ast_calloc(1, sizeof(*cdr_copy));
1080 party_a = it_cdr->party_a.snapshot;
1081 party_b = it_cdr->party_b.snapshot;
1084 ast_assert(party_a != NULL);
1085 ast_copy_string(cdr_copy->accountcode, party_a->accountcode, sizeof(cdr_copy->accountcode));
1086 cdr_copy->amaflags = party_a->amaflags;
1087 ast_copy_string(cdr_copy->channel, party_a->name, sizeof(cdr_copy->channel));
1088 ast_callerid_merge(cdr_copy->clid, sizeof(cdr_copy->clid), party_a->caller_name, party_a->caller_number, "");
1089 ast_copy_string(cdr_copy->src, party_a->caller_number, sizeof(cdr_copy->src));
1090 ast_copy_string(cdr_copy->uniqueid, party_a->uniqueid, sizeof(cdr_copy->uniqueid));
1091 ast_copy_string(cdr_copy->lastapp, it_cdr->appl, sizeof(cdr_copy->lastapp));
1092 ast_copy_string(cdr_copy->lastdata, it_cdr->data, sizeof(cdr_copy->lastdata));
1093 ast_copy_string(cdr_copy->dst, party_a->exten, sizeof(cdr_copy->dst));
1094 ast_copy_string(cdr_copy->dcontext, party_a->context, sizeof(cdr_copy->dcontext));
1098 ast_copy_string(cdr_copy->dstchannel, party_b->name, sizeof(cdr_copy->dstchannel));
1099 ast_copy_string(cdr_copy->peeraccount, party_b->accountcode, sizeof(cdr_copy->peeraccount));
1100 if (!ast_strlen_zero(it_cdr->party_b.userfield)) {
1101 snprintf(cdr_copy->userfield, sizeof(cdr_copy->userfield), "%s;%s", it_cdr->party_a.userfield, it_cdr->party_b.userfield);
1104 if (ast_strlen_zero(cdr_copy->userfield) && !ast_strlen_zero(it_cdr->party_a.userfield)) {
1105 ast_copy_string(cdr_copy->userfield, it_cdr->party_a.userfield, sizeof(cdr_copy->userfield));
1108 /* Timestamps/durations */
1109 cdr_copy->start = it_cdr->start;
1110 cdr_copy->answer = it_cdr->answer;
1111 cdr_copy->end = it_cdr->end;
1112 cdr_copy->billsec = cdr_object_get_billsec(it_cdr);
1113 cdr_copy->duration = cdr_object_get_duration(it_cdr);
1116 ast_copy_flags(cdr_copy, &it_cdr->flags, AST_FLAGS_ALL);
1117 ast_copy_string(cdr_copy->linkedid, it_cdr->linkedid, sizeof(cdr_copy->linkedid));
1118 cdr_copy->disposition = it_cdr->disposition;
1119 cdr_copy->sequence = it_cdr->sequence;
1122 copy_variables(&cdr_copy->varshead, &it_cdr->party_a.variables);
1123 AST_LIST_TRAVERSE(&it_cdr->party_b.variables, it_var, entries) {
1125 struct ast_var_t *newvariable;
1126 AST_LIST_TRAVERSE(&cdr_copy->varshead, it_copy_var, entries) {
1127 if (!strcasecmp(ast_var_name(it_var), ast_var_name(it_copy_var))) {
1132 if (!found && (newvariable = ast_var_assign(ast_var_name(it_var), ast_var_value(it_var)))) {
1133 AST_LIST_INSERT_TAIL(&cdr_copy->varshead, newvariable, entries);
1141 cdr_prev->next = cdr_copy;
1142 cdr_prev = cdr_copy;
1150 * \brief Dispatch a CDR.
1151 * \param cdr The \ref cdr_object to dispatch
1153 * This will create a \ref ast_cdr object and publish it to the various backends
1155 static void cdr_object_dispatch(struct cdr_object *cdr)
1157 RAII_VAR(struct module_config *, mod_cfg,
1158 ao2_global_obj_ref(module_configs), ao2_cleanup);
1159 struct ast_cdr *pub_cdr;
1161 CDR_DEBUG(mod_cfg, "%p - Dispatching CDR for Party A %s, Party B %s\n", cdr,
1162 cdr->party_a.snapshot->name,
1163 cdr->party_b.snapshot ? cdr->party_b.snapshot->name : "<none>");
1164 pub_cdr = cdr_object_create_public_records(cdr);
1165 cdr_detach(pub_cdr);
1169 * \brief Set the disposition on a \ref cdr_object based on a hangupcause code
1170 * \param cdr The \ref cdr_object
1171 * \param hangupcause The Asterisk hangup cause code
1173 static void cdr_object_set_disposition(struct cdr_object *cdr, int hangupcause)
1175 RAII_VAR(struct module_config *, mod_cfg,
1176 ao2_global_obj_ref(module_configs), ao2_cleanup);
1178 /* Change the disposition based on the hang up cause */
1179 switch (hangupcause) {
1180 case AST_CAUSE_BUSY:
1181 cdr->disposition = AST_CDR_BUSY;
1183 case AST_CAUSE_CONGESTION:
1184 if (!ast_test_flag(&mod_cfg->general->settings, CDR_CONGESTION)) {
1185 cdr->disposition = AST_CDR_FAILED;
1187 cdr->disposition = AST_CDR_CONGESTION;
1190 case AST_CAUSE_NO_ROUTE_DESTINATION:
1191 case AST_CAUSE_UNREGISTERED:
1192 cdr->disposition = AST_CDR_FAILED;
1194 case AST_CAUSE_NORMAL_CLEARING:
1195 case AST_CAUSE_NO_ANSWER:
1196 cdr->disposition = AST_CDR_NOANSWER;
1204 * \brief Finalize a CDR.
1206 * This function is safe to call multiple times. Note that you can call this
1207 * explicitly before going to the finalized state if there's a chance the CDR
1208 * will be re-activated, in which case the \ref cdr_object's end time should be
1209 * cleared. This function is implicitly called when a CDR transitions to the
1210 * finalized state and right before it is dispatched
1212 * \param cdr_object The CDR to finalize
1214 static void cdr_object_finalize(struct cdr_object *cdr)
1216 RAII_VAR(struct module_config *, mod_cfg,
1217 ao2_global_obj_ref(module_configs), ao2_cleanup);
1219 if (!ast_tvzero(cdr->end)) {
1222 cdr->end = ast_tvnow();
1224 if (cdr->disposition == AST_CDR_NULL) {
1225 if (!ast_tvzero(cdr->answer)) {
1226 cdr->disposition = AST_CDR_ANSWERED;
1227 } else if (cdr->party_a.snapshot->hangupcause) {
1228 cdr_object_set_disposition(cdr, cdr->party_a.snapshot->hangupcause);
1229 } else if (cdr->party_b.snapshot && cdr->party_b.snapshot->hangupcause) {
1230 cdr_object_set_disposition(cdr, cdr->party_b.snapshot->hangupcause);
1232 cdr->disposition = AST_CDR_FAILED;
1236 /* tv_usec is suseconds_t, which could be int or long */
1237 ast_debug(1, "Finalized CDR for %s - start %ld.%06ld answer %ld.%06ld end %ld.%06ld dispo %s\n",
1238 cdr->party_a.snapshot->name,
1240 (long)cdr->start.tv_usec,
1242 (long)cdr->answer.tv_usec,
1244 (long)cdr->end.tv_usec,
1245 ast_cdr_disp2str(cdr->disposition));
1249 * \brief Check to see if a CDR needs to move to the finalized state because
1250 * its Party A hungup.
1252 static void cdr_object_check_party_a_hangup(struct cdr_object *cdr)
1254 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
1256 if (ast_test_flag(&mod_cfg->general->settings, CDR_END_BEFORE_H_EXTEN)
1257 && ast_test_flag(&cdr->party_a.snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)) {
1258 cdr_object_finalize(cdr);
1261 if (ast_test_flag(&cdr->party_a.snapshot->flags, AST_FLAG_DEAD)
1262 && cdr->fn_table != &finalized_state_fn_table) {
1263 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1268 * \brief Check to see if a CDR needs to be answered based on its Party A.
1269 * Note that this is safe to call as much as you want - we won't answer twice
1271 static void cdr_object_check_party_a_answer(struct cdr_object *cdr) {
1272 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
1274 if (cdr->party_a.snapshot->state == AST_STATE_UP && ast_tvzero(cdr->answer)) {
1275 cdr->answer = ast_tvnow();
1276 /* tv_usec is suseconds_t, which could be int or long */
1277 CDR_DEBUG(mod_cfg, "%p - Set answered time to %ld.%06ld\n", cdr,
1279 (long)cdr->answer.tv_usec);
1283 /* \brief Set Caller ID information on a CDR */
1284 static void cdr_object_update_cid(struct cdr_object_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot)
1286 if (!old_snapshot->snapshot) {
1287 set_variable(&old_snapshot->variables, "dnid", new_snapshot->caller_dnid);
1288 set_variable(&old_snapshot->variables, "callingsubaddr", new_snapshot->caller_subaddr);
1289 set_variable(&old_snapshot->variables, "calledsubaddr", new_snapshot->dialed_subaddr);
1292 if (!strcmp(old_snapshot->snapshot->caller_dnid, new_snapshot->caller_dnid)) {
1293 set_variable(&old_snapshot->variables, "dnid", new_snapshot->caller_dnid);
1295 if (!strcmp(old_snapshot->snapshot->caller_subaddr, new_snapshot->caller_subaddr)) {
1296 set_variable(&old_snapshot->variables, "callingsubaddr", new_snapshot->caller_subaddr);
1298 if (!strcmp(old_snapshot->snapshot->dialed_subaddr, new_snapshot->dialed_subaddr)) {
1299 set_variable(&old_snapshot->variables, "calledsubaddr", new_snapshot->dialed_subaddr);
1304 * \brief Swap an old \ref cdr_object_snapshot's \ref ast_channel_snapshot for
1305 * a new \ref ast_channel_snapshot
1306 * \param old_snapshot The old \ref cdr_object_snapshot
1307 * \param new_snapshot The new \ref ast_channel_snapshot for old_snapshot
1309 static void cdr_object_swap_snapshot(struct cdr_object_snapshot *old_snapshot,
1310 struct ast_channel_snapshot *new_snapshot)
1312 cdr_object_update_cid(old_snapshot, new_snapshot);
1313 if (old_snapshot->snapshot) {
1314 ao2_t_ref(old_snapshot->snapshot, -1, "Drop ref for swap");
1316 ao2_t_ref(new_snapshot, +1, "Bump ref for swap");
1317 old_snapshot->snapshot = new_snapshot;
1320 /* BASE METHOD IMPLEMENTATIONS */
1322 static int base_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
1324 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
1326 ast_assert(strcasecmp(snapshot->name, cdr->party_a.snapshot->name) == 0);
1327 cdr_object_swap_snapshot(&cdr->party_a, snapshot);
1329 /* When Party A is originated to an application and the application exits, the stack
1330 * will attempt to clear the application and restore the dummy originate application
1331 * of "AppDialX". Prevent that, and any other application changes we might not want
1334 if (!ast_strlen_zero(snapshot->appl)
1335 && (strncasecmp(snapshot->appl, "appdial", 7) || ast_strlen_zero(cdr->appl))
1336 && !ast_test_flag(&cdr->flags, AST_CDR_LOCK_APP)) {
1337 ast_string_field_set(cdr, appl, snapshot->appl);
1338 ast_string_field_set(cdr, data, snapshot->data);
1341 ast_string_field_set(cdr, linkedid, snapshot->linkedid);
1342 cdr_object_check_party_a_answer(cdr);
1343 cdr_object_check_party_a_hangup(cdr);
1348 static int base_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1350 /* In general, most things shouldn't get a bridge leave */
1355 static int base_process_dial_end(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer, const char *dial_status)
1357 /* In general, most things shouldn't get a dial end. */
1362 static enum process_bridge_enter_results base_process_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1364 /* Base process bridge enter simply indicates that we can't handle it */
1365 return BRIDGE_ENTER_NEED_CDR;
1368 static int base_process_parked_channel(struct cdr_object *cdr, struct ast_parked_call_payload *parking_info)
1370 char park_info[128];
1372 ast_assert(!strcasecmp(parking_info->parkee->name, cdr->party_a.snapshot->name));
1374 /* Update Party A information regardless */
1375 cdr->fn_table->process_party_a(cdr, parking_info->parkee);
1377 /* Fake out where we're parked */
1378 ast_string_field_set(cdr, appl, "Park");
1379 snprintf(park_info, sizeof(park_info), "%s:%u", parking_info->parkinglot, parking_info->parkingspace);
1380 ast_string_field_set(cdr, data, park_info);
1382 /* Prevent any further changes to the App/Data fields for this record */
1383 ast_set_flag(&cdr->flags, AST_CDR_LOCK_APP);
1390 static void single_state_init_function(struct cdr_object *cdr) {
1391 cdr->start = ast_tvnow();
1392 cdr_object_check_party_a_answer(cdr);
1395 static void single_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
1397 /* This should never happen! */
1398 ast_assert(cdr->party_b.snapshot == NULL);
1403 static int single_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer)
1405 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
1407 if (caller && !strcasecmp(cdr->party_a.snapshot->name, caller->name)) {
1408 cdr_object_swap_snapshot(&cdr->party_a, caller);
1409 CDR_DEBUG(mod_cfg, "%p - Updated Party A %s snapshot\n", cdr,
1410 cdr->party_a.snapshot->name);
1411 cdr_object_swap_snapshot(&cdr->party_b, peer);
1412 CDR_DEBUG(mod_cfg, "%p - Updated Party B %s snapshot\n", cdr,
1413 cdr->party_b.snapshot->name);
1414 } else if (!strcasecmp(cdr->party_a.snapshot->name, peer->name)) {
1415 /* We're the entity being dialed, i.e., outbound origination */
1416 cdr_object_swap_snapshot(&cdr->party_a, peer);
1417 CDR_DEBUG(mod_cfg, "%p - Updated Party A %s snapshot\n", cdr,
1418 cdr->party_a.snapshot->name);
1421 cdr_object_transition_state(cdr, &dial_state_fn_table);
1426 * \brief Handle a comparison between our \ref cdr_object and a \ref cdr_object
1427 * already in the bridge while in the Single state. The goal of this is to find
1428 * a Party B for our CDR.
1430 * \param cdr Our \ref cdr_object in the Single state
1431 * \param cand_cdr The \ref cdr_object already in the Bridge state
1433 * \retval 0 The cand_cdr had a Party A or Party B that we could use as our
1435 * \retval 1 No party in the cand_cdr could be used as our Party B
1437 static int single_state_bridge_enter_comparison(struct cdr_object *cdr,
1438 struct cdr_object *cand_cdr)
1440 struct cdr_object_snapshot *party_a;
1442 /* Don't match on ourselves */
1443 if (!strcasecmp(cdr->party_a.snapshot->name, cand_cdr->party_a.snapshot->name)) {
1447 /* Try the candidate CDR's Party A first */
1448 party_a = cdr_object_pick_party_a(&cdr->party_a, &cand_cdr->party_a);
1449 if (!strcasecmp(party_a->snapshot->name, cdr->party_a.snapshot->name)) {
1450 cdr_object_snapshot_copy(&cdr->party_b, &cand_cdr->party_a);
1451 if (!cand_cdr->party_b.snapshot) {
1452 /* We just stole them - finalize their CDR. Note that this won't
1453 * transition their state, it just sets the end time and the
1454 * disposition - if we need to re-activate them later, we can.
1456 cdr_object_finalize(cand_cdr);
1461 /* Try their Party B, unless it's us */
1462 if (!cand_cdr->party_b.snapshot
1463 || !strcasecmp(cdr->party_a.snapshot->name, cand_cdr->party_b.snapshot->name)) {
1466 party_a = cdr_object_pick_party_a(&cdr->party_a, &cand_cdr->party_b);
1467 if (!strcasecmp(party_a->snapshot->name, cdr->party_a.snapshot->name)) {
1468 cdr_object_snapshot_copy(&cdr->party_b, &cand_cdr->party_b);
1475 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)
1477 struct ao2_iterator *it_cdrs;
1478 struct cdr_object *cand_cdr_master;
1479 char *bridge_id = ast_strdupa(bridge->uniqueid);
1482 ast_string_field_set(cdr, bridge, bridge->uniqueid);
1484 /* Get parties in the bridge */
1485 it_cdrs = ao2_callback(active_cdrs_by_channel, OBJ_MULTIPLE,
1486 cdr_object_bridge_cmp_fn, bridge_id);
1488 /* No one in the bridge yet! */
1489 cdr_object_transition_state(cdr, &bridge_state_fn_table);
1490 return BRIDGE_ENTER_ONLY_PARTY;
1493 while ((cand_cdr_master = ao2_iterator_next(it_cdrs))) {
1494 struct cdr_object *cand_cdr;
1495 RAII_VAR(struct cdr_object *, cdr_cleanup, cand_cdr_master, ao2_cleanup);
1496 SCOPED_AO2LOCK(lock, cand_cdr_master);
1498 for (cand_cdr = cand_cdr_master; cand_cdr; cand_cdr = cand_cdr->next) {
1499 /* Skip any records that are not in a bridge or in this bridge.
1500 * I'm not sure how that would happen, but it pays to be careful. */
1501 if (cand_cdr->fn_table != &bridge_state_fn_table ||
1502 strcmp(cdr->bridge, cand_cdr->bridge)) {
1506 if (single_state_bridge_enter_comparison(cdr, cand_cdr)) {
1509 /* We successfully got a party B - break out */
1514 ao2_iterator_destroy(it_cdrs);
1516 /* We always transition state, even if we didn't get a peer */
1517 cdr_object_transition_state(cdr, &bridge_state_fn_table);
1519 /* Success implies that we have a Party B */
1521 return BRIDGE_ENTER_OBTAINED_PARTY_B;
1524 return BRIDGE_ENTER_NO_PARTY_B;
1527 static int single_state_process_parking_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1529 cdr_object_transition_state(cdr, &parked_state_fn_table);
1536 static void dial_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
1538 ast_assert(snapshot != NULL);
1540 if (!cdr->party_b.snapshot
1541 || strcasecmp(cdr->party_b.snapshot->name, snapshot->name)) {
1544 cdr_object_swap_snapshot(&cdr->party_b, snapshot);
1546 /* If party B hangs up, finalize this CDR */
1547 if (ast_test_flag(&cdr->party_b.snapshot->flags, AST_FLAG_DEAD)) {
1548 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1552 static int dial_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer)
1554 /* Don't process a begin dial here. A party A already in the dial state will
1555 * who receives a dial begin for something else will be handled by the
1556 * message router callback and will add a new CDR for the party A */
1562 * \brief Convert a dial status to a CDR disposition
1564 static enum ast_cdr_disposition dial_status_to_disposition(const char *dial_status)
1566 RAII_VAR(struct module_config *, mod_cfg,
1567 ao2_global_obj_ref(module_configs), ao2_cleanup);
1569 if (!strcmp(dial_status, "ANSWER")) {
1570 return AST_CDR_ANSWERED;
1571 } else if (!strcmp(dial_status, "BUSY")) {
1572 return AST_CDR_BUSY;
1573 } else if (!strcmp(dial_status, "CANCEL") || !strcmp(dial_status, "NOANSWER")) {
1574 return AST_CDR_NOANSWER;
1575 } else if (!strcmp(dial_status, "CONGESTION")) {
1576 if (!ast_test_flag(&mod_cfg->general->settings, CDR_CONGESTION)) {
1577 return AST_CDR_FAILED;
1579 return AST_CDR_CONGESTION;
1581 } else if (!strcmp(dial_status, "FAILED")) {
1582 return AST_CDR_FAILED;
1584 return AST_CDR_FAILED;
1587 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)
1589 RAII_VAR(struct module_config *, mod_cfg,
1590 ao2_global_obj_ref(module_configs), ao2_cleanup);
1591 struct ast_channel_snapshot *party_a;
1598 ast_assert(!strcasecmp(cdr->party_a.snapshot->name, party_a->name));
1599 cdr_object_swap_snapshot(&cdr->party_a, party_a);
1601 if (cdr->party_b.snapshot) {
1602 if (strcasecmp(cdr->party_b.snapshot->name, peer->name)) {
1603 /* Not the status for this CDR - defer back to the message router */
1606 cdr_object_swap_snapshot(&cdr->party_b, peer);
1609 /* Set the disposition based on the dial string. */
1610 cdr->disposition = dial_status_to_disposition(dial_status);
1611 if (cdr->disposition == AST_CDR_ANSWERED) {
1612 /* Switch to dial pending to wait and see what the caller does */
1613 cdr_object_transition_state(cdr, &dialed_pending_state_fn_table);
1615 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1621 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)
1623 struct ao2_iterator *it_cdrs;
1624 char *bridge_id = ast_strdupa(bridge->uniqueid);
1625 struct cdr_object *cand_cdr_master;
1628 ast_string_field_set(cdr, bridge, bridge->uniqueid);
1630 /* Get parties in the bridge */
1631 it_cdrs = ao2_callback(active_cdrs_by_channel, OBJ_MULTIPLE,
1632 cdr_object_bridge_cmp_fn, bridge_id);
1634 /* No one in the bridge yet! */
1635 cdr_object_transition_state(cdr, &bridge_state_fn_table);
1636 return BRIDGE_ENTER_ONLY_PARTY;
1639 while ((cand_cdr_master = ao2_iterator_next(it_cdrs))) {
1640 struct cdr_object *cand_cdr;
1641 RAII_VAR(struct cdr_object *, cdr_cleanup, cand_cdr_master, ao2_cleanup);
1642 SCOPED_AO2LOCK(lock, cand_cdr_master);
1644 for (cand_cdr = cand_cdr_master; cand_cdr; cand_cdr = cand_cdr->next) {
1645 /* Skip any records that are not in a bridge or in this bridge.
1646 * I'm not sure how that would happen, but it pays to be careful. */
1647 if (cand_cdr->fn_table != &bridge_state_fn_table ||
1648 strcmp(cdr->bridge, cand_cdr->bridge)) {
1652 /* If we don't have a Party B (originated channel), skip it */
1653 if (!cdr->party_b.snapshot) {
1657 /* Skip any records that aren't our Party B */
1658 if (strcasecmp(cdr->party_b.snapshot->name, cand_cdr->party_a.snapshot->name)) {
1661 cdr_object_snapshot_copy(&cdr->party_b, &cand_cdr->party_a);
1662 /* If they have a Party B, they joined up with someone else as their
1663 * Party A. Don't finalize them as they're active. Otherwise, we
1664 * have stolen them so they need to be finalized.
1666 if (!cand_cdr->party_b.snapshot) {
1667 cdr_object_finalize(cand_cdr);
1673 ao2_iterator_destroy(it_cdrs);
1675 /* We always transition state, even if we didn't get a peer */
1676 cdr_object_transition_state(cdr, &bridge_state_fn_table);
1678 /* Success implies that we have a Party B */
1680 return BRIDGE_ENTER_OBTAINED_PARTY_B;
1682 return BRIDGE_ENTER_NO_PARTY_B;
1685 /* DIALED PENDING STATE */
1687 static int dialed_pending_state_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
1689 /* If we get a CEP change, we're executing dialplan. If we have a Party B
1690 * that means we need a new CDR; otherwise, switch us over to single.
1692 if (snapshot_cep_changed(cdr->party_a.snapshot, snapshot)) {
1693 if (cdr->party_b.snapshot) {
1694 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1695 cdr->fn_table->process_party_a(cdr, snapshot);
1698 cdr_object_transition_state(cdr, &single_state_fn_table);
1699 cdr->fn_table->process_party_a(cdr, snapshot);
1703 base_process_party_a(cdr, snapshot);
1707 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)
1709 cdr_object_transition_state(cdr, &dial_state_fn_table);
1710 return cdr->fn_table->process_bridge_enter(cdr, bridge, channel);
1713 static int dialed_pending_state_process_parking_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1715 /* We can't handle this as we have a Party B - ask for a new one */
1719 static int dialed_pending_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer)
1721 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1723 /* Ask for a new CDR */
1729 static void bridge_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
1731 if (!cdr->party_b.snapshot
1732 || strcasecmp(cdr->party_b.snapshot->name, snapshot->name)) {
1735 cdr_object_swap_snapshot(&cdr->party_b, snapshot);
1737 /* If party B hangs up, finalize this CDR */
1738 if (ast_test_flag(&cdr->party_b.snapshot->flags, AST_FLAG_DEAD)) {
1739 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1743 static int bridge_state_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1745 if (strcmp(cdr->bridge, bridge->uniqueid)) {
1748 if (strcasecmp(cdr->party_a.snapshot->name, channel->name)
1749 && cdr->party_b.snapshot
1750 && strcasecmp(cdr->party_b.snapshot->name, channel->name)) {
1753 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1760 static int parked_state_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1762 if (strcasecmp(cdr->party_a.snapshot->name, channel->name)) {
1765 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1770 /* FINALIZED STATE */
1772 static void finalized_state_init_function(struct cdr_object *cdr)
1774 cdr_object_finalize(cdr);
1777 static int finalized_state_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
1779 RAII_VAR(struct module_config *, mod_cfg,
1780 ao2_global_obj_ref(module_configs), ao2_cleanup);
1782 /* If we ignore hangup logic, indicate that we don't need a new CDR */
1783 if (ast_test_flag(&mod_cfg->general->settings, CDR_END_BEFORE_H_EXTEN)
1784 && ast_test_flag(&snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)) {
1788 /* Indicate that, if possible, we should get a new CDR */
1792 /* TOPIC ROUTER CALLBACKS */
1795 * \brief Handler for Stasis-Core dial messages
1796 * \param data Passed on
1797 * \param sub The stasis subscription for this message callback
1798 * \param topic The topic this message was published for
1799 * \param message The message
1801 static void handle_dial_message(void *data, struct stasis_subscription *sub, struct stasis_topic *topic, struct stasis_message *message)
1803 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
1804 RAII_VAR(struct cdr_object *, cdr, NULL, ao2_cleanup);
1805 struct ast_multi_channel_blob *payload = stasis_message_data(message);
1806 struct ast_channel_snapshot *caller;
1807 struct ast_channel_snapshot *peer;
1808 struct cdr_object *it_cdr;
1809 struct ast_json *dial_status_blob;
1810 const char *dial_status = NULL;
1813 caller = ast_multi_channel_blob_get_channel(payload, "caller");
1814 peer = ast_multi_channel_blob_get_channel(payload, "peer");
1815 if (!peer && !caller) {
1818 dial_status_blob = ast_json_object_get(ast_multi_channel_blob_get_json(payload), "dialstatus");
1819 if (dial_status_blob) {
1820 dial_status = ast_json_string_get(dial_status_blob);
1823 CDR_DEBUG(mod_cfg, "Dial %s message for %s, %s: %u.%08u\n",
1824 ast_strlen_zero(dial_status) ? "Begin" : "End",
1825 caller ? caller->name : "(none)",
1826 peer ? peer->name : "(none)",
1827 (unsigned int)stasis_message_timestamp(message)->tv_sec,
1828 (unsigned int)stasis_message_timestamp(message)->tv_usec);
1830 /* Figure out who is running this show */
1832 cdr = ao2_find(active_cdrs_by_channel, caller->name, OBJ_KEY);
1834 cdr = ao2_find(active_cdrs_by_channel, peer->name, OBJ_KEY);
1838 ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", caller ? caller->name : peer->name);
1843 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
1844 if (ast_strlen_zero(dial_status)) {
1845 if (!it_cdr->fn_table->process_dial_begin) {
1848 CDR_DEBUG(mod_cfg, "%p - Processing Dial Begin message for channel %s, peer %s\n",
1850 caller ? caller->name : "(none)",
1851 peer ? peer->name : "(none)");
1852 res &= it_cdr->fn_table->process_dial_begin(it_cdr,
1856 if (!it_cdr->fn_table->process_dial_end) {
1859 CDR_DEBUG(mod_cfg, "%p - Processing Dial End message for channel %s, peer %s\n",
1861 caller ? caller->name : "(none)",
1862 peer ? peer->name : "(none)");
1863 it_cdr->fn_table->process_dial_end(it_cdr,
1870 /* If no CDR handled a dial begin message, make a new one */
1871 if (res && ast_strlen_zero(dial_status)) {
1872 struct cdr_object *new_cdr;
1874 new_cdr = cdr_object_create_and_append(cdr);
1878 new_cdr->fn_table->process_dial_begin(new_cdr,
1885 static int cdr_object_finalize_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->party_b.snapshot
1892 && !strcasecmp(it_cdr->party_b.snapshot->name, party_b->name)) {
1893 /* Don't transition to the finalized state - let the Party A do
1894 * that when its ready
1896 cdr_object_finalize(it_cdr);
1902 static int cdr_object_update_party_b(void *obj, void *arg, int flags)
1904 struct cdr_object *cdr = obj;
1905 struct ast_channel_snapshot *party_b = arg;
1906 struct cdr_object *it_cdr;
1907 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
1908 if (!it_cdr->fn_table->process_party_b) {
1911 if (it_cdr->party_b.snapshot
1912 && !strcasecmp(it_cdr->party_b.snapshot->name, party_b->name)) {
1913 it_cdr->fn_table->process_party_b(it_cdr, party_b);
1921 * \brief Filter channel snapshots by technology
1923 static int filter_channel_snapshot(struct ast_channel_snapshot *snapshot)
1925 return snapshot->tech_properties & AST_CHAN_TP_INTERNAL;
1930 * \brief Filter a channel cache update
1932 static int filter_channel_cache_message(struct ast_channel_snapshot *old_snapshot,
1933 struct ast_channel_snapshot *new_snapshot)
1937 /* Drop cache updates from certain channel technologies */
1939 ret |= filter_channel_snapshot(old_snapshot);
1942 ret |= filter_channel_snapshot(new_snapshot);
1948 /*! \brief Determine if we need to add a new CDR based on snapshots */
1949 static int check_new_cdr_needed(struct ast_channel_snapshot *old_snapshot,
1950 struct ast_channel_snapshot *new_snapshot)
1952 RAII_VAR(struct module_config *, mod_cfg,
1953 ao2_global_obj_ref(module_configs), ao2_cleanup);
1955 if (!new_snapshot) {
1959 if (ast_test_flag(&new_snapshot->flags, AST_FLAG_DEAD)) {
1963 /* Auto-fall through will increment the priority but have no application */
1964 if (ast_strlen_zero(new_snapshot->appl)) {
1968 if (old_snapshot && !snapshot_cep_changed(old_snapshot, new_snapshot)) {
1976 * \brief Handler for Stasis-Core channel cache update messages
1977 * \param data Passed on
1978 * \param sub The stasis subscription for this message callback
1979 * \param topic The topic this message was published for
1980 * \param message The message
1982 static void handle_channel_cache_message(void *data, struct stasis_subscription *sub, struct stasis_topic *topic, struct stasis_message *message)
1984 RAII_VAR(struct cdr_object *, cdr, NULL, ao2_cleanup);
1985 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
1986 struct stasis_cache_update *update = stasis_message_data(message);
1987 struct ast_channel_snapshot *old_snapshot;
1988 struct ast_channel_snapshot *new_snapshot;
1990 struct cdr_object *it_cdr;
1992 ast_assert(update != NULL);
1993 ast_assert(ast_channel_snapshot_type() == update->type);
1995 old_snapshot = stasis_message_data(update->old_snapshot);
1996 new_snapshot = stasis_message_data(update->new_snapshot);
1997 name = new_snapshot ? new_snapshot->name : old_snapshot->name;
1999 if (filter_channel_cache_message(old_snapshot, new_snapshot)) {
2003 CDR_DEBUG(mod_cfg, "Channel Update message for %s: %u.%08u\n",
2005 (unsigned int)stasis_message_timestamp(message)->tv_sec,
2006 (unsigned int)stasis_message_timestamp(message)->tv_usec);
2008 if (new_snapshot && !old_snapshot) {
2009 cdr = cdr_object_alloc(new_snapshot);
2013 ao2_link(active_cdrs_by_channel, cdr);
2016 /* Handle Party A */
2018 cdr = ao2_find(active_cdrs_by_channel, name, OBJ_KEY);
2021 ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", name);
2026 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2027 if (!it_cdr->fn_table->process_party_a) {
2030 CDR_DEBUG(mod_cfg, "%p - Processing new channel snapshot %s\n", it_cdr, new_snapshot->name);
2031 all_reject &= it_cdr->fn_table->process_party_a(it_cdr, new_snapshot);
2033 if (all_reject && check_new_cdr_needed(old_snapshot, new_snapshot)) {
2034 /* We're not hung up and we have a new snapshot - we need a new CDR */
2035 struct cdr_object *new_cdr;
2036 new_cdr = cdr_object_create_and_append(cdr);
2038 new_cdr->fn_table->process_party_a(new_cdr, new_snapshot);
2042 CDR_DEBUG(mod_cfg, "%p - Beginning finalize/dispatch for %s\n", cdr, old_snapshot->name);
2043 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2044 cdr_object_finalize(it_cdr);
2046 cdr_object_dispatch(cdr);
2047 ao2_unlink(active_cdrs_by_channel, cdr);
2052 /* Handle Party B */
2054 ao2_callback(active_cdrs_by_channel, OBJ_NODATA, cdr_object_update_party_b,
2057 ao2_callback(active_cdrs_by_channel, OBJ_NODATA, cdr_object_finalize_party_b,
2063 struct bridge_leave_data {
2064 struct ast_bridge_snapshot *bridge;
2065 struct ast_channel_snapshot *channel;
2068 /*! \brief Callback used to notify CDRs of a Party B leaving the bridge */
2069 static int cdr_object_party_b_left_bridge_cb(void *obj, void *arg, int flags)
2071 struct cdr_object *cdr = obj;
2072 struct bridge_leave_data *leave_data = arg;
2073 struct cdr_object *it_cdr;
2075 if (strcmp(cdr->bridge, leave_data->bridge->uniqueid)) {
2078 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2079 if (it_cdr->fn_table != &bridge_state_fn_table) {
2082 if (!it_cdr->party_b.snapshot) {
2085 if (strcasecmp(it_cdr->party_b.snapshot->name, leave_data->channel->name)) {
2088 /* It is our Party B, in our bridge. Set the end time and let the handler
2089 * transition our CDR appropriately when we leave the bridge.
2091 cdr_object_finalize(it_cdr);
2096 /*! \brief Filter bridge messages based on bridge technology */
2097 static int filter_bridge_messages(struct ast_bridge_snapshot *bridge)
2099 /* Ignore holding bridge technology messages. We treat this simply as an application
2100 * that a channel enters into.
2102 if (!strcmp(bridge->technology, "holding_bridge") && strcmp(bridge->subclass, "parking")) {
2109 * \brief Handler for when a channel leaves a bridge
2110 * \param data Passed on
2111 * \param sub The stasis subscription for this message callback
2112 * \param topic The topic this message was published for
2113 * \param message The message - hopefully a bridge one!
2115 static void handle_bridge_leave_message(void *data, struct stasis_subscription *sub,
2116 struct stasis_topic *topic, struct stasis_message *message)
2118 struct ast_bridge_blob *update = stasis_message_data(message);
2119 struct ast_bridge_snapshot *bridge = update->bridge;
2120 struct ast_channel_snapshot *channel = update->channel;
2121 RAII_VAR(struct module_config *, mod_cfg,
2122 ao2_global_obj_ref(module_configs), ao2_cleanup);
2123 RAII_VAR(struct cdr_object *, cdr,
2124 ao2_find(active_cdrs_by_channel, channel->name, OBJ_KEY),
2126 struct cdr_object *it_cdr;
2127 struct bridge_leave_data leave_data = {
2131 int left_bridge = 0;
2133 if (filter_bridge_messages(bridge)) {
2137 CDR_DEBUG(mod_cfg, "Bridge Leave message for %s: %u.%08u\n",
2139 (unsigned int)stasis_message_timestamp(message)->tv_sec,
2140 (unsigned int)stasis_message_timestamp(message)->tv_usec);
2143 ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", channel->name);
2149 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2150 if (!it_cdr->fn_table->process_bridge_leave) {
2153 CDR_DEBUG(mod_cfg, "%p - Processing Bridge Leave for %s\n",
2154 it_cdr, channel->name);
2155 if (!it_cdr->fn_table->process_bridge_leave(it_cdr, bridge, channel)) {
2156 ast_string_field_set(it_cdr, bridge, "");
2166 if (strcmp(bridge->subclass, "parking")) {
2168 ao2_callback(active_cdrs_by_channel, OBJ_NODATA,
2169 cdr_object_party_b_left_bridge_cb,
2174 struct bridge_candidate {
2175 struct cdr_object *cdr; /*!< The actual CDR this candidate belongs to, either as A or B */
2176 struct cdr_object_snapshot candidate; /*!< The candidate for a new pairing */
2180 * \brief Comparison function for \ref bridge_candidate objects
2182 static int bridge_candidate_cmp_fn(void *obj, void *arg, int flags)
2184 struct bridge_candidate *left = obj;
2185 struct bridge_candidate *right = arg;
2186 const char *match = (flags & OBJ_KEY) ? arg : right->candidate.snapshot->name;
2187 return strcasecmp(left->candidate.snapshot->name, match) ? 0 : (CMP_MATCH | CMP_STOP);
2191 * \brief Hash function for \ref bridge_candidate objects
2193 static int bridge_candidate_hash_fn(const void *obj, const int flags)
2195 const struct bridge_candidate *bc = obj;
2196 const char *id = (flags & OBJ_KEY) ? obj : bc->candidate.snapshot->name;
2197 return ast_str_case_hash(id);
2200 /*! \brief \ref bridge_candidate Destructor */
2201 static void bridge_candidate_dtor(void *obj)
2203 struct bridge_candidate *bcand = obj;
2204 ao2_cleanup(bcand->cdr);
2205 ao2_cleanup(bcand->candidate.snapshot);
2206 free_variables(&bcand->candidate.variables);
2210 * \brief \ref bridge_candidate Constructor
2211 * \param cdr The \ref cdr_object that is a candidate for being compared to in
2212 * a bridge operation
2213 * \param candidate The \ref cdr_object_snapshot candidate snapshot in the CDR
2214 * that should be used during the operaton
2216 static struct bridge_candidate *bridge_candidate_alloc(struct cdr_object *cdr, struct cdr_object_snapshot *candidate)
2218 struct bridge_candidate *bcand;
2220 bcand = ao2_alloc(sizeof(*bcand), bridge_candidate_dtor);
2225 ao2_ref(bcand->cdr, +1);
2226 bcand->candidate.flags = candidate->flags;
2227 strcpy(bcand->candidate.userfield, candidate->userfield);
2228 bcand->candidate.snapshot = candidate->snapshot;
2229 ao2_ref(bcand->candidate.snapshot, +1);
2230 copy_variables(&bcand->candidate.variables, &candidate->variables);
2237 * \brief Build and add bridge candidates based on a CDR
2239 * \param bridge_id The ID of the bridge we need candidates for
2240 * \param candidates The container of \ref bridge_candidate objects
2241 * \param cdr The \ref cdr_object that is our candidate
2242 * \param party_a Non-zero if we should look at the Party A channel; 0 if Party B
2244 static void add_candidate_for_bridge(const char *bridge_id,
2245 struct ao2_container *candidates,
2246 struct cdr_object *cdr,
2249 struct cdr_object *it_cdr;
2251 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2252 struct cdr_object_snapshot *party_snapshot;
2253 RAII_VAR(struct bridge_candidate *, bcand, NULL, ao2_cleanup);
2255 party_snapshot = party_a ? &it_cdr->party_a : &it_cdr->party_b;
2257 if (it_cdr->fn_table != &bridge_state_fn_table || strcmp(bridge_id, it_cdr->bridge)) {
2261 if (!party_snapshot->snapshot) {
2265 /* Don't add a party twice */
2266 bcand = ao2_find(candidates, party_snapshot->snapshot->name, OBJ_KEY);
2271 bcand = bridge_candidate_alloc(it_cdr, party_snapshot);
2273 ao2_link(candidates, bcand);
2279 * \brief Create new \ref bridge_candidate objects for each party currently
2281 * \param bridge The \param ast_bridge_snapshot for the bridge we're processing
2283 * Note that we use two passes here instead of one so that we only create a
2284 * candidate for a party B if they are never a party A in the bridge. Otherwise,
2285 * we don't care about them.
2287 static struct ao2_container *create_candidates_for_bridge(struct ast_bridge_snapshot *bridge)
2289 struct ao2_container *candidates = ao2_container_alloc(61, bridge_candidate_hash_fn, bridge_candidate_cmp_fn);
2290 char *bridge_id = ast_strdupa(bridge->uniqueid);
2291 struct ao2_iterator *it_cdrs;
2292 struct cdr_object *cand_cdr_master;
2298 /* For each CDR that has a record in the bridge, get their Party A and
2299 * make them a candidate. Note that we do this in two passes as opposed to one so
2300 * that we give preference CDRs where the channel is Party A */
2301 it_cdrs = ao2_callback(active_cdrs_by_channel, OBJ_MULTIPLE,
2302 cdr_object_bridge_cmp_fn, bridge_id);
2304 /* No one in the bridge yet! */
2305 ao2_cleanup(candidates);
2308 for (; (cand_cdr_master = ao2_iterator_next(it_cdrs)); ao2_cleanup(cand_cdr_master)) {
2309 SCOPED_AO2LOCK(lock, cand_cdr_master);
2310 add_candidate_for_bridge(bridge->uniqueid, candidates, cand_cdr_master, 1);
2312 ao2_iterator_destroy(it_cdrs);
2313 /* For each CDR that has a record in the bridge, get their Party B and
2314 * make them a candidate. */
2315 it_cdrs = ao2_callback(active_cdrs_by_channel, OBJ_MULTIPLE,
2316 cdr_object_bridge_cmp_fn, bridge_id);
2318 /* Now it's just an error. */
2319 ao2_cleanup(candidates);
2322 for (; (cand_cdr_master = ao2_iterator_next(it_cdrs)); ao2_cleanup(cand_cdr_master)) {
2323 SCOPED_AO2LOCK(lock, cand_cdr_master);
2324 add_candidate_for_bridge(bridge->uniqueid, candidates, cand_cdr_master, 0);
2326 ao2_iterator_destroy(it_cdrs);
2333 * \brief Create a new CDR, append it to an existing CDR, and update its snapshots
2335 * \note The new CDR will be automatically transitioned to the bridge state
2337 static void bridge_candidate_add_to_cdr(struct cdr_object *cdr,
2338 const char *bridge_id,
2339 struct cdr_object_snapshot *party_b)
2341 struct cdr_object *new_cdr;
2343 new_cdr = cdr_object_create_and_append(cdr);
2347 cdr_object_snapshot_copy(&new_cdr->party_b, party_b);
2348 cdr_object_check_party_a_answer(new_cdr);
2349 ast_string_field_set(new_cdr, bridge, cdr->bridge);
2350 cdr_object_transition_state(new_cdr, &bridge_state_fn_table);
2354 * \brief Process a single \ref bridge_candidate. Note that this is called as
2355 * part of an \ref ao2_callback on an \ref ao2_container of \ref bridge_candidate
2356 * objects previously created by \ref create_candidates_for_bridge.
2358 * \param obj The \ref bridge_candidate being processed
2359 * \param arg The \ref cdr_object that is being compared against the candidates
2361 * The purpose of this function is to create the necessary CDR entries as a
2362 * result of \ref cdr_object having entered the same bridge as the CDR
2363 * represented by \ref bridge_candidate.
2365 static int bridge_candidate_process(void *obj, void *arg, int flags)
2367 struct bridge_candidate *bcand = obj;
2368 struct cdr_object *cdr = arg;
2369 struct cdr_object_snapshot *party_a;
2371 /* If the candidate is us or someone we've taken on, pass on by */
2372 if (!strcasecmp(cdr->party_a.snapshot->name, bcand->candidate.snapshot->name)
2373 || (cdr->party_b.snapshot
2374 && !strcasecmp(cdr->party_b.snapshot->name, bcand->candidate.snapshot->name))) {
2377 party_a = cdr_object_pick_party_a(&cdr->party_a, &bcand->candidate);
2378 /* We're party A - make a new CDR, append it to us, and set the candidate as
2380 if (!strcasecmp(party_a->snapshot->name, cdr->party_a.snapshot->name)) {
2381 bridge_candidate_add_to_cdr(cdr, cdr->bridge, &bcand->candidate);
2385 /* We're Party B. Check if the candidate is the CDR's Party A. If so, find out if we
2386 * can add ourselves directly as the Party B, or if we need a new CDR. */
2387 if (!strcasecmp(bcand->cdr->party_a.snapshot->name, bcand->candidate.snapshot->name)) {
2388 if (bcand->cdr->party_b.snapshot
2389 && strcasecmp(bcand->cdr->party_b.snapshot->name, cdr->party_a.snapshot->name)) {
2390 bridge_candidate_add_to_cdr(bcand->cdr, cdr->bridge, &cdr->party_a);
2392 cdr_object_snapshot_copy(&bcand->cdr->party_b, &cdr->party_a);
2393 /* It's possible that this joined at one point and was never chosen
2394 * as party A. Clear their end time, as it would be set in such a
2397 memset(&bcand->cdr->end, 0, sizeof(bcand->cdr->end));
2400 /* We are Party B to a candidate CDR's Party B. Since a candidate
2401 * CDR will only have a Party B represented here if that channel
2402 * was never a Party A in the bridge, we have to go looking for
2403 * that channel's primary CDR record.
2405 struct cdr_object *b_party = ao2_find(active_cdrs_by_channel, bcand->candidate.snapshot->name, OBJ_KEY);
2407 /* Holy cow - no CDR? */
2408 b_party = cdr_object_alloc(bcand->candidate.snapshot);
2409 cdr_object_snapshot_copy(&b_party->party_a, &bcand->candidate);
2410 cdr_object_snapshot_copy(&b_party->party_b, &cdr->party_a);
2411 cdr_object_check_party_a_answer(b_party);
2412 ast_string_field_set(b_party, bridge, cdr->bridge);
2413 cdr_object_transition_state(b_party, &bridge_state_fn_table);
2414 ao2_link(active_cdrs_by_channel, b_party);
2416 bridge_candidate_add_to_cdr(b_party, cdr->bridge, &cdr->party_a);
2418 ao2_ref(b_party, -1);
2425 * \brief Handle creating bridge pairings for the \ref cdr_object that just
2427 * \param cdr The \ref cdr_object that just entered the bridge
2428 * \param bridge The \ref ast_bridge_snapshot representing the bridge it just entered
2430 static void handle_bridge_pairings(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge)
2432 RAII_VAR(struct ao2_container *, candidates,
2433 create_candidates_for_bridge(bridge),
2439 ao2_callback(candidates, OBJ_NODATA, bridge_candidate_process, cdr);
2442 /*! \brief Handle entering into a parking bridge
2443 * \param cdr The CDR to operate on
2444 * \param bridge The bridge the channel just entered
2445 * \param channel The channel snapshot
2447 static void handle_parking_bridge_enter_message(struct cdr_object *cdr,
2448 struct ast_bridge_snapshot *bridge,
2449 struct ast_channel_snapshot *channel)
2451 RAII_VAR(struct module_config *, mod_cfg,
2452 ao2_global_obj_ref(module_configs), ao2_cleanup);
2454 struct cdr_object *it_cdr;
2455 struct cdr_object *new_cdr;
2459 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2460 if (it_cdr->fn_table->process_parking_bridge_enter) {
2461 res &= it_cdr->fn_table->process_parking_bridge_enter(it_cdr, bridge, channel);
2463 if (it_cdr->fn_table->process_party_a) {
2464 CDR_DEBUG(mod_cfg, "%p - Updating Party A %s snapshot\n", it_cdr,
2466 it_cdr->fn_table->process_party_a(it_cdr, channel);
2471 /* No one handled it - we need a new one! */
2472 new_cdr = cdr_object_create_and_append(cdr);
2474 /* Let the single state transition us to Parked */
2475 cdr_object_transition_state(new_cdr, &single_state_fn_table);
2476 new_cdr->fn_table->process_parking_bridge_enter(new_cdr, bridge, channel);
2482 /*! \brief Handle a bridge enter message for a 'normal' bridge
2483 * \param cdr The CDR to operate on
2484 * \param bridge The bridge the channel just entered
2485 * \param channel The channel snapshot
2487 static void handle_standard_bridge_enter_message(struct cdr_object *cdr,
2488 struct ast_bridge_snapshot *bridge,
2489 struct ast_channel_snapshot *channel)
2491 RAII_VAR(struct module_config *, mod_cfg,
2492 ao2_global_obj_ref(module_configs), ao2_cleanup);
2493 enum process_bridge_enter_results result;
2494 struct cdr_object *it_cdr;
2495 struct cdr_object *new_cdr;
2496 struct cdr_object *handled_cdr = NULL;
2500 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2501 if (it_cdr->fn_table->process_party_a) {
2502 CDR_DEBUG(mod_cfg, "%p - Updating Party A %s snapshot\n", it_cdr,
2504 it_cdr->fn_table->process_party_a(it_cdr, channel);
2507 /* Notify all states that they have entered a bridge */
2508 if (it_cdr->fn_table->process_bridge_enter) {
2509 CDR_DEBUG(mod_cfg, "%p - Processing bridge enter for %s\n", it_cdr,
2511 result = it_cdr->fn_table->process_bridge_enter(it_cdr, bridge, channel);
2513 case BRIDGE_ENTER_ONLY_PARTY:
2515 case BRIDGE_ENTER_OBTAINED_PARTY_B:
2517 handled_cdr = it_cdr;
2520 case BRIDGE_ENTER_NEED_CDR:
2523 case BRIDGE_ENTER_NO_PARTY_B:
2524 /* We didn't win on any - end this CDR. If someone else comes in later
2525 * that is Party B to this CDR, it can re-activate this CDR.
2528 handled_cdr = it_cdr;
2530 cdr_object_finalize(cdr);
2536 /* Create the new matchings, but only for either:
2537 * * The first CDR in the chain that handled it. This avoids issues with
2539 * * If no one handled it, the last CDR in the chain. This would occur if
2540 * a CDR joined a bridge and it wasn't Party A for anyone. We still need
2541 * to make pairings with everyone in the bridge.
2544 handle_bridge_pairings(handled_cdr, bridge);
2546 /* Nothing handled it - we need a new one! */
2547 new_cdr = cdr_object_create_and_append(cdr);
2549 /* This is guaranteed to succeed: the new CDR is created in the single state
2550 * and will be able to handle the bridge enter message
2552 handle_standard_bridge_enter_message(cdr, bridge, channel);
2559 * \brief Handler for Stasis-Core bridge enter messages
2560 * \param data Passed on
2561 * \param sub The stasis subscription for this message callback
2562 * \param topic The topic this message was published for
2563 * \param message The message - hopefully a bridge one!
2565 static void handle_bridge_enter_message(void *data, struct stasis_subscription *sub,
2566 struct stasis_topic *topic, struct stasis_message *message)
2568 struct ast_bridge_blob *update = stasis_message_data(message);
2569 struct ast_bridge_snapshot *bridge = update->bridge;
2570 struct ast_channel_snapshot *channel = update->channel;
2571 RAII_VAR(struct cdr_object *, cdr,
2572 ao2_find(active_cdrs_by_channel, channel->name, OBJ_KEY),
2574 RAII_VAR(struct module_config *, mod_cfg,
2575 ao2_global_obj_ref(module_configs), ao2_cleanup);
2577 if (filter_bridge_messages(bridge)) {
2581 if (filter_channel_snapshot(channel)) {
2585 CDR_DEBUG(mod_cfg, "Bridge Enter message for channel %s: %u.%08u\n",
2587 (unsigned int)stasis_message_timestamp(message)->tv_sec,
2588 (unsigned int)stasis_message_timestamp(message)->tv_usec);
2591 ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", channel->name);
2595 if (!strcmp(bridge->subclass, "parking")) {
2596 handle_parking_bridge_enter_message(cdr, bridge, channel);
2598 handle_standard_bridge_enter_message(cdr, bridge, channel);
2603 * \brief Handler for when a channel is parked
2604 * \param data Passed on
2605 * \param sub The stasis subscription for this message callback
2606 * \param topic The topic this message was published for
2607 * \param message The message about who got parked
2609 static void handle_parked_call_message(void *data, struct stasis_subscription *sub,
2610 struct stasis_topic *topic, struct stasis_message *message)
2612 struct ast_parked_call_payload *payload = stasis_message_data(message);
2613 struct ast_channel_snapshot *channel = payload->parkee;
2614 RAII_VAR(struct cdr_object *, cdr, NULL, ao2_cleanup);
2615 RAII_VAR(struct module_config *, mod_cfg,
2616 ao2_global_obj_ref(module_configs), ao2_cleanup);
2617 struct cdr_object *it_cdr;
2619 /* Anything other than getting parked will be handled by other updates */
2620 if (payload->event_type != PARKED_CALL) {
2624 /* No one got parked? */
2629 CDR_DEBUG(mod_cfg, "Parked Call message for channel %s: %u.%08u\n",
2631 (unsigned int)stasis_message_timestamp(message)->tv_sec,
2632 (unsigned int)stasis_message_timestamp(message)->tv_usec);
2634 cdr = ao2_find(active_cdrs_by_channel, channel->name, OBJ_KEY);
2636 ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", channel->name);
2642 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2643 if (it_cdr->fn_table->process_parked_channel) {
2644 it_cdr->fn_table->process_parked_channel(it_cdr, payload);
2652 struct ast_cdr_config *ast_cdr_get_config(void)
2654 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
2655 ao2_ref(mod_cfg->general, +1);
2656 return mod_cfg->general;
2659 void ast_cdr_set_config(struct ast_cdr_config *config)
2661 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
2662 ao2_cleanup(mod_cfg->general);
2663 mod_cfg->general = config;
2664 ao2_ref(mod_cfg->general, +1);
2667 int ast_cdr_is_enabled(void)
2669 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
2670 return ast_test_flag(&mod_cfg->general->settings, CDR_ENABLED);
2673 int ast_cdr_register(const char *name, const char *desc, ast_cdrbe be)
2675 struct cdr_beitem *i = NULL;
2681 ast_log(LOG_WARNING, "CDR engine '%s' lacks backend\n", name);
2685 AST_RWLIST_WRLOCK(&be_list);
2686 AST_RWLIST_TRAVERSE(&be_list, i, list) {
2687 if (!strcasecmp(name, i->name)) {
2688 ast_log(LOG_WARNING, "Already have a CDR backend called '%s'\n", name);
2689 AST_RWLIST_UNLOCK(&be_list);
2694 if (!(i = ast_calloc(1, sizeof(*i))))
2698 ast_copy_string(i->name, name, sizeof(i->name));
2699 ast_copy_string(i->desc, desc, sizeof(i->desc));
2701 AST_RWLIST_INSERT_HEAD(&be_list, i, list);
2702 AST_RWLIST_UNLOCK(&be_list);
2707 void ast_cdr_unregister(const char *name)
2709 struct cdr_beitem *i = NULL;
2711 AST_RWLIST_WRLOCK(&be_list);
2712 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&be_list, i, list) {
2713 if (!strcasecmp(name, i->name)) {
2714 AST_RWLIST_REMOVE_CURRENT(list);
2718 AST_RWLIST_TRAVERSE_SAFE_END;
2719 AST_RWLIST_UNLOCK(&be_list);
2722 ast_verb(2, "Unregistered '%s' CDR backend\n", name);
2727 struct ast_cdr *ast_cdr_dup(struct ast_cdr *cdr)
2729 struct ast_cdr *newcdr;
2734 newcdr = ast_cdr_alloc();
2740 AST_LIST_HEAD_INIT_NOLOCK(&newcdr->varshead);
2741 copy_variables(&newcdr->varshead, &cdr->varshead);
2742 newcdr->next = NULL;
2747 static const char *cdr_format_var_internal(struct ast_cdr *cdr, const char *name)
2749 struct ast_var_t *variables;
2751 if (ast_strlen_zero(name)) {
2755 AST_LIST_TRAVERSE(&cdr->varshead, variables, entries) {
2756 if (!strcasecmp(name, ast_var_name(variables))) {
2757 return ast_var_value(variables);
2764 static void cdr_get_tv(struct timeval when, const char *fmt, char *buf, int bufsize)
2766 if (fmt == NULL) { /* raw mode */
2767 snprintf(buf, bufsize, "%ld.%06ld", (long)when.tv_sec, (long)when.tv_usec);
2769 buf[0] = '\0';/* Ensure the buffer is initialized. */
2773 ast_localtime(&when, &tm, NULL);
2774 ast_strftime(buf, bufsize, fmt, &tm);
2779 void ast_cdr_format_var(struct ast_cdr *cdr, const char *name, char **ret, char *workspace, int workspacelen, int raw)
2781 const char *fmt = "%Y-%m-%d %T";
2790 if (!strcasecmp(name, "clid")) {
2791 ast_copy_string(workspace, cdr->clid, workspacelen);
2792 } else if (!strcasecmp(name, "src")) {
2793 ast_copy_string(workspace, cdr->src, workspacelen);
2794 } else if (!strcasecmp(name, "dst")) {
2795 ast_copy_string(workspace, cdr->dst, workspacelen);
2796 } else if (!strcasecmp(name, "dcontext")) {
2797 ast_copy_string(workspace, cdr->dcontext, workspacelen);
2798 } else if (!strcasecmp(name, "channel")) {
2799 ast_copy_string(workspace, cdr->channel, workspacelen);
2800 } else if (!strcasecmp(name, "dstchannel")) {
2801 ast_copy_string(workspace, cdr->dstchannel, workspacelen);
2802 } else if (!strcasecmp(name, "lastapp")) {
2803 ast_copy_string(workspace, cdr->lastapp, workspacelen);
2804 } else if (!strcasecmp(name, "lastdata")) {
2805 ast_copy_string(workspace, cdr->lastdata, workspacelen);
2806 } else if (!strcasecmp(name, "start")) {
2807 cdr_get_tv(cdr->start, raw ? NULL : fmt, workspace, workspacelen);
2808 } else if (!strcasecmp(name, "answer")) {
2809 cdr_get_tv(cdr->answer, raw ? NULL : fmt, workspace, workspacelen);
2810 } else if (!strcasecmp(name, "end")) {
2811 cdr_get_tv(cdr->end, raw ? NULL : fmt, workspace, workspacelen);
2812 } else if (!strcasecmp(name, "duration")) {
2813 snprintf(workspace, workspacelen, "%ld", cdr->end.tv_sec != 0 ? cdr->duration : (long)ast_tvdiff_ms(ast_tvnow(), cdr->start) / 1000);
2814 } else if (!strcasecmp(name, "billsec")) {
2815 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);
2816 } else if (!strcasecmp(name, "disposition")) {
2818 snprintf(workspace, workspacelen, "%ld", cdr->disposition);
2820 ast_copy_string(workspace, ast_cdr_disp2str(cdr->disposition), workspacelen);
2822 } else if (!strcasecmp(name, "amaflags")) {
2824 snprintf(workspace, workspacelen, "%ld", cdr->amaflags);
2826 ast_copy_string(workspace, ast_channel_amaflags2string(cdr->amaflags), workspacelen);
2828 } else if (!strcasecmp(name, "accountcode")) {
2829 ast_copy_string(workspace, cdr->accountcode, workspacelen);
2830 } else if (!strcasecmp(name, "peeraccount")) {
2831 ast_copy_string(workspace, cdr->peeraccount, workspacelen);
2832 } else if (!strcasecmp(name, "uniqueid")) {
2833 ast_copy_string(workspace, cdr->uniqueid, workspacelen);
2834 } else if (!strcasecmp(name, "linkedid")) {
2835 ast_copy_string(workspace, cdr->linkedid, workspacelen);
2836 } else if (!strcasecmp(name, "userfield")) {
2837 ast_copy_string(workspace, cdr->userfield, workspacelen);
2838 } else if (!strcasecmp(name, "sequence")) {
2839 snprintf(workspace, workspacelen, "%d", cdr->sequence);
2840 } else if ((varbuf = cdr_format_var_internal(cdr, name))) {
2841 ast_copy_string(workspace, varbuf, workspacelen);
2843 workspace[0] = '\0';
2846 if (!ast_strlen_zero(workspace)) {
2853 * \brief Callback that finds all CDRs that reference a particular channel
2855 static int cdr_object_select_all_by_channel_cb(void *obj, void *arg, int flags)
2857 struct cdr_object *cdr = obj;
2858 const char *name = arg;
2860 if (!strcasecmp(cdr->party_a.snapshot->name, name) ||
2861 (cdr->party_b.snapshot && !strcasecmp(cdr->party_b.snapshot->name, name))) {
2867 /* Read Only CDR variables */
2868 static const char * const cdr_readonly_vars[] = {
2892 int ast_cdr_setvar(const char *channel_name, const char *name, const char *value)
2894 struct cdr_object *cdr;
2895 struct cdr_object *it_cdr;
2896 struct ao2_iterator *it_cdrs;
2897 char *arg = ast_strdupa(channel_name);
2900 for (x = 0; cdr_readonly_vars[x]; x++) {
2901 if (!strcasecmp(name, cdr_readonly_vars[x])) {
2902 ast_log(LOG_ERROR, "Attempt to set the '%s' read-only variable!\n", name);
2907 it_cdrs = ao2_callback(active_cdrs_by_channel, OBJ_MULTIPLE, cdr_object_select_all_by_channel_cb, arg);
2909 ast_log(AST_LOG_ERROR, "Unable to find CDR for channel %s\n", channel_name);
2913 for (; (cdr = ao2_iterator_next(it_cdrs)); ao2_unlock(cdr), ao2_cleanup(cdr)) {
2915 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2916 struct varshead *headp = NULL;
2918 if (it_cdr->fn_table == &finalized_state_fn_table) {
2921 if (!strcasecmp(channel_name, it_cdr->party_a.snapshot->name)) {
2922 headp = &it_cdr->party_a.variables;
2923 } else if (it_cdr->party_b.snapshot
2924 && !strcasecmp(channel_name, it_cdr->party_b.snapshot->name)) {
2925 headp = &it_cdr->party_b.variables;
2928 set_variable(headp, name, value);
2932 ao2_iterator_destroy(it_cdrs);
2938 * \brief Format a variable on a \ref cdr_object
2940 static void cdr_object_format_var_internal(struct cdr_object *cdr, const char *name, char *value, size_t length)
2942 struct ast_var_t *variable;
2944 AST_LIST_TRAVERSE(&cdr->party_a.variables, variable, entries) {
2945 if (!strcasecmp(name, ast_var_name(variable))) {
2946 ast_copy_string(value, ast_var_value(variable), length);
2955 * \brief Format one of the standard properties on a \ref cdr_object
2957 static int cdr_object_format_property(struct cdr_object *cdr_obj, const char *name, char *value, size_t length)
2959 struct ast_channel_snapshot *party_a = cdr_obj->party_a.snapshot;
2960 struct ast_channel_snapshot *party_b = cdr_obj->party_b.snapshot;
2962 if (!strcasecmp(name, "clid")) {
2963 ast_callerid_merge(value, length, party_a->caller_name, party_a->caller_number, "");
2964 } else if (!strcasecmp(name, "src")) {
2965 ast_copy_string(value, party_a->caller_number, length);
2966 } else if (!strcasecmp(name, "dst")) {
2967 ast_copy_string(value, party_a->exten, length);
2968 } else if (!strcasecmp(name, "dcontext")) {
2969 ast_copy_string(value, party_a->context, length);
2970 } else if (!strcasecmp(name, "channel")) {
2971 ast_copy_string(value, party_a->name, length);
2972 } else if (!strcasecmp(name, "dstchannel")) {
2974 ast_copy_string(value, party_b->name, length);
2976 ast_copy_string(value, "", length);
2978 } else if (!strcasecmp(name, "lastapp")) {
2979 ast_copy_string(value, party_a->appl, length);
2980 } else if (!strcasecmp(name, "lastdata")) {
2981 ast_copy_string(value, party_a->data, length);
2982 } else if (!strcasecmp(name, "start")) {
2983 cdr_get_tv(cdr_obj->start, NULL, value, length);
2984 } else if (!strcasecmp(name, "answer")) {
2985 cdr_get_tv(cdr_obj->answer, NULL, value, length);
2986 } else if (!strcasecmp(name, "end")) {
2987 cdr_get_tv(cdr_obj->end, NULL, value, length);
2988 } else if (!strcasecmp(name, "duration")) {
2989 snprintf(value, length, "%ld", cdr_object_get_duration(cdr_obj));
2990 } else if (!strcasecmp(name, "billsec")) {
2991 snprintf(value, length, "%ld", cdr_object_get_billsec(cdr_obj));
2992 } else if (!strcasecmp(name, "disposition")) {
2993 snprintf(value, length, "%d", cdr_obj->disposition);
2994 } else if (!strcasecmp(name, "amaflags")) {
2995 snprintf(value, length, "%d", party_a->amaflags);
2996 } else if (!strcasecmp(name, "accountcode")) {
2997 ast_copy_string(value, party_a->accountcode, length);
2998 } else if (!strcasecmp(name, "peeraccount")) {
3000 ast_copy_string(value, party_b->accountcode, length);
3002 ast_copy_string(value, "", length);
3004 } else if (!strcasecmp(name, "uniqueid")) {
3005 ast_copy_string(value, party_a->uniqueid, length);
3006 } else if (!strcasecmp(name, "linkedid")) {
3007 ast_copy_string(value, cdr_obj->linkedid, length);
3008 } else if (!strcasecmp(name, "userfield")) {
3009 ast_copy_string(value, cdr_obj->party_a.userfield, length);
3010 } else if (!strcasecmp(name, "sequence")) {
3011 snprintf(value, length, "%d", cdr_obj->sequence);
3019 int ast_cdr_getvar(const char *channel_name, const char *name, char *value, size_t length)
3021 RAII_VAR(struct cdr_object *, cdr,
3022 ao2_find(active_cdrs_by_channel, channel_name, OBJ_KEY),
3024 struct cdr_object *cdr_obj;
3027 ast_log(AST_LOG_ERROR, "Unable to find CDR for channel %s\n", channel_name);
3031 if (ast_strlen_zero(name)) {
3037 cdr_obj = cdr->last;
3038 if (cdr_object_format_property(cdr_obj, name, value, length)) {
3039 /* Property failed; attempt variable */
3040 cdr_object_format_var_internal(cdr_obj, name, value, length);
3048 int ast_cdr_serialize_variables(const char *channel_name, struct ast_str **buf, char delim, char sep)
3050 RAII_VAR(struct cdr_object *, cdr,
3051 ao2_find(active_cdrs_by_channel, channel_name, OBJ_KEY),
3053 struct cdr_object *it_cdr;
3054 struct ast_var_t *variable;
3056 RAII_VAR(char *, workspace, ast_malloc(256), ast_free);
3057 int total = 0, x = 0, i;
3064 ast_log(AST_LOG_ERROR, "Unable to find CDR for channel %s\n", channel_name);
3068 ast_str_reset(*buf);
3071 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3073 ast_str_append(buf, 0, "\n");
3075 AST_LIST_TRAVERSE(&it_cdr->party_a.variables, variable, entries) {
3076 if (!(var = ast_var_name(variable))) {
3080 if (ast_str_append(buf, 0, "level %d: %s%c%s%c", x, var, delim, S_OR(ast_var_value(variable), ""), sep) < 0) {
3081 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
3088 for (i = 0; cdr_readonly_vars[i]; i++) {
3089 if (cdr_object_format_property(it_cdr, cdr_readonly_vars[i], workspace, sizeof(workspace))) {
3090 /* Unhandled read-only CDR variable. */
3095 if (!ast_strlen_zero(workspace)
3096 && ast_str_append(buf, 0, "level %d: %s%c%s%c", x, cdr_readonly_vars[i], delim, workspace, sep) < 0) {
3097 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
3107 void ast_cdr_free(struct ast_cdr *cdr)
3110 struct ast_cdr *next = cdr->next;
3112 free_variables(&cdr->varshead);
3118 struct ast_cdr *ast_cdr_alloc(void)
3122 x = ast_calloc(1, sizeof(*x));
3126 const char *ast_cdr_disp2str(int disposition)
3128 switch (disposition) {
3130 return "NO ANSWER"; /* by default, for backward compatibility */
3131 case AST_CDR_NOANSWER:
3133 case AST_CDR_FAILED:
3137 case AST_CDR_ANSWERED:
3139 case AST_CDR_CONGESTION:
3140 return "CONGESTION";
3145 struct party_b_userfield_update {
3146 const char *channel_name;
3147 const char *userfield;
3150 /*! \brief Callback used to update the userfield on Party B on all CDRs */
3151 static int cdr_object_update_party_b_userfield_cb(void *obj, void *arg, int flags)
3153 struct cdr_object *cdr = obj;
3154 struct party_b_userfield_update *info = arg;
3155 struct cdr_object *it_cdr;
3156 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3157 if (it_cdr->fn_table == &finalized_state_fn_table) {
3160 if (it_cdr->party_b.snapshot
3161 && !strcasecmp(it_cdr->party_b.snapshot->name, info->channel_name)) {
3162 strcpy(it_cdr->party_b.userfield, info->userfield);
3168 void ast_cdr_setuserfield(const char *channel_name, const char *userfield)
3170 RAII_VAR(struct cdr_object *, cdr,
3171 ao2_find(active_cdrs_by_channel, channel_name, OBJ_KEY),
3173 struct party_b_userfield_update party_b_info = {
3174 .channel_name = channel_name,
3175 .userfield = userfield,
3177 struct cdr_object *it_cdr;
3179 /* Handle Party A */
3182 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3183 if (it_cdr->fn_table == &finalized_state_fn_table) {
3186 strcpy(it_cdr->party_a.userfield, userfield);
3191 /* Handle Party B */
3192 ao2_callback(active_cdrs_by_channel, OBJ_NODATA,
3193 cdr_object_update_party_b_userfield_cb,
3198 static void post_cdr(struct ast_cdr *cdr)
3200 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
3201 struct cdr_beitem *i;
3203 for (; cdr ; cdr = cdr->next) {
3204 /* For people, who don't want to see unanswered single-channel events */
3205 if (!ast_test_flag(&mod_cfg->general->settings, CDR_UNANSWERED) &&
3206 cdr->disposition < AST_CDR_ANSWERED &&
3207 (ast_strlen_zero(cdr->channel) || ast_strlen_zero(cdr->dstchannel))) {
3208 ast_debug(1, "Skipping CDR for %s since we weren't answered\n", cdr->channel);
3212 if (ast_test_flag(cdr, AST_CDR_FLAG_DISABLE)) {
3215 AST_RWLIST_RDLOCK(&be_list);
3216 AST_RWLIST_TRAVERSE(&be_list, i, list) {
3219 AST_RWLIST_UNLOCK(&be_list);
3223 int ast_cdr_set_property(const char *channel_name, enum ast_cdr_options option)
3225 RAII_VAR(struct cdr_object *, cdr,
3226 ao2_find(active_cdrs_by_channel, channel_name, OBJ_KEY),
3228 struct cdr_object *it_cdr;
3235 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3236 if (it_cdr->fn_table == &finalized_state_fn_table) {
3239 /* Note: in general, set the flags on both the CDR record as well as the
3240 * Party A. Sometimes all we have is the Party A to look at.
3242 ast_set_flag(&it_cdr->flags, option);
3243 ast_set_flag(&it_cdr->party_a, option);
3250 int ast_cdr_clear_property(const char *channel_name, enum ast_cdr_options option)
3252 RAII_VAR(struct cdr_object *, cdr,
3253 ao2_find(active_cdrs_by_channel, channel_name, OBJ_KEY),
3255 struct cdr_object *it_cdr;
3262 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3263 if (it_cdr->fn_table == &finalized_state_fn_table) {
3266 ast_clear_flag(&it_cdr->flags, option);
3273 int ast_cdr_reset(const char *channel_name, struct ast_flags *options)
3275 RAII_VAR(struct cdr_object *, cdr,
3276 ao2_find(active_cdrs_by_channel, channel_name, OBJ_KEY),
3278 struct ast_var_t *vardata;
3279 struct cdr_object *it_cdr;