Asterisk - The Open Source Telephony Project  21.4.1
cdr.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2006, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
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.
13  *
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.
17  */
18 
19 /*! \file
20  *
21  * \brief Call Detail Record API
22  *
23  * \author Mark Spencer <markster@digium.com>
24  *
25  * \note Includes code and algorithms from the Zapata library.
26  *
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.
31  */
32 
33 /*! \li \ref cdr.c uses the configuration file \ref cdr.conf
34  * \addtogroup configuration_file Configuration Files
35  */
36 
37 /*!
38  * \page cdr.conf cdr.conf
39  * \verbinclude cdr.conf.sample
40  */
41 
42 /*** MODULEINFO
43  <support_level>core</support_level>
44  ***/
45 
46 #include "asterisk.h"
47 
48 #include <signal.h>
49 #include <inttypes.h>
50 
51 #include "asterisk/lock.h"
52 #include "asterisk/channel.h"
53 #include "asterisk/cdr.h"
54 #include "asterisk/callerid.h"
55 #include "asterisk/manager.h"
56 #include "asterisk/module.h"
57 #include "asterisk/causes.h"
58 #include "asterisk/linkedlists.h"
59 #include "asterisk/utils.h"
60 #include "asterisk/sched.h"
61 #include "asterisk/config.h"
62 #include "asterisk/cli.h"
63 #include "asterisk/stringfields.h"
65 #include "asterisk/json.h"
66 #include "asterisk/parking.h"
67 #include "asterisk/stasis.h"
68 #include "asterisk/stasis_channels.h"
69 #include "asterisk/stasis_bridges.h"
70 #include "asterisk/stasis_message_router.h"
71 #include "asterisk/astobj2.h"
72 #include "asterisk/taskprocessor.h"
73 
74 /*** DOCUMENTATION
75  <configInfo name="cdr" language="en_US">
76  <synopsis>Call Detail Record configuration</synopsis>
77  <description>
78  <para>CDR is Call Detail Record, which provides logging services via a variety of
79  pluggable backend modules. Detailed call information can be recorded to
80  databases, files, etc. Useful for billing, fraud prevention, compliance with
81  Sarbanes-Oxley aka The Enron Act, QOS evaluations, and more.</para>
82  </description>
83  <configFile name="cdr.conf">
84  <configObject name="general">
85  <synopsis>Global settings applied to the CDR engine.</synopsis>
86  <configOption name="debug">
87  <synopsis>Enable/disable verbose CDR debugging.</synopsis>
88  <description><para>When set to <literal>True</literal>, verbose updates
89  of changes in CDR information will be logged. Note that this is only
90  of use when debugging CDR behavior.</para>
91  </description>
92  </configOption>
93  <configOption name="enable" default="yes">
94  <synopsis>Enable/disable CDR logging.</synopsis>
95  <description><para>Define whether or not to use CDR logging. Setting this to "no" will override
96  any loading of backend CDR modules.</para>
97  </description>
98  </configOption>
99  <configOption name="channeldefaultenabled" default="yes">
100  <synopsis>Whether CDR is enabled on a channel by default</synopsis>
101  <description><para>Define whether or not CDR should be enabled on a channel by default.
102  Setting this to "yes" will enable CDR on every channel unless it is explicitly disabled.
103  Setting this to "no" will disable CDR on every channel unless it is explicitly enabled.
104  </para>
105  <para>Note that CDR must still be globally enabled (<literal>enable = yes</literal>) for this
106  option to have any effect. This only applies to whether CDR is enabled or disabled on
107  newly created channels, which can be changed in the dialplan during a call.</para>
108  <para>If this is set to "yes", you should use <literal>Set(CDR_PROP(disable)=1)</literal>
109  to disable CDR for a call.</para>
110  <para>If this is set to "no", you should use <literal>Set(CDR_PROP(disable)=0)</literal>
111  to undisable (enable) CDR for a call.</para>
112  </description>
113  </configOption>
114  <configOption name="ignorestatechanges" default="no">
115  <synopsis>Whether CDR is updated or forked by bridging changes.</synopsis>
116  <description><para>Define whether or not CDR should be updated by bridging changes.
117  This includes entering and leaving bridges and call parking.</para>
118  <para>If this is set to "no", bridging changes will be ignored for all CDRs.
119  This should only be done if these events should not affect CDRs and are undesired,
120  such as to use a single CDR for the lifetime of the channel.</para>
121  <para>This setting cannot be changed on a reload.</para>
122  </description>
123  </configOption>
124  <configOption name="ignoredialchanges" default="no">
125  <synopsis>Whether CDR is updated or forked by dial updates.</synopsis>
126  <description><para>Define whether or not CDR should be updated by dial updates.</para>
127  <para>If this is set to "no", a single CDR will be used for the channel, even if
128  multiple endpoints or destinations are dialed sequentially. Note that you will also
129  lose detailed nonanswer dial dispositions if this option is enabled, which may not be acceptable,
130  e.g. instead of detailed no-answer dispositions like BUSY and CONGESTION, the disposition
131  will always be NO ANSWER if the channel was unanswered (it will still be ANSWERED
132  if the channel was answered).</para>
133  <para>This option should be enabled if a single CDR is desired for the lifetime of
134  the channel.</para>
135  </description>
136  </configOption>
137  <configOption name="unanswered">
138  <synopsis>Log calls that are never answered and don't set an outgoing party.</synopsis>
139  <description><para>
140  Define whether or not to log unanswered calls that don't involve an outgoing party. Setting
141  this to "yes" will make calls to extensions that don't answer and don't set a side B channel
142  (such as by using the Dial application) receive CDR log entries. If this option is set to
143  "no", then those log entries will not be created. Unanswered calls which get offered to an
144  outgoing line will always receive log entries regardless of this option, and that is the
145  intended behavior.
146  </para>
147  </description>
148  </configOption>
149  <configOption name="congestion">
150  <synopsis>Log congested calls.</synopsis>
151  <description><para>Define whether or not to log congested calls. Setting this to "yes" will
152  report each call that fails to complete due to congestion conditions.</para>
153  </description>
154  </configOption>
155  <configOption name="endbeforehexten">
156  <synopsis>Don't produce CDRs while executing hangup logic</synopsis>
157  <description>
158  <para>As each CDR for a channel is finished, its end time is updated
159  and the CDR is finalized. When a channel is hung up and hangup
160  logic is present (in the form of a hangup handler or the
161  <literal>h</literal> extension), a new CDR is generated for the
162  channel. Any statistics are gathered from this new CDR. By enabling
163  this option, no new CDR is created for the dialplan logic that is
164  executed in <literal>h</literal> extensions or attached hangup handler
165  subroutines. The default value is <literal>yes</literal>, indicating
166  that a CDR will be generated during hangup logic.</para>
167  </description>
168  </configOption>
169  <configOption name="initiatedseconds">
170  <synopsis>Count microseconds for billsec purposes</synopsis>
171  <description><para>Normally, the <literal>billsec</literal> field logged to the CDR backends
172  is simply the end time (hangup time) minus the answer time in seconds. Internally,
173  asterisk stores the time in terms of microseconds and seconds. By setting
174  initiatedseconds to <literal>yes</literal>, you can force asterisk to report any seconds
175  that were initiated (a sort of round up method). Technically, this is
176  when the microsecond part of the end time is greater than the microsecond
177  part of the answer time, then the billsec time is incremented one second.</para>
178  </description>
179  </configOption>
180  <configOption name="batch">
181  <synopsis>Submit CDRs to the backends for processing in batches</synopsis>
182  <description><para>Define the CDR batch mode, where instead of posting the CDR at the end of
183  every call, the data will be stored in a buffer to help alleviate load on the
184  asterisk server.</para>
185  <warning><para>Use of batch mode may result in data loss after unsafe asterisk termination,
186  i.e., software crash, power failure, kill -9, etc.</para>
187  </warning>
188  </description>
189  </configOption>
190  <configOption name="size">
191  <synopsis>The maximum number of CDRs to accumulate before triggering a batch</synopsis>
192  <description><para>Define the maximum number of CDRs to accumulate in the buffer before posting
193  them to the backend engines. batch must be set to <literal>yes</literal>.</para>
194  </description>
195  </configOption>
196  <configOption name="time">
197  <synopsis>The maximum time to accumulate CDRs before triggering a batch</synopsis>
198  <description><para>Define the maximum time to accumulate CDRs before posting them in a batch to the
199  backend engines. If this time limit is reached, then it will post the records, regardless of the value
200  defined for size. batch must be set to <literal>yes</literal>.</para>
201  <note><para>Time is expressed in seconds.</para></note>
202  </description>
203  </configOption>
204  <configOption name="scheduleronly">
205  <synopsis>Post batched CDRs on their own thread instead of the scheduler</synopsis>
206  <description><para>The CDR engine uses the internal asterisk scheduler to determine when to post
207  records. Posting can either occur inside the scheduler thread, or a new
208  thread can be spawned for the submission of every batch. For small batches,
209  it might be acceptable to just use the scheduler thread, so set this to <literal>yes</literal>.
210  For large batches, say anything over size=10, a new thread is recommended, so
211  set this to <literal>no</literal>.</para>
212  </description>
213  </configOption>
214  <configOption name="safeshutdown">
215  <synopsis>Block shutdown of Asterisk until CDRs are submitted</synopsis>
216  <description><para>When shutting down asterisk, you can block until the CDRs are submitted. If
217  you don't, then data will likely be lost. You can always check the size of
218  the CDR batch buffer with the CLI <astcli>cdr status</astcli> command. To enable blocking on
219  submission of CDR data during asterisk shutdown, set this to <literal>yes</literal>.</para>
220  </description>
221  </configOption>
222  </configObject>
223  </configFile>
224  </configInfo>
225  ***/
226 
227 #define DEFAULT_ENABLED "1"
228 #define DEFAULT_BATCHMODE "0"
229 #define DEFAULT_UNANSWERED "0"
230 #define DEFAULT_CONGESTION "0"
231 #define DEFAULT_END_BEFORE_H_EXTEN "1"
232 #define DEFAULT_INITIATED_SECONDS "0"
233 #define DEFAULT_CHANNEL_ENABLED "1"
234 #define DEFAULT_IGNORE_STATE_CHANGES "0"
235 #define DEFAULT_IGNORE_DIAL_CHANGES "0"
236 
237 #define DEFAULT_BATCH_SIZE "100"
238 #define MAX_BATCH_SIZE 1000
239 #define DEFAULT_BATCH_TIME "300"
240 #define MAX_BATCH_TIME 86400
241 #define DEFAULT_BATCH_SCHEDULER_ONLY "0"
242 #define DEFAULT_BATCH_SAFE_SHUTDOWN "1"
243 
244 #define cdr_set_debug_mode(mod_cfg) \
245  do { \
246  cdr_debug_enabled = ast_test_flag(&(mod_cfg)->general->settings, CDR_DEBUG); \
247  } while (0)
248 
249 static int cdr_debug_enabled;
250 static int dial_changes_ignored;
251 
252 #define CDR_DEBUG(fmt, ...) \
253  do { \
254  if (cdr_debug_enabled) { \
255  ast_verbose((fmt), ##__VA_ARGS__); \
256  } \
257  } while (0)
258 
259 static void cdr_detach(struct ast_cdr *cdr);
260 static void cdr_submit_batch(int shutdown);
261 static int cdr_toggle_runtime_options(void);
262 
263 /*! \brief The configuration settings for this module */
265  struct ast_cdr_config *general; /*!< CDR global settings */
266 };
267 
268 /*! \brief The container for the module configuration */
269 static AO2_GLOBAL_OBJ_STATIC(module_configs);
270 
271 /*! \brief The type definition for general options */
272 static struct aco_type general_option = {
273  .type = ACO_GLOBAL,
274  .name = "general",
275  .item_offset = offsetof(struct module_config, general),
276  .category = "general",
277  .category_match = ACO_WHITELIST_EXACT,
278 };
279 
280 /*! Config sections used by existing modules. Do not add to this list. */
281 static const char *ignore_categories[] = {
282  "csv",
283  "custom",
284  "manager",
285  "odbc",
286  "pgsql",
287  "radius",
288  "sqlite",
289  "tds",
290  "mysql",
291  NULL,
292 };
293 
294 static struct aco_type ignore_option = {
295  .type = ACO_IGNORE,
296  .name = "modules",
297  .category = (const char*)ignore_categories,
299 };
300 
301 static void *module_config_alloc(void);
302 static void module_config_destructor(void *obj);
303 static void module_config_post_apply(void);
304 
305 /*! \brief The file definition */
306 static struct aco_file module_file_conf = {
307  .filename = "cdr.conf",
308  .types = ACO_TYPES(&general_option, &ignore_option),
309 };
310 
311 CONFIG_INFO_CORE("cdr", cfg_info, module_configs, module_config_alloc,
312  .files = ACO_FILES(&module_file_conf),
313  .post_apply_config = module_config_post_apply,
314 );
315 
316 static struct aco_type *general_options[] = ACO_TYPES(&general_option);
317 
318 static void module_config_post_apply(void)
319 {
320  struct module_config *mod_cfg;
321 
322  mod_cfg = ao2_global_obj_ref(module_configs);
323  if (!mod_cfg) {
324  return;
325  }
326  cdr_set_debug_mode(mod_cfg);
327  ao2_cleanup(mod_cfg);
328 }
329 
330 /*! \brief Dispose of a module config object */
331 static void module_config_destructor(void *obj)
332 {
333  struct module_config *cfg = obj;
334 
335  if (!cfg) {
336  return;
337  }
338  ao2_ref(cfg->general, -1);
339 }
340 
341 /*! \brief Create a new module config object */
342 static void *module_config_alloc(void)
343 {
344  struct module_config *mod_cfg;
345  struct ast_cdr_config *cdr_config;
346 
347  mod_cfg = ao2_alloc(sizeof(*mod_cfg), module_config_destructor);
348  if (!mod_cfg) {
349  return NULL;
350  }
351 
352  cdr_config = ao2_alloc(sizeof(*cdr_config), NULL);
353  if (!cdr_config) {
354  ao2_ref(cdr_config, -1);
355  return NULL;
356  }
357  mod_cfg->general = cdr_config;
358 
359  return mod_cfg;
360 }
361 
362 /*! \brief Registration object for CDR backends */
363 struct cdr_beitem {
364  char name[20];
365  char desc[80];
366  ast_cdrbe be;
367  AST_RWLIST_ENTRY(cdr_beitem) list;
368  int suspended:1;
369 };
370 
371 /*! \brief List of registered backends */
373 
374 /*! \brief List of registered modifiers */
376 
377 /*! \brief Queued CDR waiting to be batched */
379  struct ast_cdr *cdr;
380  struct cdr_batch_item *next;
381 };
382 
383 /*! \brief The actual batch queue */
384 static struct cdr_batch {
385  int size;
386  struct cdr_batch_item *head;
387  struct cdr_batch_item *tail;
388 } *batch = NULL;
389 
390 /*! \brief The global sequence counter used for CDRs */
391 static int global_cdr_sequence = 0;
392 
393 /*! \brief Scheduler items */
394 static struct ast_sched_context *sched;
395 static int cdr_sched = -1;
396 AST_MUTEX_DEFINE_STATIC(cdr_sched_lock);
397 static pthread_t cdr_thread = AST_PTHREADT_NULL;
398 
399 /*! \brief Lock protecting modifications to the batch queue */
400 AST_MUTEX_DEFINE_STATIC(cdr_batch_lock);
401 
402 /*! \brief These are used to wake up the CDR thread when there's work to do */
403 AST_MUTEX_DEFINE_STATIC(cdr_pending_lock);
404 static ast_cond_t cdr_pending_cond;
405 
406 /*! \brief A container of the active master CDRs indexed by Party A channel uniqueid */
408 
409 /*! \brief A container of all active CDRs with a Party B indexed by Party B channel name */
411 
412 /*! \brief Message router for stasis messages regarding channel state */
414 
415 /*! \brief Our subscription for bridges */
417 
418 /*! \brief Our subscription for channels */
420 
421 /*! \brief Our subscription for parking */
423 
424 /*! \brief The parent topic for all topics we want to aggregate for CDRs */
425 static struct stasis_topic *cdr_topic;
426 
427 /*! \brief A message type used to synchronize with the CDR topic */
428 STASIS_MESSAGE_TYPE_DEFN_LOCAL(cdr_sync_message_type);
429 
430 struct cdr_object;
431 
432 /*! \brief Return types for \p process_bridge_enter functions */
434  /*!
435  * The CDR was the only party in the bridge.
436  */
438  /*!
439  * The CDR was able to obtain a Party B from some other party already in the bridge
440  */
442  /*!
443  * The CDR was not able to obtain a Party B
444  */
446  /*!
447  * This CDR can't handle a bridge enter message and a new CDR needs to be created
448  */
450 };
451 
452 /*!
453  * \brief A virtual table used for \ref cdr_object.
454  *
455  * Note that all functions are optional - if a subclass does not need an
456  * implementation, it is safe to leave it NULL.
457  */
459  /*! \brief Name of the subclass */
460  const char *name;
461 
462  /*!
463  * \brief An initialization function. This will be called automatically
464  * when a \ref cdr_object is switched to this type in
465  * \ref cdr_object_transition_state
466  *
467  * \param cdr The \ref cdr_object that was just transitioned
468  */
469  void (* const init_function)(struct cdr_object *cdr);
470 
471  /*!
472  * \brief Process a Party A update for the \ref cdr_object
473  *
474  * \param cdr The \ref cdr_object to process the update
475  * \param snapshot The snapshot for the CDR's Party A
476  * \retval 0 the CDR handled the update or ignored it
477  * \retval 1 the CDR is finalized and a new one should be made to handle it
478  */
479  int (* const process_party_a)(struct cdr_object *cdr,
480  struct ast_channel_snapshot *snapshot);
481 
482  /*!
483  * \brief Process a Party B update for the \ref cdr_object
484  *
485  * \param cdr The \ref cdr_object to process the update
486  * \param snapshot The snapshot for the CDR's Party B
487  */
488  void (* const process_party_b)(struct cdr_object *cdr,
489  struct ast_channel_snapshot *snapshot);
490 
491  /*!
492  * \brief Process the beginning of a dial. A dial message implies one of two
493  * things:
494  * The \ref cdr_object's Party A has been originated
495  * The \ref cdr_object's Party A is dialing its Party B
496  *
497  * \param cdr The \ref cdr_object
498  * \param caller The originator of the dial attempt
499  * \param peer The destination of the dial attempt
500  *
501  * \retval 0 if the parties in the dial were handled by this CDR
502  * \retval 1 if the parties could not be handled by this CDR
503  */
504  int (* const process_dial_begin)(struct cdr_object *cdr,
506  struct ast_channel_snapshot *peer);
507 
508  /*!
509  * \brief Process the end of a dial. At the end of a dial, a CDR can be
510  * transitioned into one of two states - DialedPending
511  * (\ref dialed_pending_state_fn_table) or Finalized
512  * (\ref finalized_state_fn_table).
513  *
514  * \param cdr The \ref cdr_object
515  * \param caller The originator of the dial attempt
516  * \param peer the Destination of the dial attempt
517  * \param dial_status What happened
518  *
519  * \retval 0 if the parties in the dial were handled by this CDR
520  * \retval 1 if the parties could not be handled by this CDR
521  */
522  int (* const process_dial_end)(struct cdr_object *cdr,
524  struct ast_channel_snapshot *peer,
525  const char *dial_status);
526 
527  /*!
528  * \brief Process the entering of a bridge by this CDR. The purpose of this
529  * callback is to have the CDR prepare itself for the bridge and attempt to
530  * find a valid Party B. The act of creating new CDRs based on the entering
531  * of this channel into the bridge is handled by the higher level message
532  * handler.
533  *
534  * Note that this handler is for when a channel enters into a "normal"
535  * bridge, where people actually talk to each other. Parking is its own
536  * thing.
537  *
538  * \param cdr The \ref cdr_object
539  * \param bridge The bridge that the Party A just entered into
540  * \param channel The \ref ast_channel_snapshot for this CDR's Party A
541  *
542  * \return process_bridge_enter_results Defines whether or not this CDR was able
543  * to fully handle the bridge enter message.
544  */
546  struct cdr_object *cdr,
547  struct ast_bridge_snapshot *bridge,
548  struct ast_channel_snapshot *channel);
549 
550  /*!
551  * \brief Process entering into a parking bridge.
552  *
553  * \param cdr The \ref cdr_object
554  * \param bridge The parking bridge that Party A just entered into
555  * \param channel The \ref ast_channel_snapshot for this CDR's Party A
556  *
557  * \retval 0 This CDR successfully transitioned itself into the parked state
558  * \retval 1 This CDR couldn't handle the parking transition and we need a
559  * new CDR.
560  */
561  int (* const process_parking_bridge_enter)(struct cdr_object *cdr,
562  struct ast_bridge_snapshot *bridge,
563  struct ast_channel_snapshot *channel);
564 
565  /*!
566  * \brief Process the leaving of a bridge by this CDR.
567  *
568  * \param cdr The \ref cdr_object
569  * \param bridge The bridge that the Party A just left
570  * \param channel The \ref ast_channel_snapshot for this CDR's Party A
571  *
572  * \retval 0 This CDR left successfully
573  * \retval 1 Error
574  */
575  int (* const process_bridge_leave)(struct cdr_object *cdr,
576  struct ast_bridge_snapshot *bridge,
577  struct ast_channel_snapshot *channel);
578 
579  /*!
580  * \brief Process an update informing us that the channel got itself parked
581  *
582  * \param cdr The \ref cdr_object
583  * \param channel The parking information for this CDR's party A
584  *
585  * \retval 0 This CDR successfully parked itself
586  * \retval 1 This CDR couldn't handle the park
587  */
588  int (* const process_parked_channel)(struct cdr_object *cdr,
589  struct ast_parked_call_payload *parking_info);
590 };
591 
592 static int base_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot);
593 static enum process_bridge_enter_results base_process_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
594 static int base_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
595 static int base_process_dial_end(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer, const char *dial_status);
596 static int base_process_parked_channel(struct cdr_object *cdr, struct ast_parked_call_payload *parking_info);
597 
598 static void single_state_init_function(struct cdr_object *cdr);
599 static void single_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot);
600 static int single_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer);
601 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);
602 static int single_state_process_parking_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
603 
604 /*!
605  * \brief The virtual table for the Single state.
606  *
607  * A \ref cdr_object starts off in this state. This represents a channel that
608  * has no Party B information itself.
609  *
610  * A \ref cdr_object from this state can go into any of the following states:
611  * * \ref dial_state_fn_table
612  * * \ref bridge_state_fn_table
613  * * \ref finalized_state_fn_table
614  */
616  .name = "Single",
617  .init_function = single_state_init_function,
618  .process_party_a = base_process_party_a,
619  .process_party_b = single_state_process_party_b,
620  .process_dial_begin = single_state_process_dial_begin,
621  .process_dial_end = base_process_dial_end,
622  .process_bridge_enter = single_state_process_bridge_enter,
623  .process_parking_bridge_enter = single_state_process_parking_bridge_enter,
624  .process_bridge_leave = base_process_bridge_leave,
625  .process_parked_channel = base_process_parked_channel,
626 };
627 
628 static void dial_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot);
629 static int dial_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer);
630 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);
631 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);
632 
633 /*!
634  * \brief The virtual table for the Dial state.
635  *
636  * A \ref cdr_object that has begun a dial operation. This state is entered when
637  * the Party A for a CDR is determined to be dialing out to a Party B or when
638  * a CDR is for an originated channel (in which case the Party A information is
639  * the originated channel, and there is no Party B).
640  *
641  * A \ref cdr_object from this state can go in any of the following states:
642  * * \ref dialed_pending_state_fn_table
643  * * \ref bridge_state_fn_table
644  * * \ref finalized_state_fn_table
645  */
647  .name = "Dial",
648  .process_party_a = base_process_party_a,
649  .process_party_b = dial_state_process_party_b,
650  .process_dial_begin = dial_state_process_dial_begin,
651  .process_dial_end = dial_state_process_dial_end,
652  .process_bridge_enter = dial_state_process_bridge_enter,
653  .process_bridge_leave = base_process_bridge_leave,
654 };
655 
656 static int dialed_pending_state_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot);
657 static int dialed_pending_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer);
658 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);
659 static int dialed_pending_state_process_parking_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
660 
661 /*!
662  * \brief The virtual table for the Dialed Pending state.
663  *
664  * A \ref cdr_object that has successfully finished a dial operation, but we
665  * don't know what they're going to do yet. It's theoretically possible to dial
666  * a party and then have that party not be bridged with the caller; likewise,
667  * an origination can complete and the channel go off and execute dialplan. The
668  * pending state acts as a bridge between either:
669  * * Entering a bridge
670  * * Getting a new CDR for new dialplan execution
671  * * Switching from being originated to executing dialplan
672  *
673  * A \ref cdr_object from this state can go in any of the following states:
674  * * \ref single_state_fn_table
675  * * \ref dialed_pending_state_fn_table
676  * * \ref bridge_state_fn_table
677  * * \ref finalized_state_fn_table
678  */
680  .name = "DialedPending",
681  .process_party_a = dialed_pending_state_process_party_a,
682  .process_dial_begin = dialed_pending_state_process_dial_begin,
683  .process_bridge_enter = dialed_pending_state_process_bridge_enter,
684  .process_parking_bridge_enter = dialed_pending_state_process_parking_bridge_enter,
685  .process_bridge_leave = base_process_bridge_leave,
686  .process_parked_channel = base_process_parked_channel,
687 };
688 
689 static void bridge_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot);
690 static int bridge_state_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
691 
692 /*!
693  * \brief The virtual table for the Bridged state
694  *
695  * A \ref cdr_object enters this state when it receives notification that the
696  * channel has entered a bridge.
697  *
698  * A \ref cdr_object from this state can go to:
699  * * \ref finalized_state_fn_table
700  */
702  .name = "Bridged",
703  .process_party_a = base_process_party_a,
704  .process_party_b = bridge_state_process_party_b,
705  .process_bridge_leave = bridge_state_process_bridge_leave,
706  .process_parked_channel = base_process_parked_channel,
707 };
708 
709 static int parked_state_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
710 
711 /*!
712  * \brief The virtual table for the Parked state
713  *
714  * Parking is weird. Unlike typical bridges, it has to be treated somewhat
715  * uniquely - a channel in a parking bridge (which is a subclass of a holding
716  * bridge) has to be handled as if the channel went into an application.
717  * However, when the channel comes out, we need a new CDR - unlike the Single
718  * state.
719  */
721  .name = "Parked",
722  .process_party_a = base_process_party_a,
723  .process_bridge_leave = parked_state_process_bridge_leave,
724  .process_parked_channel = base_process_parked_channel,
725 };
726 
727 static void finalized_state_init_function(struct cdr_object *cdr);
728 static int finalized_state_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot);
729 
730 /*!
731  * \brief The virtual table for the finalized state.
732  *
733  * Once in the finalized state, the CDR is done. No modifications can be made
734  * to the CDR.
735  */
737  .name = "Finalized",
738  .init_function = finalized_state_init_function,
739  .process_party_a = finalized_state_process_party_a,
740  .process_bridge_enter = base_process_bridge_enter,
741 };
742 
743 /*! \brief A wrapper object around a snapshot.
744  * Fields that are mutable by the CDR engine are replicated here.
745  */
747  struct ast_channel_snapshot *snapshot; /*!< The channel snapshot */
748  char userfield[AST_MAX_USER_FIELD]; /*!< Userfield for the channel */
749  unsigned int flags; /*!< Specific flags for this party */
750  struct varshead variables; /*!< CDR variables for the channel */
751 };
752 
753 /*! \brief An in-memory representation of an active CDR */
754 struct cdr_object {
755  struct cdr_object_snapshot party_a; /*!< The Party A information */
756  struct cdr_object_snapshot party_b; /*!< The Party B information */
757  struct cdr_object_fn_table *fn_table; /*!< The current virtual table */
758 
759  enum ast_cdr_disposition disposition; /*!< The disposition of the CDR */
760  struct timeval start; /*!< When this CDR was created */
761  struct timeval answer; /*!< Either when the channel was answered, or when the path between channels was established */
762  struct timeval end; /*!< When this CDR was finalized */
763  struct timeval lastevent; /*!< The time at which the last event was created regarding this CDR */
764  unsigned int sequence; /*!< A monotonically increasing number for each CDR */
765  struct ast_flags flags; /*!< Flags on the CDR */
767  AST_STRING_FIELD(linkedid); /*!< Linked ID. Cached here as it may change out from party A, which must be immutable */
768  AST_STRING_FIELD(uniqueid); /*!< Unique id of party A. Cached here as it is the master CDR container key */
769  AST_STRING_FIELD(name); /*!< Channel name of party A. Cached here as the party A address may change */
770  AST_STRING_FIELD(bridge); /*!< The bridge the party A happens to be in. */
771  AST_STRING_FIELD(appl); /*!< The last accepted application party A was in */
772  AST_STRING_FIELD(data); /*!< The data for the last accepted application party A was in */
773  AST_STRING_FIELD(context); /*!< The accepted context for Party A */
774  AST_STRING_FIELD(exten); /*!< The accepted extension for Party A */
775  AST_STRING_FIELD(party_b_name); /*!< Party B channel name. Cached here as it is the all CDRs container key */
776  );
777  struct cdr_object *next; /*!< The next CDR object in the chain */
778  struct cdr_object *last; /*!< The last CDR object in the chain */
779  int is_root; /*!< True if this is the first CDR in the chain */
780 };
781 
782 /*!
783  * \brief Copy variables from one list to another
784  * \param to_list destination
785  * \param from_list source
786  * \return The number of copied variables
787  */
788 static int copy_variables(struct varshead *to_list, struct varshead *from_list)
789 {
790  struct ast_var_t *variables;
791  struct ast_var_t *newvariable;
792  const char *var;
793  const char *val;
794  int x = 0;
795 
796  AST_LIST_TRAVERSE(from_list, variables, entries) {
797  var = ast_var_name(variables);
798  if (ast_strlen_zero(var)) {
799  continue;
800  }
801  val = ast_var_value(variables);
802  if (ast_strlen_zero(val)) {
803  continue;
804  }
805  newvariable = ast_var_assign(var, val);
806  if (newvariable) {
807  AST_LIST_INSERT_HEAD(to_list, newvariable, entries);
808  ++x;
809  }
810  }
811 
812  return x;
813 }
814 
815 /*!
816  * \brief Delete all variables from a variable list
817  * \param headp The head pointer to the variable list to delete
818  */
819 static void free_variables(struct varshead *headp)
820 {
821  struct ast_var_t *vardata;
822 
823  while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries))) {
824  ast_var_delete(vardata);
825  }
826 }
827 
828 /*!
829  * \brief Copy a snapshot and its details
830  * \param dst The destination
831  * \param src The source
832  */
834 {
835  ao2_t_replace(dst->snapshot, src->snapshot, "CDR snapshot copy");
836  strcpy(dst->userfield, src->userfield);
837  dst->flags = src->flags;
838  copy_variables(&dst->variables, &src->variables);
839 }
840 
841 /*!
842  * \brief Transition a \ref cdr_object to a new state with initiation flag
843  * \param cdr The \ref cdr_object to transition
844  * \param fn_table The \ref cdr_object_fn_table state to go to
845  * \param do_init
846  */
847 static void cdr_object_transition_state_init(struct cdr_object *cdr, struct cdr_object_fn_table *fn_table, int do_init)
848 {
849  CDR_DEBUG("%p - Transitioning CDR for %s from state %s to %s\n",
850  cdr, cdr->party_a.snapshot->base->name,
851  cdr->fn_table ? cdr->fn_table->name : "NONE", fn_table->name);
852  cdr->fn_table = fn_table;
853 
854  if (cdr->fn_table->init_function && do_init) {
855  cdr->fn_table->init_function(cdr);
856  }
857 }
858 
859 /*!
860  * \brief Transition a \ref cdr_object to a new state
861  * \param cdr The \ref cdr_object to transition
862  * \param fn_table The \ref cdr_object_fn_table state to go to
863  */
864 static void cdr_object_transition_state(struct cdr_object *cdr, struct cdr_object_fn_table *fn_table)
865 {
866  cdr_object_transition_state_init(cdr, fn_table, 1);
867 }
868 
869 /*!
870  * \internal
871  * \brief Hash function for master CDR container indexed by Party A uniqueid.
872  */
873 static int cdr_master_hash_fn(const void *obj, const int flags)
874 {
875  const struct cdr_object *cdr;
876  const char *key;
877 
878  switch (flags & OBJ_SEARCH_MASK) {
879  case OBJ_SEARCH_KEY:
880  key = obj;
881  break;
882  case OBJ_SEARCH_OBJECT:
883  cdr = obj;
884  key = cdr->uniqueid;
885  break;
886  default:
887  ast_assert(0);
888  return 0;
889  }
890  return ast_str_case_hash(key);
891 }
892 
893 /*!
894  * \internal
895  * \brief Comparison function for master CDR container indexed by Party A uniqueid.
896  */
897 static int cdr_master_cmp_fn(void *obj, void *arg, int flags)
898 {
899  struct cdr_object *left = obj;
900  struct cdr_object *right = arg;
901  const char *right_key = arg;
902  int cmp;
903 
904  switch (flags & OBJ_SEARCH_MASK) {
905  case OBJ_SEARCH_OBJECT:
906  right_key = right->uniqueid;
907  /* Fall through */
908  case OBJ_SEARCH_KEY:
909  cmp = strcmp(left->uniqueid, right_key);
910  break;
912  /*
913  * We could also use a partial key struct containing a length
914  * so strlen() does not get called for every comparison instead.
915  */
916  cmp = strncmp(left->uniqueid, right_key, strlen(right_key));
917  break;
918  default:
919  /* Sort can only work on something with a full or partial key. */
920  ast_assert(0);
921  cmp = 0;
922  break;
923  }
924  return cmp ? 0 : CMP_MATCH;
925 }
926 
927 /*!
928  * \internal
929  * \brief Hash function for all CDR container indexed by Party B channel name.
930  */
931 static int cdr_all_hash_fn(const void *obj, const int flags)
932 {
933  const struct cdr_object *cdr;
934  const char *key;
935 
936  switch (flags & OBJ_SEARCH_MASK) {
937  case OBJ_SEARCH_KEY:
938  key = obj;
939  break;
940  case OBJ_SEARCH_OBJECT:
941  cdr = obj;
942  key = cdr->party_b_name;
943  break;
944  default:
945  ast_assert(0);
946  return 0;
947  }
948  return ast_str_case_hash(key);
949 }
950 
951 /*!
952  * \internal
953  * \brief Comparison function for all CDR container indexed by Party B channel name.
954  */
955 static int cdr_all_cmp_fn(void *obj, void *arg, int flags)
956 {
957  struct cdr_object *left = obj;
958  struct cdr_object *right = arg;
959  const char *right_key = arg;
960  int cmp;
961 
962  switch (flags & OBJ_SEARCH_MASK) {
963  case OBJ_SEARCH_OBJECT:
964  right_key = right->party_b_name;
965  /* Fall through */
966  case OBJ_SEARCH_KEY:
967  cmp = strcasecmp(left->party_b_name, right_key);
968  break;
970  /*
971  * We could also use a partial key struct containing a length
972  * so strlen() does not get called for every comparison instead.
973  */
974  cmp = strncasecmp(left->party_b_name, right_key, strlen(right_key));
975  break;
976  default:
977  /* Sort can only work on something with a full or partial key. */
978  ast_assert(0);
979  cmp = 0;
980  break;
981  }
982  return cmp ? 0 : CMP_MATCH;
983 }
984 
985 /*!
986  * \internal
987  * \brief Relink the CDR because Party B's snapshot changed.
988  * \since 13.19.0
989  */
990 static void cdr_all_relink(struct cdr_object *cdr)
991 {
992  ao2_lock(active_cdrs_all);
993  if (cdr->party_b.snapshot) {
994  if (strcasecmp(cdr->party_b_name, cdr->party_b.snapshot->base->name)) {
995  ao2_unlink_flags(active_cdrs_all, cdr, OBJ_NOLOCK);
997  ao2_link_flags(active_cdrs_all, cdr, OBJ_NOLOCK);
998  }
999  } else {
1000  ao2_unlink_flags(active_cdrs_all, cdr, OBJ_NOLOCK);
1002  }
1003  ao2_unlock(active_cdrs_all);
1004 }
1005 
1006 /*!
1007  * \internal
1008  * \brief Unlink the master CDR and chained records from the active_cdrs_all container.
1009  * \since 13.19.0
1010  */
1011 static void cdr_all_unlink(struct cdr_object *cdr)
1012 {
1013  struct cdr_object *cur;
1014  struct cdr_object *next;
1015 
1016  ast_assert(cdr->is_root);
1017 
1018  /* Hold a ref to the root CDR to ensure the list members don't go away on us. */
1019  ao2_ref(cdr, +1);
1020  ao2_lock(active_cdrs_all);
1021  for (cur = cdr; cur; cur = next) {
1022  next = cur->next;
1023  ao2_unlink_flags(active_cdrs_all, cur, OBJ_NOLOCK);
1024  /*
1025  * It is safe to still use cur after unlinking because the
1026  * root CDR holds a ref to all the CDRs in the list and we
1027  * have a ref to the root CDR.
1028  */
1030  }
1031  ao2_unlock(active_cdrs_all);
1032  ao2_ref(cdr, -1);
1033 }
1034 
1035 /*!
1036  * \brief \ref cdr_object Destructor
1037  */
1038 static void cdr_object_dtor(void *obj)
1039 {
1040  struct cdr_object *cdr = obj;
1041  struct ast_var_t *it_var;
1042 
1043  ao2_cleanup(cdr->party_a.snapshot);
1044  ao2_cleanup(cdr->party_b.snapshot);
1045  while ((it_var = AST_LIST_REMOVE_HEAD(&cdr->party_a.variables, entries))) {
1046  ast_var_delete(it_var);
1047  }
1048  while ((it_var = AST_LIST_REMOVE_HEAD(&cdr->party_b.variables, entries))) {
1049  ast_var_delete(it_var);
1050  }
1052 
1053  /* CDR destruction used to work by calling ao2_cleanup(next) and
1054  * allowing the chain to destroy itself neatly. Unfortunately, for
1055  * really long chains, this can result in a stack overflow. So now
1056  * when the root CDR is destroyed, it is responsible for unreffing
1057  * all CDRs in the chain
1058  */
1059  if (cdr->is_root) {
1060  struct cdr_object *curr = cdr->next;
1061  struct cdr_object *next;
1062 
1063  while (curr) {
1064  next = curr->next;
1065  ao2_cleanup(curr);
1066  curr = next;
1067  }
1068  }
1069 }
1070 
1071 /*!
1072  * \brief \ref cdr_object constructor
1073  * \param chan The \ref ast_channel_snapshot that is the CDR's Party A
1074  * \param event_time
1075  *
1076  * This implicitly sets the state of the newly created CDR to the Single state
1077  * (\ref single_state_fn_table)
1078  */
1079 static struct cdr_object *cdr_object_alloc(struct ast_channel_snapshot *chan, const struct timeval *event_time)
1080 {
1081  struct cdr_object *cdr;
1082 
1083  ast_assert(chan != NULL);
1084 
1085  cdr = ao2_alloc(sizeof(*cdr), cdr_object_dtor);
1086  if (!cdr) {
1087  return NULL;
1088  }
1089  cdr->last = cdr;
1090  if (ast_string_field_init(cdr, 64)) {
1091  ao2_cleanup(cdr);
1092  return NULL;
1093  }
1095  ast_string_field_set(cdr, name, chan->base->name);
1097  cdr->disposition = AST_CDR_NULL;
1098  cdr->sequence = ast_atomic_fetchadd_int(&global_cdr_sequence, +1);
1099  cdr->lastevent = *event_time;
1100 
1101  cdr->party_a.snapshot = chan;
1102  ao2_t_ref(cdr->party_a.snapshot, +1, "bump snapshot during CDR creation");
1103 
1104  CDR_DEBUG("%p - Created CDR for channel %s\n", cdr, chan->base->name);
1105 
1106  cdr_object_transition_state(cdr, &single_state_fn_table);
1107 
1108  return cdr;
1109 }
1110 
1111 /*!
1112  * \brief Create a new \ref cdr_object and append it to an existing chain
1113  * \param cdr The \ref cdr_object to append to
1114  * \param event_time
1115  */
1116 static struct cdr_object *cdr_object_create_and_append(struct cdr_object *cdr, const struct timeval *event_time)
1117 {
1118  struct cdr_object *new_cdr;
1119  struct cdr_object *it_cdr;
1120  struct cdr_object *cdr_last;
1121 
1122  cdr_last = cdr->last;
1123  new_cdr = cdr_object_alloc(cdr_last->party_a.snapshot, event_time);
1124  if (!new_cdr) {
1125  return NULL;
1126  }
1127  new_cdr->disposition = AST_CDR_NULL;
1128 
1129  /* Copy over the linkedid, as it may have changed */
1130  ast_string_field_set(new_cdr, linkedid, cdr_last->linkedid);
1131  ast_string_field_set(new_cdr, appl, cdr_last->appl);
1132  ast_string_field_set(new_cdr, data, cdr_last->data);
1133  ast_string_field_set(new_cdr, context, cdr_last->context);
1134  ast_string_field_set(new_cdr, exten, cdr_last->exten);
1135 
1136  /*
1137  * If the current CDR says to disable all future ones,
1138  * keep the disable chain going
1139  */
1140  if (ast_test_flag(&cdr_last->flags, AST_CDR_FLAG_DISABLE_ALL)) {
1141  ast_set_flag(&new_cdr->flags, AST_CDR_FLAG_DISABLE_ALL);
1142  }
1143 
1144  /* Copy over other Party A information */
1145  cdr_object_snapshot_copy(&new_cdr->party_a, &cdr_last->party_a);
1146 
1147  /* Append the CDR to the end of the list */
1148  for (it_cdr = cdr; it_cdr->next; it_cdr = it_cdr->next) {
1149  it_cdr->last = new_cdr;
1150  }
1151  it_cdr->last = new_cdr;
1152  it_cdr->next = new_cdr;
1153 
1154  return new_cdr;
1155 }
1156 
1157 /*!
1158  * \internal
1159  * \brief Determine if CDR flag is configured.
1160  *
1161  * \param cdr_flag The configured CDR flag to check.
1162  *
1163  * \retval 0 if the CDR flag is not configured.
1164  * \retval non-zero if the CDR flag is configured.
1165  */
1166 static int is_cdr_flag_set(unsigned int cdr_flag)
1167 {
1168  struct module_config *mod_cfg;
1169  int flag_set;
1170 
1171  mod_cfg = ao2_global_obj_ref(module_configs);
1172  flag_set = mod_cfg && ast_test_flag(&mod_cfg->general->settings, cdr_flag);
1173  ao2_cleanup(mod_cfg);
1174  return flag_set;
1175 }
1176 
1177 /*!
1178  * \brief Return whether or not a channel has changed its state in the dialplan, subject
1179  * to endbeforehexten logic
1180  *
1181  * \param old_snapshot The previous state
1182  * \param new_snapshot The new state
1183  *
1184  * \retval 0 if the state has not changed
1185  * \retval 1 if the state changed
1186  */
1187 static int snapshot_cep_changed(struct ast_channel_snapshot *old_snapshot,
1188  struct ast_channel_snapshot *new_snapshot)
1189 {
1190  /* If we ignore hangup logic, don't indicate that we're executing anything new */
1191  if (ast_test_flag(&new_snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)
1192  && is_cdr_flag_set(CDR_END_BEFORE_H_EXTEN)) {
1193  return 0;
1194  }
1195 
1196  /* When Party A is originated to an application and the application exits, the stack
1197  * will attempt to clear the application and restore the dummy originate application
1198  * of "AppDialX". Ignore application changes to AppDialX as a result.
1199  */
1200  if (strcmp(new_snapshot->dialplan->appl, old_snapshot->dialplan->appl)
1201  && strncasecmp(new_snapshot->dialplan->appl, "appdial", 7)
1202  && (strcmp(new_snapshot->dialplan->context, old_snapshot->dialplan->context)
1203  || strcmp(new_snapshot->dialplan->exten, old_snapshot->dialplan->exten)
1204  || new_snapshot->dialplan->priority != old_snapshot->dialplan->priority)) {
1205  return 1;
1206  }
1207 
1208  return 0;
1209 }
1210 
1211 /*!
1212  * \brief Return whether or not a \ref ast_channel_snapshot is for a channel
1213  * that was created as the result of a dial operation
1214  *
1215  * \retval 0 the channel was not created as the result of a dial
1216  * \retval 1 the channel was created as the result of a dial
1217  */
1218 static int snapshot_is_dialed(struct ast_channel_snapshot *snapshot)
1219 {
1220  return (ast_test_flag(&snapshot->flags, AST_FLAG_OUTGOING)
1221  && !(ast_test_flag(&snapshot->flags, AST_FLAG_ORIGINATED)));
1222 }
1223 
1224 /*!
1225  * \brief Given two CDR snapshots, figure out who should be Party A for the
1226  * resulting CDR
1227  * \param left One of the snapshots
1228  * \param right The other snapshot
1229  * \return The snapshot that won
1230  */
1232 {
1233  /* Check whether or not the party is dialed. A dialed party is never the
1234  * Party A with a party that was not dialed.
1235  */
1236  if (!snapshot_is_dialed(left->snapshot) && snapshot_is_dialed(right->snapshot)) {
1237  return left;
1238  } else if (snapshot_is_dialed(left->snapshot) && !snapshot_is_dialed(right->snapshot)) {
1239  return right;
1240  }
1241 
1242  /* Try the Party A flag */
1243  if (ast_test_flag(left, AST_CDR_FLAG_PARTY_A) && !ast_test_flag(right, AST_CDR_FLAG_PARTY_A)) {
1244  return left;
1245  } else if (!ast_test_flag(left, AST_CDR_FLAG_PARTY_A) && ast_test_flag(right, AST_CDR_FLAG_PARTY_A)) {
1246  return right;
1247  }
1248 
1249  /* Neither party is dialed and neither has the Party A flag - defer to
1250  * creation time */
1251  if (left->snapshot->base->creationtime.tv_sec < right->snapshot->base->creationtime.tv_sec) {
1252  return left;
1253  } else if (left->snapshot->base->creationtime.tv_sec > right->snapshot->base->creationtime.tv_sec) {
1254  return right;
1255  } else if (left->snapshot->base->creationtime.tv_usec > right->snapshot->base->creationtime.tv_usec) {
1256  return right;
1257  } else {
1258  /* Okay, fine, take the left one */
1259  return left;
1260  }
1261 }
1262 
1263 /*!
1264  * Compute the duration for a \ref cdr_object
1265  */
1266 static long cdr_object_get_duration(struct cdr_object *cdr)
1267 {
1268  return (long)(ast_tvdiff_ms(ast_tvzero(cdr->end) ? ast_tvnow() : cdr->end, cdr->start) / 1000);
1269 }
1270 
1271 /*!
1272  * \brief Compute the billsec for a \ref cdr_object
1273  */
1274 static long cdr_object_get_billsec(struct cdr_object *cdr)
1275 {
1276  long int ms;
1277 
1278  if (ast_tvzero(cdr->answer)) {
1279  return 0;
1280  }
1281 
1282  ms = ast_tvdiff_ms(ast_tvzero(cdr->end) ? ast_tvnow() : cdr->end, cdr->answer);
1283  if (ms % 1000 >= 500
1284  && is_cdr_flag_set(CDR_INITIATED_SECONDS)) {
1285  ms = (ms / 1000) + 1;
1286  } else {
1287  ms = ms / 1000;
1288  }
1289 
1290  return ms;
1291 }
1292 
1293 /*!
1294  * \internal
1295  * \brief Set a variable on a CDR object
1296  *
1297  * \param headp The header pointer to the variable to set
1298  * \param name The name of the variable
1299  * \param value The value of the variable
1300  */
1301 static void set_variable(struct varshead *headp, const char *name, const char *value)
1302 {
1303  struct ast_var_t *newvariable;
1304 
1305  AST_LIST_TRAVERSE_SAFE_BEGIN(headp, newvariable, entries) {
1306  if (!strcasecmp(ast_var_name(newvariable), name)) {
1307  AST_LIST_REMOVE_CURRENT(entries);
1308  ast_var_delete(newvariable);
1309  break;
1310  }
1311  }
1313 
1314  if (value && (newvariable = ast_var_assign(name, value))) {
1315  AST_LIST_INSERT_HEAD(headp, newvariable, entries);
1316  }
1317 }
1318 
1319 /*!
1320  * \brief Create a chain of \ref ast_cdr objects from a chain of \ref cdr_object
1321  * suitable for consumption by the registered CDR backends
1322  * \param cdr The \ref cdr_object to convert to a public record
1323  * \return A chain of \ref ast_cdr objects on success
1324  * \retval NULL on failure
1325  */
1327 {
1328  struct ast_cdr *pub_cdr = NULL, *cdr_prev = NULL;
1329  struct cdr_object *it_cdr;
1330  struct ast_var_t *it_var, *it_copy_var;
1331  struct ast_channel_snapshot *party_a;
1332  struct ast_channel_snapshot *party_b;
1333 
1334  for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
1335  struct ast_cdr *cdr_copy;
1336 
1337  /* Don't create records for CDRs where the party A was a dialed channel */
1338  if (snapshot_is_dialed(it_cdr->party_a.snapshot) && !it_cdr->party_b.snapshot) {
1339  ast_debug(1, "CDR for %s is dialed and has no Party B; discarding\n",
1340  it_cdr->party_a.snapshot->base->name);
1341  continue;
1342  }
1343 
1344  cdr_copy = ast_calloc(1, sizeof(*cdr_copy));
1345  if (!cdr_copy) {
1346  ast_free(pub_cdr);
1347  return NULL;
1348  }
1349 
1350  party_a = it_cdr->party_a.snapshot;
1351  party_b = it_cdr->party_b.snapshot;
1352 
1353  /* Party A */
1354  ast_assert(party_a != NULL);
1355  ast_copy_string(cdr_copy->accountcode, party_a->base->accountcode, sizeof(cdr_copy->accountcode));
1356  cdr_copy->amaflags = party_a->amaflags;
1357  ast_copy_string(cdr_copy->channel, party_a->base->name, sizeof(cdr_copy->channel));
1358  ast_callerid_merge(cdr_copy->clid, sizeof(cdr_copy->clid), party_a->caller->name, party_a->caller->number, "");
1359  ast_copy_string(cdr_copy->src, party_a->caller->number, sizeof(cdr_copy->src));
1360  ast_copy_string(cdr_copy->uniqueid, party_a->base->uniqueid, sizeof(cdr_copy->uniqueid));
1361  ast_copy_string(cdr_copy->lastapp, it_cdr->appl, sizeof(cdr_copy->lastapp));
1362  ast_copy_string(cdr_copy->lastdata, it_cdr->data, sizeof(cdr_copy->lastdata));
1363  ast_copy_string(cdr_copy->dst, it_cdr->exten, sizeof(cdr_copy->dst));
1364  ast_copy_string(cdr_copy->dcontext, it_cdr->context, sizeof(cdr_copy->dcontext));
1365 
1366  /* Party B */
1367  if (party_b) {
1368  ast_copy_string(cdr_copy->dstchannel, party_b->base->name, sizeof(cdr_copy->dstchannel));
1369  ast_copy_string(cdr_copy->peeraccount, party_b->base->accountcode, sizeof(cdr_copy->peeraccount));
1370  if (!ast_strlen_zero(it_cdr->party_b.userfield)) {
1371  snprintf(cdr_copy->userfield, sizeof(cdr_copy->userfield), "%s;%s", it_cdr->party_a.userfield, it_cdr->party_b.userfield);
1372  }
1373  }
1374  if (ast_strlen_zero(cdr_copy->userfield) && !ast_strlen_zero(it_cdr->party_a.userfield)) {
1375  ast_copy_string(cdr_copy->userfield, it_cdr->party_a.userfield, sizeof(cdr_copy->userfield));
1376  }
1377 
1378  /* Timestamps/durations */
1379  cdr_copy->start = it_cdr->start;
1380  cdr_copy->answer = it_cdr->answer;
1381  cdr_copy->end = it_cdr->end;
1382  cdr_copy->billsec = cdr_object_get_billsec(it_cdr);
1383  cdr_copy->duration = cdr_object_get_duration(it_cdr);
1384 
1385  /* Flags and IDs */
1386  ast_copy_flags(cdr_copy, &it_cdr->flags, AST_FLAGS_ALL);
1387  ast_copy_string(cdr_copy->linkedid, it_cdr->linkedid, sizeof(cdr_copy->linkedid));
1388  cdr_copy->disposition = it_cdr->disposition;
1389  cdr_copy->sequence = it_cdr->sequence;
1390 
1391  /* Variables */
1392  copy_variables(&cdr_copy->varshead, &it_cdr->party_a.variables);
1393  AST_LIST_TRAVERSE(&it_cdr->party_b.variables, it_var, entries) {
1394  int found = 0;
1395  struct ast_var_t *newvariable;
1396  AST_LIST_TRAVERSE(&cdr_copy->varshead, it_copy_var, entries) {
1397  if (!strcasecmp(ast_var_name(it_var), ast_var_name(it_copy_var))) {
1398  found = 1;
1399  break;
1400  }
1401  }
1402  if (!found && (newvariable = ast_var_assign(ast_var_name(it_var), ast_var_value(it_var)))) {
1403  AST_LIST_INSERT_TAIL(&cdr_copy->varshead, newvariable, entries);
1404  }
1405  }
1406 
1407  if (!pub_cdr) {
1408  pub_cdr = cdr_copy;
1409  cdr_prev = pub_cdr;
1410  } else {
1411  cdr_prev->next = cdr_copy;
1412  cdr_prev = cdr_copy;
1413  }
1414  }
1415 
1416  return pub_cdr;
1417 }
1418 
1419 /*!
1420  * \brief Dispatch a CDR.
1421  * \param cdr The \ref cdr_object to dispatch
1422  *
1423  * This will create a \ref ast_cdr object and publish it to the various backends
1424  */
1425 static void cdr_object_dispatch(struct cdr_object *cdr)
1426 {
1427  struct ast_cdr *pub_cdr;
1428 
1429  CDR_DEBUG("%p - Dispatching CDR for Party A %s, Party B %s\n", cdr,
1430  cdr->party_a.snapshot->base->name,
1431  cdr->party_b.snapshot ? cdr->party_b.snapshot->base->name : "<none>");
1432  pub_cdr = cdr_object_create_public_records(cdr);
1433  cdr_detach(pub_cdr);
1434 }
1435 
1436 /*!
1437  * \brief Set the disposition on a \ref cdr_object based on a hangupcause code
1438  * \param cdr The \ref cdr_object
1439  * \param hangupcause The Asterisk hangup cause code
1440  */
1441 static void cdr_object_set_disposition(struct cdr_object *cdr, int hangupcause)
1442 {
1443  /* Change the disposition based on the hang up cause */
1444  switch (hangupcause) {
1445  case AST_CAUSE_BUSY:
1446  cdr->disposition = AST_CDR_BUSY;
1447  break;
1448  case AST_CAUSE_CONGESTION:
1449  if (!is_cdr_flag_set(CDR_CONGESTION)) {
1450  cdr->disposition = AST_CDR_FAILED;
1451  } else {
1452  cdr->disposition = AST_CDR_CONGESTION;
1453  }
1454  break;
1455  case AST_CAUSE_NO_ROUTE_DESTINATION:
1456  case AST_CAUSE_UNREGISTERED:
1457  cdr->disposition = AST_CDR_FAILED;
1458  break;
1459  case AST_CAUSE_NORMAL_CLEARING:
1460  case AST_CAUSE_NO_ANSWER:
1461  cdr->disposition = AST_CDR_NOANSWER;
1462  break;
1463  default:
1464  break;
1465  }
1466 }
1467 
1468 /*!
1469  * \brief Finalize a CDR.
1470  *
1471  * This function is safe to call multiple times. Note that you can call this
1472  * explicitly before going to the finalized state if there's a chance the CDR
1473  * will be re-activated, in which case the \p cdr's end time should be
1474  * cleared. This function is implicitly called when a CDR transitions to the
1475  * finalized state and right before it is dispatched
1476  *
1477  * \param cdr The CDR to finalize
1478  */
1479 static void cdr_object_finalize(struct cdr_object *cdr)
1480 {
1481  if (!ast_tvzero(cdr->end)) {
1482  return;
1483  }
1484  cdr->end = cdr->lastevent;
1485 
1486  if (cdr->disposition == AST_CDR_NULL) {
1487  if (!ast_tvzero(cdr->answer)) {
1488  cdr->disposition = AST_CDR_ANSWERED;
1489  } else if (cdr->party_a.snapshot->hangup->cause) {
1491  } else if (cdr->party_b.snapshot && cdr->party_b.snapshot->hangup->cause) {
1493  } else {
1494  cdr->disposition = AST_CDR_FAILED;
1495  }
1496  }
1497 
1498  /* tv_usec is suseconds_t, which could be int or long */
1499  ast_debug(1, "Finalized CDR for %s - start %ld.%06ld answer %ld.%06ld end %ld.%06ld dur %.3f bill %.3f dispo %s\n",
1500  cdr->party_a.snapshot->base->name,
1501  (long)cdr->start.tv_sec,
1502  (long)cdr->start.tv_usec,
1503  (long)cdr->answer.tv_sec,
1504  (long)cdr->answer.tv_usec,
1505  (long)cdr->end.tv_sec,
1506  (long)cdr->end.tv_usec,
1507  (double)ast_tvdiff_ms(cdr->end, cdr->start) / 1000.0,
1508  (double)ast_tvdiff_ms(cdr->end, cdr->answer) / 1000.0,
1510 }
1511 
1512 /*!
1513  * \brief Check to see if a CDR needs to move to the finalized state because
1514  * its Party A hungup.
1515  */
1517 {
1518  if (ast_test_flag(&cdr->party_a.snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)
1519  && is_cdr_flag_set(CDR_END_BEFORE_H_EXTEN)) {
1520  cdr_object_finalize(cdr);
1521  }
1522 
1523  if (ast_test_flag(&cdr->party_a.snapshot->flags, AST_FLAG_DEAD)
1524  && cdr->fn_table != &finalized_state_fn_table) {
1525  cdr_object_transition_state(cdr, &finalized_state_fn_table);
1526  }
1527 }
1528 
1529 /*!
1530  * \brief Check to see if a CDR needs to be answered based on its Party A.
1531  * Note that this is safe to call as much as you want - we won't answer twice
1532  */
1534 {
1535  if (cdr->party_a.snapshot->state == AST_STATE_UP && ast_tvzero(cdr->answer)) {
1536  cdr->answer = cdr->lastevent;
1537  /* tv_usec is suseconds_t, which could be int or long */
1538  CDR_DEBUG("%p - Set answered time to %ld.%06ld\n", cdr,
1539  (long)cdr->answer.tv_sec,
1540  (long)cdr->answer.tv_usec);
1541  }
1542 }
1543 
1544 /*! \brief Set Caller ID information on a CDR */
1545 static void cdr_object_update_cid(struct cdr_object_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot)
1546 {
1547  if (!old_snapshot->snapshot) {
1548  set_variable(&old_snapshot->variables, "dnid", new_snapshot->caller->dnid);
1549  set_variable(&old_snapshot->variables, "callingsubaddr", new_snapshot->caller->subaddr);
1550  set_variable(&old_snapshot->variables, "calledsubaddr", new_snapshot->caller->dialed_subaddr);
1551  return;
1552  }
1553  if (strcmp(old_snapshot->snapshot->caller->dnid, new_snapshot->caller->dnid)) {
1554  set_variable(&old_snapshot->variables, "dnid", new_snapshot->caller->dnid);
1555  }
1556  if (strcmp(old_snapshot->snapshot->caller->subaddr, new_snapshot->caller->subaddr)) {
1557  set_variable(&old_snapshot->variables, "callingsubaddr", new_snapshot->caller->subaddr);
1558  }
1559  if (strcmp(old_snapshot->snapshot->caller->dialed_subaddr, new_snapshot->caller->dialed_subaddr)) {
1560  set_variable(&old_snapshot->variables, "calledsubaddr", new_snapshot->caller->dialed_subaddr);
1561  }
1562 }
1563 
1564 /*!
1565  * \brief Swap an old \ref cdr_object_snapshot's \ref ast_channel_snapshot for
1566  * a new \ref ast_channel_snapshot
1567  * \param old_snapshot The old \ref cdr_object_snapshot
1568  * \param new_snapshot The new \ref ast_channel_snapshot for old_snapshot
1569  */
1570 static void cdr_object_swap_snapshot(struct cdr_object_snapshot *old_snapshot,
1571  struct ast_channel_snapshot *new_snapshot)
1572 {
1573  cdr_object_update_cid(old_snapshot, new_snapshot);
1574  ao2_t_replace(old_snapshot->snapshot, new_snapshot, "Swap CDR shapshot");
1575 }
1576 
1577 /* BASE METHOD IMPLEMENTATIONS */
1578 
1579 static int base_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
1580 {
1581  ast_assert(strcasecmp(snapshot->base->name, cdr->party_a.snapshot->base->name) == 0);
1582 
1583  /* Finalize the CDR if we're in hangup logic and we're set to do so */
1584  if (ast_test_flag(&snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)
1585  && is_cdr_flag_set(CDR_END_BEFORE_H_EXTEN)) {
1586  cdr_object_finalize(cdr);
1587  return 0;
1588  }
1589 
1590  /*
1591  * Only record the context and extension if we aren't in a subroutine, or if
1592  * we are executing hangup logic.
1593  */
1594  if (!ast_test_flag(&snapshot->flags, AST_FLAG_SUBROUTINE_EXEC)
1595  || ast_test_flag(&snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)) {
1596  if (strcmp(cdr->context, snapshot->dialplan->context)) {
1597  ast_string_field_set(cdr, context, snapshot->dialplan->context);
1598  }
1599  if (strcmp(cdr->exten, snapshot->dialplan->exten)) {
1600  ast_string_field_set(cdr, exten, snapshot->dialplan->exten);
1601  }
1602  }
1603 
1604  cdr_object_swap_snapshot(&cdr->party_a, snapshot);
1605 
1606  /* When Party A is originated to an application and the application exits, the stack
1607  * will attempt to clear the application and restore the dummy originate application
1608  * of "AppDialX". Prevent that, and any other application changes we might not want
1609  * here.
1610  */
1611  if (!ast_test_flag(&cdr->flags, AST_CDR_LOCK_APP)
1612  && !ast_strlen_zero(snapshot->dialplan->appl)
1613  && (strncasecmp(snapshot->dialplan->appl, "appdial", 7) || ast_strlen_zero(cdr->appl))) {
1614  if (strcmp(cdr->appl, snapshot->dialplan->appl)) {
1615  ast_string_field_set(cdr, appl, snapshot->dialplan->appl);
1616  }
1617  if (strcmp(cdr->data, snapshot->dialplan->data)) {
1618  ast_string_field_set(cdr, data, snapshot->dialplan->data);
1619  }
1620 
1621  /* Dial (app_dial) is a special case. Because pre-dial handlers, which
1622  * execute before the dial begins, will alter the application/data to
1623  * something people typically don't want to see, if we see a channel enter
1624  * into Dial here, we set the appl/data accordingly and lock it.
1625  */
1626  if (!strcmp(snapshot->dialplan->appl, "Dial")) {
1627  ast_set_flag(&cdr->flags, AST_CDR_LOCK_APP);
1628  }
1629  }
1630 
1631  if (strcmp(cdr->linkedid, snapshot->peer->linkedid)) {
1632  ast_string_field_set(cdr, linkedid, snapshot->peer->linkedid);
1633  }
1636 
1637  return 0;
1638 }
1639 
1640 static int base_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1641 {
1642  return 0;
1643 }
1644 
1645 static int base_process_dial_end(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer, const char *dial_status)
1646 {
1647  return 0;
1648 }
1649 
1650 static enum process_bridge_enter_results base_process_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1651 {
1652  /* Base process bridge enter simply indicates that we can't handle it */
1653  return BRIDGE_ENTER_NEED_CDR;
1654 }
1655 
1656 static int base_process_parked_channel(struct cdr_object *cdr, struct ast_parked_call_payload *parking_info)
1657 {
1658  char park_info[128];
1659 
1660  ast_assert(!strcasecmp(parking_info->parkee->base->name, cdr->party_a.snapshot->base->name));
1661 
1662  /* Update Party A information regardless */
1663  cdr->fn_table->process_party_a(cdr, parking_info->parkee);
1664 
1665  /* Fake out where we're parked */
1666  ast_string_field_set(cdr, appl, "Park");
1667  snprintf(park_info, sizeof(park_info), "%s:%u", parking_info->parkinglot, parking_info->parkingspace);
1668  ast_string_field_set(cdr, data, park_info);
1669 
1670  /* Prevent any further changes to the App/Data fields for this record */
1671  ast_set_flag(&cdr->flags, AST_CDR_LOCK_APP);
1672 
1673  return 0;
1674 }
1675 
1676 /* SINGLE STATE */
1677 
1678 static void single_state_init_function(struct cdr_object *cdr)
1679 {
1680  cdr->start = cdr->lastevent;
1682 }
1683 
1684 static void single_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
1685 {
1686  /* This should never happen! */
1687  ast_assert(cdr->party_b.snapshot == NULL);
1688  ast_assert(0);
1689  return;
1690 }
1691 
1692 static int single_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer)
1693 {
1694  if (caller && !strcasecmp(cdr->party_a.snapshot->base->name, caller->base->name)) {
1695  base_process_party_a(cdr, caller);
1696  CDR_DEBUG("%p - Updated Party A %s snapshot\n", cdr,
1697  cdr->party_a.snapshot->base->name);
1698  cdr_object_swap_snapshot(&cdr->party_b, peer);
1699  cdr_all_relink(cdr);
1700  CDR_DEBUG("%p - Updated Party B %s snapshot\n", cdr,
1701  cdr->party_b.snapshot->base->name);
1702 
1703  /* If we have two parties, lock the application that caused the
1704  * two parties to be associated. This prevents mid-call event
1705  * gosubs from perturbing the CDR application/data
1706  */
1707  ast_set_flag(&cdr->flags, AST_CDR_LOCK_APP);
1708  } else if (!strcasecmp(cdr->party_a.snapshot->base->name, peer->base->name)) {
1709  /* We're the entity being dialed, i.e., outbound origination */
1710  base_process_party_a(cdr, peer);
1711  CDR_DEBUG("%p - Updated Party A %s snapshot\n", cdr,
1712  cdr->party_a.snapshot->base->name);
1713  }
1714 
1715  cdr_object_transition_state(cdr, &dial_state_fn_table);
1716  return 0;
1717 }
1718 
1719 /*!
1720  * \brief Handle a comparison between our \ref cdr_object and a \ref cdr_object
1721  * already in the bridge while in the Single state. The goal of this is to find
1722  * a Party B for our CDR.
1723  *
1724  * \param cdr Our \ref cdr_object in the Single state
1725  * \param cand_cdr The \ref cdr_object already in the Bridge state
1726  *
1727  * \retval 0 The cand_cdr had a Party A or Party B that we could use as our
1728  * Party B
1729  * \retval 1 No party in the cand_cdr could be used as our Party B
1730  */
1732  struct cdr_object *cand_cdr)
1733 {
1734  struct cdr_object_snapshot *party_a;
1735 
1736  /* Don't match on ourselves */
1737  if (!strcasecmp(cdr->party_a.snapshot->base->name, cand_cdr->party_a.snapshot->base->name)) {
1738  return 1;
1739  }
1740 
1741  /* Try the candidate CDR's Party A first */
1742  party_a = cdr_object_pick_party_a(&cdr->party_a, &cand_cdr->party_a);
1743  if (!strcasecmp(party_a->snapshot->base->name, cdr->party_a.snapshot->base->name)) {
1744  CDR_DEBUG("%p - Party A %s has new Party B %s\n",
1745  cdr, cdr->party_a.snapshot->base->name, cand_cdr->party_a.snapshot->base->name);
1746  cdr_object_snapshot_copy(&cdr->party_b, &cand_cdr->party_a);
1747  cdr_all_relink(cdr);
1748  if (!cand_cdr->party_b.snapshot) {
1749  /* We just stole them - finalize their CDR. Note that this won't
1750  * transition their state, it just sets the end time and the
1751  * disposition - if we need to re-activate them later, we can.
1752  */
1753  cdr_object_finalize(cand_cdr);
1754  }
1755  return 0;
1756  }
1757 
1758  /* Try their Party B, unless it's us */
1759  if (!cand_cdr->party_b.snapshot
1760  || !strcasecmp(cdr->party_a.snapshot->base->name, cand_cdr->party_b.snapshot->base->name)) {
1761  return 1;
1762  }
1763  party_a = cdr_object_pick_party_a(&cdr->party_a, &cand_cdr->party_b);
1764  if (!strcasecmp(party_a->snapshot->base->name, cdr->party_a.snapshot->base->name)) {
1765  CDR_DEBUG("%p - Party A %s has new Party B %s\n",
1766  cdr, cdr->party_a.snapshot->base->name, cand_cdr->party_b.snapshot->base->name);
1767  cdr_object_snapshot_copy(&cdr->party_b, &cand_cdr->party_b);
1768  cdr_all_relink(cdr);
1769  return 0;
1770  }
1771 
1772  return 1;
1773 }
1774 
1775 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)
1776 {
1777  struct ao2_iterator it_cdrs;
1778  char *channel_id;
1779  int success = 0;
1780 
1781  ast_string_field_set(cdr, bridge, bridge->uniqueid);
1782 
1783  if (ao2_container_count(bridge->channels) == 1) {
1784  /* No one in the bridge yet but us! */
1785  cdr_object_transition_state(cdr, &bridge_state_fn_table);
1786  return BRIDGE_ENTER_ONLY_PARTY;
1787  }
1788 
1789  for (it_cdrs = ao2_iterator_init(bridge->channels, 0);
1790  !success && (channel_id = ao2_iterator_next(&it_cdrs));
1791  ao2_ref(channel_id, -1)) {
1792  struct cdr_object *cand_cdr_master;
1793  struct cdr_object *cand_cdr;
1794 
1795  cand_cdr_master = ao2_find(active_cdrs_master, channel_id, OBJ_SEARCH_KEY);
1796  if (!cand_cdr_master) {
1797  continue;
1798  }
1799 
1800  ao2_lock(cand_cdr_master);
1801  for (cand_cdr = cand_cdr_master; cand_cdr; cand_cdr = cand_cdr->next) {
1802  /* Skip any records that are not in a bridge or in this bridge.
1803  * I'm not sure how that would happen, but it pays to be careful. */
1804  if (cand_cdr->fn_table != &bridge_state_fn_table ||
1805  strcmp(cdr->bridge, cand_cdr->bridge)) {
1806  continue;
1807  }
1808 
1809  if (single_state_bridge_enter_comparison(cdr, cand_cdr)) {
1810  continue;
1811  }
1812  /* We successfully got a party B - break out */
1813  success = 1;
1814  break;
1815  }
1816  ao2_unlock(cand_cdr_master);
1817  ao2_cleanup(cand_cdr_master);
1818  }
1819  ao2_iterator_destroy(&it_cdrs);
1820 
1821  /* We always transition state, even if we didn't get a peer */
1822  cdr_object_transition_state(cdr, &bridge_state_fn_table);
1823 
1824  /* Success implies that we have a Party B */
1825  if (success) {
1827  }
1828 
1829  return BRIDGE_ENTER_NO_PARTY_B;
1830 }
1831 
1832 static int single_state_process_parking_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
1833 {
1834  cdr_object_transition_state(cdr, &parked_state_fn_table);
1835  return 0;
1836 }
1837 
1838 
1839 /* DIAL STATE */
1840 
1841 static void dial_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
1842 {
1843  ast_assert(snapshot != NULL);
1844  ast_assert(cdr->party_b.snapshot
1845  && !strcasecmp(cdr->party_b.snapshot->base->name, snapshot->base->name));
1846 
1847  cdr_object_swap_snapshot(&cdr->party_b, snapshot);
1848 
1849  /* If party B hangs up, finalize this CDR */
1850  if (ast_test_flag(&cdr->party_b.snapshot->flags, AST_FLAG_DEAD)) {
1851  cdr_object_transition_state(cdr, &finalized_state_fn_table);
1852  }
1853 }
1854 
1855 static int dial_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer)
1856 {
1857  /* Don't process a begin dial here. A party A already in the dial state will
1858  * who receives a dial begin for something else will be handled by the
1859  * message router callback and will add a new CDR for the party A */
1860  return 1;
1861 }
1862 
1863 /*!
1864  * \internal
1865  * \brief Convert a dial status to a CDR disposition
1866  */
1867 static enum ast_cdr_disposition dial_status_to_disposition(const char *dial_status)
1868 {
1869  if (!strcmp(dial_status, "ANSWER")) {
1870  return AST_CDR_ANSWERED;
1871  } else if (!strcmp(dial_status, "BUSY")) {
1872  return AST_CDR_BUSY;
1873  } else if (!strcmp(dial_status, "CANCEL") || !strcmp(dial_status, "NOANSWER")) {
1874  return AST_CDR_NOANSWER;
1875  } else if (!strcmp(dial_status, "CONGESTION")) {
1876  if (!is_cdr_flag_set(CDR_CONGESTION)) {
1877  return AST_CDR_FAILED;
1878  } else {
1879  return AST_CDR_CONGESTION;
1880  }
1881  } else if (!strcmp(dial_status, "FAILED")) {
1882  return AST_CDR_FAILED;
1883  }
1884  return AST_CDR_FAILED;
1885 }
1886 
1887 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)
1888 {
1889  struct ast_channel_snapshot *party_a;
1890 
1891  if (caller) {
1892  party_a = caller;
1893  } else {
1894  party_a = peer;
1895  }
1896  ast_assert(!strcasecmp(cdr->party_a.snapshot->base->name, party_a->base->name));
1897  cdr_object_swap_snapshot(&cdr->party_a, party_a);
1898 
1899  if (cdr->party_b.snapshot) {
1900  if (strcasecmp(cdr->party_b.snapshot->base->name, peer->base->name)) {
1901  /* Not the status for this CDR - defer back to the message router */
1902  return 1;
1903  }
1904  cdr_object_swap_snapshot(&cdr->party_b, peer);
1905  }
1906 
1907  /* Set the disposition based on the dial string. */
1908  cdr->disposition = dial_status_to_disposition(dial_status);
1909  if (cdr->disposition == AST_CDR_ANSWERED) {
1910  /* Switch to dial pending to wait and see what the caller does */
1911  cdr_object_transition_state(cdr, &dialed_pending_state_fn_table);
1912  } else {
1913  cdr_object_transition_state(cdr, &finalized_state_fn_table);
1914  }
1915 
1916  return 0;
1917 }
1918 
1919 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)
1920 {
1921  int success = 0;
1922 
1923  ast_string_field_set(cdr, bridge, bridge->uniqueid);
1924 
1925  /* Get parties in the bridge */
1926  if (ao2_container_count(bridge->channels) == 1) {
1927  /* No one in the bridge yet but us! */
1928  cdr_object_transition_state(cdr, &bridge_state_fn_table);
1929  return BRIDGE_ENTER_ONLY_PARTY;
1930  }
1931 
1932  /* If we don't have a Party B (originated channel), skip it */
1933  if (cdr->party_b.snapshot) {
1934  struct ao2_iterator it_cdrs;
1935  char *channel_id;
1936 
1937  for (it_cdrs = ao2_iterator_init(bridge->channels, 0);
1938  !success && (channel_id = ao2_iterator_next(&it_cdrs));
1939  ao2_ref(channel_id, -1)) {
1940  struct cdr_object *cand_cdr_master;
1941  struct cdr_object *cand_cdr;
1942 
1943  cand_cdr_master = ao2_find(active_cdrs_master, channel_id, OBJ_SEARCH_KEY);
1944  if (!cand_cdr_master) {
1945  continue;
1946  }
1947 
1948  ao2_lock(cand_cdr_master);
1949  for (cand_cdr = cand_cdr_master; cand_cdr; cand_cdr = cand_cdr->next) {
1950  /* Skip any records that are not in a bridge or in this bridge.
1951  * I'm not sure how that would happen, but it pays to be careful. */
1952  if (cand_cdr->fn_table != &bridge_state_fn_table
1953  || strcmp(cdr->bridge, cand_cdr->bridge)) {
1954  continue;
1955  }
1956 
1957  /* Skip any records that aren't our Party B */
1958  if (strcasecmp(cdr->party_b.snapshot->base->name, cand_cdr->party_a.snapshot->base->name)) {
1959  continue;
1960  }
1961  cdr_object_snapshot_copy(&cdr->party_b, &cand_cdr->party_a);
1962  /* If they have a Party B, they joined up with someone else as their
1963  * Party A. Don't finalize them as they're active. Otherwise, we
1964  * have stolen them so they need to be finalized.
1965  */
1966  if (!cand_cdr->party_b.snapshot) {
1967  cdr_object_finalize(cand_cdr);
1968  }
1969  success = 1;
1970  break;
1971  }
1972  ao2_unlock(cand_cdr_master);
1973  ao2_cleanup(cand_cdr_master);
1974  }
1975  ao2_iterator_destroy(&it_cdrs);
1976  }
1977 
1978  /* We always transition state, even if we didn't get a peer */
1979  cdr_object_transition_state(cdr, &bridge_state_fn_table);
1980 
1981  /* Success implies that we have a Party B */
1982  if (success) {
1984  }
1985  return BRIDGE_ENTER_NO_PARTY_B;
1986 }
1987 
1988 /* DIALED PENDING STATE */
1989 
1990 static int dialed_pending_state_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
1991 {
1992  /* If we get a CEP change, we're executing dialplan. If we have a Party B
1993  * that means we need a new CDR; otherwise, switch us over to single.
1994  */
1995  if (snapshot_cep_changed(cdr->party_a.snapshot, snapshot)) {
1996  if (cdr->party_b.snapshot) {
1997  cdr_object_transition_state(cdr, &finalized_state_fn_table);
1998  cdr->fn_table->process_party_a(cdr, snapshot);
1999  return 1;
2000  } else {
2001  /* The CDR does not need to be reinitialized when transitioning
2002  * to its single state as this would overwrite the start time,
2003  * causing potentially both the answer and the start time to be
2004  * the same which is incorrect.
2005  */
2006  cdr_object_transition_state_init(cdr, &single_state_fn_table, 0);
2007  cdr->fn_table->process_party_a(cdr, snapshot);
2008  return 0;
2009  }
2010  }
2011  base_process_party_a(cdr, snapshot);
2012  return 0;
2013 }
2014 
2015 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)
2016 {
2017  cdr_object_transition_state(cdr, &dial_state_fn_table);
2018  return cdr->fn_table->process_bridge_enter(cdr, bridge, channel);
2019 }
2020 
2021 static int dialed_pending_state_process_parking_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
2022 {
2023  if (cdr->party_b.snapshot) {
2024  /* We can't handle this as we have a Party B - ask for a new one */
2025  return 1;
2026  }
2027  cdr_object_transition_state(cdr, &parked_state_fn_table);
2028  return 0;
2029 }
2030 
2031 static int dialed_pending_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer)
2032 {
2033  cdr_object_transition_state(cdr, &finalized_state_fn_table);
2034 
2035  /* Ask for a new CDR */
2036  return 1;
2037 }
2038 
2039 /* BRIDGE STATE */
2040 
2041 static void bridge_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
2042 {
2043  ast_assert(cdr->party_b.snapshot
2044  && !strcasecmp(cdr->party_b.snapshot->base->name, snapshot->base->name));
2045 
2046  cdr_object_swap_snapshot(&cdr->party_b, snapshot);
2047 
2048  /* If party B hangs up, finalize this CDR */
2049  if (ast_test_flag(&cdr->party_b.snapshot->flags, AST_FLAG_DEAD)) {
2050  cdr_object_transition_state(cdr, &finalized_state_fn_table);
2051  }
2052 }
2053 
2054 static int bridge_state_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
2055 {
2056  if (strcmp(cdr->bridge, bridge->uniqueid)) {
2057  return 1;
2058  }
2059  if (strcasecmp(cdr->party_a.snapshot->base->name, channel->base->name)
2060  && cdr->party_b.snapshot
2061  && strcasecmp(cdr->party_b.snapshot->base->name, channel->base->name)) {
2062  return 1;
2063  }
2064  cdr_object_transition_state(cdr, &finalized_state_fn_table);
2065 
2066  return 0;
2067 }
2068 
2069 /* PARKED STATE */
2070 
2071 static int parked_state_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
2072 {
2073  if (strcasecmp(cdr->party_a.snapshot->base->name, channel->base->name)) {
2074  return 1;
2075  }
2076  cdr_object_transition_state(cdr, &finalized_state_fn_table);
2077 
2078  return 0;
2079 }
2080 
2081 /* FINALIZED STATE */
2082 
2083 static void finalized_state_init_function(struct cdr_object *cdr)
2084 {
2085  cdr_object_finalize(cdr);
2086 }
2087 
2088 static int finalized_state_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
2089 {
2090  if (ast_test_flag(&snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)
2091  && is_cdr_flag_set(CDR_END_BEFORE_H_EXTEN)) {
2092  return 0;
2093  }
2094 
2095  /* Indicate that, if possible, we should get a new CDR */
2096  return 1;
2097 }
2098 
2099 /*!
2100  * \internal
2101  * \brief Filter channel snapshots by technology
2102  */
2103 static int filter_channel_snapshot(struct ast_channel_snapshot *snapshot)
2104 {
2105  return snapshot->base->tech_properties & AST_CHAN_TP_INTERNAL;
2106 }
2107 
2108 /*!
2109  * \internal
2110  * \brief Filter a channel snapshot update
2111  */
2112 static int filter_channel_snapshot_message(struct ast_channel_snapshot *old_snapshot,
2113  struct ast_channel_snapshot *new_snapshot)
2114 {
2115  int ret = 0;
2116 
2117  /* Drop cache updates from certain channel technologies */
2118  if (old_snapshot) {
2119  ret |= filter_channel_snapshot(old_snapshot);
2120  }
2121  if (new_snapshot) {
2122  ret |= filter_channel_snapshot(new_snapshot);
2123  }
2124 
2125  return ret;
2126 }
2127 
2128 static int dial_status_end(const char *dialstatus)
2129 {
2130  return (strcmp(dialstatus, "RINGING") &&
2131  strcmp(dialstatus, "PROCEEDING") &&
2132  strcmp(dialstatus, "PROGRESS"));
2133 }
2134 
2135 /* TOPIC ROUTER CALLBACKS */
2136 
2137 /*!
2138  * \brief Handler for Stasis-Core dial messages
2139  * \param data Passed on
2140  * \param sub The stasis subscription for this message callback
2141  * \param message The message
2142  */
2143 static void handle_dial_message(void *data, struct stasis_subscription *sub, struct stasis_message *message)
2144 {
2145  struct cdr_object *cdr;
2146  struct ast_multi_channel_blob *payload = stasis_message_data(message);
2147  struct ast_channel_snapshot *caller;
2148  struct ast_channel_snapshot *peer;
2149  struct cdr_object *it_cdr;
2150  struct ast_json *dial_status_blob;
2151  const char *dial_status = NULL;
2152  int res = 1;
2153 
2154  caller = ast_multi_channel_blob_get_channel(payload, "caller");
2155  peer = ast_multi_channel_blob_get_channel(payload, "peer");
2156  if (!peer && !caller) {
2157  return;
2158  }
2159 
2160  if (peer && filter_channel_snapshot(peer)) {
2161  return;
2162  }
2163 
2164  if (caller && filter_channel_snapshot(caller)) {
2165  return;
2166  }
2167 
2168  dial_status_blob = ast_json_object_get(ast_multi_channel_blob_get_json(payload), "dialstatus");
2169  if (dial_status_blob) {
2170  dial_status = ast_json_string_get(dial_status_blob);
2171  }
2172 
2173  CDR_DEBUG("Dial %s message for %s, %s: %u.%08u\n",
2174  ast_strlen_zero(dial_status) ? "Begin" : "End",
2175  caller ? caller->base->name : "(none)",
2176  peer ? peer->base->name : "(none)",
2177  (unsigned int)stasis_message_timestamp(message)->tv_sec,
2178  (unsigned int)stasis_message_timestamp(message)->tv_usec);
2179 
2180  /* Figure out who is running this show */
2181  if (caller) {
2182  cdr = ao2_find(active_cdrs_master, caller->base->uniqueid, OBJ_SEARCH_KEY);
2183  } else {
2184  cdr = ao2_find(active_cdrs_master, peer->base->uniqueid, OBJ_SEARCH_KEY);
2185  }
2186  if (!cdr) {
2187  ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", caller ? caller->base->name : peer->base->name);
2188  ast_assert(0);
2189  return;
2190  }
2191 
2192  ao2_lock(cdr);
2193  for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2194  it_cdr->lastevent = *stasis_message_timestamp(message);
2195  if (ast_strlen_zero(dial_status)) {
2196  if (!it_cdr->fn_table->process_dial_begin) {
2197  continue;
2198  }
2199  if (dial_changes_ignored) {
2200  CDR_DEBUG("%p - Ignoring Dial Begin message\n", it_cdr);
2201  continue;
2202  }
2203  CDR_DEBUG("%p - Processing Dial Begin message for channel %s, peer %s\n",
2204  it_cdr,
2205  caller ? caller->base->name : "(none)",
2206  peer ? peer->base->name : "(none)");
2207  res &= it_cdr->fn_table->process_dial_begin(it_cdr,
2208  caller,
2209  peer);
2210  } else if (dial_status_end(dial_status)) {
2211  if (!it_cdr->fn_table->process_dial_end) {
2212  continue;
2213  }
2214  if (dial_changes_ignored) {
2215  /* Set the disposition, and do nothing else. */
2216  it_cdr->disposition = dial_status_to_disposition(dial_status);
2217  CDR_DEBUG("%p - Setting disposition and that's it (%s)\n", it_cdr, dial_status);
2218  continue;
2219  }
2220  CDR_DEBUG("%p - Processing Dial End message for channel %s, peer %s\n",
2221  it_cdr,
2222  caller ? caller->base->name : "(none)",
2223  peer ? peer->base->name : "(none)");
2224  it_cdr->fn_table->process_dial_end(it_cdr,
2225  caller,
2226  peer,
2227  dial_status);
2228  }
2229  }
2230 
2231  /* If we're ignoring dial changes, don't allow multiple CDRs for this channel. */
2232  if (!dial_changes_ignored) {
2233  /* If no CDR handled a dial begin message, make a new one */
2234  if (res && ast_strlen_zero(dial_status)) {
2235  struct cdr_object *new_cdr;
2236 
2237  new_cdr = cdr_object_create_and_append(cdr, stasis_message_timestamp(message));
2238  if (new_cdr) {
2239  new_cdr->fn_table->process_dial_begin(new_cdr, caller, peer);
2240  }
2241  }
2242  }
2243 
2244  ao2_unlock(cdr);
2245  ao2_cleanup(cdr);
2246 }
2247 
2248 static int cdr_object_finalize_party_b(void *obj, void *arg, void *data, int flags)
2249 {
2250  struct cdr_object *cdr = obj;
2251 
2252  if (!strcasecmp(cdr->party_b_name, arg)) {
2253 #ifdef AST_DEVMODE
2254  struct ast_channel_snapshot *party_b = data;
2255 
2256  /*
2257  * For sanity's sake we also assert the party_b snapshot
2258  * is consistent with the key.
2259  */
2260  ast_assert(cdr->party_b.snapshot
2261  && !strcasecmp(cdr->party_b.snapshot->base->name, party_b->base->name));
2262 #endif
2263 
2264  /* Don't transition to the finalized state - let the Party A do
2265  * that when its ready
2266  */
2267  cdr_object_finalize(cdr);
2268  }
2269  return 0;
2270 }
2271 
2272 static int cdr_object_update_party_b(void *obj, void *arg, void *data, int flags)
2273 {
2274  struct cdr_object *cdr = obj;
2275 
2276  if (cdr->fn_table->process_party_b
2277  && !strcasecmp(cdr->party_b_name, arg)) {
2278  struct ast_channel_snapshot *party_b = data;
2279 
2280  /*
2281  * For sanity's sake we also check the party_b snapshot
2282  * for consistency with the key. The callback needs and
2283  * asserts the snapshot to be this way.
2284  */
2285  if (!cdr->party_b.snapshot
2286  || strcasecmp(cdr->party_b.snapshot->base->name, party_b->base->name)) {
2287  ast_log(LOG_NOTICE,
2288  "CDR for Party A %s(%s) has inconsistent Party B %s name. Message can be ignored but this shouldn't happen.\n",
2289  cdr->linkedid,
2290  cdr->party_a.snapshot->base->name,
2291  cdr->party_b_name);
2292  return 0;
2293  }
2294 
2295  cdr->fn_table->process_party_b(cdr, party_b);
2296  }
2297  return 0;
2298 }
2299 
2300 /*! \brief Determine if we need to add a new CDR based on snapshots */
2301 static int check_new_cdr_needed(struct ast_channel_snapshot *old_snapshot,
2302  struct ast_channel_snapshot *new_snapshot)
2303 {
2304  /* If we're dead, we don't need a new CDR */
2305  if (!new_snapshot
2306  || (ast_test_flag(&new_snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)
2307  && is_cdr_flag_set(CDR_END_BEFORE_H_EXTEN))) {
2308  return 0;
2309  }
2310 
2311  /* Auto-fall through will increment the priority but have no application */
2312  if (ast_strlen_zero(new_snapshot->dialplan->appl)) {
2313  return 0;
2314  }
2315 
2316  if (old_snapshot && !snapshot_cep_changed(old_snapshot, new_snapshot)) {
2317  return 0;
2318  }
2319 
2320  return 1;
2321 }
2322 
2323 /*!
2324  * \brief Handler for channel snapshot update messages
2325  * \param data Passed on
2326  * \param sub The stasis subscription for this message callback
2327  * \param message The message
2328  */
2330 {
2331  struct cdr_object *cdr;
2332  struct ast_channel_snapshot_update *update = stasis_message_data(message);
2333  struct cdr_object *it_cdr;
2334 
2335  if (filter_channel_snapshot_message(update->old_snapshot, update->new_snapshot)) {
2336  return;
2337  }
2338 
2339  if (update->new_snapshot && !update->old_snapshot) {
2340  struct module_config *mod_cfg = NULL;
2341 
2342  cdr = cdr_object_alloc(update->new_snapshot, stasis_message_timestamp(message));
2343  if (!cdr) {
2344  return;
2345  }
2346  mod_cfg = ao2_global_obj_ref(module_configs);
2347  cdr->is_root = 1;
2348  ao2_link(active_cdrs_master, cdr);
2349 
2350  /* If CDR should be disabled unless enabled on a per-channel basis, then disable
2351  CDR, right from the get go */
2352  if (mod_cfg) {
2353  if (!ast_test_flag(&mod_cfg->general->settings, CDR_CHANNEL_DEFAULT_ENABLED)) {
2354  ast_debug(3, "Disable CDR by default\n");
2355  ast_set_flag(&cdr->flags, AST_CDR_FLAG_DISABLE_ALL);
2356  }
2357  ao2_cleanup(mod_cfg);
2358  }
2359  } else {
2360  cdr = ao2_find(active_cdrs_master, update->new_snapshot->base->uniqueid, OBJ_SEARCH_KEY);
2361  }
2362 
2363  /* Handle Party A */
2364  if (!cdr) {
2365  ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", update->new_snapshot->base->name);
2366  ast_assert(0);
2367  } else {
2368  int all_reject = 1;
2369 
2370  ao2_lock(cdr);
2371  for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2372  it_cdr->lastevent = *stasis_message_timestamp(message);
2373  if (!it_cdr->fn_table->process_party_a) {
2374  continue;
2375  }
2376  all_reject &= it_cdr->fn_table->process_party_a(it_cdr, update->new_snapshot);
2377  }
2378  if (all_reject && check_new_cdr_needed(update->old_snapshot, update->new_snapshot)) {
2379  /* We're not hung up and we have a new snapshot - we need a new CDR */
2380  struct cdr_object *new_cdr;
2381 
2382  new_cdr = cdr_object_create_and_append(cdr, stasis_message_timestamp(message));
2383  if (new_cdr) {
2384  new_cdr->fn_table->process_party_a(new_cdr, update->new_snapshot);
2385  }
2386  }
2387  ao2_unlock(cdr);
2388  }
2389 
2390  if (ast_test_flag(&update->new_snapshot->flags, AST_FLAG_DEAD)) {
2391  ao2_lock(cdr);
2392  CDR_DEBUG("%p - Beginning finalize/dispatch for %s\n", cdr, update->old_snapshot->base->name);
2393  for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2394  it_cdr->lastevent = *stasis_message_timestamp(message);
2395  cdr_object_finalize(it_cdr);
2396  }
2397  cdr_object_dispatch(cdr);
2398  ao2_unlock(cdr);
2399 
2400  cdr_all_unlink(cdr);
2401  ao2_unlink(active_cdrs_master, cdr);
2402  }
2403 
2404  /* Handle Party B */
2405  if (update->new_snapshot) {
2406  ao2_callback_data(active_cdrs_all, OBJ_NODATA | OBJ_MULTIPLE | OBJ_SEARCH_KEY,
2407  cdr_object_update_party_b, (char *) update->new_snapshot->base->name, update->new_snapshot);
2408  }
2409 
2410  if (ast_test_flag(&update->new_snapshot->flags, AST_FLAG_DEAD)) {
2411  ao2_callback_data(active_cdrs_all, OBJ_NODATA | OBJ_MULTIPLE | OBJ_SEARCH_KEY,
2412  cdr_object_finalize_party_b, (char *) update->new_snapshot->base->name, update->new_snapshot);
2413  }
2414 
2415  ao2_cleanup(cdr);
2416 }
2417 
2419  struct ast_bridge_snapshot *bridge;
2420  struct ast_channel_snapshot *channel;
2421  const struct timeval *lastevent;
2422 };
2423 
2424 /*! \brief Callback used to notify CDRs of a Party B leaving the bridge */
2425 static int cdr_object_party_b_left_bridge_cb(void *obj, void *arg, void *data, int flags)
2426 {
2427  struct cdr_object *cdr = obj;
2428  struct bridge_leave_data *leave_data = data;
2429 
2430  if (cdr->fn_table == &bridge_state_fn_table
2431  && !strcmp(cdr->bridge, leave_data->bridge->uniqueid)
2432  && !strcasecmp(cdr->party_b_name, arg)) {
2433  /*
2434  * For sanity's sake we also assert the party_b snapshot
2435  * is consistent with the key.
2436  */
2437  ast_assert(cdr->party_b.snapshot
2438  && !strcasecmp(cdr->party_b.snapshot->base->name, leave_data->channel->base->name));
2439 
2440  /* It is our Party B, in our bridge. Set the last event and let the handler
2441  * transition our CDR appropriately when we leave the bridge.
2442  */
2443  cdr->lastevent = *leave_data->lastevent;
2444  cdr_object_finalize(cdr);
2445  }
2446  return 0;
2447 }
2448 
2449 /*! \brief Filter bridge messages based on bridge technology */
2451 {
2452  /* Ignore holding bridge technology messages. We treat this simply as an application
2453  * that a channel enters into.
2454  */
2455  if (!strcmp(bridge->technology, "holding_bridge") && strcmp(bridge->subclass, "parking")) {
2456  return 1;
2457  }
2458  return 0;
2459 }
2460 
2461 /*!
2462  * \brief Handler for when a channel leaves a bridge
2463  * \param data Passed on
2464  * \param sub The stasis subscription for this message callback
2465  * \param message The message - hopefully a bridge one!
2466  */
2467 static void handle_bridge_leave_message(void *data, struct stasis_subscription *sub,
2468  struct stasis_message *message)
2469 {
2470  struct ast_bridge_blob *update = stasis_message_data(message);
2471  struct ast_bridge_snapshot *bridge = update->bridge;
2472  struct ast_channel_snapshot *channel = update->channel;
2473  struct cdr_object *cdr;
2474  struct cdr_object *it_cdr;
2475  struct bridge_leave_data leave_data = {
2476  .bridge = bridge,
2477  .channel = channel,
2478  .lastevent = stasis_message_timestamp(message)
2479  };
2480  int left_bridge = 0;
2481 
2482  if (filter_bridge_messages(bridge)) {
2483  return;
2484  }
2485 
2486  if (filter_channel_snapshot(channel)) {
2487  return;
2488  }
2489 
2490  CDR_DEBUG("Bridge Leave message for %s: %u.%08u\n",
2491  channel->base->name,
2492  (unsigned int)leave_data.lastevent->tv_sec,
2493  (unsigned int)leave_data.lastevent->tv_usec);
2494 
2495  cdr = ao2_find(active_cdrs_master, channel->base->uniqueid, OBJ_SEARCH_KEY);
2496  if (!cdr) {
2497  ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", channel->base->name);
2498  ast_assert(0);
2499  return;
2500  }
2501 
2502  /* Party A */
2503  ao2_lock(cdr);
2504  for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2505  it_cdr->lastevent = *leave_data.lastevent;
2506  if (!it_cdr->fn_table->process_bridge_leave) {
2507  continue;
2508  }
2509  CDR_DEBUG("%p - Processing Bridge Leave for %s\n",
2510  it_cdr, channel->base->name);
2511  if (!it_cdr->fn_table->process_bridge_leave(it_cdr, bridge, channel)) {
2512  ast_string_field_set(it_cdr, bridge, "");
2513  left_bridge = 1;
2514  }
2515  }
2516  ao2_unlock(cdr);
2517 
2518  /* Party B */
2519  if (left_bridge
2520  && strcmp(bridge->subclass, "parking")) {
2521  ao2_callback_data(active_cdrs_all, OBJ_NODATA | OBJ_MULTIPLE | OBJ_SEARCH_KEY,
2522  cdr_object_party_b_left_bridge_cb, (char *) leave_data.channel->base->name,
2523  &leave_data);
2524  }
2525 
2526  ao2_cleanup(cdr);
2527 }
2528 
2529 /*!
2530  * \internal
2531  * \brief Create a new CDR, append it to an existing CDR, and update its snapshots
2532  *
2533  * \note The new CDR will be automatically transitioned to the bridge state
2534  */
2535 static void bridge_candidate_add_to_cdr(struct cdr_object *cdr,
2536  struct cdr_object_snapshot *party_b)
2537 {
2538  struct cdr_object *new_cdr;
2539 
2540  new_cdr = cdr_object_create_and_append(cdr, &cdr->lastevent);
2541  if (!new_cdr) {
2542  return;
2543  }
2544  cdr_object_snapshot_copy(&new_cdr->party_b, party_b);
2545  cdr_all_relink(new_cdr);
2547  ast_string_field_set(new_cdr, bridge, cdr->bridge);
2548  cdr_object_transition_state(new_cdr, &bridge_state_fn_table);
2549  CDR_DEBUG("%p - Party A %s has new Party B %s\n",
2550  new_cdr, new_cdr->party_a.snapshot->base->name,
2551  party_b->snapshot->base->name);
2552 }
2553 
2554 /*!
2555  * \brief Process a single \c bridge_candidate
2556  *
2557  * When a CDR enters a bridge, it needs to make pairings with everyone else
2558  * that it is not currently paired with. This function determines, for the
2559  * CDR for the channel that entered the bridge and the CDR for every other
2560  * channel currently in the bridge, who is Party A and makes new CDRs.
2561  *
2562  * \param cdr The \ref cdr_object being processed
2563  * \param base_cand_cdr The \ref cdr_object that is a candidate
2564  *
2565  */
2566 static void bridge_candidate_process(struct cdr_object *cdr, struct cdr_object *base_cand_cdr)
2567 {
2568  struct cdr_object_snapshot *party_a;
2569  struct cdr_object *cand_cdr;
2570 
2571  ao2_lock(base_cand_cdr);
2572 
2573  for (cand_cdr = base_cand_cdr; cand_cdr; cand_cdr = cand_cdr->next) {
2574  /* Skip any records that are not in this bridge */
2575  if (strcmp(cand_cdr->bridge, cdr->bridge)) {
2576  continue;
2577  }
2578 
2579  /* If the candidate is us or someone we've taken on, pass on by */
2580  if (!strcasecmp(cdr->party_a.snapshot->base->name, cand_cdr->party_a.snapshot->base->name)
2581  || (cdr->party_b.snapshot
2582  && !strcasecmp(cdr->party_b.snapshot->base->name, cand_cdr->party_a.snapshot->base->name))) {
2583  break;
2584  }
2585 
2586  party_a = cdr_object_pick_party_a(&cdr->party_a, &cand_cdr->party_a);
2587  /* We're party A - make a new CDR, append it to us, and set the candidate as
2588  * Party B */
2589  if (!strcasecmp(party_a->snapshot->base->name, cdr->party_a.snapshot->base->name)) {
2590  bridge_candidate_add_to_cdr(cdr, &cand_cdr->party_a);
2591  break;
2592  }
2593 
2594  /* We're Party B. Check if we can add ourselves immediately or if we need
2595  * a new CDR for them (they already have a Party B) */
2596  if (cand_cdr->party_b.snapshot
2597  && strcasecmp(cand_cdr->party_b.snapshot->base->name, cdr->party_a.snapshot->base->name)) {
2598  bridge_candidate_add_to_cdr(cand_cdr, &cdr->party_a);
2599  } else {
2600  CDR_DEBUG("%p - Party A %s has new Party B %s\n",
2601  cand_cdr, cand_cdr->party_a.snapshot->base->name,
2602  cdr->party_a.snapshot->base->name);
2603  cdr_object_snapshot_copy(&cand_cdr->party_b, &cdr->party_a);
2604  cdr_all_relink(cand_cdr);
2605  /* It's possible that this joined at one point and was never chosen
2606  * as party A. Clear their end time, as it would be set in such a
2607  * case.
2608  */
2609  memset(&cand_cdr->end, 0, sizeof(cand_cdr->end));
2610  }
2611 
2612  break;
2613  }
2614 
2615  ao2_unlock(base_cand_cdr);
2616 }
2617 
2618 /*!
2619  * \brief Handle creating bridge pairings for the \ref cdr_object that just
2620  * entered a bridge
2621  * \param cdr The \ref cdr_object that just entered the bridge
2622  * \param bridge The \ref ast_bridge_snapshot representing the bridge it just entered
2623  */
2624 static void handle_bridge_pairings(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge)
2625 {
2626  struct ao2_iterator it_channels;
2627  char *channel_id;
2628 
2629  it_channels = ao2_iterator_init(bridge->channels, 0);
2630  while ((channel_id = ao2_iterator_next(&it_channels))) {
2631  struct cdr_object *cand_cdr;
2632 
2633  cand_cdr = ao2_find(active_cdrs_master, channel_id, OBJ_SEARCH_KEY);
2634  if (cand_cdr) {
2635  bridge_candidate_process(cdr, cand_cdr);
2636  ao2_ref(cand_cdr, -1);
2637  }
2638 
2639  ao2_ref(channel_id, -1);
2640  }
2641  ao2_iterator_destroy(&it_channels);
2642 }
2643 
2644 /*! \brief Handle entering into a parking bridge
2645  * \param cdr The CDR to operate on
2646  * \param bridge The bridge the channel just entered
2647  * \param channel The channel snapshot
2648  * \param event_time
2649  */
2651  struct ast_bridge_snapshot *bridge,
2652  struct ast_channel_snapshot *channel,
2653  const struct timeval *event_time)
2654 {
2655  int res = 1;
2656  struct cdr_object *it_cdr;
2657  struct cdr_object *new_cdr;
2658 
2659  ao2_lock(cdr);
2660 
2661  for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2662  it_cdr->lastevent = *event_time;
2663 
2664  if (it_cdr->fn_table->process_parking_bridge_enter) {
2665  res &= it_cdr->fn_table->process_parking_bridge_enter(it_cdr, bridge, channel);
2666  }
2667  if (it_cdr->fn_table->process_party_a) {
2668  CDR_DEBUG("%p - Updating Party A %s snapshot\n", it_cdr,
2669  channel->base->name);
2670  it_cdr->fn_table->process_party_a(it_cdr, channel);
2671  }
2672  }
2673 
2674  if (res) {
2675  /* No one handled it - we need a new one! */
2676  new_cdr = cdr_object_create_and_append(cdr, event_time);
2677  if (new_cdr) {
2678  /* Let the single state transition us to Parked */
2679  cdr_object_transition_state(new_cdr, &single_state_fn_table);
2680  new_cdr->fn_table->process_parking_bridge_enter(new_cdr, bridge, channel);
2681  }
2682  }
2683  ao2_unlock(cdr);
2684 }
2685 
2686 /*! \brief Handle a bridge enter message for a 'normal' bridge
2687  * \param cdr The CDR to operate on
2688  * \param bridge The bridge the channel just entered
2689  * \param channel The channel snapshot
2690  * \param event_time
2691  */
2693  struct ast_bridge_snapshot *bridge,
2694  struct ast_channel_snapshot *channel,
2695  const struct timeval *event_time)
2696 {
2697  enum process_bridge_enter_results result;
2698  struct cdr_object *it_cdr;
2699  struct cdr_object *new_cdr;
2700  struct cdr_object *handled_cdr = NULL;
2701 
2702  ao2_lock(cdr);
2703 
2704 try_again:
2705  for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2706  it_cdr->lastevent = *event_time;
2707 
2708  if (it_cdr->fn_table->process_party_a) {
2709  CDR_DEBUG("%p - Updating Party A %s snapshot\n", it_cdr,
2710  channel->base->name);
2711  it_cdr->fn_table->process_party_a(it_cdr, channel);
2712  }
2713 
2714  /* Notify all states that they have entered a bridge */
2715  if (it_cdr->fn_table->process_bridge_enter) {
2716  CDR_DEBUG("%p - Processing bridge enter for %s\n", it_cdr,
2717  channel->base->name);
2718  result = it_cdr->fn_table->process_bridge_enter(it_cdr, bridge, channel);
2719  switch (result) {
2721  /* Fall through */
2723  if (!handled_cdr) {
2724  handled_cdr = it_cdr;
2725  }
2726  break;
2727  case BRIDGE_ENTER_NEED_CDR:
2728  /* Pass */
2729  break;
2731  /* We didn't win on any - end this CDR. If someone else comes in later
2732  * that is Party B to this CDR, it can re-activate this CDR.
2733  */
2734  if (!handled_cdr) {
2735  handled_cdr = it_cdr;
2736  }
2737  cdr_object_finalize(cdr);
2738  break;
2739  }
2740  }
2741  }
2742 
2743  /* Create the new matchings, but only for either:
2744  * * The first CDR in the chain that handled it. This avoids issues with
2745  * forked CDRs.
2746  * * If no one handled it, the last CDR in the chain. This would occur if
2747  * a CDR joined a bridge and it wasn't Party A for anyone. We still need
2748  * to make pairings with everyone in the bridge.
2749  */
2750  if (handled_cdr) {
2751  handle_bridge_pairings(handled_cdr, bridge);
2752  } else {
2753  /* Nothing handled it - we need a new one! */
2754  new_cdr = cdr_object_create_and_append(cdr, event_time);
2755  if (new_cdr) {
2756  /* This is guaranteed to succeed: the new CDR is created in the single state
2757  * and will be able to handle the bridge enter message
2758  */
2759  goto try_again;
2760  }
2761  }
2762  ao2_unlock(cdr);
2763 }
2764 
2765 /*!
2766  * \internal
2767  * \brief Handler for Stasis-Core bridge enter messages
2768  * \param data Passed on
2769  * \param sub The stasis subscription for this message callback
2770  * \param message The message - hopefully a bridge one!
2771  */
2772 static void handle_bridge_enter_message(void *data, struct stasis_subscription *sub,
2773  struct stasis_message *message)
2774 {
2775  struct ast_bridge_blob *update = stasis_message_data(message);
2776  struct ast_bridge_snapshot *bridge = update->bridge;
2777  struct ast_channel_snapshot *channel = update->channel;
2778  struct cdr_object *cdr;
2779 
2780  if (filter_bridge_messages(bridge)) {
2781  return;
2782  }
2783 
2784  if (filter_channel_snapshot(channel)) {
2785  return;
2786  }
2787 
2788  CDR_DEBUG("Bridge Enter message for channel %s: %u.%08u\n",
2789  channel->base->name,
2790  (unsigned int)stasis_message_timestamp(message)->tv_sec,
2791  (unsigned int)stasis_message_timestamp(message)->tv_usec);
2792 
2793  cdr = ao2_find(active_cdrs_master, channel->base->uniqueid, OBJ_SEARCH_KEY);
2794  if (!cdr) {
2795  ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", channel->base->name);
2796  ast_assert(0);
2797  return;
2798  }
2799 
2800  if (!strcmp(bridge->subclass, "parking")) {
2801  handle_parking_bridge_enter_message(cdr, bridge, channel, stasis_message_timestamp(message));
2802  } else {
2803  handle_standard_bridge_enter_message(cdr, bridge, channel, stasis_message_timestamp(message));
2804  }
2805  ao2_cleanup(cdr);
2806 }
2807 
2808 /*!
2809  * \brief Handler for when a channel is parked
2810  * \param data Passed on
2811  * \param sub The stasis subscription for this message callback
2812  * \param message The message about who got parked
2813  * */
2814 static void handle_parked_call_message(void *data, struct stasis_subscription *sub,
2815  struct stasis_message *message)
2816 {
2817  struct ast_parked_call_payload *payload = stasis_message_data(message);
2818  struct ast_channel_snapshot *channel = payload->parkee;
2819  struct cdr_object *cdr;
2820  int unhandled = 1;
2821  struct cdr_object *it_cdr;
2822 
2823  /* Anything other than getting parked will be handled by other updates */
2824  if (payload->event_type != PARKED_CALL) {
2825  return;
2826  }
2827 
2828  /* No one got parked? */
2829  if (!channel) {
2830  return;
2831  }
2832 
2833  if (filter_channel_snapshot(channel)) {
2834  return;
2835  }
2836 
2837  CDR_DEBUG("Parked Call message for channel %s: %u.%08u\n",
2838  channel->base->name,
2839  (unsigned int)stasis_message_timestamp(message)->tv_sec,
2840  (unsigned int)stasis_message_timestamp(message)->tv_usec);
2841 
2842  cdr = ao2_find(active_cdrs_master, channel->base->uniqueid, OBJ_SEARCH_KEY);
2843  if (!cdr) {
2844  ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", channel->base->name);
2845  ast_assert(0);
2846  return;
2847  }
2848 
2849  ao2_lock(cdr);
2850 
2851  for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
2852  it_cdr->lastevent = *stasis_message_timestamp(message);
2853  if (it_cdr->fn_table->process_parked_channel) {
2854  unhandled &= it_cdr->fn_table->process_parked_channel(it_cdr, payload);
2855  }
2856  }
2857 
2858  if (unhandled) {
2859  /* Nothing handled the messgae - we need a new one! */
2860  struct cdr_object *new_cdr;
2861 
2862  new_cdr = cdr_object_create_and_append(cdr, stasis_message_timestamp(message));
2863  if (new_cdr) {
2864  /* As the new CDR is created in the single state, it is guaranteed
2865  * to have a function for the parked call message and will handle
2866  * the message */
2867  new_cdr->fn_table->process_parked_channel(new_cdr, payload);
2868  }
2869  }
2870 
2871  ao2_unlock(cdr);
2872 
2873  ao2_cleanup(cdr);
2874 }
2875 
2876 /*!
2877  * \brief Handler for a synchronization message
2878  * \param data Passed on
2879  * \param sub The stasis subscription for this message callback
2880  * \param message A blank ao2 object
2881  * */
2882 static void handle_cdr_sync_message(void *data, struct stasis_subscription *sub,
2883  struct stasis_message *message)
2884 {
2885  return;
2886 }
2887 
2889 {
2890  struct ast_cdr_config *general;
2891  struct module_config *mod_cfg;
2892 
2893  mod_cfg = ao2_global_obj_ref(module_configs);
2894  if (!mod_cfg) {
2895  return NULL;
2896  }
2897  general = ao2_bump(mod_cfg->general);
2898  ao2_cleanup(mod_cfg);
2899  return general;
2900 }
2901 
2903 {
2904  struct module_config *mod_cfg;
2905 
2906  if (!config) {
2907  return;
2908  }
2909 
2910  mod_cfg = ao2_global_obj_ref(module_configs);
2911  if (!mod_cfg) {
2912  return;
2913  }
2914 
2915  ao2_replace(mod_cfg->general, config);
2916 
2917  cdr_set_debug_mode(mod_cfg);
2919 
2920  ao2_cleanup(mod_cfg);
2921 }
2922 
2924 {
2925  return is_cdr_flag_set(CDR_ENABLED);
2926 }
2927 
2928 int ast_cdr_backend_suspend(const char *name)
2929 {
2930  int success = -1;
2931  struct cdr_beitem *i = NULL;
2932 
2934  AST_RWLIST_TRAVERSE(&be_list, i, list) {
2935  if (!strcasecmp(name, i->name)) {
2936  ast_debug(3, "Suspending CDR backend %s\n", i->name);
2937  i->suspended = 1;
2938  success = 0;
2939  }
2940  }
2942 
2943  return success;
2944 }
2945 
2946 int ast_cdr_backend_unsuspend(const char *name)
2947 {
2948  int success = -1;
2949  struct cdr_beitem *i = NULL;
2950 
2952  AST_RWLIST_TRAVERSE(&be_list, i, list) {
2953  if (!strcasecmp(name, i->name)) {
2954  ast_debug(3, "Unsuspending CDR backend %s\n", i->name);
2955  i->suspended = 0;
2956  success = 0;
2957  }
2958  }
2960 
2961  return success;
2962 }
2963 
2964 static int cdr_generic_register(struct be_list *generic_list, const char *name, const char *desc, ast_cdrbe be)
2965 {
2966  struct cdr_beitem *i;
2967  struct cdr_beitem *cur;
2968 
2969  if (!name) {
2970  return -1;
2971  }
2972 
2973  if (!be) {
2974  ast_log(LOG_WARNING, "CDR engine '%s' lacks backend\n", name);
2975 
2976  return -1;
2977  }
2978 
2979  i = ast_calloc(1, sizeof(*i));
2980  if (!i) {
2981  return -1;
2982  }
2983 
2984  i->be = be;
2985  ast_copy_string(i->name, name, sizeof(i->name));
2986  ast_copy_string(i->desc, desc, sizeof(i->desc));
2987 
2988  AST_RWLIST_WRLOCK(generic_list);
2989  AST_RWLIST_TRAVERSE(generic_list, cur, list) {
2990  if (!strcasecmp(name, cur->name)) {
2991  ast_log(LOG_WARNING, "Already have a CDR backend called '%s'\n", name);
2992  AST_RWLIST_UNLOCK(generic_list);
2993  ast_free(i);
2994 
2995  return -1;
2996  }
2997  }
2998 
2999  AST_RWLIST_INSERT_HEAD(generic_list, i, list);
3000  AST_RWLIST_UNLOCK(generic_list);
3001 
3002  return 0;
3003 }
3004 
3005 int ast_cdr_register(const char *name, const char *desc, ast_cdrbe be)
3006 {
3007  return cdr_generic_register(&be_list, name, desc, be);
3008 }
3009 
3010 int ast_cdr_modifier_register(const char *name, const char *desc, ast_cdrbe be)
3011 {
3012  return cdr_generic_register((struct be_list *)&mo_list, name, desc, be);
3013 }
3014 
3015 static int ast_cdr_generic_unregister(struct be_list *generic_list, const char *name)
3016 {
3017  struct cdr_beitem *match = NULL;
3018  int active_count;
3019 
3020  AST_RWLIST_WRLOCK(generic_list);
3021  AST_RWLIST_TRAVERSE(generic_list, match, list) {
3022  if (!strcasecmp(name, match->name)) {
3023  break;
3024  }
3025  }
3026 
3027  if (!match) {
3028  AST_RWLIST_UNLOCK(generic_list);
3029  return 0;
3030  }
3031 
3032  active_count = ao2_container_count(active_cdrs_master);
3033 
3034  if (!match->suspended && active_count != 0) {
3035  AST_RWLIST_UNLOCK(generic_list);
3036  ast_log(AST_LOG_WARNING, "Unable to unregister CDR backend %s; %d CDRs are still active\n",
3037  name, active_count);
3038  return -1;
3039  }
3040 
3041  AST_RWLIST_REMOVE(generic_list, match, list);
3042  AST_RWLIST_UNLOCK(generic_list);
3043 
3044  ast_verb(5, "Unregistered '%s' CDR backend\n", name);
3045  ast_free(match);
3046 
3047  return 0;
3048 }
3049 
3050 int ast_cdr_unregister(const char *name)
3051 {
3052  return ast_cdr_generic_unregister(&be_list, name);
3053 }
3054 
3055 int ast_cdr_modifier_unregister(const char *name)
3056 {
3057  return ast_cdr_generic_unregister((struct be_list *)&mo_list, name);
3058 }
3059 
3060 struct ast_cdr *ast_cdr_dup(struct ast_cdr *cdr)
3061 {
3062  struct ast_cdr *newcdr;
3063 
3064  if (!cdr) {
3065  return NULL;
3066  }
3067  newcdr = ast_cdr_alloc();
3068  if (!newcdr) {
3069  return NULL;
3070  }
3071 
3072  *newcdr = *cdr;
3074  copy_variables(&newcdr->varshead, &cdr->varshead);
3075  newcdr->next = NULL;
3076 
3077  return newcdr;
3078 }
3079 
3080 static const char *cdr_format_var_internal(struct ast_cdr *cdr, const char *name)
3081 {
3082  struct ast_var_t *variables;
3083 
3084  if (ast_strlen_zero(name)) {
3085  return NULL;
3086  }
3087 
3088  AST_LIST_TRAVERSE(&cdr->varshead, variables, entries) {
3089  if (!strcasecmp(name, ast_var_name(variables))) {
3090  return ast_var_value(variables);
3091  }
3092  }
3093 
3094  return NULL;
3095 }
3096 
3097 static void cdr_get_tv(struct timeval when, const char *fmt, char *buf, int bufsize)
3098 {
3099  if (fmt == NULL) { /* raw mode */
3100  snprintf(buf, bufsize, "%ld.%06ld", (long)when.tv_sec, (long)when.tv_usec);
3101  } else {
3102  buf[0] = '\0';/* Ensure the buffer is initialized. */
3103  if (when.tv_sec) {
3104  struct ast_tm tm;
3105 
3106  ast_localtime(&when, &tm, NULL);
3107  ast_strftime(buf, bufsize, fmt, &tm);
3108  }
3109  }
3110 }
3111 
3112 void ast_cdr_format_var(struct ast_cdr *cdr, const char *name, char **ret, char *workspace, int workspacelen, int raw)
3113 {
3114  const char *fmt = "%Y-%m-%d %T";
3115  const char *varbuf;
3116 
3117  if (!cdr) {
3118  return;
3119  }
3120 
3121  *ret = NULL;
3122 
3123  if (!strcasecmp(name, "clid")) {
3124  ast_copy_string(workspace, cdr->clid, workspacelen);
3125  } else if (!strcasecmp(name, "src")) {
3126  ast_copy_string(workspace, cdr->src, workspacelen);
3127  } else if (!strcasecmp(name, "dst")) {
3128  ast_copy_string(workspace, cdr->dst, workspacelen);
3129  } else if (!strcasecmp(name, "dcontext")) {
3130  ast_copy_string(workspace, cdr->dcontext, workspacelen);
3131  } else if (!strcasecmp(name, "channel")) {
3132  ast_copy_string(workspace, cdr->channel, workspacelen);
3133  } else if (!strcasecmp(name, "dstchannel")) {
3134  ast_copy_string(workspace, cdr->dstchannel, workspacelen);
3135  } else if (!strcasecmp(name, "lastapp")) {
3136  ast_copy_string(workspace, cdr->lastapp, workspacelen);
3137  } else if (!strcasecmp(name, "lastdata")) {
3138  ast_copy_string(workspace, cdr->lastdata, workspacelen);
3139  } else if (!strcasecmp(name, "start")) {
3140  cdr_get_tv(cdr->start, raw ? NULL : fmt, workspace, workspacelen);
3141  } else if (!strcasecmp(name, "answer")) {
3142  cdr_get_tv(cdr->answer, raw ? NULL : fmt, workspace, workspacelen);
3143  } else if (!strcasecmp(name, "end")) {
3144  cdr_get_tv(cdr->end, raw ? NULL : fmt, workspace, workspacelen);
3145  } else if (!strcasecmp(name, "duration")) {
3146  snprintf(workspace, workspacelen, "%ld", cdr->end.tv_sec != 0 ? cdr->duration : (long)ast_tvdiff_ms(ast_tvnow(), cdr->start) / 1000);
3147  } else if (!strcasecmp(name, "billsec")) {
3148  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);
3149  } else if (!strcasecmp(name, "disposition")) {
3150  if (raw) {
3151  snprintf(workspace, workspacelen, "%ld", cdr->disposition);
3152  } else {
3153  ast_copy_string(workspace, ast_cdr_disp2str(cdr->disposition), workspacelen);
3154  }
3155  } else if (!strcasecmp(name, "amaflags")) {
3156  if (raw) {
3157  snprintf(workspace, workspacelen, "%ld", cdr->amaflags);
3158  } else {
3159  ast_copy_string(workspace, ast_channel_amaflags2string(cdr->amaflags), workspacelen);
3160  }
3161  } else if (!strcasecmp(name, "accountcode")) {
3162  ast_copy_string(workspace, cdr->accountcode, workspacelen);
3163  } else if (!strcasecmp(name, "peeraccount")) {
3164  ast_copy_string(workspace, cdr->peeraccount, workspacelen);
3165  } else if (!strcasecmp(name, "uniqueid")) {
3166  ast_copy_string(workspace, cdr->uniqueid, workspacelen);
3167  } else if (!strcasecmp(name, "linkedid")) {
3168  ast_copy_string(workspace, cdr->linkedid, workspacelen);
3169  } else if (!strcasecmp(name, "userfield")) {
3170  ast_copy_string(workspace, cdr->userfield, workspacelen);
3171  } else if (!strcasecmp(name, "sequence")) {
3172  snprintf(workspace, workspacelen, "%d", cdr->sequence);
3173  } else if ((varbuf = cdr_format_var_internal(cdr, name))) {
3174  ast_copy_string(workspace, varbuf, workspacelen);
3175  } else {
3176  workspace[0] = '\0';
3177  }
3178 
3179  if (!ast_strlen_zero(workspace)) {
3180  *ret = workspace;
3181  }
3182 }
3183 
3184 /*!
3185  * \internal
3186  * \brief Callback that finds all CDRs that reference a particular channel by name
3187  */
3188 static int cdr_object_select_all_by_name_cb(void *obj, void *arg, int flags)
3189 {
3190  struct cdr_object *cdr = obj;
3191  const char *name = arg;
3192 
3193  if (!strcasecmp(cdr->party_a.snapshot->base->name, name) ||
3194  (cdr->party_b.snapshot && !strcasecmp(cdr->party_b.snapshot->base->name, name))) {
3195  return CMP_MATCH;
3196  }
3197  return 0;
3198 }
3199 
3200 /*!
3201  * \internal
3202  * \brief Callback that finds a CDR by channel name
3203  */
3204 static int cdr_object_get_by_name_cb(void *obj, void *arg, int flags)
3205 {
3206  struct cdr_object *cdr = obj;
3207  const char *name = arg;
3208 
3209  if (!strcasecmp(cdr->party_a.snapshot->base->name, name)) {
3210  return CMP_MATCH;
3211  }
3212  return 0;
3213 }
3214 
3215 /* Read Only CDR variables */
3216 static const char * const cdr_readonly_vars[] = {
3217  "clid",
3218  "src",
3219  "dst",
3220  "dcontext",
3221  "channel",
3222  "dstchannel",
3223  "lastapp",
3224  "lastdata",
3225  "start",
3226  "answer",
3227  "end",
3228  "duration",
3229  "billsec",
3230  "disposition",
3231  "amaflags",
3232  "accountcode",
3233  "uniqueid",
3234  "linkedid",
3235  "userfield",
3236  "sequence",
3237  NULL
3238 };
3239 
3240 int ast_cdr_setvar(const char *channel_name, const char *name, const char *value)
3241 {
3242  struct cdr_object *cdr;
3243  struct cdr_object *it_cdr;
3244  struct ao2_iterator *it_cdrs;
3245  char *arg = ast_strdupa(channel_name);
3246  int x;
3247 
3248  for (x = 0; cdr_readonly_vars[x]; x++) {
3249  if (!strcasecmp(name, cdr_readonly_vars[x])) {
3250  ast_log(LOG_ERROR, "Attempt to set the '%s' read-only variable!\n", name);
3251  return -1;
3252  }
3253  }
3254 
3255  it_cdrs = ao2_callback(active_cdrs_master, OBJ_MULTIPLE, cdr_object_select_all_by_name_cb, arg);
3256  if (!it_cdrs) {
3257  ast_log(AST_LOG_ERROR, "Unable to find CDR for channel %s\n", channel_name);
3258  return -1;
3259  }
3260 
3261  for (; (cdr = ao2_iterator_next(it_cdrs)); ao2_unlock(cdr), ao2_cleanup(cdr)) {
3262  ao2_lock(cdr);
3263  for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3264  struct varshead *headp = NULL;
3265 
3266  if (it_cdr->fn_table == &finalized_state_fn_table && it_cdr->next != NULL) {
3267  continue;
3268  }
3269  if (!strcasecmp(channel_name, it_cdr->party_a.snapshot->base->name)) {
3270  headp = &it_cdr->party_a.variables;
3271  } else if (it_cdr->party_b.snapshot
3272  && !strcasecmp(channel_name, it_cdr->party_b.snapshot->base->name)) {
3273  headp = &it_cdr->party_b.variables;
3274  }
3275  if (headp) {
3276  set_variable(headp, name, value);
3277  }
3278  }
3279  }
3280  ao2_iterator_destroy(it_cdrs);
3281 
3282  return 0;
3283 }
3284 
3285 /*!
3286  * \brief Format a variable on a \ref cdr_object
3287  */
3288 static void cdr_object_format_var_internal(struct cdr_object *cdr, const char *name, char *value, size_t length)
3289 {
3290  struct ast_var_t *variable;
3291 
3292  AST_LIST_TRAVERSE(&cdr->party_a.variables, variable, entries) {
3293  if (!strcasecmp(name, ast_var_name(variable))) {
3294  ast_copy_string(value, ast_var_value(variable), length);
3295  return;
3296  }
3297  }
3298 
3299  *value = '\0';
3300 }
3301 
3302 /*!
3303  * \brief Format one of the standard properties on a \ref cdr_object
3304  */
3305 static int cdr_object_format_property(struct cdr_object *cdr_obj, const char *name, char *value, size_t length)
3306 {
3307  struct ast_channel_snapshot *party_a = cdr_obj->party_a.snapshot;
3308  struct ast_channel_snapshot *party_b = cdr_obj->party_b.snapshot;
3309 
3310  if (!strcasecmp(name, "clid")) {
3311  ast_callerid_merge(value, length, party_a->caller->name, party_a->caller->number, "");
3312  } else if (!strcasecmp(name, "src")) {
3313  ast_copy_string(value, party_a->caller->number, length);
3314  } else if (!strcasecmp(name, "dst")) {
3315  ast_copy_string(value, party_a->dialplan->exten, length);
3316  } else if (!strcasecmp(name, "dcontext")) {
3317  ast_copy_string(value, party_a->dialplan->context, length);
3318  } else if (!strcasecmp(name, "channel")) {
3319  ast_copy_string(value, party_a->base->name, length);
3320  } else if (!strcasecmp(name, "dstchannel")) {
3321  if (party_b) {
3322  ast_copy_string(value, party_b->base->name, length);
3323  } else {
3324  ast_copy_string(value, "", length);
3325  }
3326  } else if (!strcasecmp(name, "lastapp")) {
3327  ast_copy_string(value, party_a->dialplan->appl, length);
3328  } else if (!strcasecmp(name, "lastdata")) {
3329  ast_copy_string(value, party_a->dialplan->data, length);
3330  } else if (!strcasecmp(name, "start")) {
3331  cdr_get_tv(cdr_obj->start, NULL, value, length);
3332  } else if (!strcasecmp(name, "answer")) {
3333  cdr_get_tv(cdr_obj->answer, NULL, value, length);
3334  } else if (!strcasecmp(name, "end")) {
3335  cdr_get_tv(cdr_obj->end, NULL, value, length);
3336  } else if (!strcasecmp(name, "duration")) {
3337  snprintf(value, length, "%ld", cdr_object_get_duration(cdr_obj));
3338  } else if (!strcasecmp(name, "billsec")) {
3339  snprintf(value, length, "%ld", cdr_object_get_billsec(cdr_obj));
3340  } else if (!strcasecmp(name, "disposition")) {
3341  snprintf(value, length, "%u", cdr_obj->disposition);
3342  } else if (!strcasecmp(name, "amaflags")) {
3343  snprintf(value, length, "%d", party_a->amaflags);
3344  } else if (!strcasecmp(name, "accountcode")) {
3345  ast_copy_string(value, party_a->base->accountcode, length);
3346  } else if (!strcasecmp(name, "peeraccount")) {
3347  if (party_b) {
3348  ast_copy_string(value, party_b->base->accountcode, length);
3349  } else {
3350  ast_copy_string(value, "", length);
3351  }
3352  } else if (!strcasecmp(name, "uniqueid")) {
3353  ast_copy_string(value, party_a->base->uniqueid, length);
3354  } else if (!strcasecmp(name, "linkedid")) {
3355  ast_copy_string(value, cdr_obj->linkedid, length);
3356  } else if (!strcasecmp(name, "userfield")) {
3357  ast_copy_string(value, cdr_obj->party_a.userfield, length);
3358  } else if (!strcasecmp(name, "sequence")) {
3359  snprintf(value, length, "%u", cdr_obj->sequence);
3360  } else {
3361  return 1;
3362  }
3363 
3364  return 0;
3365 }
3366 
3367 /*! \internal
3368  * \brief Look up and retrieve a CDR object by channel name
3369  * \param name The name of the channel
3370  * \retval NULL on error
3371  * \return The \ref cdr_object for the channel on success, with the reference
3372  * count bumped by one.
3373  */
3374 static struct cdr_object *cdr_object_get_by_name(const char *name)
3375 {
3376  char *param;
3377 
3378  if (ast_strlen_zero(name)) {
3379  return NULL;
3380  }
3381 
3382  param = ast_strdupa(name);
3383  return ao2_callback(active_cdrs_master, 0, cdr_object_get_by_name_cb, param);
3384 }
3385 
3386 int ast_cdr_getvar(const char *channel_name, const char *name, char *value, size_t length)
3387 {
3388  struct cdr_object *cdr;
3389  struct cdr_object *cdr_obj;
3390 
3391  if (ast_strlen_zero(name)) {
3392  return 1;
3393  }
3394 
3395  cdr = cdr_object_get_by_name(channel_name);
3396  if (!cdr) {
3397  ast_log(AST_LOG_ERROR, "Unable to find CDR for channel %s\n", channel_name);
3398  return 1;
3399  }
3400 
3401  ao2_lock(cdr);
3402 
3403  cdr_obj = cdr->last;
3404  if (cdr_object_format_property(cdr_obj, name, value, length)) {
3405  /* Property failed; attempt variable */
3406  cdr_object_format_var_internal(cdr_obj, name, value, length);
3407  }
3408 
3409  ao2_unlock(cdr);
3410 
3411  ao2_cleanup(cdr);
3412  return 0;
3413 }
3414 
3415 int ast_cdr_serialize_variables(const char *channel_name, struct ast_str **buf, char delim, char sep)
3416 {
3417  struct cdr_object *cdr;
3418  struct cdr_object *it_cdr;
3419  struct ast_var_t *variable;
3420  const char *var;
3421  char workspace[256];
3422  int total = 0, x = 0, i;
3423 
3424  cdr = cdr_object_get_by_name(channel_name);
3425  if (!cdr) {
3426  if (is_cdr_flag_set(CDR_ENABLED)) {
3427  ast_log(AST_LOG_ERROR, "Unable to find CDR for channel %s\n", channel_name);
3428  }
3429  return 0;
3430  }
3431 
3432  ast_str_reset(*buf);
3433 
3434  ao2_lock(cdr);
3435  for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3436  if (++x > 1) {
3437  ast_str_append(buf, 0, "\n");
3438  }
3439 
3440  AST_LIST_TRAVERSE(&it_cdr->party_a.variables, variable, entries) {
3441  if (!(var = ast_var_name(variable))) {
3442  continue;
3443  }
3444 
3445  if (ast_str_append(buf, 0, "level %d: %s%c%s%c", x, var, delim, S_OR(ast_var_value(variable), ""), sep) < 0) {
3446  ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
3447  break;
3448  }
3449 
3450  total++;
3451  }
3452 
3453  for (i = 0; cdr_readonly_vars[i]; i++) {
3454  if (cdr_object_format_property(it_cdr, cdr_readonly_vars[i], workspace, sizeof(workspace))) {
3455  /* Unhandled read-only CDR variable. */
3456  ast_assert(0);
3457  continue;
3458  }
3459 
3460  if (!ast_strlen_zero(workspace)
3461  && ast_str_append(buf, 0, "level %d: %s%c%s%c", x, cdr_readonly_vars[i], delim, workspace, sep) < 0) {
3462  ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
3463  break;
3464  }
3465  total++;
3466  }
3467  }
3468  ao2_unlock(cdr);
3469  ao2_cleanup(cdr);
3470  return total;
3471 }
3472 
3473 void ast_cdr_free(struct ast_cdr *cdr)
3474 {
3475  while (cdr) {
3476  struct ast_cdr *next = cdr->next;
3477 
3478  free_variables(&cdr->varshead);
3479  ast_free(cdr);
3480  cdr = next;
3481  }
3482 }
3483 
3484 struct ast_cdr *ast_cdr_alloc(void)
3485 {
3486  struct ast_cdr *x;
3487 
3488  x = ast_calloc(1, sizeof(*x));
3489  return x;
3490 }
3491 
3492 const char *ast_cdr_disp2str(int disposition)
3493 {
3494  switch (disposition) {
3495  case AST_CDR_NULL:
3496  return "NO ANSWER"; /* by default, for backward compatibility */
3497  case AST_CDR_NOANSWER:
3498  return "NO ANSWER";
3499  case AST_CDR_FAILED:
3500  return "FAILED";
3501  case AST_CDR_BUSY:
3502  return "BUSY";
3503  case AST_CDR_ANSWERED:
3504  return "ANSWERED";
3505  case AST_CDR_CONGESTION:
3506  return "CONGESTION";
3507  }
3508  return "UNKNOWN";
3509 }
3510 
3512  const char *channel_name;
3513  const char *userfield;
3514 };
3515 
3516 /*! \brief Callback used to update the userfield on Party B on all CDRs */
3517 static int cdr_object_update_party_b_userfield_cb(void *obj, void *arg, void *data, int flags)
3518 {
3519  struct cdr_object *cdr = obj;
3520 
3521  if ((cdr->fn_table != &finalized_state_fn_table || !cdr->next)
3522  && !strcasecmp(cdr->party_b_name, arg)) {
3523  struct party_b_userfield_update *info = data;
3524 
3525  /*
3526  * For sanity's sake we also assert the party_b snapshot
3527  * is consistent with the key.
3528  */
3529  ast_assert(cdr->party_b.snapshot
3530  && !strcasecmp(cdr->party_b.snapshot->base->name, info->channel_name));
3531 
3532  ast_copy_string(cdr->party_b.userfield, info->userfield,
3533  sizeof(cdr->party_b.userfield));
3534  }
3535 
3536  return 0;
3537 }
3538 
3539 void ast_cdr_setuserfield(const char *channel_name, const char *userfield)
3540 {
3541  struct cdr_object *cdr;
3542  struct party_b_userfield_update party_b_info = {
3543  .channel_name = channel_name,
3544  .userfield = userfield,
3545  };
3546  struct cdr_object *it_cdr;
3547 
3548  /* Handle Party A */
3549  cdr = cdr_object_get_by_name(channel_name);
3550  if (cdr) {
3551  ao2_lock(cdr);
3552  for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3553  if (it_cdr->fn_table == &finalized_state_fn_table && it_cdr->next != NULL) {
3554  continue;
3555  }
3556  ast_copy_string(it_cdr->party_a.userfield, userfield,
3557  sizeof(it_cdr->party_a.userfield));
3558  }
3559  ao2_unlock(cdr);
3560  }
3561 
3562  /* Handle Party B */
3563  ao2_callback_data(active_cdrs_all, OBJ_NODATA | OBJ_MULTIPLE | OBJ_SEARCH_KEY,
3564  cdr_object_update_party_b_userfield_cb, (char *) party_b_info.channel_name,
3565  &party_b_info);
3566 
3567  ao2_cleanup(cdr);
3568 }
3569 
3570 static void post_cdr(struct ast_cdr *cdr)
3571 {
3572  struct module_config *mod_cfg;
3573  struct cdr_beitem *i;
3574 
3575  mod_cfg = ao2_global_obj_ref(module_configs);
3576  if (!mod_cfg) {
3577  return;
3578  }
3579 
3580  for (; cdr ; cdr = cdr->next) {
3581  /* For people, who don't want to see unanswered single-channel events */
3582  if (!ast_test_flag(&mod_cfg->general->settings, CDR_UNANSWERED) &&
3583  cdr->disposition < AST_CDR_ANSWERED &&
3584  (ast_strlen_zero(cdr->channel) || ast_strlen_zero(cdr->dstchannel))) {
3585  ast_debug(1, "Skipping CDR for %s since we weren't answered\n", cdr->channel);
3586  continue;
3587  }
3588 
3589  /* Modify CDR's */
3591  AST_RWLIST_TRAVERSE(&mo_list, i, list) {
3592  i->be(cdr);
3593  }
3595 
3596  if (ast_test_flag(cdr, AST_CDR_FLAG_DISABLE)) {
3597  continue;
3598  }
3600  AST_RWLIST_TRAVERSE(&be_list, i, list) {
3601  if (!i->suspended) {
3602  i->be(cdr);
3603  }
3604  }
3606  }
3607  ao2_cleanup(mod_cfg);
3608 }
3609 
3610 int ast_cdr_set_property(const char *channel_name, enum ast_cdr_options option)
3611 {
3612  struct cdr_object *cdr;
3613  struct cdr_object *it_cdr;
3614 
3615  cdr = cdr_object_get_by_name(channel_name);
3616  if (!cdr) {
3617  return -1;
3618  }
3619 
3620  ao2_lock(cdr);
3621  for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3622  if (it_cdr->fn_table == &finalized_state_fn_table) {
3623  continue;
3624  }
3625  /* Note: in general, set the flags on both the CDR record as well as the
3626  * Party A. Sometimes all we have is the Party A to look at.
3627  */
3628  ast_set_flag(&it_cdr->flags, option);
3629  ast_set_flag(&it_cdr->party_a, option);
3630  }
3631  ao2_unlock(cdr);
3632 
3633  ao2_cleanup(cdr);
3634  return 0;
3635 }
3636 
3637 int ast_cdr_clear_property(const char *channel_name, enum ast_cdr_options option)
3638 {
3639  struct cdr_object *cdr;
3640  struct cdr_object *it_cdr;
3641 
3642  cdr = cdr_object_get_by_name(channel_name);
3643  if (!cdr) {
3644  return -1;
3645  }
3646 
3647  ao2_lock(cdr);
3648  for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3649  if (it_cdr->fn_table == &finalized_state_fn_table) {
3650  continue;
3651  }
3652  ast_clear_flag(&it_cdr->flags, option);
3653  }
3654  ao2_unlock(cdr);
3655 
3656  ao2_cleanup(cdr);
3657  return 0;
3658 }
3659 
3660 int ast_cdr_reset(const char *channel_name, int keep_variables)
3661 {
3662  struct cdr_object *cdr;
3663  struct ast_var_t *vardata;
3664  struct cdr_object *it_cdr;
3665 
3666  cdr = cdr_object_get_by_name(channel_name);
3667  if (!cdr) {
3668  return -1;
3669  }
3670 
3671  ao2_lock(cdr);
3672  for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
3673  /* clear variables */
3674  if (!keep_variables) {
3675  while ((vardata = AST_LIST_REMOVE_HEAD(&it_cdr->party_a.variables, entries))) {
3676  ast_var_delete(vardata);
3677  }
3678  if (cdr->party_b.snapshot) {
3679  while ((vardata = AST_LIST_REMOVE_HEAD(&it_cdr->party_b.variables, entries))) {
3680  ast_var_delete(vardata);
3681  }
3682  }
3683  }
3684 
3685  /* Reset to initial state */
3686  memset(&it_cdr->start, 0, sizeof(it_cdr->start));
3687  memset(&it_cdr->end, 0, sizeof(it_cdr->end));
3688  memset(&it_cdr->answer, 0, sizeof(it_cdr->answer));
3689  it_cdr->start = ast_tvnow();
3690  it_cdr->lastevent = it_cdr->start;
3692  }
3693  ao2_unlock(cdr);
3694 
3695  ao2_cleanup(cdr);
3696  return 0;
3697 }
3698 
3699 int ast_cdr_fork(const char *channel_name, struct ast_flags *options)
3700 {
3701  RAII_VAR(struct cdr_object *, cdr, cdr_object_get_by_name(channel_name), ao2_cleanup);
3702  struct cdr_object *new_cdr;
3703  struct cdr_object *it_cdr;
3704  struct cdr_object *cdr_obj;
3705 
3706  if (!cdr) {
3707  return -1;
3708  }
3709 
3710  {
3711  SCOPED_AO2LOCK(lock, cdr);
3712  struct timeval now = ast_tvnow();
3713 
3714  cdr_obj = cdr->last;
3715  if (cdr_obj->fn_table == &finalized_state_fn_table) {
3716  /* If the last CDR in the chain is finalized, don't allow a fork -
3717  * things are already dying at this point
3718  */
3719  return -1;
3720  }
3721 
3722  /* Copy over the basic CDR information. The Party A information is
3723  * copied over automatically as part of the append
3724  */
3725  ast_debug(1, "Forking CDR for channel %s\n", cdr->party_a.snapshot->base->name);
3726  new_cdr = cdr_object_create_and_append(cdr, &now);
3727  if (!new_cdr) {
3728  return -1;
3729  }
3730  new_cdr->fn_table = cdr_obj->fn_table;
3731  ast_string_field_set(new_cdr, bridge, cdr->bridge);
3732  ast_string_field_set(new_cdr, appl, cdr->appl);
3733  ast_string_field_set(new_cdr, data, cdr->data);
3734  ast_string_field_set(new_cdr, context, cdr->context);
3735  ast_string_field_set(new_cdr, exten, cdr->exten);
3736  new_cdr->flags = cdr->flags;
3737  /* Explicitly clear the AST_CDR_LOCK_APP flag - we want
3738  * the application to be changed on the new CDR if the
3739  * dialplan demands it
3740  */
3741  ast_clear_flag(&new_cdr->flags, AST_CDR_LOCK_APP);
3742 
3743  /* If there's a Party B, copy it over as well */
3744  if (cdr_obj->party_b.snapshot) {
3745  new_cdr->party_b.snapshot = cdr_obj->party_b.snapshot;
3746  ao2_ref(new_cdr->party_b.snapshot, +1);
3747  cdr_all_relink(new_cdr);
3748  strcpy(new_cdr->party_b.userfield, cdr_obj->party_b.userfield);
3749  new_cdr->party_b.flags = cdr_obj->party_b.flags;
3750  if (ast_test_flag(options, AST_CDR_FLAG_KEEP_VARS)) {
3751  copy_variables(&new_cdr->party_b.variables, &cdr_obj->party_b.variables);
3752  }
3753  }
3754  new_cdr->start = cdr_obj->start;
3755  new_cdr->answer = cdr_obj->answer;
3756  new_cdr->lastevent = ast_tvnow();
3757 
3758  /* Modify the times based on the flags passed in */
3759  if (ast_test_flag(options, AST_CDR_FLAG_SET_ANSWER)
3760  && new_cdr->party_a.snapshot->state == AST_STATE_UP) {
3761  new_cdr->answer = ast_tvnow();
3762  }
3763  if (ast_test_flag(options, AST_CDR_FLAG_RESET)) {
3764  new_cdr->answer = ast_tvnow();
3765  new_cdr->start = ast_tvnow();
3766  }
3767 
3768  /* Create and append, by default, copies over the variables */
3769  if (!ast_test_flag(options, AST_CDR_FLAG_KEEP_VARS)) {
3770  free_variables(&new_cdr->party_a.variables);
3771  }
3772 
3773  /* Finalize any current CDRs */
3774  if (ast_test_flag(options, AST_CDR_FLAG_FINALIZE)) {
3775  for (it_cdr = cdr; it_cdr != new_cdr; it_cdr = it_cdr->next) {
3776  if (it_cdr->fn_table == &finalized_state_fn_table) {
3777  continue;
3778  }
3779  /* Force finalization on the CDR. This will bypass any checks for
3780  * end before 'h' extension.
3781  */
3782  cdr_object_finalize(it_cdr);
3783  cdr_object_transition_state(it_cdr, &finalized_state_fn_table);
3784  }
3785  }
3786  }
3787 
3788  return 0;
3789 }
3790 
3791 /*! \note Don't call without cdr_batch_lock */
3792 static void reset_batch(void)
3793 {
3794  batch->size = 0;
3795  batch->head = NULL;
3796  batch->tail = NULL;
3797 }
3798 
3799 /*! \note Don't call without cdr_batch_lock */
3800 static int init_batch(void)
3801 {
3802  /* This is the single meta-batch used to keep track of all CDRs during the entire life of the program */
3803  if (!(batch = ast_malloc(sizeof(*batch))))
3804  return -1;
3805 
3806  reset_batch();
3807 
3808  return 0;
3809 }
3810 
3811 static void *do_batch_backend_process(void *data)
3812 {
3813  struct cdr_batch_item *processeditem;
3814  struct cdr_batch_item *batchitem = data;
3815 
3816  /* Push each CDR into storage mechanism(s) and free all the memory */
3817  while (batchitem) {
3818  post_cdr(batchitem->cdr);
3819  ast_cdr_free(batchitem->cdr);
3820  processeditem = batchitem;
3821  batchitem = batchitem->next;
3822  ast_free(processeditem);
3823  }
3824 
3825  return NULL;
3826 }
3827 
3828 static void cdr_submit_batch(int do_shutdown)
3829 {
3830  struct module_config *mod_cfg;
3831  struct cdr_batch_item *oldbatchitems = NULL;
3832  pthread_t batch_post_thread = AST_PTHREADT_NULL;
3833 
3834  /* if there's no batch, or no CDRs in the batch, then there's nothing to do */
3835  if (!batch || !batch->head) {
3836  return;
3837  }
3838 
3839  /* move the old CDRs aside, and prepare a new CDR batch */
3840  ast_mutex_lock(&cdr_batch_lock);
3841  oldbatchitems = batch->head;
3842  reset_batch();
3843  ast_mutex_unlock(&cdr_batch_lock);
3844 
3845  mod_cfg = ao2_global_obj_ref(module_configs);
3846 
3847  /* if configured, spawn a new thread to post these CDRs,
3848  also try to save as much as possible if we are shutting down safely */
3849  if (!mod_cfg
3850  || ast_test_flag(&mod_cfg->general->batch_settings.settings, BATCH_MODE_SCHEDULER_ONLY)
3851  || do_shutdown) {
3852  ast_debug(1, "CDR single-threaded batch processing begins now\n");
3853  do_batch_backend_process(oldbatchitems);
3854  } else {
3855  if (ast_pthread_create_detached_background(&batch_post_thread, NULL, do_batch_backend_process, oldbatchitems)) {
3856  ast_log(LOG_WARNING, "CDR processing thread could not detach, now trying in this thread\n");
3857  do_batch_backend_process(oldbatchitems);
3858  } else {
3859  ast_debug(1, "CDR multi-threaded batch processing begins now\n");
3860  }
3861  }
3862 
3863  ao2_cleanup(mod_cfg);
3864 }
3865 
3866 static int submit_scheduled_batch(const void *data)
3867 {
3868  struct module_config *mod_cfg;
3869  int nextms;
3870 
3871  cdr_submit_batch(0);
3872 
3873  mod_cfg = ao2_global_obj_ref(module_configs);
3874  if (!mod_cfg) {
3875  return 0;
3876  }
3877 
3878  /* Calculate the next scheduled interval */
3879  nextms = mod_cfg->general->batch_settings.time * 1000;
3880 
3881  ao2_cleanup(mod_cfg);
3882 
3883  return nextms;
3884 }
3885 
3886 /*! Do not hold the batch lock while calling this function */
3887 static void start_batch_mode(void)
3888 {
3889  /* Prevent two deletes from happening at the same time */
3890  ast_mutex_lock(&cdr_sched_lock);
3891  /* this is okay since we are not being called from within the scheduler */
3892  AST_SCHED_DEL(sched, cdr_sched);
3893  /* schedule the submission to occur ASAP (1 ms) */
3894  cdr_sched = ast_sched_add_variable(sched, 1, submit_scheduled_batch, NULL, 1);
3895  ast_mutex_unlock(&cdr_sched_lock);
3896 
3897  /* signal the do_cdr thread to wakeup early and do some work (that lazy thread ;) */
3898  ast_mutex_lock(&cdr_pending_lock);
3899  ast_cond_signal(&cdr_pending_cond);
3900  ast_mutex_unlock(&cdr_pending_lock);
3901 }
3902 
3903 static void cdr_detach(struct ast_cdr *cdr)
3904 {
3905  struct cdr_batch_item *newtail;
3906  int curr;
3907  RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
3908  int submit_batch = 0;
3909 
3910  if (!cdr) {
3911  return;
3912  }
3913 
3914  /* maybe they disabled CDR stuff completely, so just drop it */
3915  if (!mod_cfg || !ast_test_flag(&mod_cfg->general->settings, CDR_ENABLED)) {
3916  ast_debug(1, "Dropping CDR !\n");
3917  ast_cdr_free(cdr);
3918  return;
3919  }
3920 
3921  /* post stuff immediately if we are not in batch mode, this is legacy behaviour */
3922  if (!ast_test_flag(&mod_cfg->general->settings, CDR_BATCHMODE)) {
3923  post_cdr(cdr);
3924  ast_cdr_free(cdr);
3925  return;
3926  }
3927 
3928  /* otherwise, each CDR gets put into a batch list (at the end) */
3929  ast_debug(1, "CDR detaching from this thread\n");
3930 
3931  /* we'll need a new tail for every CDR */
3932  if (!(newtail = ast_calloc(1, sizeof(*newtail)))) {
3933  post_cdr(cdr);
3934  ast_cdr_free(cdr);
3935  return;
3936  }
3937 
3938  /* don't traverse a whole list (just keep track of the tail) */
3939  ast_mutex_lock(&cdr_batch_lock);
3940  if (!batch)
3941  init_batch();
3942  if (!batch->head) {
3943  /* new batch is empty, so point the head at the new tail */
3944  batch->head = newtail;
3945  } else {
3946  /* already got a batch with something in it, so just append a new tail */
3947  batch->tail->next = newtail;
3948  }
3949  newtail->cdr = cdr;
3950  batch->tail = newtail;
3951  curr = batch->size++;
3952 
3953  /* if we have enough stuff to post, then do it */
3954  if (curr >= (mod_cfg->general->batch_settings.size - 1)) {
3955  submit_batch = 1;
3956  }
3957  ast_mutex_unlock(&cdr_batch_lock);
3958 
3959  /* Don't submit a batch with cdr_batch_lock held */
3960  if (submit_batch) {
3961  start_batch_mode();
3962  }
3963 }
3964 
3965 static void *do_cdr(void *data)
3966 {
3967  struct timespec timeout;
3968  int schedms;
3969  int numevents = 0;
3970 
3971  for (;;) {
3972  struct timeval now;
3973  schedms = ast_sched_wait(sched);
3974  /* this shouldn't happen, but provide a 1 second default just in case */
3975  if (schedms < 0)
3976  schedms = 1000;
3977  now = ast_tvadd(ast_tvnow(), ast_samp2tv(schedms, 1000));
3978  timeout.tv_sec = now.tv_sec;
3979  timeout.tv_nsec = now.tv_usec * 1000;
3980  /* prevent stuff from clobbering cdr_pending_cond, then wait on signals sent to it until the timeout expires */
3981  ast_mutex_lock(&cdr_pending_lock);
3982  ast_cond_timedwait(&cdr_pending_cond, &cdr_pending_lock, &timeout);
3983  numevents = ast_sched_runq(sched);
3984  ast_mutex_unlock(&cdr_pending_lock);
3985  ast_debug(2, "Processed %d CDR batches from the run queue\n", numevents);
3986  }
3987 
3988  return NULL;
3989 }
3990 
3991 static char *handle_cli_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
3992 {
3993  struct module_config *mod_cfg;
3994 
3995  switch (cmd) {
3996  case CLI_INIT:
3997  e->command = "cdr set debug [on|off]";
3998  e->usage = "Enable or disable extra debugging in the CDR Engine. Note\n"
3999  "that this will dump debug information to the VERBOSE setting\n"
4000  "and should only be used when debugging information from the\n"
4001  "CDR engine is needed.\n";
4002  return NULL;
4003  case CLI_GENERATE:
4004  return NULL;
4005  }
4006 
4007  if (a->argc != 4) {
4008  return CLI_SHOWUSAGE;
4009  }
4010 
4011  mod_cfg = ao2_global_obj_ref(module_configs);
4012  if (!mod_cfg) {
4013  ast_cli(a->fd, "Could not set CDR debugging mode\n");
4014  return CLI_SUCCESS;
4015  }
4016  if (!strcasecmp(a->argv[3], "on")
4017  && !ast_test_flag(&mod_cfg->general->settings, CDR_DEBUG)) {
4018  ast_set_flag(&mod_cfg->general->settings, CDR_DEBUG);
4019  ast_cli(a->fd, "CDR debugging enabled\n");
4020  } else if (!strcasecmp(a->argv[3], "off")
4021  && ast_test_flag(&mod_cfg->general->settings, CDR_DEBUG)) {
4022  ast_clear_flag(&mod_cfg->general->settings, CDR_DEBUG);
4023  ast_cli(a->fd, "CDR debugging disabled\n");
4024  }
4025  cdr_set_debug_mode(mod_cfg);
4026  ao2_cleanup(mod_cfg);
4027 
4028  return CLI_SUCCESS;
4029 }
4030 
4031 /*! \brief Complete user input for 'cdr show' */
4032 static char *cli_complete_show(struct ast_cli_args *a)
4033 {
4034  int wordlen = strlen(a->word);
4035  struct ao2_iterator it_cdrs;
4036  struct cdr_object *cdr;
4037 
4038  it_cdrs = ao2_iterator_init(active_cdrs_master, 0);
4039  while ((cdr = ao2_iterator_next(&it_cdrs))) {
4040  if (!strncasecmp(a->word, cdr->party_a.snapshot->base->name, wordlen)) {
4042  ao2_ref(cdr, -1);
4043  break;
4044  }
4045  }
4046  ao2_ref(cdr, -1);
4047  }
4048  ao2_iterator_destroy(&it_cdrs);
4049 
4050  return NULL;
4051 }
4052 
4053 static void cli_show_channels(struct ast_cli_args *a)
4054 {
4055  struct ao2_iterator it_cdrs;
4056  struct cdr_object *cdr;
4057  char start_time_buffer[64];
4058  char answer_time_buffer[64];
4059  char end_time_buffer[64];
4060 
4061 #define TITLE_STRING "%-25.25s %-25.25s %-15.15s %-8.8s %-8.8s %-8.8s %-8.8s %-8.8s\n"
4062 #define FORMAT_STRING "%-25.25s %-25.25s %-15.15s %-8.8s %-8.8s %-8.8s %-8.8ld %-8.8ld\n"
4063 
4064  ast_cli(a->fd, "\n");
4065  ast_cli(a->fd, "Channels with Call Detail Record (CDR) Information\n");
4066  ast_cli(a->fd, "--------------------------------------------------\n");
4067  ast_cli(a->fd, TITLE_STRING, "Channel", "Dst. Channel", "LastApp", "Start", "Answer", "End", "Billsec", "Duration");
4068 
4069  it_cdrs = ao2_iterator_init(active_cdrs_master, 0);
4070  for (; (cdr = ao2_iterator_next(&it_cdrs)); ao2_cleanup(cdr)) {
4071  struct cdr_object *it_cdr;
4072  struct timeval start_time = { 0, };
4073  struct timeval answer_time = { 0, };
4074  struct timeval end_time = { 0, };
4075 
4076  SCOPED_AO2LOCK(lock, cdr);
4077 
4078  /* Calculate the start, end, answer, billsec, and duration over the
4079  * life of all of the CDR entries
4080  */
4081  for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
4082  if (snapshot_is_dialed(it_cdr->party_a.snapshot)) {
4083  continue;
4084  }
4085  if (ast_tvzero(start_time)) {
4086  start_time = it_cdr->start;
4087  }
4088  if (!ast_tvzero(it_cdr->answer) && ast_tvzero(answer_time)) {
4089  answer_time = it_cdr->answer;
4090  }
4091  }
4092 
4093  /* If there was no start time, then all CDRs were for a dialed channel; skip */
4094  if (ast_tvzero(start_time)) {
4095  continue;
4096  }
4097  it_cdr = cdr->last;
4098 
4099  end_time = ast_tvzero(it_cdr->end) ? ast_tvnow() : it_cdr->end;
4100  cdr_get_tv(start_time, "%T", start_time_buffer, sizeof(start_time_buffer));
4101  cdr_get_tv(answer_time, "%T", answer_time_buffer, sizeof(answer_time_buffer));
4102  cdr_get_tv(end_time, "%T", end_time_buffer, sizeof(end_time_buffer));
4103  ast_cli(a->fd, FORMAT_STRING, it_cdr->party_a.snapshot->base->name,
4104  it_cdr->party_b.snapshot ? it_cdr->party_b.snapshot->base->name : "<none>",
4105  it_cdr->appl,
4106  start_time_buffer,
4107  answer_time_buffer,
4108  end_time_buffer,
4109  ast_tvzero(answer_time) ? 0 : (long)ast_tvdiff_ms(end_time, answer_time) / 1000,
4110  (long)ast_tvdiff_ms(end_time, start_time) / 1000);
4111  }
4112  ao2_iterator_destroy(&it_cdrs);
4113 #undef FORMAT_STRING
4114 #undef TITLE_STRING
4115 }
4116 
4117 static void cli_show_channel(struct ast_cli_args *a)
4118 {
4119  struct cdr_object *it_cdr;
4120  char clid[64];
4121  char start_time_buffer[64];
4122  char answer_time_buffer[64];
4123  char end_time_buffer[64];
4124  const char *channel_name = a->argv[3];
4125  struct cdr_object *cdr;
4126 
4127 #define TITLE_STRING "%-10.10s %-20.20s %-25.25s %-15.15s %-15.15s %-8.8s %-8.8s %-8.8s %-8.8s %-8.8s\n"
4128 #define FORMAT_STRING "%-10.10s %-20.20s %-25.25s %-15.15s %-15.15s %-8.8s %-8.8s %-8.8s %-8.8ld %-8.8ld\n"
4129 
4130  cdr = cdr_object_get_by_name(channel_name);
4131  if (!cdr) {
4132  ast_cli(a->fd, "Unknown channel: %s\n", channel_name);
4133  return;
4134  }
4135 
4136  ast_cli(a->fd, "\n");
4137  ast_cli(a->fd, "Call Detail Record (CDR) Information for %s\n", channel_name);
4138  ast_cli(a->fd, "--------------------------------------------------\n");
4139  ast_cli(a->fd, TITLE_STRING, "AccountCode", "CallerID", "Dst. Channel", "LastApp", "Data", "Start", "Answer", "End", "Billsec", "Duration");
4140 
4141  ao2_lock(cdr);
4142  for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
4143  struct timeval end;
4144 
4145  if (snapshot_is_dialed(it_cdr->party_a.snapshot)) {
4146  continue;
4147  }
4148  ast_callerid_merge(clid, sizeof(clid), it_cdr->party_a.snapshot->caller->name, it_cdr->party_a.snapshot->caller->number, "");
4149  if (ast_tvzero(it_cdr->end)) {
4150  end = ast_tvnow();
4151  } else {
4152  end = it_cdr->end;
4153  }
4154  cdr_get_tv(it_cdr->start, "%T", start_time_buffer, sizeof(start_time_buffer));
4155  cdr_get_tv(it_cdr->answer, "%T", answer_time_buffer, sizeof(answer_time_buffer));
4156  cdr_get_tv(end, "%T", end_time_buffer, sizeof(end_time_buffer));
4157  ast_cli(a->fd, FORMAT_STRING,
4158  it_cdr->party_a.snapshot->base->accountcode,
4159  clid,
4160  it_cdr->party_b.snapshot ? it_cdr->party_b.snapshot->base->name : "<none>",
4161  it_cdr->appl,
4162  it_cdr->data,
4163  start_time_buffer,
4164  answer_time_buffer,
4165  end_time_buffer,
4166  (long)ast_tvdiff_ms(end, it_cdr->answer) / 1000,
4167  (long)ast_tvdiff_ms(end, it_cdr->start) / 1000);
4168  }
4169  ao2_unlock(cdr);
4170 
4171  ao2_cleanup(cdr);
4172 
4173 #undef FORMAT_STRING
4174 #undef TITLE_STRING
4175 }
4176 
4177 static char *handle_cli_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
4178 {
4179  switch (cmd) {
4180  case CLI_INIT:
4181  e->command = "cdr show active";
4182  e->usage =
4183  "Usage: cdr show active [channel]\n"
4184  " Displays a summary of all Call Detail Records when [channel]\n"
4185  " is omitted; displays all of the Call Detail Records\n"
4186  " currently in flight for a given [channel] when [channel] is\n"
4187  " specified.\n\n"
4188  " Note that this will not display Call Detail Records that\n"
4189  " have already been dispatched to a backend storage, nor for\n"
4190  " channels that are no longer active.\n";
4191  return NULL;
4192  case CLI_GENERATE:
4193  return cli_complete_show(a);
4194  }
4195 
4196  if (a->argc > 4) {
4197  return CLI_SHOWUSAGE;
4198  } else if (a->argc < 4) {
4199  cli_show_channels(a);
4200  } else {
4201  cli_show_channel(a);
4202  }
4203 
4204  return CLI_SUCCESS;
4205 }
4206 
4207 static char *handle_cli_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
4208 {
4209  struct cdr_beitem *beitem = NULL;
4210  struct module_config *mod_cfg;
4211  int cnt = 0;
4212  long nextbatchtime = 0;
4213 
4214  switch (cmd) {
4215  case CLI_INIT:
4216  e->command = "cdr show status";
4217  e->usage =
4218  "Usage: cdr show status\n"
4219  " Displays the Call Detail Record engine system status.\n";
4220  return NULL;
4221  case CLI_GENERATE:
4222  return NULL;
4223  }
4224 
4225  if (a->argc > 3) {
4226  return CLI_SHOWUSAGE;
4227  }
4228 
4229  mod_cfg = ao2_global_obj_ref(module_configs);
4230  if (!mod_cfg) {
4231  return CLI_FAILURE;
4232  }
4233 
4234  ast_cli(a->fd, "\n");
4235  ast_cli(a->fd, "Call Detail Record (CDR) settings\n");
4236  ast_cli(a->fd, "----------------------------------\n");
4237  ast_cli(a->fd, " Logging: %s\n", ast_test_flag(&mod_cfg->general->settings, CDR_ENABLED) ? "Enabled" : "Disabled");
4238  ast_cli(a->fd, " Mode: %s\n", ast_test_flag(&mod_cfg->general->settings, CDR_BATCHMODE) ? "Batch" : "Simple");
4239  if (ast_test_flag(&mod_cfg->general->settings, CDR_ENABLED)) {
4240  ast_cli(a->fd, " Log calls by default: %s\n", ast_test_flag(&mod_cfg->general->settings, CDR_CHANNEL_DEFAULT_ENABLED) ? "Yes" : "No");
4241  ast_cli(a->fd, " Log unanswered calls: %s\n", ast_test_flag(&mod_cfg->general->settings, CDR_UNANSWERED) ? "Yes" : "No");
4242  ast_cli(a->fd, " Log congestion: %s\n\n", ast_test_flag(&mod_cfg->general->settings, CDR_CONGESTION) ? "Yes" : "No");
4243  ast_cli(a->fd, " Ignore bridging changes: %s\n\n", ast_test_flag(&mod_cfg->general->settings, CDR_IGNORE_STATE_CHANGES) ? "Yes" : "No");
4244  ast_cli(a->fd, " Ignore dial state changes: %s\n\n", ast_test_flag(&mod_cfg->general->settings, CDR_IGNORE_DIAL_CHANGES) ? "Yes" : "No");
4245  if (ast_test_flag(&mod_cfg->general->settings, CDR_BATCHMODE)) {
4246  ast_cli(a->fd, "* Batch Mode Settings\n");
4247  ast_cli(a->fd, " -------------------\n");
4248  if (batch)
4249  cnt = batch->size;
4250  if (cdr_sched > -1)
4251  nextbatchtime = ast_sched_when(sched, cdr_sched);
4252  ast_cli(a->fd, " Safe shutdown: %s\n", ast_test_flag(&mod_cfg->general->batch_settings.settings, BATCH_MODE_SAFE_SHUTDOWN) ? "Enabled" : "Disabled");
4253  ast_cli(a->fd, " Threading model: %s\n", ast_test_flag(&mod_cfg->general->batch_settings.settings, BATCH_MODE_SCHEDULER_ONLY) ? "Scheduler only" : "Scheduler plus separate threads");
4254  ast_cli(a->fd, " Current batch size: %d record%s\n", cnt, ESS(cnt));
4255  ast_cli(a->fd, " Maximum batch size: %u record%s\n", mod_cfg->general->batch_settings.size, ESS(mod_cfg->general->batch_settings.size));
4256  ast_cli(a->fd, " Maximum batch time: %u second%s\n", mod_cfg->general->batch_settings.time, ESS(mod_cfg->general->batch_settings.time));
4257  ast_cli(a->fd, " Next batch processing time: %ld second%s\n\n", nextbatchtime, ESS(nextbatchtime));
4258  }
4259  ast_cli(a->fd, "* Registered Backends\n");
4260  ast_cli(a->fd, " -------------------\n");
4262  if (AST_RWLIST_EMPTY(&be_list)) {
4263  ast_cli(a->fd, " (none)\n");
4264  } else {
4265  AST_RWLIST_TRAVERSE(&be_list, beitem, list) {
4266  ast_cli(a->fd, " %s%s\n", beitem->name, beitem->suspended ? " (suspended) " : "");
4267  }
4268  }
4270  ast_cli(a->fd, "\n");
4271  }
4272 
4273  ao2_cleanup(mod_cfg);
4274  return CLI_SUCCESS;
4275 }
4276 
4277 static char *handle_cli_submit(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
4278 {
4279  struct module_config *mod_cfg;
4280 
4281  switch (cmd) {
4282  case CLI_INIT:
4283  e->command = "cdr submit";
4284  e->usage =
4285  "Usage: cdr submit\n"
4286  "Posts all pending batched CDR data to the configured CDR\n"
4287  "backend engine modules.\n";
4288  return NULL;
4289  case CLI_GENERATE:
4290  return NULL;
4291  }
4292  if (a->argc > 2) {
4293  return CLI_SHOWUSAGE;
4294  }
4295 
4296  mod_cfg = ao2_global_obj_ref(module_configs);
4297  if (!mod_cfg) {
4298  return CLI_FAILURE;
4299  }
4300 
4301  if (!ast_test_flag(&mod_cfg->general->settings, CDR_ENABLED)) {
4302  ast_cli(a->fd, "Cannot submit CDR batch: CDR engine disabled.\n");
4303  } else if (!ast_test_flag(&mod_cfg->general->settings, CDR_BATCHMODE)) {
4304  ast_cli(a->fd, "Cannot submit CDR batch: batch mode not enabled.\n");
4305  } else {
4306  start_batch_mode();
4307  ast_cli(a->fd, "Submitted CDRs to backend engines for processing. This may take a while.\n");
4308  }
4309  ao2_cleanup(mod_cfg);
4310 
4311  return CLI_SUCCESS;
4312 }
4313 
4314 static struct ast_cli_entry cli_commands[] = {
4315  AST_CLI_DEFINE(handle_cli_submit, "Posts all pending batched CDR data"),
4316  AST_CLI_DEFINE(handle_cli_status, "Display the CDR status"),
4317  AST_CLI_DEFINE(handle_cli_show, "Display active CDRs for channels"),
4318  AST_CLI_DEFINE(handle_cli_debug, "Enable debugging in the CDR engine"),
4319 };
4320 
4321 /*!
4322  * \brief This dispatches *all* \ref cdr_object. It should only be used during
4323  * shutdown, so that we get billing records for everything that we can.
4324  */
4325 static int cdr_object_dispatch_all_cb(void *obj, void *arg, int flags)
4326 {
4327  struct cdr_object *cdr = obj;
4328  struct cdr_object *it_cdr;
4329 
4330  ao2_lock(cdr);
4331  for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
4332  cdr_object_transition_state(it_cdr, &finalized_state_fn_table);
4333  }
4334  cdr_object_dispatch(cdr);
4335  ao2_unlock(cdr);
4336 
4337  cdr_all_unlink(cdr);
4338 
4339  return CMP_MATCH;
4340 }
4341 
4342 static void finalize_batch_mode(void)
4343 {
4344  if (cdr_thread == AST_PTHREADT_NULL) {
4345  return;
4346  }
4347  /* wake up the thread so it will exit */
4348  pthread_cancel(cdr_thread);
4349  pthread_kill(cdr_thread, SIGURG);
4350  pthread_join(cdr_thread, NULL);
4351  cdr_thread = AST_PTHREADT_NULL;
4352  ast_cond_destroy(&cdr_pending_cond);
4354 }
4355 
4357 {
4358  if (!stasis_router) {
4359  return NULL;
4360  }
4361 
4362  ao2_bump(stasis_router);
4363  return stasis_router;
4364 }
4365 
4366 /*!
4367  * \brief Destroy the active Stasis subscriptions
4368  */
4369 static void destroy_subscriptions(void)
4370 {
4371  channel_subscription = stasis_forward_cancel(channel_subscription);
4372  bridge_subscription = stasis_forward_cancel(bridge_subscription);
4373  parking_subscription = stasis_forward_cancel(parking_subscription);
4374 }
4375 
4376 /*!
4377  * \brief Create the Stasis subcriptions for CDRs
4378  */
4379 static int create_subscriptions(void)
4380 {
4381  if (!cdr_topic) {
4382  return -1;
4383  }
4384 
4385  if (channel_subscription || bridge_subscription || parking_subscription) {
4386  return 0;
4387  }
4388 
4389  channel_subscription = stasis_forward_all(ast_channel_topic_all(), cdr_topic);
4390  if (!channel_subscription) {
4391  return -1;
4392  }
4393  bridge_subscription = stasis_forward_all(ast_bridge_topic_all(), cdr_topic);
4394  if (!bridge_subscription) {
4395  return -1;
4396  }
4397  parking_subscription = stasis_forward_all(ast_parking_topic(), cdr_topic);
4398  if (!parking_subscription) {
4399  return -1;
4400  }
4401 
4402  return 0;
4403 }
4404 
4405 static int process_config(int reload)
4406 {
4407  if (!reload) {
4408  if (aco_info_init(&cfg_info)) {
4409  return 1;
4410  }
4411 
4412  aco_option_register(&cfg_info, "enable", ACO_EXACT, general_options, DEFAULT_ENABLED, OPT_BOOLFLAG_T, 1, FLDSET(struct ast_cdr_config, settings), CDR_ENABLED);
4413  aco_option_register(&cfg_info, "debug", ACO_EXACT, general_options, 0, OPT_BOOLFLAG_T, 1, FLDSET(struct ast_cdr_config, settings), CDR_DEBUG);
4414  aco_option_register(&cfg_info, "unanswered", ACO_EXACT, general_options, DEFAULT_UNANSWERED, OPT_BOOLFLAG_T, 1, FLDSET(struct ast_cdr_config, settings), CDR_UNANSWERED);
4415  aco_option_register(&cfg_info, "congestion", ACO_EXACT, general_options, 0, OPT_BOOLFLAG_T, 1, FLDSET(struct ast_cdr_config, settings), CDR_CONGESTION);
4416  aco_option_register(&cfg_info, "batch", ACO_EXACT, general_options, DEFAULT_BATCHMODE, OPT_BOOLFLAG_T, 1, FLDSET(struct ast_cdr_config, settings), CDR_BATCHMODE);
4417  aco_option_register(&cfg_info, "endbeforehexten", ACO_EXACT, general_options, DEFAULT_END_BEFORE_H_EXTEN, OPT_BOOLFLAG_T, 1, FLDSET(struct ast_cdr_config, settings), CDR_END_BEFORE_H_EXTEN);
4418  aco_option_register(&cfg_info, "initiatedseconds", ACO_EXACT, general_options, DEFAULT_INITIATED_SECONDS, OPT_BOOLFLAG_T, 1, FLDSET(struct ast_cdr_config, settings), CDR_INITIATED_SECONDS);
4419  aco_option_register(&cfg_info, "scheduleronly", ACO_EXACT, general_options, DEFAULT_BATCH_SCHEDULER_ONLY, OPT_BOOLFLAG_T, 1, FLDSET(struct ast_cdr_config, batch_settings.settings), BATCH_MODE_SCHEDULER_ONLY);
4420  aco_option_register(&cfg_info, "safeshutdown", ACO_EXACT, general_options, DEFAULT_BATCH_SAFE_SHUTDOWN, OPT_BOOLFLAG_T, 1, FLDSET(struct ast_cdr_config, batch_settings.settings), BATCH_MODE_SAFE_SHUTDOWN);
4421  aco_option_register(&cfg_info, "size", ACO_EXACT, general_options, DEFAULT_BATCH_SIZE, OPT_UINT_T, PARSE_IN_RANGE, FLDSET(struct ast_cdr_config, batch_settings.size), 0, MAX_BATCH_SIZE);
4422  aco_option_register(&cfg_info, "time", ACO_EXACT, general_options, DEFAULT_BATCH_TIME, OPT_UINT_T, PARSE_IN_RANGE, FLDSET(struct ast_cdr_config, batch_settings.time), 1, MAX_BATCH_TIME);
4423  aco_option_register(&cfg_info, "channeldefaultenabled", ACO_EXACT, general_options, DEFAULT_CHANNEL_ENABLED, OPT_BOOLFLAG_T, 1, FLDSET(struct ast_cdr_config, settings), CDR_CHANNEL_DEFAULT_ENABLED);
4424  aco_option_register(&cfg_info, "ignorestatechanges", ACO_EXACT, general_options, DEFAULT_IGNORE_STATE_CHANGES, OPT_BOOLFLAG_T, 1, FLDSET(struct ast_cdr_config, settings), CDR_IGNORE_STATE_CHANGES);
4425  aco_option_register(&cfg_info, "ignoredialchanges", ACO_EXACT, general_options, DEFAULT_IGNORE_DIAL_CHANGES, OPT_BOOLFLAG_T, 1, FLDSET(struct ast_cdr_config, settings), CDR_IGNORE_DIAL_CHANGES);
4426  }
4427 
4428  if (aco_process_config(&cfg_info, reload) == ACO_PROCESS_ERROR) {
4429  struct module_config *mod_cfg;
4430 
4431  if (reload) {
4432  return 1;
4433  }
4434 
4435  /* If we couldn't process the configuration and this wasn't a reload,
4436  * create a default config
4437  */
4438  mod_cfg = module_config_alloc();
4439  if (!mod_cfg
4440  || aco_set_defaults(&general_option, "general", mod_cfg->general)) {
4441  ao2_cleanup(mod_cfg);
4442  return 1;
4443  }
4444  ast_log(LOG_NOTICE, "Failed to process CDR configuration; using defaults\n");
4445  ao2_global_obj_replace_unref(module_configs, mod_cfg);
4446  cdr_set_debug_mode(mod_cfg);
4447  ao2_cleanup(mod_cfg);
4448  }
4449 
4450  return 0;
4451 }
4452 
4453 static void cdr_engine_shutdown(void)
4454 {
4456  stasis_router = NULL;
4457 
4458  ao2_cleanup(cdr_topic);
4459  cdr_topic = NULL;
4460 
4461  STASIS_MESSAGE_TYPE_CLEANUP(cdr_sync_message_type);
4462 
4463  ao2_callback(active_cdrs_master, OBJ_NODATA | OBJ_MULTIPLE | OBJ_UNLINK,
4465  finalize_batch_mode();
4466  ast_cli_unregister_multiple(cli_commands, ARRAY_LEN(cli_commands));
4468  sched = NULL;
4469  ast_free(batch);
4470  batch = NULL;
4471 
4472  aco_info_destroy(&cfg_info);
4473  ao2_global_obj_release(module_configs);
4474 
4475  ao2_container_unregister("cdrs_master");
4476  ao2_cleanup(active_cdrs_master);
4477  active_cdrs_master = NULL;
4478 
4479  ao2_container_unregister("cdrs_all");
4480  ao2_cleanup(active_cdrs_all);
4481  active_cdrs_all = NULL;
4482 }
4483 
4484 static void cdr_enable_batch_mode(struct ast_cdr_config *config)
4485 {
4486  /* Only create the thread level portions once */
4487  if (cdr_thread == AST_PTHREADT_NULL) {
4488  ast_cond_init(&cdr_pending_cond, NULL);
4489  if (ast_pthread_create_background(&cdr_thread, NULL, do_cdr, NULL) < 0) {
4490  ast_log(LOG_ERROR, "Unable to start CDR thread.\n");
4491  return;
4492  }
4493  }
4494 
4495  /* Start the batching process */
4496  start_batch_mode();
4497 
4498  ast_log(LOG_NOTICE, "CDR batch mode logging enabled, first of either size %u or time %u seconds.\n",
4499  config->batch_settings.size, config->batch_settings.time);
4500 }
4501 
4502 /*!
4503  * \internal
4504  * \brief Print master CDR container object.
4505  * \since 12.0.0
4506  *
4507  * \param v_obj A pointer to the object we want printed.
4508  * \param where User data needed by prnt to determine where to put output.
4509  * \param prnt Print output callback function to use.
4510  */
4511 static void cdr_master_print_fn(void *v_obj, void *where, ao2_prnt_fn *prnt)
4512 {
4513  struct cdr_object *cdr = v_obj;
4514  struct cdr_object *it_cdr;
4515 
4516  if (!cdr) {
4517  return;
4518  }
4519  for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
4520  prnt(where, "Party A: %s; Party B: %s; Bridge %s\n",
4521  it_cdr->party_a.snapshot->base->name,
4522  it_cdr->party_b.snapshot ? it_cdr->party_b.snapshot->base->name : "<unknown>",
4523  it_cdr->bridge);
4524  }
4525 }
4526 
4527 /*!
4528  * \internal
4529  * \brief Print all CDR container object.
4530  * \since 13.19.0
4531  *
4532  * \param v_obj A pointer to the object we want printed.
4533  * \param where User data needed by prnt to determine where to put output.
4534  * \param prnt Print output callback function to use.
4535  */
4536 static void cdr_all_print_fn(void *v_obj, void *where, ao2_prnt_fn *prnt)
4537 {
4538  struct cdr_object *cdr = v_obj;
4539 
4540  if (!cdr) {
4541  return;
4542  }
4543  prnt(where, "Party A: %s; Party B: %s; Bridge %s",
4544  cdr->party_a.snapshot->base->name,
4545  cdr->party_b.snapshot ? cdr->party_b.snapshot->base->name : "<unknown>",
4546  cdr->bridge);
4547 }
4548 
4549 /*!
4550  * \brief Checks if CDRs are enabled and enables/disables the necessary options
4551  */
4553 {
4554  struct module_config *mod_cfg;
4555 
4556  mod_cfg = ao2_global_obj_ref(module_configs);
4557  if (mod_cfg
4558  && ast_test_flag(&mod_cfg->general->settings, CDR_ENABLED)) {
4559  if (create_subscriptions()) {
4561  ast_log(AST_LOG_ERROR, "Failed to create Stasis subscriptions\n");
4562  ao2_cleanup(mod_cfg);
4563  return -1;
4564  }
4565  if (ast_test_flag(&mod_cfg->general->settings, CDR_BATCHMODE)) {
4566  cdr_enable_batch_mode(mod_cfg->general);
4567  } else {
4568  ast_log(LOG_NOTICE, "CDR simple logging enabled.\n");
4569  }
4570  } else {
4572  ast_log(LOG_NOTICE, "CDR logging disabled.\n");
4573  }
4574  ao2_cleanup(mod_cfg);
4575 
4576  return mod_cfg ? 0 : -1;
4577 }
4578 
4579 static int unload_module(void)
4580 {
4582 
4583  return 0;
4584 }
4585 
4586 static int load_module(void)
4587 {
4588  struct module_config *mod_cfg = NULL;
4589  if (process_config(0)) {
4590  return AST_MODULE_LOAD_FAILURE;
4591  }
4592 
4593  cdr_topic = stasis_topic_create("cdr:aggregator");
4594  if (!cdr_topic) {
4595  return AST_MODULE_LOAD_FAILURE;
4596  }
4597 
4598  stasis_router = stasis_message_router_create(cdr_topic);
4599  if (!stasis_router) {
4600  return AST_MODULE_LOAD_FAILURE;
4601  }
4604 
4605  if (STASIS_MESSAGE_TYPE_INIT(cdr_sync_message_type)) {
4606  return AST_MODULE_LOAD_FAILURE;
4607  }
4608 
4609  mod_cfg = ao2_global_obj_ref(module_configs);
4610 
4612 
4613  /* Always process dial messages, because even if we ignore most of it, we do want the dial status for the disposition. */
4615  if (!mod_cfg || !ast_test_flag(&mod_cfg->general->settings, CDR_IGNORE_DIAL_CHANGES)) {
4616  dial_changes_ignored = 0;
4617  } else {
4618  dial_changes_ignored = 1;
4619  CDR_DEBUG("Dial messages will be mostly ignored\n");
4620  }
4621 
4622  /* If explicitly instructed to ignore call state changes, then ignore bridging events, parking, etc. */
4623  if (!mod_cfg || !ast_test_flag(&mod_cfg->general->settings, CDR_IGNORE_STATE_CHANGES)) {
4624  stasis_message_router_add(stasis_router, ast_channel_entered_bridge_type(), handle_bridge_enter_message, NULL);
4625  stasis_message_router_add(stasis_router, ast_channel_left_bridge_type(), handle_bridge_leave_message, NULL);
4627  } else {
4628  CDR_DEBUG("All bridge and parking messages will be ignored\n");
4629  }
4630 
4631  stasis_message_router_add(stasis_router, cdr_sync_message_type(), handle_cdr_sync_message, NULL);
4632 
4633  if (mod_cfg) {
4634  ao2_cleanup(mod_cfg);
4635  } else {
4636  ast_log(LOG_WARNING, "Unable to obtain CDR configuration during module load?\n");
4637  }
4638 
4639  active_cdrs_master = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_MUTEX, 0,
4640  AST_NUM_CHANNEL_BUCKETS, cdr_master_hash_fn, NULL, cdr_master_cmp_fn);
4641  if (!active_cdrs_master) {
4642  return AST_MODULE_LOAD_FAILURE;
4643  }
4644  ao2_container_register("cdrs_master", active_cdrs_master, cdr_master_print_fn);
4645 
4647  AST_NUM_CHANNEL_BUCKETS, cdr_all_hash_fn, NULL, cdr_all_cmp_fn);
4648  if (!active_cdrs_all) {
4649  return AST_MODULE_LOAD_FAILURE;
4650  }
4651  ao2_container_register("cdrs_all", active_cdrs_all, cdr_all_print_fn);
4652 
4653  sched = ast_sched_context_create();
4654  if (!sched) {
4655  ast_log(LOG_ERROR, "Unable to create schedule context.\n");
4656  return AST_MODULE_LOAD_FAILURE;
4657  }
4658 
4659  ast_cli_register_multiple(cli_commands, ARRAY_LEN(cli_commands));
4660  ast_register_atexit(cdr_engine_shutdown);
4661 
4663 }
4664 
4666 {
4667  RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
4668 
4669  /* Since this is called explicitly during process shutdown, we might not have ever
4670  * been initialized. If so, the config object will be NULL.
4671  */
4672  if (!mod_cfg) {
4673  return;
4674  }
4675 
4676  if (cdr_sync_message_type()) {
4677  void *payload;
4678  struct stasis_message *message;
4679 
4680  if (!stasis_router) {
4681  return;
4682  }
4683 
4684  /* Make sure we have the needed items */
4685  payload = ao2_alloc(sizeof(*payload), NULL);
4686  if (!payload) {
4687  return;
4688  }
4689 
4690  ast_debug(1, "CDR Engine termination request received; waiting on messages...\n");
4691 
4692  message = stasis_message_create(cdr_sync_message_type(), payload);
4693  if (message) {
4694  stasis_message_router_publish_sync(stasis_router, message);
4695  }
4696  ao2_cleanup(message);
4697  ao2_cleanup(payload);
4698  }
4699 
4700  if (ast_test_flag(&mod_cfg->general->settings, CDR_BATCHMODE)) {
4701  cdr_submit_batch(ast_test_flag(&mod_cfg->general->batch_settings.settings, BATCH_MODE_SAFE_SHUTDOWN));
4702  }
4703 }
4704 
4705 static int reload_module(void)
4706 {
4707  struct module_config *old_mod_cfg;
4708  struct module_config *mod_cfg;
4709 
4710  old_mod_cfg = ao2_global_obj_ref(module_configs);
4711 
4712  if (!old_mod_cfg || process_config(1)) {
4713  ao2_cleanup(old_mod_cfg);
4714  return -1;
4715  }
4716 
4717  mod_cfg = ao2_global_obj_ref(module_configs);
4718  if (!mod_cfg
4719  || !ast_test_flag(&mod_cfg->general->settings, CDR_ENABLED)
4720  || !ast_test_flag(&mod_cfg->general->settings, CDR_BATCHMODE)) {
4721  /* If batch mode used to be enabled, finalize the batch */
4722  if (ast_test_flag(&old_mod_cfg->general->settings, CDR_BATCHMODE)) {
4723  finalize_batch_mode();
4724  }
4725  }
4726  ao2_cleanup(mod_cfg);
4727 
4728  ao2_cleanup(old_mod_cfg);
4729  return cdr_toggle_runtime_options();
4730 }
4731 
4732 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER, "CDR Engine",
4733  .support_level = AST_MODULE_SUPPORT_CORE,
4734  .load = load_module,
4735  .unload = unload_module,
4736  .reload = reload_module,
4737  .load_pri = AST_MODPRI_CORE,
4738  .requires = "extconfig",
4739 );
static struct stasis_message_router * stasis_router
Message router for stasis messages regarding channel state.
Definition: cdr.c:413
const ast_string_field data
static long cdr_object_get_billsec(struct cdr_object *cdr)
Compute the billsec for a cdr_object.
Definition: cdr.c:1274
struct ao2_container * channels
Definition: bridge.h:331
char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: cdr.h:311
static int cdr_object_update_party_b_userfield_cb(void *obj, void *arg, void *data, int flags)
Callback used to update the userfield on Party B on all CDRs.
Definition: cdr.c:3517
void( ao2_prnt_fn)(void *where, const char *fmt,...)
Print output.
Definition: astobj2.h:1435
struct ast_channel_snapshot_base * base
Asterisk locking-related definitions:
Channels with this particular technology are an implementation detail of Asterisk and should generall...
Definition: channel.h:971
static void * module_config_alloc(void)
Create a new module config object.
Definition: cdr.c:342
Asterisk main include file. File version handling, generic pbx functions.
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
struct varshead variables
Definition: cdr.c:750
int ast_cdr_reset(const char *channel_name, int keep_variables)
Reset the detail record.
Definition: cdr.c:3660
static void reset_batch(void)
Definition: cdr.c:3792
struct ast_cdr_config * ast_cdr_get_config(void)
Obtain the current CDR configuration.
Definition: cdr.c:2888
int stasis_message_router_add(struct stasis_message_router *router, struct stasis_message_type *message_type, stasis_subscription_cb callback, void *data)
Add a route to a message router.
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
struct ast_channel_snapshot * channel
char dstchannel[AST_MAX_EXTENSION]
Definition: cdr.h:291
int ast_sched_runq(struct ast_sched_context *con)
Runs the queue.
Definition: sched.c:786
int(*const process_parked_channel)(struct cdr_object *cdr, struct ast_parked_call_payload *parking_info)
Process an update informing us that the channel got itself parked.
Definition: cdr.c:588
Call Parking API.
const ast_string_field name
static void bridge_candidate_process(struct cdr_object *cdr, struct cdr_object *base_cand_cdr)
Process a single bridge_candidate.
Definition: cdr.c:2566
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1101
struct ast_flags settings
Definition: cdr.h:268
static void cdr_object_format_var_internal(struct cdr_object *cdr, const char *name, char *value, size_t length)
Format a variable on a cdr_object.
Definition: cdr.c:3288
int stasis_message_router_set_congestion_limits(struct stasis_message_router *router, long low_water, long high_water)
Set the high and low alert water marks of the stasis message router.
struct ast_channel_snapshot * snapshot
Definition: cdr.c:747
static const char * ignore_categories[]
Definition: cdr.c:281
static void handle_bridge_leave_message(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Handler for when a channel leaves a bridge.
Definition: cdr.c:2467
#define STASIS_MESSAGE_TYPE_INIT(name)
Boiler-plate messaging macro for initializing message types.
Definition: stasis.h:1493
int ast_cdr_set_property(const char *channel_name, enum ast_cdr_options option)
Set a property on a CDR for a channel.
Definition: cdr.c:3610
long int billsec
Definition: cdr.h:305
static void handle_parking_bridge_enter_message(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel, const struct timeval *event_time)
Handle entering into a parking bridge.
Definition: cdr.c:2650
Stasis Message Bus API. See Stasis Message Bus API for detailed documentation.
descriptor for a cli entry.
Definition: cli.h:171
struct stasis_message_type * ast_parked_call_type(void)
accessor for the parked call stasis message type
#define AST_TASKPROCESSOR_HIGH_WATER_LEVEL
Definition: taskprocessor.h:64
static void cdr_object_dtor(void *obj)
cdr_object Destructor
Definition: cdr.c:1038
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container, as described below.
Definition: astobj2.h:1693
struct ast_cdr * ast_cdr_alloc(void)
Allocate a CDR record.
Definition: cdr.c:3484
Structure that contains a snapshot of information about a bridge.
Definition: bridge.h:314
#define aco_option_register(info, name, matchtype, types, default_val, opt_type, flags,...)
Register a config option.
char dcontext[AST_MAX_EXTENSION]
Definition: cdr.h:287
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:78
int ast_cdr_register(const char *name, const char *desc, ast_cdrbe be)
Register a CDR handling engine.
Definition: cdr.c:3005
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
static int process_config(int reload)
Load (or reload) configuration.
static void destroy_subscriptions(void)
Destroy the active Stasis subscriptions.
Definition: cdr.c:4369
struct cdr_object * next
Definition: cdr.c:777
struct cdr_object_snapshot party_b
Definition: cdr.c:756
Structure representing a snapshot of channel state.
int(*const process_party_a)(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
Process a Party A update for the cdr_object.
Definition: cdr.c:479
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:117
A wrapper object around a snapshot. Fields that are mutable by the CDR engine are replicated here...
Definition: cdr.c:746
#define STASIS_MESSAGE_TYPE_CLEANUP(name)
Boiler-plate messaging macro for cleaning up message types.
Definition: stasis.h:1515
Assume that the ao2_container is already locked.
Definition: astobj2.h:1063
int ast_sched_add_variable(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data, int variable) attribute_warn_unused_result
Adds a scheduled event with rescheduling support.
Definition: sched.c:526
static struct stasis_topic * cdr_topic
The parent topic for all topics we want to aggregate for CDRs.
Definition: cdr.c:425
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:52
int sequence
Definition: cdr.h:323
const ast_string_field accountcode
const ast_string_field exten
Definition: cdr.c:776
static struct cdr_object * cdr_object_alloc(struct ast_channel_snapshot *chan, const struct timeval *event_time)
cdr_object constructor
Definition: cdr.c:1079
#define AST_NUM_CHANNEL_BUCKETS
Definition: channel.h:155
int(* ast_cdrbe)(struct ast_cdr *cdr)
CDR backend callback.
Definition: cdr.h:461
const char * ast_channel_amaflags2string(enum ama_flags flags)
Convert the enum representation of an AMA flag to a string representation.
Definition: channel.c:4373
struct timeval answer
Definition: cdr.c:761
const ast_string_field uniqueid
struct stasis_topic * ast_bridge_topic_all(void)
A topic which publishes the events for all bridges.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1139
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
enum aco_process_status aco_process_config(struct aco_info *info, int reload)
Process a config info via the options registered with an aco_info.
static void handle_dial_message(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Handler for Stasis-Core dial messages.
Definition: cdr.c:2143
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
#define AST_DECLARE_STRING_FIELDS(field_list)
Declare the fields needed in a structure.
Definition: stringfields.h:341
CONFIG_INFO_CORE("stasis", cfg_info, globals, stasis_config_alloc,.files=ACO_FILES(&stasis_conf),)
Register information about the configs being processed by this module.
unsigned int sequence
Definition: cdr.c:764
static void cdr_object_set_disposition(struct cdr_object *cdr, int hangupcause)
Set the disposition on a cdr_object based on a hangupcause code.
Definition: cdr.c:1441
#define ao2_link_flags(container, obj, flags)
Add an object to a container.
Definition: astobj2.h:1554
Type for default option handler for bools (ast_true/ast_false) that are stored in a flag...
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:107
A parked call message payload.
Definition: parking.h:59
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
struct timeval start
Definition: cdr.c:760
unsigned int flags
Definition: cdr.c:749
static int copy_variables(struct varshead *to_list, struct varshead *from_list)
Copy variables from one list to another.
Definition: cdr.c:788
static long cdr_object_get_duration(struct cdr_object *cdr)
Definition: cdr.c:1266
The representation of a single configuration file to be processed.
ast_cdr_options
CDR manipulation options. Certain function calls will manipulate the state of a CDR object based on t...
Definition: cdr.h:242
Structure representing a change of snapshot of channel state.
enum aco_type_t type
enum ast_parked_call_event_type event_type
Definition: parking.h:62
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:615
#define ACO_TYPES(...)
A helper macro to ensure that aco_info types always have a sentinel.
static void handle_channel_snapshot_update_message(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Handler for channel snapshot update messages.
Definition: cdr.c:2329
struct ast_channel_snapshot_dialplan * dialplan
Registration object for CDR backends.
Definition: cdr.c:363
struct cdr_object_snapshot party_a
Definition: cdr.c:755
void stasis_message_router_unsubscribe_and_join(struct stasis_message_router *router)
Unsubscribe the router from the upstream topic, blocking until the final message has been processed...
void(*const init_function)(struct cdr_object *cdr)
An initialization function. This will be called automatically when a cdr_object is switched to this t...
Definition: cdr.c:469
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:757
void ast_cdr_engine_term(void)
Definition: cdr.c:4665
struct ast_json * ast_multi_channel_blob_get_json(struct ast_multi_channel_blob *obj)
Retrieve the JSON blob from a ast_multi_channel_blob. Returned ast_json is still owned by obj...
enum process_bridge_enter_results(*const process_bridge_enter)(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
Process the entering of a bridge by this CDR. The purpose of this callback is to have the CDR prepare...
Definition: cdr.c:545
Utility functions.
A virtual table used for cdr_object.
Definition: cdr.c:458
static struct stasis_forward * bridge_subscription
Our subscription for bridges.
Definition: cdr.c:416
const ast_string_field appl
Definition: cdr.c:776
#define AST_RWLIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a read/write list of specified type, statically initialized...
Definition: linkedlists.h:333
struct varshead varshead
Definition: cdr.h:326
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
const ast_string_field context
Definition: cdr.c:776
static int cdr_object_dispatch_all_cb(void *obj, void *arg, int flags)
This dispatches all cdr_object. It should only be used during shutdown, so that we get billing record...
Definition: cdr.c:4325
Call Detail Record API.
const ast_string_field dialed_subaddr
char lastdata[AST_MAX_EXTENSION]
Definition: cdr.h:295
const ast_string_field context
Configuration File Parser.
long int amaflags
Definition: cdr.h:309
int is_root
Definition: cdr.c:779
void ao2_container_unregister(const char *name)
Unregister a container for CLI stats and integrity check.
struct ast_bridge_snapshot * bridge
static int global_cdr_sequence
The global sequence counter used for CDRs.
Definition: cdr.c:391
struct stasis_topic * ast_channel_topic_all(void)
A topic which publishes the events for all channels.
int ao2_container_register(const char *name, struct ao2_container *self, ao2_prnt_obj_fn *prnt_obj)
Register a container for CLI stats and integrity check.
The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
Definition: astobj2.h:1116
char userfield[AST_MAX_USER_FIELD]
Definition: cdr.c:748
#define FLDSET(type,...)
Convert a struct and list of fields to an argument list of field offsets.
const ast_string_field technology
Definition: bridge.h:328
struct ast_flags flags
Definition: cdr.c:765
ast_mutex_t lock
void ast_cdr_free(struct ast_cdr *cdr)
Free a CDR record.
Definition: cdr.c:3473
int aco_info_init(struct aco_info *info)
Initialize an aco_info structure.
struct ast_channel_snapshot * parkee
Definition: parking.h:60
General Asterisk PBX channel definitions.
Asterisk JSON abstraction layer.
static int create_subscriptions(void)
Create the Stasis subcriptions for CDRs.
Definition: cdr.c:4379
#define AST_SCHED_DEL(sched, id)
Remove a scheduler entry.
Definition: sched.h:46
int(*const process_dial_begin)(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer)
Process the beginning of a dial. A dial message implies one of two things: The cdr_object's Party A h...
Definition: cdr.c:504
const ast_string_field appl
Type for default option handler for unsigned integers.
static int cdr_object_format_property(struct cdr_object *cdr_obj, const char *name, char *value, size_t length)
Format one of the standard properties on a cdr_object.
Definition: cdr.c:3305
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
static void cdr_object_dispatch(struct cdr_object *cdr)
Dispatch a CDR.
Definition: cdr.c:1425
const struct timeval * stasis_message_timestamp(const struct stasis_message *msg)
Get the time when a message was created.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
process_bridge_enter_results
Return types for process_bridge_enter functions.
Definition: cdr.c:433
Scheduler Routines (derived from cheops)
char linkedid[AST_MAX_UNIQUEID]
Definition: cdr.h:319
#define AST_STRING_FIELD(name)
Declare a string field.
Definition: stringfields.h:303
const ast_string_field linkedid
Definition: cdr.c:776
int ast_cdr_unregister(const char *name)
Unregister a CDR handling engine.
Definition: cdr.c:3050
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:557
static ast_mutex_t cdr_pending_lock
These are used to wake up the CDR thread when there's work to do.
Definition: cdr.c:403
static void module_config_destructor(void *obj)
Dispose of a module config object.
Definition: cdr.c:331
static struct aco_file module_file_conf
The file definition.
Definition: cdr.c:306
const ast_string_field subaddr
int ast_register_atexit(void(*func)(void))
Register a function to be executed before Asterisk exits.
Definition: clicompat.c:13
struct timeval ast_samp2tv(unsigned int _nsamp, unsigned int _rate)
Returns a timeval corresponding to the duration of n samples at rate r. Useful to convert samples to ...
Definition: time.h:282
struct cdr_object_fn_table parked_state_fn_table
The virtual table for the Parked state.
Definition: cdr.c:720
const ast_string_field exten
static int filter_bridge_messages(struct ast_bridge_snapshot *bridge)
Filter bridge messages based on bridge technology.
Definition: cdr.c:2450
static void handle_bridge_pairings(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge)
Handle creating bridge pairings for the cdr_object that just entered a bridge.
Definition: cdr.c:2624
char uniqueid[AST_MAX_UNIQUEID]
Definition: cdr.h:317
struct ast_channel_snapshot_hangup * hangup
char dst[AST_MAX_EXTENSION]
Definition: cdr.h:285
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
Definition: json.c:283
static int init_batch(void)
Definition: cdr.c:3800
struct cdr_object_fn_table dialed_pending_state_fn_table
The virtual table for the Dialed Pending state.
Definition: cdr.c:679
A set of macros to manage forward-linked lists.
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
The configuration settings for this module.
Definition: cdr.c:264
Definition: cdr.h:226
#define ast_debug(level,...)
Log a DEBUG message.
void ast_cdr_setuserfield(const char *channel_name, const char *userfield)
Set CDR user field for channel (stored in CDR)
Definition: cdr.c:3539
struct stasis_topic * stasis_topic_create(const char *name)
Create a new topic.
Definition: stasis.c:617
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833
Blob of data associated with a bridge.
enum aco_category_op category_match
static AO2_GLOBAL_OBJ_STATIC(module_configs)
The container for the module configuration.
static void free_variables(struct varshead *headp)
Delete all variables from a variable list.
Definition: cdr.c:819
static int snapshot_cep_changed(struct ast_channel_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot)
Return whether or not a channel has changed its state in the dialplan, subject to endbeforehexten log...
Definition: cdr.c:1187
struct cdr_object_fn_table * fn_table
Definition: cdr.c:757
Their was an error and no changes were applied.
struct ast_sched_context * ast_sched_context_create(void)
Create a scheduler context.
Definition: sched.c:238
enum ast_cdr_disposition disposition
Definition: cdr.c:759
int ast_cdr_getvar(const char *channel_name, const char *name, char *value, size_t length)
Retrieve a CDR variable from a channel's current CDR.
Definition: cdr.c:3386
struct ast_channel_snapshot_caller * caller
List of registered modifiers.
Definition: cdr.c:375
static struct cdr_object_snapshot * cdr_object_pick_party_a(struct cdr_object_snapshot *left, struct cdr_object_snapshot *right)
Given two CDR snapshots, figure out who should be Party A for the resulting CDR.
Definition: cdr.c:1231
An in-memory representation of an active CDR.
Definition: cdr.c:754
The actual batch queue.
Definition: cdr.c:384
struct cdr_object * last
Definition: cdr.c:778
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
static void cdr_object_transition_state_init(struct cdr_object *cdr, struct cdr_object_fn_table *fn_table, int do_init)
Transition a cdr_object to a new state with initiation flag.
Definition: cdr.c:847
Queued CDR waiting to be batched.
Definition: cdr.c:378
struct ast_flags softhangup_flags
Responsible for call detail data.
Definition: cdr.h:279
Configuration option-handling.
char lastapp[AST_MAX_EXTENSION]
Definition: cdr.h:293
const ast_string_field data
Definition: cdr.c:776
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
Definition: astobj2.h:1303
int ast_cdr_backend_unsuspend(const char *name)
Unsuspend a CDR backend.
Definition: cdr.c:2946
struct cdr_object_fn_table single_state_fn_table
The virtual table for the Single state.
Definition: cdr.c:615
Support for dynamic strings.
Definition: strings.h:623
const ast_string_field dnid
#define ao2_unlink(container, obj)
Remove an object from a container.
Definition: astobj2.h:1578
static struct ast_cdr * cdr_object_create_public_records(struct cdr_object *cdr)
Create a chain of ast_cdr objects from a chain of cdr_object suitable for consumption by the register...
Definition: cdr.c:1326
static ast_mutex_t cdr_batch_lock
Lock protecting modifications to the batch queue.
Definition: cdr.c:400
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
void aco_info_destroy(struct aco_info *info)
Destroy an initialized aco_info struct.
int ast_cdr_fork(const char *channel_name, struct ast_flags *options)
Fork a CDR.
Definition: cdr.c:3699
int ast_cdr_serialize_variables(const char *channel_name, struct ast_str **buf, char delim, char sep)
Serializes all the data and variables for a current CDR record.
Definition: cdr.c:3415
unsigned int parkingspace
Definition: parking.h:65
struct stasis_message * stasis_message_create(struct stasis_message_type *type, void *data)
Create a new message.
#define ao2_global_obj_release(holder)
Release the ao2 object held in the global holder.
Definition: astobj2.h:859
static void cdr_object_check_party_a_hangup(struct cdr_object *cdr)
Check to see if a CDR needs to move to the finalized state because its Party A hungup.
Definition: cdr.c:1516
int ast_cdr_clear_property(const char *channel_name, enum ast_cdr_options option)
Clear a property on a CDR for a channel.
Definition: cdr.c:3637
const char * name
Name of the subclass.
Definition: cdr.c:460
static struct ao2_container * active_cdrs_master
A container of the active master CDRs indexed by Party A channel uniqueid.
Definition: cdr.c:407
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2282
void(*const process_party_b)(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
Process a Party B update for the cdr_object.
Definition: cdr.c:488
static int single_state_bridge_enter_comparison(struct cdr_object *cdr, struct cdr_object *cand_cdr)
Handle a comparison between our cdr_object and a cdr_object already in the bridge while in the Single...
Definition: cdr.c:1731
struct stasis_message_router * ast_cdr_message_router(void)
Return the message router for the CDR engine.
Definition: cdr.c:4356
unsigned int flags
Definition: cdr.h:315
const ast_string_field party_b_name
Definition: cdr.c:776
long ast_sched_when(struct ast_sched_context *con, int id)
Returns the number of seconds before an event takes place.
Definition: sched.c:851
struct timeval lastevent
Definition: cdr.c:763
static int snapshot_is_dialed(struct ast_channel_snapshot *snapshot)
Return whether or not a ast_channel_snapshot is for a channel that was created as the result of a dia...
Definition: cdr.c:1218
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:711
struct timeval end
Definition: cdr.c:762
#define ESS(x)
Definition: cli.h:59
#define SCOPED_AO2LOCK(varname, obj)
scoped lock specialization for ao2 mutexes.
Definition: lock.h:604
char * command
Definition: cli.h:186
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
static void start_batch_mode(void)
Definition: cdr.c:3887
const ast_string_field name
Definition: cdr.c:776
int aco_set_defaults(struct aco_type *type, const char *category, void *obj)
Set all default options of obj.
Module could not be loaded properly.
Definition: module.h:102
struct ast_channel_snapshot * new_snapshot
long int duration
Definition: cdr.h:303
static void cdr_object_snapshot_copy(struct cdr_object_snapshot *dst, struct cdr_object_snapshot *src)
Copy a snapshot and its details.
Definition: cdr.c:833
enum ast_channel_state state
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Definition: localtime.c:2524
const ast_string_field uniqueid
Definition: bridge.h:328
An API for managing task processing threads that can be shared across modules.
const ast_string_field parkinglot
Definition: parking.h:69
struct stasis_message_type * ast_channel_snapshot_type(void)
Message type for ast_channel_snapshot_update.
int(*const process_parking_bridge_enter)(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
Process entering into a parking bridge.
Definition: cdr.c:561
int ast_cdr_modifier_unregister(const char *name)
Unregister a CDR modifier.
Definition: cdr.c:3055
struct ast_channel_snapshot * old_snapshot
Structure used to handle boolean flags.
Definition: utils.h:199
const char * usage
Definition: cli.h:177
char src[AST_MAX_EXTENSION]
Definition: cdr.h:283
char peeraccount[AST_MAX_ACCOUNT_CODE]
Definition: cdr.h:313
void ast_cdr_set_config(struct ast_cdr_config *config)
Set the current CDR configuration.
Definition: cdr.c:2902
struct cdr_object_fn_table finalized_state_fn_table
The virtual table for the finalized state.
Definition: cdr.c:736
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:693
#define ao2_global_obj_replace_unref(holder, obj)
Replace an ao2 object in the global holder, throwing away any old object.
Definition: astobj2.h:901
STASIS_MESSAGE_TYPE_DEFN_LOCAL(cdr_sync_message_type)
A message type used to synchronize with the CDR topic.
The arg parameter is an object of the same type.
Definition: astobj2.h:1087
struct stasis_topic * ast_parking_topic(void)
accessor for the parking stasis topic
Definition: parking.c:67
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:681
static int cdr_object_party_b_left_bridge_cb(void *obj, void *arg, void *data, int flags)
Callback used to notify CDRs of a Party B leaving the bridge.
Definition: cdr.c:2425
struct ast_flags settings
Definition: cdr.h:272
#define ao2_replace(dst, src)
Replace one object reference with another cleaning up the original.
Definition: astobj2.h:501
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
void stasis_message_router_publish_sync(struct stasis_message_router *router, struct stasis_message *message)
Publish a message to a message router's subscription synchronously.
int ast_cdr_is_enabled(void)
Return TRUE if CDR subsystem is enabled.
Definition: cdr.c:2923
Standard Command Line Interface.
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
Definition: json.c:407
ast_cdr_disposition
CDR Flags - Disposition.
Definition: cdr.h:256
Type information about a category-level configurable object.
const ast_string_field number
int ast_cdr_modifier_register(const char *name, const char *desc, ast_cdrbe be)
Register a CDR modifier.
Definition: cdr.c:3010
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
int ast_cdr_backend_suspend(const char *name)
Suspend a CDR backend temporarily.
Definition: cdr.c:2928
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:80
static void handle_parked_call_message(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Handler for when a channel is parked.
Definition: cdr.c:2814
struct ast_flags flags
struct ast_channel_snapshot * ast_multi_channel_blob_get_channel(struct ast_multi_channel_blob *obj, const char *role)
Retrieve a channel snapshot associated with a specific role from a ast_multi_channel_blob.
const char * filename
static struct aco_type general_option
The type definition for general options.
Definition: cdr.c:272
A multi channel blob data structure for multi_channel_blob stasis messages.
int ast_cdr_setvar(const char *channel_name, const char *name, const char *value)
Set a variable on a CDR.
Definition: cdr.c:3240
static void handle_standard_bridge_enter_message(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel, const struct timeval *event_time)
Handle a bridge enter message for a 'normal' bridge.
Definition: cdr.c:2692
static char * cli_complete_show(struct ast_cli_args *a)
Complete user input for 'cdr show'.
Definition: cdr.c:4032
int ast_sched_wait(struct ast_sched_context *con) attribute_warn_unused_result
Determines number of seconds until the next outstanding event to take place.
Definition: sched.c:433
static struct ao2_container * active_cdrs_all
A container of all active CDRs with a Party B indexed by Party B channel name.
Definition: cdr.c:410
#define ao2_unlink_flags(container, obj, flags)
Remove an object from a container.
Definition: astobj2.h:1600
static void cdr_object_check_party_a_answer(struct cdr_object *cdr)
Check to see if a CDR needs to be answered based on its Party A. Note that this is safe to call as mu...
Definition: cdr.c:1533
Internal Asterisk hangup causes.
Abstract JSON element (object, array, string, int, ...).
int(*const process_bridge_leave)(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
Process the leaving of a bridge by this CDR.
Definition: cdr.c:575
static void cdr_object_swap_snapshot(struct cdr_object_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot)
Swap an old cdr_object_snapshot's ast_channel_snapshot for a new ast_channel_snapshot.
Definition: cdr.c:1570
Forwarding information.
Definition: stasis.c:1531
The global options available for CDRs.
Definition: cdr.h:267
struct stasis_message_type * ast_channel_dial_type(void)
Message type for when a channel dials another channel.
static void cdr_object_update_cid(struct cdr_object_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot)
Set Caller ID information on a CDR.
Definition: cdr.c:1545
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:529
static struct stasis_forward * channel_subscription
Our subscription for channels.
Definition: cdr.c:419
struct cdr_object_fn_table bridge_state_fn_table
The virtual table for the Bridged state.
Definition: cdr.c:701
Generic container type.
long int disposition
Definition: cdr.h:307
char clid[AST_MAX_EXTENSION]
Definition: cdr.h:281
Search option field mask.
Definition: astobj2.h:1072
struct stasis_forward * stasis_forward_all(struct stasis_topic *from_topic, struct stasis_topic *to_topic)
Create a subscription which forwards all messages from one topic to another.
Definition: stasis.c:1578
const ast_string_field uniqueid
Definition: cdr.c:776
struct cdr_object_fn_table dial_state_fn_table
The virtual table for the Dial state.
Definition: cdr.c:646
int ast_cli_completion_add(char *value)
Add a result to a request for completion options.
Definition: main/cli.c:2761
struct ast_channel_snapshot_peer * peer
static struct cdr_object * cdr_object_create_and_append(struct cdr_object *cdr, const struct timeval *event_time)
Create a new cdr_object and append it to an existing chain.
Definition: cdr.c:1116
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
struct ast_cdr_config * general
Definition: cdr.c:265
int(*const process_dial_end)(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer, const char *dial_status)
Process the end of a dial. At the end of a dial, a CDR can be transitioned into one of two states - D...
Definition: cdr.c:522
static int check_new_cdr_needed(struct ast_channel_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot)
Determine if we need to add a new CDR based on snapshots.
Definition: cdr.c:2301
Asterisk module definitions.
static void cdr_object_finalize(struct cdr_object *cdr)
Finalize a CDR.
Definition: cdr.c:1479
const ast_string_field subclass
Definition: bridge.h:328
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
static struct stasis_forward * parking_subscription
Our subscription for parking.
Definition: cdr.c:422
static void handle_cdr_sync_message(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Handler for a synchronization message.
Definition: cdr.c:2882
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:374
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
static int cdr_toggle_runtime_options(void)
Checks if CDRs are enabled and enables/disables the necessary options.
Definition: cdr.c:4552
void ast_sched_context_destroy(struct ast_sched_context *c)
destroys a schedule context
Definition: sched.c:271
List of registered backends.
Definition: cdr.c:372
static force_inline int attribute_pure ast_str_case_hash(const char *str)
Compute a hash value on a case-insensitive string.
Definition: strings.h:1303
const ast_string_field bridge
Definition: cdr.c:776
const ast_string_field name
void ast_cdr_format_var(struct ast_cdr *cdr, const char *name, char **ret, char *workspace, int workspacelen, int raw)
Format a CDR variable from an already posted CDR.
Definition: cdr.c:3112
char userfield[AST_MAX_USER_FIELD]
Definition: cdr.h:321
static void cdr_object_transition_state(struct cdr_object *cdr, struct cdr_object_fn_table *fn_table)
Transition a cdr_object to a new state.
Definition: cdr.c:864
const char * ast_cdr_disp2str(int disposition)
Disposition to a string.
Definition: cdr.c:3492
static struct ast_sched_context * sched
Scheduler items.
Definition: cdr.c:394
struct ast_cdr * ast_cdr_dup(struct ast_cdr *cdr)
Duplicate a public CDR.
Definition: cdr.c:3060
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
#define AST_MAX_USER_FIELD
Definition: channel.h:174
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532