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 id */
331 static struct ao2_container *active_cdrs_by_channel;
333 /*! \brief Message router for stasis messages regarding channel state */
334 static struct stasis_message_router *stasis_router;
336 /*! \brief Our subscription for bridges */
337 static struct stasis_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(uniqueid); /*!< Unique id of party A. Cached here as it is the primary key of this CDR */
686 AST_STRING_FIELD(name); /*!< Channel name of party A. Cached here as the party A address may change */
687 AST_STRING_FIELD(bridge); /*!< The bridge the party A happens to be in. */
688 AST_STRING_FIELD(appl); /*!< The last accepted application party A was in */
689 AST_STRING_FIELD(data); /*!< The data for the last accepted application party A was in */
691 struct cdr_object *next; /*!< The next CDR object in the chain */
692 struct cdr_object *last; /*!< The last CDR object in the chain */
696 * \brief Copy variables from one list to another
697 * \param to_list destination
698 * \param from_list source
699 * \retval The number of copied variables
701 static int copy_variables(struct varshead *to_list, struct varshead *from_list)
703 struct ast_var_t *variables;
704 struct ast_var_t *newvariable;
709 AST_LIST_TRAVERSE(from_list, variables, entries) {
710 var = ast_var_name(variables);
711 if (ast_strlen_zero(var)) {
714 val = ast_var_value(variables);
715 if (ast_strlen_zero(val)) {
718 newvariable = ast_var_assign(var, val);
720 AST_LIST_INSERT_HEAD(to_list, newvariable, entries);
729 * \brief Delete all variables from a variable list
730 * \param headp The head pointer to the variable list to delete
732 static void free_variables(struct varshead *headp)
734 struct ast_var_t *vardata;
736 while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries))) {
737 ast_var_delete(vardata);
742 * \brief Copy a snapshot and its details
743 * \param dst The destination
744 * \param src The source
746 static void cdr_object_snapshot_copy(struct cdr_object_snapshot *dst, struct cdr_object_snapshot *src)
749 ao2_t_ref(dst->snapshot, -1, "release old snapshot during copy");
751 dst->snapshot = src->snapshot;
752 ao2_t_ref(dst->snapshot, +1, "bump new snapshot during copy");
753 strcpy(dst->userfield, src->userfield);
754 dst->flags = src->flags;
755 copy_variables(&dst->variables, &src->variables);
759 * \brief Transition a \ref cdr_object to a new state
760 * \param cdr The \ref cdr_object to transition
761 * \param fn_table The \ref cdr_object_fn_table state to go to
763 static void cdr_object_transition_state(struct cdr_object *cdr, struct cdr_object_fn_table *fn_table)
765 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
767 CDR_DEBUG(mod_cfg, "%p - Transitioning CDR for %s from state %s to %s\n",
768 cdr, cdr->party_a.snapshot->name,
769 cdr->fn_table ? cdr->fn_table->name : "NONE", fn_table->name);
770 cdr->fn_table = fn_table;
771 if (cdr->fn_table->init_function) {
772 cdr->fn_table->init_function(cdr);
776 * \brief Hash function for containers of CDRs indexing by Party A uniqueid */
777 static int cdr_object_channel_hash_fn(const void *obj, const int flags)
779 const struct cdr_object *cdr;
782 switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
794 return ast_str_case_hash(key);
798 * \brief Comparison function for containers of CDRs indexing by Party A uniqueid
800 static int cdr_object_channel_cmp_fn(void *obj, void *arg, int flags)
802 struct cdr_object *left = obj;
803 struct cdr_object *right = arg;
804 const char *right_key = arg;
807 switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
809 right_key = right->uniqueid;
812 cmp = strcmp(left->uniqueid, right_key);
814 case OBJ_PARTIAL_KEY:
816 * We could also use a partial key struct containing a length
817 * so strlen() does not get called for every comparison instead.
819 cmp = strncmp(left->uniqueid, right_key, strlen(right_key));
822 /* Sort can only work on something with a full or partial key. */
827 return cmp ? 0 : CMP_MATCH;
831 * \brief \ref cdr_object Destructor
833 static void cdr_object_dtor(void *obj)
835 struct cdr_object *cdr = obj;
836 struct ast_var_t *it_var;
838 ao2_cleanup(cdr->party_a.snapshot);
839 ao2_cleanup(cdr->party_b.snapshot);
840 while ((it_var = AST_LIST_REMOVE_HEAD(&cdr->party_a.variables, entries))) {
841 ast_var_delete(it_var);
843 while ((it_var = AST_LIST_REMOVE_HEAD(&cdr->party_b.variables, entries))) {
844 ast_var_delete(it_var);
846 ast_string_field_free_memory(cdr);
848 ao2_cleanup(cdr->next);
852 * \brief \ref cdr_object constructor
853 * \param chan The \ref ast_channel_snapshot that is the CDR's Party A
855 * This implicitly sets the state of the newly created CDR to the Single state
856 * (\ref single_state_fn_table)
858 static struct cdr_object *cdr_object_alloc(struct ast_channel_snapshot *chan)
860 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
861 struct cdr_object *cdr;
863 ast_assert(chan != NULL);
865 cdr = ao2_alloc(sizeof(*cdr), cdr_object_dtor);
870 if (ast_string_field_init(cdr, 64)) {
874 ast_string_field_set(cdr, uniqueid, chan->uniqueid);
875 ast_string_field_set(cdr, name, chan->name);
876 ast_string_field_set(cdr, linkedid, chan->linkedid);
877 cdr->disposition = AST_CDR_NULL;
878 cdr->sequence = ast_atomic_fetchadd_int(&global_cdr_sequence, +1);
880 cdr->party_a.snapshot = chan;
881 ao2_t_ref(cdr->party_a.snapshot, +1, "bump snapshot during CDR creation");
883 CDR_DEBUG(mod_cfg, "%p - Created CDR for channel %s\n", cdr, chan->name);
885 cdr_object_transition_state(cdr, &single_state_fn_table);
891 * \brief Create a new \ref cdr_object and append it to an existing chain
892 * \param cdr The \ref cdr_object to append to
894 static struct cdr_object *cdr_object_create_and_append(struct cdr_object *cdr)
896 struct cdr_object *new_cdr;
897 struct cdr_object *it_cdr;
898 struct cdr_object *cdr_last;
900 cdr_last = cdr->last;
901 new_cdr = cdr_object_alloc(cdr_last->party_a.snapshot);
905 new_cdr->disposition = AST_CDR_NULL;
907 /* Copy over the linkedid, as it may have changed */
908 ast_string_field_set(new_cdr, linkedid, cdr_last->linkedid);
909 ast_string_field_set(new_cdr, appl, cdr_last->appl);
910 ast_string_field_set(new_cdr, data, cdr_last->data);
912 /* Copy over other Party A information */
913 cdr_object_snapshot_copy(&new_cdr->party_a, &cdr_last->party_a);
915 /* Append the CDR to the end of the list */
916 for (it_cdr = cdr; it_cdr->next; it_cdr = it_cdr->next) {
917 it_cdr->last = new_cdr;
919 it_cdr->last = new_cdr;
920 it_cdr->next = new_cdr;
926 * \brief Return whether or not a channel has changed its state in the dialplan, subject
927 * to endbeforehexten logic
929 * \param old_snapshot The previous state
930 * \param new_snapshot The new state
932 * \retval 0 if the state has not changed
933 * \retval 1 if the state changed
935 static int snapshot_cep_changed(struct ast_channel_snapshot *old_snapshot,
936 struct ast_channel_snapshot *new_snapshot)
938 RAII_VAR(struct module_config *, mod_cfg,
939 ao2_global_obj_ref(module_configs), ao2_cleanup);
941 /* If we ignore hangup logic, don't indicate that we're executing anything new */
942 if (ast_test_flag(&mod_cfg->general->settings, CDR_END_BEFORE_H_EXTEN)
943 && ast_test_flag(&new_snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)) {
947 /* When Party A is originated to an application and the application exits, the stack
948 * will attempt to clear the application and restore the dummy originate application
949 * of "AppDialX". Ignore application changes to AppDialX as a result.
951 if (strcmp(new_snapshot->appl, old_snapshot->appl) && strncasecmp(new_snapshot->appl, "appdial", 7)
952 && (strcmp(new_snapshot->context, old_snapshot->context)
953 || strcmp(new_snapshot->exten, old_snapshot->exten)
954 || new_snapshot->priority != old_snapshot->priority)) {
962 * \brief Return whether or not a \ref ast_channel_snapshot is for a channel
963 * that was created as the result of a dial operation
965 * \retval 0 the channel was not created as the result of a dial
966 * \retval 1 the channel was created as the result of a dial
968 static int snapshot_is_dialed(struct ast_channel_snapshot *snapshot)
970 return (ast_test_flag(&snapshot->flags, AST_FLAG_OUTGOING)
971 && !(ast_test_flag(&snapshot->flags, AST_FLAG_ORIGINATED)));
975 * \brief Given two CDR snapshots, figure out who should be Party A for the
977 * \param left One of the snapshots
978 * \param right The other snapshot
979 * \retval The snapshot that won
981 static struct cdr_object_snapshot *cdr_object_pick_party_a(struct cdr_object_snapshot *left, struct cdr_object_snapshot *right)
983 /* Check whether or not the party is dialed. A dialed party is never the
984 * Party A with a party that was not dialed.
986 if (!snapshot_is_dialed(left->snapshot) && snapshot_is_dialed(right->snapshot)) {
988 } else if (snapshot_is_dialed(left->snapshot) && !snapshot_is_dialed(right->snapshot)) {
992 /* Try the Party A flag */
993 if (ast_test_flag(left, AST_CDR_FLAG_PARTY_A) && !ast_test_flag(right, AST_CDR_FLAG_PARTY_A)) {
995 } else if (!ast_test_flag(right, AST_CDR_FLAG_PARTY_A) && ast_test_flag(right, AST_CDR_FLAG_PARTY_A)) {
999 /* Neither party is dialed and neither has the Party A flag - defer to
1001 if (left->snapshot->creationtime.tv_sec < right->snapshot->creationtime.tv_sec) {
1003 } else if (left->snapshot->creationtime.tv_sec > right->snapshot->creationtime.tv_sec) {
1005 } else if (left->snapshot->creationtime.tv_usec > right->snapshot->creationtime.tv_usec) {
1008 /* Okay, fine, take the left one */
1014 * Compute the duration for a \ref cdr_object
1016 static long cdr_object_get_duration(struct cdr_object *cdr)
1018 return (long)(ast_tvdiff_ms(ast_tvzero(cdr->end) ? ast_tvnow() : cdr->end, cdr->start) / 1000);
1022 * \brief Compute the billsec for a \ref cdr_object
1024 static long cdr_object_get_billsec(struct cdr_object *cdr)
1026 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
1029 if (ast_tvzero(cdr->answer)) {
1032 ms = ast_tvdiff_ms(ast_tvzero(cdr->end) ? ast_tvnow() : cdr->end, cdr->answer);
1033 if (ast_test_flag(&mod_cfg->general->settings, CDR_INITIATED_SECONDS)
1034 && (ms % 1000 >= 500)) {
1035 ms = (ms / 1000) + 1;
1045 * \brief Set a variable on a CDR object
1047 * \param headp The header pointer to the variable to set
1048 * \param name The name of the variable
1049 * \param value The value of the variable
1051 static void set_variable(struct varshead *headp, const char *name, const char *value)
1053 struct ast_var_t *newvariable;
1055 AST_LIST_TRAVERSE_SAFE_BEGIN(headp, newvariable, entries) {
1056 if (!strcasecmp(ast_var_name(newvariable), name)) {
1057 AST_LIST_REMOVE_CURRENT(entries);
1058 ast_var_delete(newvariable);
1062 AST_LIST_TRAVERSE_SAFE_END;
1064 if (value && (newvariable = ast_var_assign(name, value))) {
1065 AST_LIST_INSERT_HEAD(headp, newvariable, entries);
1070 * \brief Create a chain of \ref ast_cdr objects from a chain of \ref cdr_object
1071 * suitable for consumption by the registered CDR backends
1072 * \param cdr The \ref cdr_object to convert to a public record
1073 * \retval A chain of \ref ast_cdr objects on success
1074 * \retval NULL on failure
1076 static struct ast_cdr *cdr_object_create_public_records(struct cdr_object *cdr)
1078 struct ast_cdr *pub_cdr = NULL, *cdr_prev = NULL;
1079 struct cdr_object *it_cdr;
1080 struct ast_var_t *it_var, *it_copy_var;
1081 struct ast_channel_snapshot *party_a;
1082 struct ast_channel_snapshot *party_b;
1083 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
1085 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
1086 struct ast_cdr *cdr_copy;
1088 /* Don't create records for CDRs where the party A was a dialed channel */
1089 if (snapshot_is_dialed(it_cdr->party_a.snapshot) && !it_cdr->party_b.snapshot) {
1090 CDR_DEBUG(mod_cfg, "%p - %s is dialed and has no Party B; discarding\n", it_cdr,
1091 it_cdr->party_a.snapshot->name);
1095 cdr_copy = ast_calloc(1, sizeof(*cdr_copy));
1101 party_a = it_cdr->party_a.snapshot;
1102 party_b = it_cdr->party_b.snapshot;
1105 ast_assert(party_a != NULL);
1106 ast_copy_string(cdr_copy->accountcode, party_a->accountcode, sizeof(cdr_copy->accountcode));
1107 cdr_copy->amaflags = party_a->amaflags;
1108 ast_copy_string(cdr_copy->channel, party_a->name, sizeof(cdr_copy->channel));
1109 ast_callerid_merge(cdr_copy->clid, sizeof(cdr_copy->clid), party_a->caller_name, party_a->caller_number, "");
1110 ast_copy_string(cdr_copy->src, party_a->caller_number, sizeof(cdr_copy->src));
1111 ast_copy_string(cdr_copy->uniqueid, party_a->uniqueid, sizeof(cdr_copy->uniqueid));
1112 ast_copy_string(cdr_copy->lastapp, it_cdr->appl, sizeof(cdr_copy->lastapp));
1113 ast_copy_string(cdr_copy->lastdata, it_cdr->data, sizeof(cdr_copy->lastdata));
1114 ast_copy_string(cdr_copy->dst, party_a->exten, sizeof(cdr_copy->dst));
1115 ast_copy_string(cdr_copy->dcontext, party_a->context, sizeof(cdr_copy->dcontext));
1119 ast_copy_string(cdr_copy->dstchannel, party_b->name, sizeof(cdr_copy->dstchannel));
1120 ast_copy_string(cdr_copy->peeraccount, party_b->accountcode, sizeof(cdr_copy->peeraccount));
1121 if (!ast_strlen_zero(it_cdr->party_b.userfield)) {
1122 snprintf(cdr_copy->userfield, sizeof(cdr_copy->userfield), "%s;%s", it_cdr->party_a.userfield, it_cdr->party_b.userfield);
1125 if (ast_strlen_zero(cdr_copy->userfield) && !ast_strlen_zero(it_cdr->party_a.userfield)) {
1126 ast_copy_string(cdr_copy->userfield, it_cdr->party_a.userfield, sizeof(cdr_copy->userfield));
1129 /* Timestamps/durations */
1130 cdr_copy->start = it_cdr->start;
1131 cdr_copy->answer = it_cdr->answer;
1132 cdr_copy->end = it_cdr->end;
1133 cdr_copy->billsec = cdr_object_get_billsec(it_cdr);
1134 cdr_copy->duration = cdr_object_get_duration(it_cdr);
1137 ast_copy_flags(cdr_copy, &it_cdr->flags, AST_FLAGS_ALL);
1138 ast_copy_string(cdr_copy->linkedid, it_cdr->linkedid, sizeof(cdr_copy->linkedid));
1139 cdr_copy->disposition = it_cdr->disposition;
1140 cdr_copy->sequence = it_cdr->sequence;
1143 copy_variables(&cdr_copy->varshead, &it_cdr->party_a.variables);
1144 AST_LIST_TRAVERSE(&it_cdr->party_b.variables, it_var, entries) {
1146 struct ast_var_t *newvariable;
1147 AST_LIST_TRAVERSE(&cdr_copy->varshead, it_copy_var, entries) {
1148 if (!strcasecmp(ast_var_name(it_var), ast_var_name(it_copy_var))) {
1153 if (!found && (newvariable = ast_var_assign(ast_var_name(it_var), ast_var_value(it_var)))) {
1154 AST_LIST_INSERT_TAIL(&cdr_copy->varshead, newvariable, entries);
1162 cdr_prev->next = cdr_copy;
1163 cdr_prev = cdr_copy;
1171 * \brief Dispatch a CDR.
1172 * \param cdr The \ref cdr_object to dispatch
1174 * This will create a \ref ast_cdr object and publish it to the various backends
1176 static void cdr_object_dispatch(struct cdr_object *cdr)
1178 RAII_VAR(struct module_config *, mod_cfg,
1179 ao2_global_obj_ref(module_configs), ao2_cleanup);
1180 struct ast_cdr *pub_cdr;
1182 CDR_DEBUG(mod_cfg, "%p - Dispatching CDR for Party A %s, Party B %s\n", cdr,
1183 cdr->party_a.snapshot->name,
1184 cdr->party_b.snapshot ? cdr->party_b.snapshot->name : "<none>");
1185 pub_cdr = cdr_object_create_public_records(cdr);
1186 cdr_detach(pub_cdr);
1190 * \brief Set the disposition on a \ref cdr_object based on a hangupcause code
1191 * \param cdr The \ref cdr_object
1192 * \param hangupcause The Asterisk hangup cause code
1194 static void cdr_object_set_disposition(struct cdr_object *cdr, int hangupcause)
1196 RAII_VAR(struct module_config *, mod_cfg,
1197 ao2_global_obj_ref(module_configs), ao2_cleanup);
1199 /* Change the disposition based on the hang up cause */
1200 switch (hangupcause) {
1201 case AST_CAUSE_BUSY:
1202 cdr->disposition = AST_CDR_BUSY;
1204 case AST_CAUSE_CONGESTION:
1205 if (!ast_test_flag(&mod_cfg->general->settings, CDR_CONGESTION)) {
1206 cdr->disposition = AST_CDR_FAILED;
1208 cdr->disposition = AST_CDR_CONGESTION;
1211 case AST_CAUSE_NO_ROUTE_DESTINATION:
1212 case AST_CAUSE_UNREGISTERED:
1213 cdr->disposition = AST_CDR_FAILED;
1215 case AST_CAUSE_NORMAL_CLEARING:
1216 case AST_CAUSE_NO_ANSWER:
1217 cdr->disposition = AST_CDR_NOANSWER;
1225 * \brief Finalize a CDR.
1227 * This function is safe to call multiple times. Note that you can call this
1228 * explicitly before going to the finalized state if there's a chance the CDR
1229 * will be re-activated, in which case the \ref cdr_object's end time should be
1230 * cleared. This function is implicitly called when a CDR transitions to the
1231 * finalized state and right before it is dispatched
1233 * \param cdr_object The CDR to finalize
1235 static void cdr_object_finalize(struct cdr_object *cdr)
1237 RAII_VAR(struct module_config *, mod_cfg,
1238 ao2_global_obj_ref(module_configs), ao2_cleanup);
1240 if (!ast_tvzero(cdr->end)) {
1243 cdr->end = ast_tvnow();
1245 if (cdr->disposition == AST_CDR_NULL) {
1246 if (!ast_tvzero(cdr->answer)) {
1247 cdr->disposition = AST_CDR_ANSWERED;
1248 } else if (cdr->party_a.snapshot->hangupcause) {
1249 cdr_object_set_disposition(cdr, cdr->party_a.snapshot->hangupcause);
1250 } else if (cdr->party_b.snapshot && cdr->party_b.snapshot->hangupcause) {
1251 cdr_object_set_disposition(cdr, cdr->party_b.snapshot->hangupcause);
1253 cdr->disposition = AST_CDR_FAILED;
1257 /* tv_usec is suseconds_t, which could be int or long */
1258 ast_debug(1, "Finalized CDR for %s - start %ld.%06ld answer %ld.%06ld end %ld.%06ld dispo %s\n",
1259 cdr->party_a.snapshot->name,
1261 (long)cdr->start.tv_usec,
1263 (long)cdr->answer.tv_usec,
1265 (long)cdr->end.tv_usec,
1266 ast_cdr_disp2str(cdr->disposition));
1270 * \brief Check to see if a CDR needs to move to the finalized state because
1271 * its Party A hungup.
1273 static void cdr_object_check_party_a_hangup(struct cdr_object *cdr)
1275 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
1277 if (ast_test_flag(&mod_cfg->general->settings, CDR_END_BEFORE_H_EXTEN)
1278 && ast_test_flag(&cdr->party_a.snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)) {
1279 cdr_object_finalize(cdr);
1282 if (ast_test_flag(&cdr->party_a.snapshot->flags, AST_FLAG_DEAD)
1283 && cdr->fn_table != &finalized_state_fn_table) {
1284 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1289 * \brief Check to see if a CDR needs to be answered based on its Party A.
1290 * Note that this is safe to call as much as you want - we won't answer twice
1292 static void cdr_object_check_party_a_answer(struct cdr_object *cdr) {
1293 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
1295 if (cdr->party_a.snapshot->state == AST_STATE_UP && ast_tvzero(cdr->answer)) {
1296 cdr->answer = ast_tvnow();
1297 /* tv_usec is suseconds_t, which could be int or long */
1298 CDR_DEBUG(mod_cfg, "%p - Set answered time to %ld.%06ld\n", cdr,
1300 (long)cdr->answer.tv_usec);
1304 /* \brief Set Caller ID information on a CDR */
1305 static void cdr_object_update_cid(struct cdr_object_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot)
1307 if (!old_snapshot->snapshot) {
1308 set_variable(&old_snapshot->variables, "dnid", new_snapshot->caller_dnid);
1309 set_variable(&old_snapshot->variables, "callingsubaddr", new_snapshot->caller_subaddr);
1310 set_variable(&old_snapshot->variables, "calledsubaddr", new_snapshot->dialed_subaddr);
1313 if (!strcmp(old_snapshot->snapshot->caller_dnid, new_snapshot->caller_dnid)) {
1314 set_variable(&old_snapshot->variables, "dnid", new_snapshot->caller_dnid);
1316 if (!strcmp(old_snapshot->snapshot->caller_subaddr, new_snapshot->caller_subaddr)) {
1317 set_variable(&old_snapshot->variables, "callingsubaddr", new_snapshot->caller_subaddr);
1319 if (!strcmp(old_snapshot->snapshot->dialed_subaddr, new_snapshot->dialed_subaddr)) {
1320 set_variable(&old_snapshot->variables, "calledsubaddr", new_snapshot->dialed_subaddr);
1325 * \brief Swap an old \ref cdr_object_snapshot's \ref ast_channel_snapshot for
1326 * a new \ref ast_channel_snapshot
1327 * \param old_snapshot The old \ref cdr_object_snapshot
1328 * \param new_snapshot The new \ref ast_channel_snapshot for old_snapshot
1330 static void cdr_object_swap_snapshot(struct cdr_object_snapshot *old_snapshot,
1331 struct ast_channel_snapshot *new_snapshot)
1333 cdr_object_update_cid(old_snapshot, new_snapshot);
1334 if (old_snapshot->snapshot) {
1335 ao2_t_ref(old_snapshot->snapshot, -1, "Drop ref for swap");
1337 ao2_t_ref(new_snapshot, +1, "Bump ref for swap");
1338 old_snapshot->snapshot = new_snapshot;
1341 /* BASE METHOD IMPLEMENTATIONS */
1343 static int base_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
1345 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
1347 ast_assert(strcasecmp(snapshot->name, cdr->party_a.snapshot->name) == 0);
1348 cdr_object_swap_snapshot(&cdr->party_a, snapshot);
1350 /* When Party A is originated to an application and the application exits, the stack
1351 * will attempt to clear the application and restore the dummy originate application
1352 * of "AppDialX". Prevent that, and any other application changes we might not want
1355 if (!ast_strlen_zero(snapshot->appl)
1356 && (strncasecmp(snapshot->appl, "appdial", 7) || ast_strlen_zero(cdr->appl))
1357 && !ast_test_flag(&cdr->flags, AST_CDR_LOCK_APP)) {
1358 ast_string_field_set(cdr, appl, snapshot->appl);
1359 ast_string_field_set(cdr, data, snapshot->data);
1362 ast_string_field_set(cdr, linkedid, snapshot->linkedid);
1363 cdr_object_check_party_a_answer(cdr);
1364 cdr_object_check_party_a_hangup(cdr);
1369 static int base_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1371 /* In general, most things shouldn't get a bridge leave */
1376 static int base_process_dial_end(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer, const char *dial_status)
1378 /* In general, most things shouldn't get a dial end. */
1383 static enum process_bridge_enter_results base_process_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1385 /* Base process bridge enter simply indicates that we can't handle it */
1386 return BRIDGE_ENTER_NEED_CDR;
1389 static int base_process_parked_channel(struct cdr_object *cdr, struct ast_parked_call_payload *parking_info)
1391 char park_info[128];
1393 ast_assert(!strcasecmp(parking_info->parkee->name, cdr->party_a.snapshot->name));
1395 /* Update Party A information regardless */
1396 cdr->fn_table->process_party_a(cdr, parking_info->parkee);
1398 /* Fake out where we're parked */
1399 ast_string_field_set(cdr, appl, "Park");
1400 snprintf(park_info, sizeof(park_info), "%s:%u", parking_info->parkinglot, parking_info->parkingspace);
1401 ast_string_field_set(cdr, data, park_info);
1403 /* Prevent any further changes to the App/Data fields for this record */
1404 ast_set_flag(&cdr->flags, AST_CDR_LOCK_APP);
1411 static void single_state_init_function(struct cdr_object *cdr) {
1412 cdr->start = ast_tvnow();
1413 cdr_object_check_party_a_answer(cdr);
1416 static void single_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
1418 /* This should never happen! */
1419 ast_assert(cdr->party_b.snapshot == NULL);
1424 static int single_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer)
1426 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
1428 if (caller && !strcasecmp(cdr->party_a.snapshot->name, caller->name)) {
1429 cdr_object_swap_snapshot(&cdr->party_a, caller);
1430 CDR_DEBUG(mod_cfg, "%p - Updated Party A %s snapshot\n", cdr,
1431 cdr->party_a.snapshot->name);
1432 cdr_object_swap_snapshot(&cdr->party_b, peer);
1433 CDR_DEBUG(mod_cfg, "%p - Updated Party B %s snapshot\n", cdr,
1434 cdr->party_b.snapshot->name);
1435 } else if (!strcasecmp(cdr->party_a.snapshot->name, peer->name)) {
1436 /* We're the entity being dialed, i.e., outbound origination */
1437 cdr_object_swap_snapshot(&cdr->party_a, peer);
1438 CDR_DEBUG(mod_cfg, "%p - Updated Party A %s snapshot\n", cdr,
1439 cdr->party_a.snapshot->name);
1442 cdr_object_transition_state(cdr, &dial_state_fn_table);
1447 * \brief Handle a comparison between our \ref cdr_object and a \ref cdr_object
1448 * already in the bridge while in the Single state. The goal of this is to find
1449 * a Party B for our CDR.
1451 * \param cdr Our \ref cdr_object in the Single state
1452 * \param cand_cdr The \ref cdr_object already in the Bridge state
1454 * \retval 0 The cand_cdr had a Party A or Party B that we could use as our
1456 * \retval 1 No party in the cand_cdr could be used as our Party B
1458 static int single_state_bridge_enter_comparison(struct cdr_object *cdr,
1459 struct cdr_object *cand_cdr)
1461 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
1462 struct cdr_object_snapshot *party_a;
1464 /* Don't match on ourselves */
1465 if (!strcasecmp(cdr->party_a.snapshot->name, cand_cdr->party_a.snapshot->name)) {
1469 /* Try the candidate CDR's Party A first */
1470 party_a = cdr_object_pick_party_a(&cdr->party_a, &cand_cdr->party_a);
1471 if (!strcasecmp(party_a->snapshot->name, cdr->party_a.snapshot->name)) {
1472 CDR_DEBUG(mod_cfg, "%p - Party A %s has new Party B %s\n",
1473 cdr, cdr->party_a.snapshot->name, cand_cdr->party_a.snapshot->name);
1474 cdr_object_snapshot_copy(&cdr->party_b, &cand_cdr->party_a);
1475 if (!cand_cdr->party_b.snapshot) {
1476 /* We just stole them - finalize their CDR. Note that this won't
1477 * transition their state, it just sets the end time and the
1478 * disposition - if we need to re-activate them later, we can.
1480 cdr_object_finalize(cand_cdr);
1485 /* Try their Party B, unless it's us */
1486 if (!cand_cdr->party_b.snapshot
1487 || !strcasecmp(cdr->party_a.snapshot->name, cand_cdr->party_b.snapshot->name)) {
1490 party_a = cdr_object_pick_party_a(&cdr->party_a, &cand_cdr->party_b);
1491 if (!strcasecmp(party_a->snapshot->name, cdr->party_a.snapshot->name)) {
1492 CDR_DEBUG(mod_cfg, "%p - Party A %s has new Party B %s\n",
1493 cdr, cdr->party_a.snapshot->name, cand_cdr->party_b.snapshot->name);
1494 cdr_object_snapshot_copy(&cdr->party_b, &cand_cdr->party_b);
1501 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)
1503 struct ao2_iterator it_cdrs;
1507 ast_string_field_set(cdr, bridge, bridge->uniqueid);
1509 if (ao2_container_count(bridge->channels) == 1) {
1510 /* No one in the bridge yet but us! */
1511 cdr_object_transition_state(cdr, &bridge_state_fn_table);
1512 return BRIDGE_ENTER_ONLY_PARTY;
1515 for (it_cdrs = ao2_iterator_init(bridge->channels, 0);
1516 !success && (channel_id = ao2_iterator_next(&it_cdrs));
1517 ao2_ref(channel_id, -1)) {
1518 RAII_VAR(struct cdr_object *, cand_cdr_master,
1519 ao2_find(active_cdrs_by_channel, channel_id, OBJ_KEY),
1521 struct cdr_object *cand_cdr;
1523 if (!cand_cdr_master) {
1527 ao2_lock(cand_cdr_master);
1528 for (cand_cdr = cand_cdr_master; cand_cdr; cand_cdr = cand_cdr->next) {
1529 /* Skip any records that are not in a bridge or in this bridge.
1530 * I'm not sure how that would happen, but it pays to be careful. */
1531 if (cand_cdr->fn_table != &bridge_state_fn_table ||
1532 strcmp(cdr->bridge, cand_cdr->bridge)) {
1536 if (single_state_bridge_enter_comparison(cdr, cand_cdr)) {
1539 /* We successfully got a party B - break out */
1543 ao2_unlock(cand_cdr_master);
1545 ao2_iterator_destroy(&it_cdrs);
1547 /* We always transition state, even if we didn't get a peer */
1548 cdr_object_transition_state(cdr, &bridge_state_fn_table);
1550 /* Success implies that we have a Party B */
1552 return BRIDGE_ENTER_OBTAINED_PARTY_B;
1555 return BRIDGE_ENTER_NO_PARTY_B;
1558 static int single_state_process_parking_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1560 cdr_object_transition_state(cdr, &parked_state_fn_table);
1567 static void dial_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
1569 ast_assert(snapshot != NULL);
1571 if (!cdr->party_b.snapshot
1572 || strcasecmp(cdr->party_b.snapshot->name, snapshot->name)) {
1575 cdr_object_swap_snapshot(&cdr->party_b, snapshot);
1577 /* If party B hangs up, finalize this CDR */
1578 if (ast_test_flag(&cdr->party_b.snapshot->flags, AST_FLAG_DEAD)) {
1579 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1583 static int dial_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer)
1585 /* Don't process a begin dial here. A party A already in the dial state will
1586 * who receives a dial begin for something else will be handled by the
1587 * message router callback and will add a new CDR for the party A */
1593 * \brief Convert a dial status to a CDR disposition
1595 static enum ast_cdr_disposition dial_status_to_disposition(const char *dial_status)
1597 RAII_VAR(struct module_config *, mod_cfg,
1598 ao2_global_obj_ref(module_configs), ao2_cleanup);
1600 if (!strcmp(dial_status, "ANSWER")) {
1601 return AST_CDR_ANSWERED;
1602 } else if (!strcmp(dial_status, "BUSY")) {
1603 return AST_CDR_BUSY;
1604 } else if (!strcmp(dial_status, "CANCEL") || !strcmp(dial_status, "NOANSWER")) {
1605 return AST_CDR_NOANSWER;
1606 } else if (!strcmp(dial_status, "CONGESTION")) {
1607 if (!ast_test_flag(&mod_cfg->general->settings, CDR_CONGESTION)) {
1608 return AST_CDR_FAILED;
1610 return AST_CDR_CONGESTION;
1612 } else if (!strcmp(dial_status, "FAILED")) {
1613 return AST_CDR_FAILED;
1615 return AST_CDR_FAILED;
1618 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)
1620 RAII_VAR(struct module_config *, mod_cfg,
1621 ao2_global_obj_ref(module_configs), ao2_cleanup);
1622 struct ast_channel_snapshot *party_a;
1629 ast_assert(!strcasecmp(cdr->party_a.snapshot->name, party_a->name));
1630 cdr_object_swap_snapshot(&cdr->party_a, party_a);
1632 if (cdr->party_b.snapshot) {
1633 if (strcasecmp(cdr->party_b.snapshot->name, peer->name)) {
1634 /* Not the status for this CDR - defer back to the message router */
1637 cdr_object_swap_snapshot(&cdr->party_b, peer);
1640 /* Set the disposition based on the dial string. */
1641 cdr->disposition = dial_status_to_disposition(dial_status);
1642 if (cdr->disposition == AST_CDR_ANSWERED) {
1643 /* Switch to dial pending to wait and see what the caller does */
1644 cdr_object_transition_state(cdr, &dialed_pending_state_fn_table);
1646 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1652 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)
1654 struct ao2_iterator it_cdrs;
1658 ast_string_field_set(cdr, bridge, bridge->uniqueid);
1660 /* Get parties in the bridge */
1661 if (ao2_container_count(bridge->channels) == 1) {
1662 /* No one in the bridge yet but us! */
1663 cdr_object_transition_state(cdr, &bridge_state_fn_table);
1664 return BRIDGE_ENTER_ONLY_PARTY;
1667 for (it_cdrs = ao2_iterator_init(bridge->channels, 0);
1668 !success && (channel_id = ao2_iterator_next(&it_cdrs));
1669 ao2_ref(channel_id, -1)) {
1670 RAII_VAR(struct cdr_object *, cand_cdr_master,
1671 ao2_find(active_cdrs_by_channel, channel_id, OBJ_KEY),
1673 struct cdr_object *cand_cdr;
1675 if (!cand_cdr_master) {
1679 ao2_lock(cand_cdr_master);
1680 for (cand_cdr = cand_cdr_master; cand_cdr; cand_cdr = cand_cdr->next) {
1681 /* Skip any records that are not in a bridge or in this bridge.
1682 * I'm not sure how that would happen, but it pays to be careful. */
1683 if (cand_cdr->fn_table != &bridge_state_fn_table ||
1684 strcmp(cdr->bridge, cand_cdr->bridge)) {
1688 /* If we don't have a Party B (originated channel), skip it */
1689 if (!cdr->party_b.snapshot) {
1693 /* Skip any records that aren't our Party B */
1694 if (strcasecmp(cdr->party_b.snapshot->name, cand_cdr->party_a.snapshot->name)) {
1697 cdr_object_snapshot_copy(&cdr->party_b, &cand_cdr->party_a);
1698 /* If they have a Party B, they joined up with someone else as their
1699 * Party A. Don't finalize them as they're active. Otherwise, we
1700 * have stolen them so they need to be finalized.
1702 if (!cand_cdr->party_b.snapshot) {
1703 cdr_object_finalize(cand_cdr);
1708 ao2_unlock(cand_cdr_master);
1710 ao2_iterator_destroy(&it_cdrs);
1712 /* We always transition state, even if we didn't get a peer */
1713 cdr_object_transition_state(cdr, &bridge_state_fn_table);
1715 /* Success implies that we have a Party B */
1717 return BRIDGE_ENTER_OBTAINED_PARTY_B;
1719 return BRIDGE_ENTER_NO_PARTY_B;
1722 /* DIALED PENDING STATE */
1724 static int dialed_pending_state_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
1726 /* If we get a CEP change, we're executing dialplan. If we have a Party B
1727 * that means we need a new CDR; otherwise, switch us over to single.
1729 if (snapshot_cep_changed(cdr->party_a.snapshot, snapshot)) {
1730 if (cdr->party_b.snapshot) {
1731 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1732 cdr->fn_table->process_party_a(cdr, snapshot);
1735 cdr_object_transition_state(cdr, &single_state_fn_table);
1736 cdr->fn_table->process_party_a(cdr, snapshot);
1740 base_process_party_a(cdr, snapshot);
1744 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)
1746 cdr_object_transition_state(cdr, &dial_state_fn_table);
1747 return cdr->fn_table->process_bridge_enter(cdr, bridge, channel);
1750 static int dialed_pending_state_process_parking_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1752 if (cdr->party_b.snapshot) {
1753 /* We can't handle this as we have a Party B - ask for a new one */
1756 cdr_object_transition_state(cdr, &parked_state_fn_table);
1760 static int dialed_pending_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer)
1762 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1764 /* Ask for a new CDR */
1770 static void bridge_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
1772 if (!cdr->party_b.snapshot
1773 || strcasecmp(cdr->party_b.snapshot->name, snapshot->name)) {
1776 cdr_object_swap_snapshot(&cdr->party_b, snapshot);
1778 /* If party B hangs up, finalize this CDR */
1779 if (ast_test_flag(&cdr->party_b.snapshot->flags, AST_FLAG_DEAD)) {
1780 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1784 static int bridge_state_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1786 if (strcmp(cdr->bridge, bridge->uniqueid)) {
1789 if (strcasecmp(cdr->party_a.snapshot->name, channel->name)
1790 && cdr->party_b.snapshot
1791 && strcasecmp(cdr->party_b.snapshot->name, channel->name)) {
1794 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1801 static int parked_state_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1803 if (strcasecmp(cdr->party_a.snapshot->name, channel->name)) {
1806 cdr_object_transition_state(cdr, &finalized_state_fn_table);
1811 /* FINALIZED STATE */
1813 static void finalized_state_init_function(struct cdr_object *cdr)
1815 cdr_object_finalize(cdr);
1818 static int finalized_state_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
1820 RAII_VAR(struct module_config *, mod_cfg,
1821 ao2_global_obj_ref(module_configs), ao2_cleanup);
1823 /* If we ignore hangup logic, indicate that we don't need a new CDR */
1824 if (ast_test_flag(&mod_cfg->general->settings, CDR_END_BEFORE_H_EXTEN)
1825 && ast_test_flag(&snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)) {
1829 /* Indicate that, if possible, we should get a new CDR */
1833 /* TOPIC ROUTER CALLBACKS */
1836 * \brief Handler for Stasis-Core dial messages
1837 * \param data Passed on
1838 * \param sub The stasis subscription for this message callback
1839 * \param topic The topic this message was published for
1840 * \param message The message
1842 static void handle_dial_message(void *data, struct stasis_subscription *sub, struct stasis_topic *topic, struct stasis_message *message)
1844 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
1845 RAII_VAR(struct cdr_object *, cdr, NULL, ao2_cleanup);
1846 struct ast_multi_channel_blob *payload = stasis_message_data(message);
1847 struct ast_channel_snapshot *caller;
1848 struct ast_channel_snapshot *peer;
1849 struct cdr_object *it_cdr;
1850 struct ast_json *dial_status_blob;
1851 const char *dial_status = NULL;
1854 caller = ast_multi_channel_blob_get_channel(payload, "caller");
1855 peer = ast_multi_channel_blob_get_channel(payload, "peer");
1856 if (!peer && !caller) {
1859 dial_status_blob = ast_json_object_get(ast_multi_channel_blob_get_json(payload), "dialstatus");
1860 if (dial_status_blob) {
1861 dial_status = ast_json_string_get(dial_status_blob);
1864 CDR_DEBUG(mod_cfg, "Dial %s message for %s, %s: %u.%08u\n",
1865 ast_strlen_zero(dial_status) ? "Begin" : "End",
1866 caller ? caller->name : "(none)",
1867 peer ? peer->name : "(none)",
1868 (unsigned int)stasis_message_timestamp(message)->tv_sec,
1869 (unsigned int)stasis_message_timestamp(message)->tv_usec);
1871 /* Figure out who is running this show */
1873 cdr = ao2_find(active_cdrs_by_channel, caller->uniqueid, OBJ_KEY);
1875 cdr = ao2_find(active_cdrs_by_channel, peer->uniqueid, OBJ_KEY);
1879 ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", caller ? caller->name : peer->name);
1884 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
1885 if (ast_strlen_zero(dial_status)) {
1886 if (!it_cdr->fn_table->process_dial_begin) {
1889 CDR_DEBUG(mod_cfg, "%p - Processing Dial Begin message for channel %s, peer %s\n",
1891 caller ? caller->name : "(none)",
1892 peer ? peer->name : "(none)");
1893 res &= it_cdr->fn_table->process_dial_begin(it_cdr,
1897 if (!it_cdr->fn_table->process_dial_end) {
1900 CDR_DEBUG(mod_cfg, "%p - Processing Dial End message for channel %s, peer %s\n",
1902 caller ? caller->name : "(none)",
1903 peer ? peer->name : "(none)");
1904 it_cdr->fn_table->process_dial_end(it_cdr,
1911 /* If no CDR handled a dial begin message, make a new one */
1912 if (res && ast_strlen_zero(dial_status)) {
1913 struct cdr_object *new_cdr;
1915 new_cdr = cdr_object_create_and_append(cdr);
1919 new_cdr->fn_table->process_dial_begin(new_cdr,
1926 static int cdr_object_finalize_party_b(void *obj, void *arg, int flags)
1928 struct cdr_object *cdr = obj;
1929 struct ast_channel_snapshot *party_b = arg;
1930 struct cdr_object *it_cdr;
1931 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
1932 if (it_cdr->party_b.snapshot
1933 && !strcasecmp(it_cdr->party_b.snapshot->name, party_b->name)) {
1934 /* Don't transition to the finalized state - let the Party A do
1935 * that when its ready
1937 cdr_object_finalize(it_cdr);
1943 static int cdr_object_update_party_b(void *obj, void *arg, int flags)
1945 struct cdr_object *cdr = obj;
1946 struct ast_channel_snapshot *party_b = arg;
1947 struct cdr_object *it_cdr;
1948 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
1949 if (!it_cdr->fn_table->process_party_b) {
1952 if (it_cdr->party_b.snapshot
1953 && !strcasecmp(it_cdr->party_b.snapshot->name, party_b->name)) {
1954 it_cdr->fn_table->process_party_b(it_cdr, party_b);
1962 * \brief Filter channel snapshots by technology
1964 static int filter_channel_snapshot(struct ast_channel_snapshot *snapshot)
1966 return snapshot->tech_properties & AST_CHAN_TP_INTERNAL;
1971 * \brief Filter a channel cache update
1973 static int filter_channel_cache_message(struct ast_channel_snapshot *old_snapshot,
1974 struct ast_channel_snapshot *new_snapshot)
1978 /* Drop cache updates from certain channel technologies */
1980 ret |= filter_channel_snapshot(old_snapshot);
1983 ret |= filter_channel_snapshot(new_snapshot);
1989 /*! \brief Determine if we need to add a new CDR based on snapshots */
1990 static int check_new_cdr_needed(struct ast_channel_snapshot *old_snapshot,
1991 struct ast_channel_snapshot *new_snapshot)
1993 RAII_VAR(struct module_config *, mod_cfg,
1994 ao2_global_obj_ref(module_configs), ao2_cleanup);
1996 if (!new_snapshot) {
2000 if (ast_test_flag(&new_snapshot->flags, AST_FLAG_DEAD)) {
2004 /* Auto-fall through will increment the priority but have no application */
2005 if (ast_strlen_zero(new_snapshot->appl)) {
2009 if (old_snapshot && !snapshot_cep_changed(old_snapshot, new_snapshot)) {
2017 * \brief Handler for Stasis-Core channel cache update messages
2018 * \param data Passed on
2019 * \param sub The stasis subscription for this message callback
2020 * \param topic The topic this message was published for
2021 * \param message The message
2023 static void handle_channel_cache_message(void *data, struct stasis_subscription *sub, struct stasis_topic *topic, struct stasis_message *message)
2025 RAII_VAR(struct cdr_object *, cdr, NULL, ao2_cleanup);
2026 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
2027 struct stasis_cache_update *update = stasis_message_data(message);
2028 struct ast_channel_snapshot *old_snapshot;
2029 struct ast_channel_snapshot *new_snapshot;
2030 const char *uniqueid;
2032 struct cdr_object *it_cdr;
2034 ast_assert(update != NULL);
2035 ast_assert(ast_channel_snapshot_type() == update->type);
2037 old_snapshot = stasis_message_data(update->old_snapshot);
2038 new_snapshot = stasis_message_data(update->new_snapshot);
2039 uniqueid = new_snapshot ? new_snapshot->uniqueid : old_snapshot->uniqueid;
2040 name = new_snapshot ? new_snapshot->name : old_snapshot->name;
2042 if (filter_channel_cache_message(old_snapshot, new_snapshot)) {
2046 if (new_snapshot && !old_snapshot) {
2047 cdr = cdr_object_alloc(new_snapshot);
2051 ao2_link(active_cdrs_by_channel, cdr);
2054 /* Handle Party A */
2056 cdr = ao2_find(active_cdrs_by_channel, uniqueid, OBJ_KEY);
2059 ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", name);
2064 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2065 if (!it_cdr->fn_table->process_party_a) {
2068 all_reject &= it_cdr->fn_table->process_party_a(it_cdr, new_snapshot);
2070 if (all_reject && check_new_cdr_needed(old_snapshot, new_snapshot)) {
2071 /* We're not hung up and we have a new snapshot - we need a new CDR */
2072 struct cdr_object *new_cdr;
2073 new_cdr = cdr_object_create_and_append(cdr);
2075 new_cdr->fn_table->process_party_a(new_cdr, new_snapshot);
2079 CDR_DEBUG(mod_cfg, "%p - Beginning finalize/dispatch for %s\n", cdr, old_snapshot->name);
2080 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2081 cdr_object_finalize(it_cdr);
2083 cdr_object_dispatch(cdr);
2084 ao2_unlink(active_cdrs_by_channel, cdr);
2089 /* Handle Party B */
2091 ao2_callback(active_cdrs_by_channel, OBJ_NODATA, cdr_object_update_party_b,
2094 ao2_callback(active_cdrs_by_channel, OBJ_NODATA, cdr_object_finalize_party_b,
2100 struct bridge_leave_data {
2101 struct ast_bridge_snapshot *bridge;
2102 struct ast_channel_snapshot *channel;
2105 /*! \brief Callback used to notify CDRs of a Party B leaving the bridge */
2106 static int cdr_object_party_b_left_bridge_cb(void *obj, void *arg, int flags)
2108 struct cdr_object *cdr = obj;
2109 struct bridge_leave_data *leave_data = arg;
2110 struct cdr_object *it_cdr;
2112 if (strcmp(cdr->bridge, leave_data->bridge->uniqueid)) {
2115 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2116 if (it_cdr->fn_table != &bridge_state_fn_table) {
2119 if (!it_cdr->party_b.snapshot) {
2122 if (strcasecmp(it_cdr->party_b.snapshot->name, leave_data->channel->name)) {
2125 /* It is our Party B, in our bridge. Set the end time and let the handler
2126 * transition our CDR appropriately when we leave the bridge.
2128 cdr_object_finalize(it_cdr);
2133 /*! \brief Filter bridge messages based on bridge technology */
2134 static int filter_bridge_messages(struct ast_bridge_snapshot *bridge)
2136 /* Ignore holding bridge technology messages. We treat this simply as an application
2137 * that a channel enters into.
2139 if (!strcmp(bridge->technology, "holding_bridge") && strcmp(bridge->subclass, "parking")) {
2146 * \brief Handler for when a channel leaves a bridge
2147 * \param data Passed on
2148 * \param sub The stasis subscription for this message callback
2149 * \param topic The topic this message was published for
2150 * \param message The message - hopefully a bridge one!
2152 static void handle_bridge_leave_message(void *data, struct stasis_subscription *sub,
2153 struct stasis_topic *topic, struct stasis_message *message)
2155 struct ast_bridge_blob *update = stasis_message_data(message);
2156 struct ast_bridge_snapshot *bridge = update->bridge;
2157 struct ast_channel_snapshot *channel = update->channel;
2158 RAII_VAR(struct module_config *, mod_cfg,
2159 ao2_global_obj_ref(module_configs), ao2_cleanup);
2160 RAII_VAR(struct cdr_object *, cdr,
2161 ao2_find(active_cdrs_by_channel, channel->uniqueid, OBJ_KEY),
2163 struct cdr_object *it_cdr;
2164 struct bridge_leave_data leave_data = {
2168 int left_bridge = 0;
2170 if (filter_bridge_messages(bridge)) {
2174 CDR_DEBUG(mod_cfg, "Bridge Leave message for %s: %u.%08u\n",
2176 (unsigned int)stasis_message_timestamp(message)->tv_sec,
2177 (unsigned int)stasis_message_timestamp(message)->tv_usec);
2180 ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", channel->name);
2186 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2187 if (!it_cdr->fn_table->process_bridge_leave) {
2190 CDR_DEBUG(mod_cfg, "%p - Processing Bridge Leave for %s\n",
2191 it_cdr, channel->name);
2192 if (!it_cdr->fn_table->process_bridge_leave(it_cdr, bridge, channel)) {
2193 ast_string_field_set(it_cdr, bridge, "");
2203 if (strcmp(bridge->subclass, "parking")) {
2205 ao2_callback(active_cdrs_by_channel, OBJ_NODATA,
2206 cdr_object_party_b_left_bridge_cb,
2213 * \brief Create a new CDR, append it to an existing CDR, and update its snapshots
2215 * \note The new CDR will be automatically transitioned to the bridge state
2217 static void bridge_candidate_add_to_cdr(struct cdr_object *cdr,
2218 struct cdr_object_snapshot *party_b)
2220 RAII_VAR(struct module_config *, mod_cfg,
2221 ao2_global_obj_ref(module_configs), ao2_cleanup);
2222 struct cdr_object *new_cdr;
2224 new_cdr = cdr_object_create_and_append(cdr);
2228 cdr_object_snapshot_copy(&new_cdr->party_b, party_b);
2229 cdr_object_check_party_a_answer(new_cdr);
2230 ast_string_field_set(new_cdr, bridge, cdr->bridge);
2231 cdr_object_transition_state(new_cdr, &bridge_state_fn_table);
2232 CDR_DEBUG(mod_cfg, "%p - Party A %s has new Party B %s\n",
2233 new_cdr, new_cdr->party_a.snapshot->name,
2234 party_b->snapshot->name);
2238 * \brief Process a single \ref bridge_candidate
2240 * When a CDR enters a bridge, it needs to make pairings with everyone else
2241 * that it is not currently paired with. This function determines, for the
2242 * CDR for the channel that entered the bridge and the CDR for every other
2243 * channel currently in the bridge, who is Party A and makes new CDRs.
2245 * \param cdr The \ref cdr_obj being processed
2246 * \param cand_cdr The \ref cdr_object that is a candidate
2249 static int bridge_candidate_process(struct cdr_object *cdr, struct cdr_object *base_cand_cdr)
2251 RAII_VAR(struct module_config *, mod_cfg,
2252 ao2_global_obj_ref(module_configs), ao2_cleanup);
2253 struct cdr_object_snapshot *party_a;
2254 struct cdr_object *cand_cdr;
2256 SCOPED_AO2LOCK(lock, base_cand_cdr);
2258 for (cand_cdr = base_cand_cdr; cand_cdr; cand_cdr = cand_cdr->next) {
2259 /* Skip any records that are not in this bridge */
2260 if (strcmp(cand_cdr->bridge, cdr->bridge)) {
2264 /* If the candidate is us or someone we've taken on, pass on by */
2265 if (!strcasecmp(cdr->party_a.snapshot->name, cand_cdr->party_a.snapshot->name)
2266 || (cdr->party_b.snapshot
2267 && !strcasecmp(cdr->party_b.snapshot->name, cand_cdr->party_a.snapshot->name))) {
2271 party_a = cdr_object_pick_party_a(&cdr->party_a, &cand_cdr->party_a);
2272 /* We're party A - make a new CDR, append it to us, and set the candidate as
2274 if (!strcasecmp(party_a->snapshot->name, cdr->party_a.snapshot->name)) {
2275 bridge_candidate_add_to_cdr(cdr, &cand_cdr->party_a);
2279 /* We're Party B. Check if we can add ourselves immediately or if we need
2280 * a new CDR for them (they already have a Party B) */
2281 if (cand_cdr->party_b.snapshot
2282 && strcasecmp(cand_cdr->party_b.snapshot->name, cdr->party_a.snapshot->name)) {
2283 bridge_candidate_add_to_cdr(cand_cdr, &cdr->party_a);
2285 CDR_DEBUG(mod_cfg, "%p - Party A %s has new Party B %s\n",
2286 cand_cdr, cand_cdr->party_a.snapshot->name,
2287 cdr->party_a.snapshot->name);
2288 cdr_object_snapshot_copy(&cand_cdr->party_b, &cdr->party_a);
2289 /* It's possible that this joined at one point and was never chosen
2290 * as party A. Clear their end time, as it would be set in such a
2293 memset(&cand_cdr->end, 0, sizeof(cand_cdr->end));
2300 * \brief Handle creating bridge pairings for the \ref cdr_object that just
2302 * \param cdr The \ref cdr_object that just entered the bridge
2303 * \param bridge The \ref ast_bridge_snapshot representing the bridge it just entered
2305 static void handle_bridge_pairings(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge)
2307 struct ao2_iterator it_channels;
2310 it_channels = ao2_iterator_init(bridge->channels, 0);
2311 while ((channel_id = ao2_iterator_next(&it_channels))) {
2312 RAII_VAR(struct cdr_object *, cand_cdr,
2313 ao2_find(active_cdrs_by_channel, channel_id, OBJ_KEY),
2317 ao2_ref(channel_id, -1);
2321 bridge_candidate_process(cdr, cand_cdr);
2323 ao2_ref(channel_id, -1);
2325 ao2_iterator_destroy(&it_channels);
2328 /*! \brief Handle entering into a parking bridge
2329 * \param cdr The CDR to operate on
2330 * \param bridge The bridge the channel just entered
2331 * \param channel The channel snapshot
2333 static void handle_parking_bridge_enter_message(struct cdr_object *cdr,
2334 struct ast_bridge_snapshot *bridge,
2335 struct ast_channel_snapshot *channel)
2337 RAII_VAR(struct module_config *, mod_cfg,
2338 ao2_global_obj_ref(module_configs), ao2_cleanup);
2340 struct cdr_object *it_cdr;
2341 struct cdr_object *new_cdr;
2345 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2346 if (it_cdr->fn_table->process_parking_bridge_enter) {
2347 res &= it_cdr->fn_table->process_parking_bridge_enter(it_cdr, bridge, channel);
2349 if (it_cdr->fn_table->process_party_a) {
2350 CDR_DEBUG(mod_cfg, "%p - Updating Party A %s snapshot\n", it_cdr,
2352 it_cdr->fn_table->process_party_a(it_cdr, channel);
2357 /* No one handled it - we need a new one! */
2358 new_cdr = cdr_object_create_and_append(cdr);
2360 /* Let the single state transition us to Parked */
2361 cdr_object_transition_state(new_cdr, &single_state_fn_table);
2362 new_cdr->fn_table->process_parking_bridge_enter(new_cdr, bridge, channel);
2368 /*! \brief Handle a bridge enter message for a 'normal' bridge
2369 * \param cdr The CDR to operate on
2370 * \param bridge The bridge the channel just entered
2371 * \param channel The channel snapshot
2373 static void handle_standard_bridge_enter_message(struct cdr_object *cdr,
2374 struct ast_bridge_snapshot *bridge,
2375 struct ast_channel_snapshot *channel)
2377 RAII_VAR(struct module_config *, mod_cfg,
2378 ao2_global_obj_ref(module_configs), ao2_cleanup);
2379 enum process_bridge_enter_results result;
2380 struct cdr_object *it_cdr;
2381 struct cdr_object *new_cdr;
2382 struct cdr_object *handled_cdr = NULL;
2386 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2387 if (it_cdr->fn_table->process_party_a) {
2388 CDR_DEBUG(mod_cfg, "%p - Updating Party A %s snapshot\n", it_cdr,
2390 it_cdr->fn_table->process_party_a(it_cdr, channel);
2393 /* Notify all states that they have entered a bridge */
2394 if (it_cdr->fn_table->process_bridge_enter) {
2395 CDR_DEBUG(mod_cfg, "%p - Processing bridge enter for %s\n", it_cdr,
2397 result = it_cdr->fn_table->process_bridge_enter(it_cdr, bridge, channel);
2399 case BRIDGE_ENTER_ONLY_PARTY:
2401 case BRIDGE_ENTER_OBTAINED_PARTY_B:
2403 handled_cdr = it_cdr;
2406 case BRIDGE_ENTER_NEED_CDR:
2409 case BRIDGE_ENTER_NO_PARTY_B:
2410 /* We didn't win on any - end this CDR. If someone else comes in later
2411 * that is Party B to this CDR, it can re-activate this CDR.
2414 handled_cdr = it_cdr;
2416 cdr_object_finalize(cdr);
2422 /* Create the new matchings, but only for either:
2423 * * The first CDR in the chain that handled it. This avoids issues with
2425 * * If no one handled it, the last CDR in the chain. This would occur if
2426 * a CDR joined a bridge and it wasn't Party A for anyone. We still need
2427 * to make pairings with everyone in the bridge.
2430 handle_bridge_pairings(handled_cdr, bridge);
2432 /* Nothing handled it - we need a new one! */
2433 new_cdr = cdr_object_create_and_append(cdr);
2435 /* This is guaranteed to succeed: the new CDR is created in the single state
2436 * and will be able to handle the bridge enter message
2438 handle_standard_bridge_enter_message(cdr, bridge, channel);
2446 * \brief Handler for Stasis-Core bridge enter messages
2447 * \param data Passed on
2448 * \param sub The stasis subscription for this message callback
2449 * \param topic The topic this message was published for
2450 * \param message The message - hopefully a bridge one!
2452 static void handle_bridge_enter_message(void *data, struct stasis_subscription *sub,
2453 struct stasis_topic *topic, struct stasis_message *message)
2455 struct ast_bridge_blob *update = stasis_message_data(message);
2456 struct ast_bridge_snapshot *bridge = update->bridge;
2457 struct ast_channel_snapshot *channel = update->channel;
2458 RAII_VAR(struct cdr_object *, cdr,
2459 ao2_find(active_cdrs_by_channel, channel->uniqueid, OBJ_KEY),
2461 RAII_VAR(struct module_config *, mod_cfg,
2462 ao2_global_obj_ref(module_configs), ao2_cleanup);
2464 if (filter_bridge_messages(bridge)) {
2468 if (filter_channel_snapshot(channel)) {
2472 CDR_DEBUG(mod_cfg, "Bridge Enter message for channel %s: %u.%08u\n",
2474 (unsigned int)stasis_message_timestamp(message)->tv_sec,
2475 (unsigned int)stasis_message_timestamp(message)->tv_usec);
2478 ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", channel->name);
2482 if (!strcmp(bridge->subclass, "parking")) {
2483 handle_parking_bridge_enter_message(cdr, bridge, channel);
2485 handle_standard_bridge_enter_message(cdr, bridge, channel);
2490 * \brief Handler for when a channel is parked
2491 * \param data Passed on
2492 * \param sub The stasis subscription for this message callback
2493 * \param topic The topic this message was published for
2494 * \param message The message about who got parked
2496 static void handle_parked_call_message(void *data, struct stasis_subscription *sub,
2497 struct stasis_topic *topic, struct stasis_message *message)
2499 struct ast_parked_call_payload *payload = stasis_message_data(message);
2500 struct ast_channel_snapshot *channel = payload->parkee;
2501 RAII_VAR(struct cdr_object *, cdr, NULL, ao2_cleanup);
2502 RAII_VAR(struct module_config *, mod_cfg,
2503 ao2_global_obj_ref(module_configs), ao2_cleanup);
2505 struct cdr_object *it_cdr;
2507 /* Anything other than getting parked will be handled by other updates */
2508 if (payload->event_type != PARKED_CALL) {
2512 /* No one got parked? */
2517 CDR_DEBUG(mod_cfg, "Parked Call message for channel %s: %u.%08u\n",
2519 (unsigned int)stasis_message_timestamp(message)->tv_sec,
2520 (unsigned int)stasis_message_timestamp(message)->tv_usec);
2522 cdr = ao2_find(active_cdrs_by_channel, channel->uniqueid, OBJ_KEY);
2524 ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", channel->name);
2530 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2531 if (it_cdr->fn_table->process_parked_channel) {
2532 unhandled &= it_cdr->fn_table->process_parked_channel(it_cdr, payload);
2537 /* Nothing handled the messgae - we need a new one! */
2538 struct cdr_object *new_cdr = cdr_object_create_and_append(cdr);
2540 /* As the new CDR is created in the single state, it is guaranteed
2541 * to have a function for the parked call message and will handle
2543 new_cdr->fn_table->process_parked_channel(new_cdr, payload);
2551 struct ast_cdr_config *ast_cdr_get_config(void)
2553 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
2554 ao2_ref(mod_cfg->general, +1);
2555 return mod_cfg->general;
2558 void ast_cdr_set_config(struct ast_cdr_config *config)
2560 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
2561 ao2_cleanup(mod_cfg->general);
2562 mod_cfg->general = config;
2563 ao2_ref(mod_cfg->general, +1);
2566 int ast_cdr_is_enabled(void)
2568 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
2569 return ast_test_flag(&mod_cfg->general->settings, CDR_ENABLED);
2572 int ast_cdr_register(const char *name, const char *desc, ast_cdrbe be)
2574 struct cdr_beitem *i = NULL;
2580 ast_log(LOG_WARNING, "CDR engine '%s' lacks backend\n", name);
2584 AST_RWLIST_WRLOCK(&be_list);
2585 AST_RWLIST_TRAVERSE(&be_list, i, list) {
2586 if (!strcasecmp(name, i->name)) {
2587 ast_log(LOG_WARNING, "Already have a CDR backend called '%s'\n", name);
2588 AST_RWLIST_UNLOCK(&be_list);
2593 if (!(i = ast_calloc(1, sizeof(*i))))
2597 ast_copy_string(i->name, name, sizeof(i->name));
2598 ast_copy_string(i->desc, desc, sizeof(i->desc));
2600 AST_RWLIST_INSERT_HEAD(&be_list, i, list);
2601 AST_RWLIST_UNLOCK(&be_list);
2606 void ast_cdr_unregister(const char *name)
2608 struct cdr_beitem *i = NULL;
2610 AST_RWLIST_WRLOCK(&be_list);
2611 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&be_list, i, list) {
2612 if (!strcasecmp(name, i->name)) {
2613 AST_RWLIST_REMOVE_CURRENT(list);
2617 AST_RWLIST_TRAVERSE_SAFE_END;
2618 AST_RWLIST_UNLOCK(&be_list);
2621 ast_verb(2, "Unregistered '%s' CDR backend\n", name);
2626 struct ast_cdr *ast_cdr_dup(struct ast_cdr *cdr)
2628 struct ast_cdr *newcdr;
2633 newcdr = ast_cdr_alloc();
2639 AST_LIST_HEAD_INIT_NOLOCK(&newcdr->varshead);
2640 copy_variables(&newcdr->varshead, &cdr->varshead);
2641 newcdr->next = NULL;
2646 static const char *cdr_format_var_internal(struct ast_cdr *cdr, const char *name)
2648 struct ast_var_t *variables;
2650 if (ast_strlen_zero(name)) {
2654 AST_LIST_TRAVERSE(&cdr->varshead, variables, entries) {
2655 if (!strcasecmp(name, ast_var_name(variables))) {
2656 return ast_var_value(variables);
2663 static void cdr_get_tv(struct timeval when, const char *fmt, char *buf, int bufsize)
2665 if (fmt == NULL) { /* raw mode */
2666 snprintf(buf, bufsize, "%ld.%06ld", (long)when.tv_sec, (long)when.tv_usec);
2668 buf[0] = '\0';/* Ensure the buffer is initialized. */
2672 ast_localtime(&when, &tm, NULL);
2673 ast_strftime(buf, bufsize, fmt, &tm);
2678 void ast_cdr_format_var(struct ast_cdr *cdr, const char *name, char **ret, char *workspace, int workspacelen, int raw)
2680 const char *fmt = "%Y-%m-%d %T";
2689 if (!strcasecmp(name, "clid")) {
2690 ast_copy_string(workspace, cdr->clid, workspacelen);
2691 } else if (!strcasecmp(name, "src")) {
2692 ast_copy_string(workspace, cdr->src, workspacelen);
2693 } else if (!strcasecmp(name, "dst")) {
2694 ast_copy_string(workspace, cdr->dst, workspacelen);
2695 } else if (!strcasecmp(name, "dcontext")) {
2696 ast_copy_string(workspace, cdr->dcontext, workspacelen);
2697 } else if (!strcasecmp(name, "channel")) {
2698 ast_copy_string(workspace, cdr->channel, workspacelen);
2699 } else if (!strcasecmp(name, "dstchannel")) {
2700 ast_copy_string(workspace, cdr->dstchannel, workspacelen);
2701 } else if (!strcasecmp(name, "lastapp")) {
2702 ast_copy_string(workspace, cdr->lastapp, workspacelen);
2703 } else if (!strcasecmp(name, "lastdata")) {
2704 ast_copy_string(workspace, cdr->lastdata, workspacelen);
2705 } else if (!strcasecmp(name, "start")) {
2706 cdr_get_tv(cdr->start, raw ? NULL : fmt, workspace, workspacelen);
2707 } else if (!strcasecmp(name, "answer")) {
2708 cdr_get_tv(cdr->answer, raw ? NULL : fmt, workspace, workspacelen);
2709 } else if (!strcasecmp(name, "end")) {
2710 cdr_get_tv(cdr->end, raw ? NULL : fmt, workspace, workspacelen);
2711 } else if (!strcasecmp(name, "duration")) {
2712 snprintf(workspace, workspacelen, "%ld", cdr->end.tv_sec != 0 ? cdr->duration : (long)ast_tvdiff_ms(ast_tvnow(), cdr->start) / 1000);
2713 } else if (!strcasecmp(name, "billsec")) {
2714 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);
2715 } else if (!strcasecmp(name, "disposition")) {
2717 snprintf(workspace, workspacelen, "%ld", cdr->disposition);
2719 ast_copy_string(workspace, ast_cdr_disp2str(cdr->disposition), workspacelen);
2721 } else if (!strcasecmp(name, "amaflags")) {
2723 snprintf(workspace, workspacelen, "%ld", cdr->amaflags);
2725 ast_copy_string(workspace, ast_channel_amaflags2string(cdr->amaflags), workspacelen);
2727 } else if (!strcasecmp(name, "accountcode")) {
2728 ast_copy_string(workspace, cdr->accountcode, workspacelen);
2729 } else if (!strcasecmp(name, "peeraccount")) {
2730 ast_copy_string(workspace, cdr->peeraccount, workspacelen);
2731 } else if (!strcasecmp(name, "uniqueid")) {
2732 ast_copy_string(workspace, cdr->uniqueid, workspacelen);
2733 } else if (!strcasecmp(name, "linkedid")) {
2734 ast_copy_string(workspace, cdr->linkedid, workspacelen);
2735 } else if (!strcasecmp(name, "userfield")) {
2736 ast_copy_string(workspace, cdr->userfield, workspacelen);
2737 } else if (!strcasecmp(name, "sequence")) {
2738 snprintf(workspace, workspacelen, "%d", cdr->sequence);
2739 } else if ((varbuf = cdr_format_var_internal(cdr, name))) {
2740 ast_copy_string(workspace, varbuf, workspacelen);
2742 workspace[0] = '\0';
2745 if (!ast_strlen_zero(workspace)) {
2752 * \brief Callback that finds all CDRs that reference a particular channel by name
2754 static int cdr_object_select_all_by_name_cb(void *obj, void *arg, int flags)
2756 struct cdr_object *cdr = obj;
2757 const char *name = arg;
2759 if (!strcasecmp(cdr->party_a.snapshot->name, name) ||
2760 (cdr->party_b.snapshot && !strcasecmp(cdr->party_b.snapshot->name, name))) {
2768 * \brief Callback that finds a CDR by channel name
2770 static int cdr_object_get_by_name_cb(void *obj, void *arg, int flags)
2772 struct cdr_object *cdr = obj;
2773 const char *name = arg;
2775 if (!strcasecmp(cdr->party_a.snapshot->name, name)) {
2781 /* Read Only CDR variables */
2782 static const char * const cdr_readonly_vars[] = {
2806 int ast_cdr_setvar(const char *channel_name, const char *name, const char *value)
2808 struct cdr_object *cdr;
2809 struct cdr_object *it_cdr;
2810 struct ao2_iterator *it_cdrs;
2811 char *arg = ast_strdupa(channel_name);
2814 for (x = 0; cdr_readonly_vars[x]; x++) {
2815 if (!strcasecmp(name, cdr_readonly_vars[x])) {
2816 ast_log(LOG_ERROR, "Attempt to set the '%s' read-only variable!\n", name);
2821 it_cdrs = ao2_callback(active_cdrs_by_channel, OBJ_MULTIPLE, cdr_object_select_all_by_name_cb, arg);
2823 ast_log(AST_LOG_ERROR, "Unable to find CDR for channel %s\n", channel_name);
2827 for (; (cdr = ao2_iterator_next(it_cdrs)); ao2_unlock(cdr), ao2_cleanup(cdr)) {
2829 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2830 struct varshead *headp = NULL;
2832 if (it_cdr->fn_table == &finalized_state_fn_table) {
2835 if (!strcasecmp(channel_name, it_cdr->party_a.snapshot->name)) {
2836 headp = &it_cdr->party_a.variables;
2837 } else if (it_cdr->party_b.snapshot
2838 && !strcasecmp(channel_name, it_cdr->party_b.snapshot->name)) {
2839 headp = &it_cdr->party_b.variables;
2842 set_variable(headp, name, value);
2846 ao2_iterator_destroy(it_cdrs);
2852 * \brief Format a variable on a \ref cdr_object
2854 static void cdr_object_format_var_internal(struct cdr_object *cdr, const char *name, char *value, size_t length)
2856 struct ast_var_t *variable;
2858 AST_LIST_TRAVERSE(&cdr->party_a.variables, variable, entries) {
2859 if (!strcasecmp(name, ast_var_name(variable))) {
2860 ast_copy_string(value, ast_var_value(variable), length);
2869 * \brief Format one of the standard properties on a \ref cdr_object
2871 static int cdr_object_format_property(struct cdr_object *cdr_obj, const char *name, char *value, size_t length)
2873 struct ast_channel_snapshot *party_a = cdr_obj->party_a.snapshot;
2874 struct ast_channel_snapshot *party_b = cdr_obj->party_b.snapshot;
2876 if (!strcasecmp(name, "clid")) {
2877 ast_callerid_merge(value, length, party_a->caller_name, party_a->caller_number, "");
2878 } else if (!strcasecmp(name, "src")) {
2879 ast_copy_string(value, party_a->caller_number, length);
2880 } else if (!strcasecmp(name, "dst")) {
2881 ast_copy_string(value, party_a->exten, length);
2882 } else if (!strcasecmp(name, "dcontext")) {
2883 ast_copy_string(value, party_a->context, length);
2884 } else if (!strcasecmp(name, "channel")) {
2885 ast_copy_string(value, party_a->name, length);
2886 } else if (!strcasecmp(name, "dstchannel")) {
2888 ast_copy_string(value, party_b->name, length);
2890 ast_copy_string(value, "", length);
2892 } else if (!strcasecmp(name, "lastapp")) {
2893 ast_copy_string(value, party_a->appl, length);
2894 } else if (!strcasecmp(name, "lastdata")) {
2895 ast_copy_string(value, party_a->data, length);
2896 } else if (!strcasecmp(name, "start")) {
2897 cdr_get_tv(cdr_obj->start, NULL, value, length);
2898 } else if (!strcasecmp(name, "answer")) {
2899 cdr_get_tv(cdr_obj->answer, NULL, value, length);
2900 } else if (!strcasecmp(name, "end")) {
2901 cdr_get_tv(cdr_obj->end, NULL, value, length);
2902 } else if (!strcasecmp(name, "duration")) {
2903 snprintf(value, length, "%ld", cdr_object_get_duration(cdr_obj));
2904 } else if (!strcasecmp(name, "billsec")) {
2905 snprintf(value, length, "%ld", cdr_object_get_billsec(cdr_obj));
2906 } else if (!strcasecmp(name, "disposition")) {
2907 snprintf(value, length, "%d", cdr_obj->disposition);
2908 } else if (!strcasecmp(name, "amaflags")) {
2909 snprintf(value, length, "%d", party_a->amaflags);
2910 } else if (!strcasecmp(name, "accountcode")) {
2911 ast_copy_string(value, party_a->accountcode, length);
2912 } else if (!strcasecmp(name, "peeraccount")) {
2914 ast_copy_string(value, party_b->accountcode, length);
2916 ast_copy_string(value, "", length);
2918 } else if (!strcasecmp(name, "uniqueid")) {
2919 ast_copy_string(value, party_a->uniqueid, length);
2920 } else if (!strcasecmp(name, "linkedid")) {
2921 ast_copy_string(value, cdr_obj->linkedid, length);
2922 } else if (!strcasecmp(name, "userfield")) {
2923 ast_copy_string(value, cdr_obj->party_a.userfield, length);
2924 } else if (!strcasecmp(name, "sequence")) {
2925 snprintf(value, length, "%d", cdr_obj->sequence);
2934 * \brief Look up and retrieve a CDR object by channel name
2935 * \param name The name of the channel
2936 * \retval NULL on error
2937 * \retval The \ref cdr_object for the channel on success, with the reference
2938 * count bumped by one.
2940 static struct cdr_object *cdr_object_get_by_name(const char *name)
2944 if (ast_strlen_zero(name)) {
2948 param = ast_strdupa(name);
2949 return ao2_callback(active_cdrs_by_channel, 0, cdr_object_get_by_name_cb, param);
2952 int ast_cdr_getvar(const char *channel_name, const char *name, char *value, size_t length)
2954 RAII_VAR(struct cdr_object *, cdr, cdr_object_get_by_name(channel_name), ao2_cleanup);
2955 struct cdr_object *cdr_obj;
2958 ast_log(AST_LOG_ERROR, "Unable to find CDR for channel %s\n", channel_name);
2962 if (ast_strlen_zero(name)) {
2968 cdr_obj = cdr->last;
2969 if (cdr_object_format_property(cdr_obj, name, value, length)) {
2970 /* Property failed; attempt variable */
2971 cdr_object_format_var_internal(cdr_obj, name, value, length);
2979 int ast_cdr_serialize_variables(const char *channel_name, struct ast_str **buf, char delim, char sep)
2981 RAII_VAR(struct cdr_object *, cdr, cdr_object_get_by_name(channel_name), ao2_cleanup);
2982 struct cdr_object *it_cdr;
2983 struct ast_var_t *variable;
2985 RAII_VAR(char *, workspace, ast_malloc(256), ast_free);
2986 int total = 0, x = 0, i;
2993 ast_log(AST_LOG_ERROR, "Unable to find CDR for channel %s\n", channel_name);
2997 ast_str_reset(*buf);
3000 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3002 ast_str_append(buf, 0, "\n");
3004 AST_LIST_TRAVERSE(&it_cdr->party_a.variables, variable, entries) {
3005 if (!(var = ast_var_name(variable))) {
3009 if (ast_str_append(buf, 0, "level %d: %s%c%s%c", x, var, delim, S_OR(ast_var_value(variable), ""), sep) < 0) {
3010 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
3017 for (i = 0; cdr_readonly_vars[i]; i++) {
3018 if (cdr_object_format_property(it_cdr, cdr_readonly_vars[i], workspace, sizeof(workspace))) {
3019 /* Unhandled read-only CDR variable. */
3024 if (!ast_strlen_zero(workspace)
3025 && ast_str_append(buf, 0, "level %d: %s%c%s%c", x, cdr_readonly_vars[i], delim, workspace, sep) < 0) {
3026 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
3036 void ast_cdr_free(struct ast_cdr *cdr)
3039 struct ast_cdr *next = cdr->next;
3041 free_variables(&cdr->varshead);
3047 struct ast_cdr *ast_cdr_alloc(void)
3051 x = ast_calloc(1, sizeof(*x));
3055 const char *ast_cdr_disp2str(int disposition)
3057 switch (disposition) {
3059 return "NO ANSWER"; /* by default, for backward compatibility */
3060 case AST_CDR_NOANSWER:
3062 case AST_CDR_FAILED:
3066 case AST_CDR_ANSWERED:
3068 case AST_CDR_CONGESTION:
3069 return "CONGESTION";
3074 struct party_b_userfield_update {
3075 const char *channel_name;
3076 const char *userfield;
3079 /*! \brief Callback used to update the userfield on Party B on all CDRs */
3080 static int cdr_object_update_party_b_userfield_cb(void *obj, void *arg, int flags)
3082 struct cdr_object *cdr = obj;
3083 struct party_b_userfield_update *info = arg;
3084 struct cdr_object *it_cdr;
3085 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3086 if (it_cdr->fn_table == &finalized_state_fn_table) {
3089 if (it_cdr->party_b.snapshot
3090 && !strcasecmp(it_cdr->party_b.snapshot->name, info->channel_name)) {
3091 strcpy(it_cdr->party_b.userfield, info->userfield);
3097 void ast_cdr_setuserfield(const char *channel_name, const char *userfield)
3099 RAII_VAR(struct cdr_object *, cdr, cdr_object_get_by_name(channel_name), ao2_cleanup);
3100 struct party_b_userfield_update party_b_info = {
3101 .channel_name = channel_name,
3102 .userfield = userfield,
3104 struct cdr_object *it_cdr;
3106 /* Handle Party A */
3109 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3110 if (it_cdr->fn_table == &finalized_state_fn_table) {
3113 strcpy(it_cdr->party_a.userfield, userfield);
3118 /* Handle Party B */
3119 ao2_callback(active_cdrs_by_channel, OBJ_NODATA,
3120 cdr_object_update_party_b_userfield_cb,
3125 static void post_cdr(struct ast_cdr *cdr)
3127 RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
3128 struct cdr_beitem *i;
3130 for (; cdr ; cdr = cdr->next) {
3131 /* For people, who don't want to see unanswered single-channel events */
3132 if (!ast_test_flag(&mod_cfg->general->settings, CDR_UNANSWERED) &&
3133 cdr->disposition < AST_CDR_ANSWERED &&
3134 (ast_strlen_zero(cdr->channel) || ast_strlen_zero(cdr->dstchannel))) {
3135 ast_debug(1, "Skipping CDR for %s since we weren't answered\n", cdr->channel);
3139 if (ast_test_flag(cdr, AST_CDR_FLAG_DISABLE)) {
3142 AST_RWLIST_RDLOCK(&be_list);
3143 AST_RWLIST_TRAVERSE(&be_list, i, list) {
3146 AST_RWLIST_UNLOCK(&be_list);
3150 int ast_cdr_set_property(const char *channel_name, enum ast_cdr_options option)
3152 RAII_VAR(struct cdr_object *, cdr, cdr_object_get_by_name(channel_name), ao2_cleanup);
3153 struct cdr_object *it_cdr;
3160 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3161 if (it_cdr->fn_table == &finalized_state_fn_table) {
3164 /* Note: in general, set the flags on both the CDR record as well as the
3165 * Party A. Sometimes all we have is the Party A to look at.
3167 ast_set_flag(&it_cdr->flags, option);
3168 ast_set_flag(&it_cdr->party_a, option);
3175 int ast_cdr_clear_property(const char *channel_name, enum ast_cdr_options option)
3177 RAII_VAR(struct cdr_object *, cdr, cdr_object_get_by_name(channel_name), ao2_cleanup);
3178 struct cdr_object *it_cdr;
3185 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3186 if (it_cdr->fn_table == &finalized_state_fn_table) {
3189 ast_clear_flag(&it_cdr->flags, option);
3196 int ast_cdr_reset(const char *channel_name, struct ast_flags *options)
3198 RAII_VAR(struct cdr_object *, cdr, cdr_object_get_by_name(channel_name), ao2_cleanup);
3199 struct ast_var_t *vardata;
3200 struct cdr_object *it_cdr;
3207 for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3208 /* clear variables */
3209 if (!ast_test_flag(options, AST_CDR_FLAG_KEEP_VARS)) {
3210 while ((vardata = AST_LIST_REMOVE_HEAD(&it_cdr->party_a.variables, entries))) {
3211 ast_var_delete(vardata);
3213 if (cdr->party_b.snapshot) {
3214 while ((vardata = AST_LIST_REMOVE_HEAD(&it_cdr->party_b.variables, entries))) {
3215 ast_var_delete(vardata);
3220 /* Reset to initial state */
3221 memset(&it_cdr->start, 0, sizeof(it_cdr->start));
3222 memset(&it_cdr->end, 0, sizeof(it_cdr->end));
3223 memset(&it_cdr->answer, 0, sizeof(it_cdr->answer));
3224 it_cdr->start = ast_tvnow();
3225 cdr_object_check_party_a_answer(it_cdr);
3232 int ast_cdr_fork(const char *channel_name, struct ast_flags *options)
3234 RAII_VAR(struct cdr_object *, cdr, cdr_object_get_by_name(channel_name), ao2_cleanup);
3235 struct cdr_object *new_cdr;
3236 struct cdr_object *it_cdr;
3237 struct cdr_object *cdr_obj;
3244 SCOPED_AO2LOCK(lock, cdr);
3245 cdr_obj = cdr->last;
3246 if (cdr_obj->fn_table == &finalized_state_fn_table) {
3247 /* If the last CDR in the chain is finalized, don't allow a fork -
3248 * things are already dying at this point
3253 /* Copy over the basic CDR information. The Party A information is
3254 * copied over automatically as part of the append
3256 ast_debug(1, "Forking CDR for channel %s\n", cdr->party_a.snapshot->name);
3257 new_cdr = cdr_object_create_and_append(cdr);
3261 new_cdr->fn_table = cdr_obj->fn_table;
3262 ast_string_field_set(new_cdr, bridge, cdr->bridge);
3263 new_cdr->flags = cdr->flags;
3265 /* If there's a Party B, copy it over as well */
3266 if (cdr_obj->party_b.snapshot) {
3267 new_cdr->party_b.snapshot = cdr_obj->party_b.snapshot;
3268 ao2_ref(new_cdr->party_b.snapshot, +1);
3269 strcpy(new_cdr->party_b.userfield, cdr_obj->party_b.userfield);
3270 new_cdr->party_b.flags = cdr_obj->party_b.flags;
3271 if (ast_test_flag(options, AST_CDR_FLAG_KEEP_VARS)) {