cdr.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2006, Digium, Inc.
00005  *
00006  * Mark Spencer <markster@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*! \file
00020  *
00021  * \brief Call Detail Record API
00022  *
00023  * \author Mark Spencer <markster@digium.com>
00024  *
00025  * \note Includes code and algorithms from the Zapata library.
00026  *
00027  * \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
00028  * through our fingers somehow.  If someone allocates a CDR, it must be completely handled normally
00029  * or a WARNING shall be logged, so that we can best keep track of any escape condition where the CDR
00030  * isn't properly generated and posted.
00031  */
00032 
00033 /*! \li \ref cdr.c uses the configuration file \ref cdr.conf
00034  * \addtogroup configuration_file Configuration Files
00035  */
00036 
00037 /*!
00038  * \page cdr.conf cdr.conf
00039  * \verbinclude cdr.conf.sample
00040  */
00041 
00042 /*** MODULEINFO
00043    <support_level>core</support_level>
00044  ***/
00045 
00046 #include "asterisk.h"
00047 
00048 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 433270 $")
00049 
00050 #include <signal.h>
00051 #include <inttypes.h>
00052 
00053 #include "asterisk/lock.h"
00054 #include "asterisk/channel.h"
00055 #include "asterisk/cdr.h"
00056 #include "asterisk/callerid.h"
00057 #include "asterisk/manager.h"
00058 #include "asterisk/causes.h"
00059 #include "asterisk/linkedlists.h"
00060 #include "asterisk/utils.h"
00061 #include "asterisk/sched.h"
00062 #include "asterisk/config.h"
00063 #include "asterisk/cli.h"
00064 #include "asterisk/stringfields.h"
00065 #include "asterisk/data.h"
00066 #include "asterisk/config_options.h"
00067 #include "asterisk/json.h"
00068 #include "asterisk/parking.h"
00069 #include "asterisk/stasis.h"
00070 #include "asterisk/stasis_channels.h"
00071 #include "asterisk/stasis_bridges.h"
00072 #include "asterisk/stasis_message_router.h"
00073 #include "asterisk/astobj2.h"
00074 
00075 /*** DOCUMENTATION
00076    <configInfo name="cdr" language="en_US">
00077       <synopsis>Call Detail Record configuration</synopsis>
00078       <description>
00079          <para>CDR is Call Detail Record, which provides logging services via a variety of
00080          pluggable backend modules. Detailed call information can be recorded to
00081          databases, files, etc. Useful for billing, fraud prevention, compliance with
00082          Sarbanes-Oxley aka The Enron Act, QOS evaluations, and more.</para>
00083       </description>
00084       <configFile name="cdr.conf">
00085          <configObject name="general">
00086             <synopsis>Global settings applied to the CDR engine.</synopsis>
00087             <configOption name="debug">
00088                <synopsis>Enable/disable verbose CDR debugging.</synopsis>
00089                <description><para>When set to <literal>True</literal>, verbose updates
00090                of changes in CDR information will be logged. Note that this is only
00091                of use when debugging CDR behavior.</para>
00092                </description>
00093             </configOption>
00094             <configOption name="enable">
00095                <synopsis>Enable/disable CDR logging.</synopsis>
00096                <description><para>Define whether or not to use CDR logging. Setting this to "no" will override
00097                any loading of backend CDR modules.  Default is "yes".</para>
00098                </description>
00099             </configOption>
00100             <configOption name="unanswered">
00101                <synopsis>Log calls that are never answered and don't set an outgoing party.</synopsis>
00102                <description><para>
00103                Define whether or not to log unanswered calls that don't involve an outgoing party. Setting
00104                this to "yes" will make calls to extensions that don't answer and don't set a side B channel
00105                (such as by using the Dial application) receive CDR log entries. If this option is set to
00106                "no", then those log entries will not be created. Unanswered calls which get offered to an
00107                outgoing line will always receive log entries regardless of this option, and that is the
00108                intended behavior.
00109                </para>
00110                </description>
00111             </configOption>
00112             <configOption name="congestion">
00113                <synopsis>Log congested calls.</synopsis>
00114                <description><para>Define whether or not to log congested calls. Setting this to "yes" will
00115                report each call that fails to complete due to congestion conditions.</para>
00116                </description>
00117             </configOption>
00118             <configOption name="endbeforehexten">
00119                <synopsis>Don't produce CDRs while executing hangup logic</synopsis>
00120                <description>
00121                   <para>As each CDR for a channel is finished, its end time is updated
00122                   and the CDR is finalized. When a channel is hung up and hangup
00123                   logic is present (in the form of a hangup handler or the
00124                   <literal>h</literal> extension), a new CDR is generated for the
00125                   channel. Any statistics are gathered from this new CDR. By enabling
00126                   this option, no new CDR is created for the dialplan logic that is
00127                   executed in <literal>h</literal> extensions or attached hangup handler
00128                   subroutines. The default value is <literal>yes</literal>, indicating
00129                   that a CDR will be generated during hangup logic.</para>
00130                </description>
00131             </configOption>
00132             <configOption name="initiatedseconds">
00133                <synopsis>Count microseconds for billsec purposes</synopsis>
00134                <description><para>Normally, the <literal>billsec</literal> field logged to the CDR backends
00135                is simply the end time (hangup time) minus the answer time in seconds. Internally,
00136                asterisk stores the time in terms of microseconds and seconds. By setting
00137                initiatedseconds to <literal>yes</literal>, you can force asterisk to report any seconds
00138                that were initiated (a sort of round up method). Technically, this is
00139                when the microsecond part of the end time is greater than the microsecond
00140                part of the answer time, then the billsec time is incremented one second.</para>
00141                </description>
00142             </configOption>
00143             <configOption name="batch">
00144                <synopsis>Submit CDRs to the backends for processing in batches</synopsis>
00145                <description><para>Define the CDR batch mode, where instead of posting the CDR at the end of
00146                every call, the data will be stored in a buffer to help alleviate load on the
00147                asterisk server.</para>
00148                <warning><para>Use of batch mode may result in data loss after unsafe asterisk termination,
00149                i.e., software crash, power failure, kill -9, etc.</para>
00150                </warning>
00151                </description>
00152             </configOption>
00153             <configOption name="size">
00154                <synopsis>The maximum number of CDRs to accumulate before triggering a batch</synopsis>
00155                <description><para>Define the maximum number of CDRs to accumulate in the buffer before posting
00156                them to the backend engines. batch must be set to <literal>yes</literal>.</para>
00157                </description>
00158             </configOption>
00159             <configOption name="time">
00160                <synopsis>The maximum time to accumulate CDRs before triggering a batch</synopsis>
00161                <description><para>Define the maximum time to accumulate CDRs before posting them in a batch to the
00162                backend engines. If this time limit is reached, then it will post the records, regardless of the value
00163                defined for size. batch must be set to <literal>yes</literal>.</para>
00164                <note><para>Time is expressed in seconds.</para></note>
00165                </description>
00166             </configOption>
00167             <configOption name="scheduleronly">
00168                <synopsis>Post batched CDRs on their own thread instead of the scheduler</synopsis>
00169                <description><para>The CDR engine uses the internal asterisk scheduler to determine when to post
00170                records.  Posting can either occur inside the scheduler thread, or a new
00171                thread can be spawned for the submission of every batch.  For small batches,
00172                it might be acceptable to just use the scheduler thread, so set this to <literal>yes</literal>.
00173                For large batches, say anything over size=10, a new thread is recommended, so
00174                set this to <literal>no</literal>.</para>
00175                </description>
00176             </configOption>
00177             <configOption name="safeshutdown">
00178                <synopsis>Block shutdown of Asterisk until CDRs are submitted</synopsis>
00179                <description><para>When shutting down asterisk, you can block until the CDRs are submitted.  If
00180                you don't, then data will likely be lost.  You can always check the size of
00181                the CDR batch buffer with the CLI <astcli>cdr status</astcli> command.  To enable blocking on
00182                submission of CDR data during asterisk shutdown, set this to <literal>yes</literal>.</para>
00183                </description>
00184             </configOption>
00185          </configObject>
00186       </configFile>
00187    </configInfo>
00188  ***/
00189 
00190 
00191 /* The prime here should be similar in size to the channel container. */
00192 #ifdef LOW_MEMORY
00193 #define NUM_CDR_BUCKETS 61
00194 #else
00195 #define NUM_CDR_BUCKETS 769
00196 #endif
00197 
00198 #define DEFAULT_ENABLED "1"
00199 #define DEFAULT_BATCHMODE "0"
00200 #define DEFAULT_UNANSWERED "0"
00201 #define DEFAULT_CONGESTION "0"
00202 #define DEFAULT_END_BEFORE_H_EXTEN "1"
00203 #define DEFAULT_INITIATED_SECONDS "0"
00204 
00205 #define DEFAULT_BATCH_SIZE "100"
00206 #define MAX_BATCH_SIZE 1000
00207 #define DEFAULT_BATCH_TIME "300"
00208 #define MAX_BATCH_TIME 86400
00209 #define DEFAULT_BATCH_SCHEDULER_ONLY "0"
00210 #define DEFAULT_BATCH_SAFE_SHUTDOWN "1"
00211 
00212 #define CDR_DEBUG(mod_cfg, fmt, ...) \
00213    do { \
00214       if (ast_test_flag(&(mod_cfg)->general->settings, CDR_DEBUG)) { \
00215          ast_verbose((fmt), ##__VA_ARGS__); \
00216       } \
00217    } while (0)
00218 
00219 static void cdr_detach(struct ast_cdr *cdr);
00220 static void cdr_submit_batch(int shutdown);
00221 static int cdr_toggle_runtime_options(void);
00222 
00223 /*! \brief The configuration settings for this module */
00224 struct module_config {
00225    struct ast_cdr_config *general;     /*< CDR global settings */
00226 };
00227 
00228 /*! \brief The container for the module configuration */
00229 static AO2_GLOBAL_OBJ_STATIC(module_configs);
00230 
00231 /*! \brief The type definition for general options */
00232 static struct aco_type general_option = {
00233    .type = ACO_GLOBAL,
00234    .name = "general",
00235    .item_offset = offsetof(struct module_config, general),
00236    .category = "^general$",
00237    .category_match = ACO_WHITELIST,
00238 };
00239 
00240 static void *module_config_alloc(void);
00241 static void module_config_destructor(void *obj);
00242 
00243 /*! \brief The file definition */
00244 static struct aco_file module_file_conf = {
00245    .filename = "cdr.conf",
00246    .skip_category = "(^csv$|^custom$|^manager$|^odbc$|^pgsql$|^radius$|^sqlite$|^tds$|^mysql$)",
00247    .types = ACO_TYPES(&general_option),
00248 };
00249 
00250 CONFIG_INFO_CORE("cdr", cfg_info, module_configs, module_config_alloc,
00251    .files = ACO_FILES(&module_file_conf),
00252 );
00253 
00254 static struct aco_type *general_options[] = ACO_TYPES(&general_option);
00255 
00256 /*! \brief Dispose of a module config object */
00257 static void module_config_destructor(void *obj)
00258 {
00259    struct module_config *cfg = obj;
00260 
00261    if (!cfg) {
00262       return;
00263    }
00264    ao2_ref(cfg->general, -1);
00265 }
00266 
00267 /*! \brief Create a new module config object */
00268 static void *module_config_alloc(void)
00269 {
00270    struct module_config *mod_cfg;
00271    struct ast_cdr_config *cdr_config;
00272 
00273    mod_cfg = ao2_alloc(sizeof(*mod_cfg), module_config_destructor);
00274    if (!mod_cfg) {
00275       return NULL;
00276    }
00277 
00278    cdr_config = ao2_alloc(sizeof(*cdr_config), NULL);
00279    if (!cdr_config) {
00280       ao2_ref(cdr_config, -1);
00281       return NULL;
00282    }
00283    mod_cfg->general = cdr_config;
00284 
00285    return mod_cfg;
00286 }
00287 
00288 /*! \brief Registration object for CDR backends */
00289 struct cdr_beitem {
00290    char name[20];
00291    char desc[80];
00292    ast_cdrbe be;
00293    AST_RWLIST_ENTRY(cdr_beitem) list;
00294    int suspended:1;
00295 };
00296 
00297 /*! \brief List of registered backends */
00298 static AST_RWLIST_HEAD_STATIC(be_list, cdr_beitem);
00299 
00300 /*! \brief Queued CDR waiting to be batched */
00301 struct cdr_batch_item {
00302    struct ast_cdr *cdr;
00303    struct cdr_batch_item *next;
00304 };
00305 
00306 /*! \brief The actual batch queue */
00307 static struct cdr_batch {
00308    int size;
00309    struct cdr_batch_item *head;
00310    struct cdr_batch_item *tail;
00311 } *batch = NULL;
00312 
00313 /*! \brief The global sequence counter used for CDRs */
00314 static int global_cdr_sequence =  0;
00315 
00316 /*! \brief Scheduler items */
00317 static struct ast_sched_context *sched;
00318 static int cdr_sched = -1;
00319 AST_MUTEX_DEFINE_STATIC(cdr_sched_lock);
00320 static pthread_t cdr_thread = AST_PTHREADT_NULL;
00321 
00322 /*! \brief Lock protecting modifications to the batch queue */
00323 AST_MUTEX_DEFINE_STATIC(cdr_batch_lock);
00324 
00325 /*! \brief These are used to wake up the CDR thread when there's work to do */
00326 AST_MUTEX_DEFINE_STATIC(cdr_pending_lock);
00327 static ast_cond_t cdr_pending_cond;
00328 
00329 /*! \brief A container of the active CDRs indexed by Party A channel id */
00330 static struct ao2_container *active_cdrs_by_channel;
00331 
00332 /*! \brief Message router for stasis messages regarding channel state */
00333 static struct stasis_message_router *stasis_router;
00334 
00335 /*! \brief Our subscription for bridges */
00336 static struct stasis_forward *bridge_subscription;
00337 
00338 /*! \brief Our subscription for channels */
00339 static struct stasis_forward *channel_subscription;
00340 
00341 /*! \brief Our subscription for parking */
00342 static struct stasis_forward *parking_subscription;
00343 
00344 /*! \brief The parent topic for all topics we want to aggregate for CDRs */
00345 static struct stasis_topic *cdr_topic;
00346 
00347 /*! \brief A message type used to synchronize with the CDR topic */
00348 STASIS_MESSAGE_TYPE_DEFN_LOCAL(cdr_sync_message_type);
00349 
00350 struct cdr_object;
00351 
00352 /*! \brief Return types for \ref process_bridge_enter functions */
00353 enum process_bridge_enter_results {
00354    /*!
00355     * The CDR was the only party in the bridge.
00356     */
00357    BRIDGE_ENTER_ONLY_PARTY,
00358    /*!
00359     * The CDR was able to obtain a Party B from some other party already in the bridge
00360     */
00361    BRIDGE_ENTER_OBTAINED_PARTY_B,
00362    /*!
00363     * The CDR was not able to obtain a Party B
00364     */
00365    BRIDGE_ENTER_NO_PARTY_B,
00366    /*!
00367     * This CDR can't handle a bridge enter message and a new CDR needs to be created
00368     */
00369    BRIDGE_ENTER_NEED_CDR,
00370 };
00371 
00372 /*!
00373  * \brief A virtual table used for \ref cdr_object.
00374  *
00375  * Note that all functions are optional - if a subclass does not need an
00376  * implementation, it is safe to leave it NULL.
00377  */
00378 struct cdr_object_fn_table {
00379    /*! \brief Name of the subclass */
00380    const char *name;
00381 
00382    /*!
00383     * \brief An initialization function. This will be called automatically
00384     * when a \ref cdr_object is switched to this type in
00385     * \ref cdr_object_transition_state
00386     *
00387     * \param cdr The \ref cdr_object that was just transitioned
00388     */
00389    void (* const init_function)(struct cdr_object *cdr);
00390 
00391    /*!
00392     * \brief Process a Party A update for the \ref cdr_object
00393     *
00394     * \param cdr The \ref cdr_object to process the update
00395     * \param snapshot The snapshot for the CDR's Party A
00396     * \retval 0 the CDR handled the update or ignored it
00397     * \retval 1 the CDR is finalized and a new one should be made to handle it
00398     */
00399    int (* const process_party_a)(struct cdr_object *cdr,
00400          struct ast_channel_snapshot *snapshot);
00401 
00402    /*!
00403     * \brief Process a Party B update for the \ref cdr_object
00404     *
00405     * \param cdr The \ref cdr_object to process the update
00406     * \param snapshot The snapshot for the CDR's Party B
00407     */
00408    void (* const process_party_b)(struct cdr_object *cdr,
00409          struct ast_channel_snapshot *snapshot);
00410 
00411    /*!
00412     * \brief Process the beginning of a dial. A dial message implies one of two
00413     * things:
00414     * The \ref cdr_object's Party A has been originated
00415     * The \ref cdr_object's Party A is dialing its Party B
00416     *
00417     * \param cdr The \ref cdr_object
00418     * \param caller The originator of the dial attempt
00419     * \param peer The destination of the dial attempt
00420     *
00421     * \retval 0 if the parties in the dial were handled by this CDR
00422     * \retval 1 if the parties could not be handled by this CDR
00423     */
00424    int (* const process_dial_begin)(struct cdr_object *cdr,
00425          struct ast_channel_snapshot *caller,
00426          struct ast_channel_snapshot *peer);
00427 
00428    /*!
00429     * \brief Process the end of a dial. At the end of a dial, a CDR can be
00430     * transitioned into one of two states - DialedPending
00431     * (\ref dialed_pending_state_fn_table) or Finalized
00432     * (\ref finalized_state_fn_table).
00433     *
00434     * \param cdr The \ref cdr_object
00435     * \param caller The originator of the dial attempt
00436     * \param peer the Destination of the dial attempt
00437     * \param dial_status What happened
00438     *
00439     * \retval 0 if the parties in the dial were handled by this CDR
00440     * \retval 1 if the parties could not be handled by this CDR
00441     */
00442    int (* const process_dial_end)(struct cdr_object *cdr,
00443          struct ast_channel_snapshot *caller,
00444          struct ast_channel_snapshot *peer,
00445          const char *dial_status);
00446 
00447    /*!
00448     * \brief Process the entering of a bridge by this CDR. The purpose of this
00449     * callback is to have the CDR prepare itself for the bridge and attempt to
00450     * find a valid Party B. The act of creating new CDRs based on the entering
00451     * of this channel into the bridge is handled by the higher level message
00452     * handler.
00453     *
00454     * Note that this handler is for when a channel enters into a "normal"
00455     * bridge, where people actually talk to each other. Parking is its own
00456     * thing.
00457     *
00458     * \param cdr The \ref cdr_object
00459     * \param bridge The bridge that the Party A just entered into
00460     * \param channel The \ref ast_channel_snapshot for this CDR's Party A
00461     *
00462     * \retval process_bridge_enter_results Defines whether or not this CDR was able
00463     * to fully handle the bridge enter message.
00464     */
00465    enum process_bridge_enter_results (* const process_bridge_enter)(
00466          struct cdr_object *cdr,
00467          struct ast_bridge_snapshot *bridge,
00468          struct ast_channel_snapshot *channel);
00469 
00470    /*!
00471     * \brief Process entering into a parking bridge.
00472     *
00473     * \param cdr The \ref cdr_object
00474     * \param bridge The parking bridge that Party A just entered into
00475     * \param channel The \ref ast_channel_snapshot for this CDR's Party A
00476     *
00477     * \retval 0 This CDR successfully transitioned itself into the parked state
00478     * \retval 1 This CDR couldn't handle the parking transition and we need a
00479     *  new CDR.
00480     */
00481    int (* const process_parking_bridge_enter)(struct cdr_object *cdr,
00482          struct ast_bridge_snapshot *bridge,
00483          struct ast_channel_snapshot *channel);
00484 
00485    /*!
00486     * \brief Process the leaving of a bridge by this CDR.
00487     *
00488     * \param cdr The \ref cdr_object
00489     * \param bridge The bridge that the Party A just left
00490     * \param channel The \ref ast_channel_snapshot for this CDR's Party A
00491     *
00492     * \retval 0 This CDR left successfully
00493     * \retval 1 Error
00494     */
00495    int (* const process_bridge_leave)(struct cdr_object *cdr,
00496          struct ast_bridge_snapshot *bridge,
00497          struct ast_channel_snapshot *channel);
00498 
00499    /*!
00500     * \brief Process an update informing us that the channel got itself parked
00501     *
00502     * \param cdr The \ref cdr_object
00503     * \param channel The parking information for this CDR's party A
00504     *
00505     * \retval 0 This CDR successfully parked itself
00506     * \retval 1 This CDR couldn't handle the park
00507     */
00508    int (* const process_parked_channel)(struct cdr_object *cdr,
00509          struct ast_parked_call_payload *parking_info);
00510 };
00511 
00512 static int base_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot);
00513 static enum process_bridge_enter_results base_process_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
00514 static int base_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
00515 static int base_process_dial_end(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer, const char *dial_status);
00516 static int base_process_parked_channel(struct cdr_object *cdr, struct ast_parked_call_payload *parking_info);
00517 
00518 static void single_state_init_function(struct cdr_object *cdr);
00519 static void single_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot);
00520 static int single_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer);
00521 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);
00522 static int single_state_process_parking_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
00523 
00524 /*!
00525  * \brief The virtual table for the Single state.
00526  *
00527  * A \ref cdr_object starts off in this state. This represents a channel that
00528  * has no Party B information itself.
00529  *
00530  * A \ref cdr_object from this state can go into any of the following states:
00531  * * \ref dial_state_fn_table
00532  * * \ref bridge_state_fn_table
00533  * * \ref finalized_state_fn_table
00534  */
00535 struct cdr_object_fn_table single_state_fn_table = {
00536    .name = "Single",
00537    .init_function = single_state_init_function,
00538    .process_party_a = base_process_party_a,
00539    .process_party_b = single_state_process_party_b,
00540    .process_dial_begin = single_state_process_dial_begin,
00541    .process_dial_end = base_process_dial_end,
00542    .process_bridge_enter = single_state_process_bridge_enter,
00543    .process_parking_bridge_enter = single_state_process_parking_bridge_enter,
00544    .process_bridge_leave = base_process_bridge_leave,
00545    .process_parked_channel = base_process_parked_channel,
00546 };
00547 
00548 static void dial_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot);
00549 static int dial_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer);
00550 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);
00551 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);
00552 
00553 /*!
00554  * \brief The virtual table for the Dial state.
00555  *
00556  * A \ref cdr_object that has begun a dial operation. This state is entered when
00557  * the Party A for a CDR is determined to be dialing out to a Party B or when
00558  * a CDR is for an originated channel (in which case the Party A information is
00559  * the originated channel, and there is no Party B).
00560  *
00561  * A \ref cdr_object from this state can go in any of the following states:
00562  * * \ref dialed_pending_state_fn_table
00563  * * \ref bridge_state_fn_table
00564  * * \ref finalized_state_fn_table
00565  */
00566 struct cdr_object_fn_table dial_state_fn_table = {
00567    .name = "Dial",
00568    .process_party_a = base_process_party_a,
00569    .process_party_b = dial_state_process_party_b,
00570    .process_dial_begin = dial_state_process_dial_begin,
00571    .process_dial_end = dial_state_process_dial_end,
00572    .process_bridge_enter = dial_state_process_bridge_enter,
00573    .process_bridge_leave = base_process_bridge_leave,
00574 };
00575 
00576 static int dialed_pending_state_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot);
00577 static int dialed_pending_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer);
00578 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);
00579 static int dialed_pending_state_process_parking_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
00580 
00581 /*!
00582  * \brief The virtual table for the Dialed Pending state.
00583  *
00584  * A \ref cdr_object that has successfully finished a dial operation, but we
00585  * don't know what they're going to do yet. It's theoretically possible to dial
00586  * a party and then have that party not be bridged with the caller; likewise,
00587  * an origination can complete and the channel go off and execute dialplan. The
00588  * pending state acts as a bridge between either:
00589  * * Entering a bridge
00590  * * Getting a new CDR for new dialplan execution
00591  * * Switching from being originated to executing dialplan
00592  *
00593  * A \ref cdr_object from this state can go in any of the following states:
00594  * * \ref single_state_fn_table
00595  * * \ref dialed_pending_state_fn_table
00596  * * \ref bridge_state_fn_table
00597  * * \ref finalized_state_fn_table
00598  */
00599 struct cdr_object_fn_table dialed_pending_state_fn_table = {
00600    .name = "DialedPending",
00601    .process_party_a = dialed_pending_state_process_party_a,
00602    .process_dial_begin = dialed_pending_state_process_dial_begin,
00603    .process_bridge_enter = dialed_pending_state_process_bridge_enter,
00604    .process_parking_bridge_enter = dialed_pending_state_process_parking_bridge_enter,
00605    .process_bridge_leave = base_process_bridge_leave,
00606    .process_parked_channel = base_process_parked_channel,
00607 };
00608 
00609 static void bridge_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot);
00610 static int bridge_state_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
00611 
00612 /*!
00613  * \brief The virtual table for the Bridged state
00614  *
00615  * A \ref cdr_object enters this state when it receives notification that the
00616  * channel has entered a bridge.
00617  *
00618  * A \ref cdr_object from this state can go to:
00619  * * \ref finalized_state_fn_table
00620  */
00621 struct cdr_object_fn_table bridge_state_fn_table = {
00622    .name = "Bridged",
00623    .process_party_a = base_process_party_a,
00624    .process_party_b = bridge_state_process_party_b,
00625    .process_bridge_leave = bridge_state_process_bridge_leave,
00626    .process_parked_channel = base_process_parked_channel,
00627 };
00628 
00629 static int parked_state_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel);
00630 
00631 /*!
00632  * \brief The virtual table for the Parked state
00633  *
00634  * Parking is weird. Unlike typical bridges, it has to be treated somewhat
00635  * uniquely - a channel in a parking bridge (which is a subclass of a holding
00636  * bridge) has to be handled as if the channel went into an application.
00637  * However, when the channel comes out, we need a new CDR - unlike the Single
00638  * state.
00639  */
00640 struct cdr_object_fn_table parked_state_fn_table = {
00641    .name = "Parked",
00642    .process_party_a = base_process_party_a,
00643    .process_bridge_leave = parked_state_process_bridge_leave,
00644    .process_parked_channel = base_process_parked_channel,
00645 };
00646 
00647 static void finalized_state_init_function(struct cdr_object *cdr);
00648 static int finalized_state_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot);
00649 
00650 /*!
00651  * \brief The virtual table for the finalized state.
00652  *
00653  * Once in the finalized state, the CDR is done. No modifications can be made
00654  * to the CDR.
00655  */
00656 struct cdr_object_fn_table finalized_state_fn_table = {
00657    .name = "Finalized",
00658    .init_function = finalized_state_init_function,
00659    .process_party_a = finalized_state_process_party_a,
00660    .process_bridge_enter = base_process_bridge_enter,
00661 };
00662 
00663 /*! \brief A wrapper object around a snapshot.
00664  * Fields that are mutable by the CDR engine are replicated here.
00665  */
00666 struct cdr_object_snapshot {
00667    struct ast_channel_snapshot *snapshot;  /*!< The channel snapshot */
00668    char userfield[AST_MAX_USER_FIELD];     /*!< Userfield for the channel */
00669    unsigned int flags;                     /*!< Specific flags for this party */
00670    struct varshead variables;              /*!< CDR variables for the channel */
00671 };
00672 
00673 /*! \brief An in-memory representation of an active CDR */
00674 struct cdr_object {
00675    struct cdr_object_snapshot party_a;     /*!< The Party A information */
00676    struct cdr_object_snapshot party_b;     /*!< The Party B information */
00677    struct cdr_object_fn_table *fn_table;   /*!< The current virtual table */
00678 
00679    enum ast_cdr_disposition disposition;   /*!< The disposition of the CDR */
00680    struct timeval start;                   /*!< When this CDR was created */
00681    struct timeval answer;                  /*!< Either when the channel was answered, or when the path between channels was established */
00682    struct timeval end;                     /*!< When this CDR was finalized */
00683    unsigned int sequence;                  /*!< A monotonically increasing number for each CDR */
00684    struct ast_flags flags;                 /*!< Flags on the CDR */
00685    AST_DECLARE_STRING_FIELDS(
00686       AST_STRING_FIELD(linkedid);         /*!< Linked ID. Cached here as it may change out from party A, which must be immutable */
00687       AST_STRING_FIELD(uniqueid);         /*!< Unique id of party A. Cached here as it is the primary key of this CDR */
00688       AST_STRING_FIELD(name);             /*!< Channel name of party A. Cached here as the party A address may change */
00689       AST_STRING_FIELD(bridge);           /*!< The bridge the party A happens to be in. */
00690       AST_STRING_FIELD(appl);             /*!< The last accepted application party A was in */
00691       AST_STRING_FIELD(data);             /*!< The data for the last accepted application party A was in */
00692       AST_STRING_FIELD(context);          /*!< The accepted context for Party A */
00693       AST_STRING_FIELD(exten);            /*!< The accepted extension for Party A */
00694    );
00695    struct cdr_object *next;                /*!< The next CDR object in the chain */
00696    struct cdr_object *last;                /*!< The last CDR object in the chain */
00697 };
00698 
00699 /*!
00700  * \brief Copy variables from one list to another
00701  * \param to_list destination
00702  * \param from_list source
00703  * \retval The number of copied variables
00704  */
00705 static int copy_variables(struct varshead *to_list, struct varshead *from_list)
00706 {
00707    struct ast_var_t *variables;
00708    struct ast_var_t *newvariable;
00709    const char *var;
00710    const char *val;
00711    int x = 0;
00712 
00713    AST_LIST_TRAVERSE(from_list, variables, entries) {
00714       var = ast_var_name(variables);
00715       if (ast_strlen_zero(var)) {
00716          continue;
00717       }
00718       val = ast_var_value(variables);
00719       if (ast_strlen_zero(val)) {
00720          continue;
00721       }
00722       newvariable = ast_var_assign(var, val);
00723       if (newvariable) {
00724          AST_LIST_INSERT_HEAD(to_list, newvariable, entries);
00725          ++x;
00726       }
00727    }
00728 
00729    return x;
00730 }
00731 
00732 /*!
00733  * \brief Delete all variables from a variable list
00734  * \param headp The head pointer to the variable list to delete
00735  */
00736 static void free_variables(struct varshead *headp)
00737 {
00738    struct ast_var_t *vardata;
00739 
00740    while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries))) {
00741       ast_var_delete(vardata);
00742    }
00743 }
00744 
00745 /*!
00746  * \brief Copy a snapshot and its details
00747  * \param dst The destination
00748  * \param src The source
00749  */
00750 static void cdr_object_snapshot_copy(struct cdr_object_snapshot *dst, struct cdr_object_snapshot *src)
00751 {
00752    if (dst->snapshot) {
00753       ao2_t_ref(dst->snapshot, -1, "release old snapshot during copy");
00754    }
00755    dst->snapshot = src->snapshot;
00756    ao2_t_ref(dst->snapshot, +1, "bump new snapshot during copy");
00757    strcpy(dst->userfield, src->userfield);
00758    dst->flags = src->flags;
00759    copy_variables(&dst->variables, &src->variables);
00760 }
00761 
00762 /*!
00763  * \brief Transition a \ref cdr_object to a new state
00764  * \param cdr The \ref cdr_object to transition
00765  * \param fn_table The \ref cdr_object_fn_table state to go to
00766  */
00767 static void cdr_object_transition_state(struct cdr_object *cdr, struct cdr_object_fn_table *fn_table)
00768 {
00769    RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
00770 
00771    CDR_DEBUG(mod_cfg, "%p - Transitioning CDR for %s from state %s to %s\n",
00772       cdr, cdr->party_a.snapshot->name,
00773       cdr->fn_table ? cdr->fn_table->name : "NONE", fn_table->name);
00774    cdr->fn_table = fn_table;
00775    if (cdr->fn_table->init_function) {
00776       cdr->fn_table->init_function(cdr);
00777    }
00778 }
00779 /*! \internal
00780  * \brief Hash function for containers of CDRs indexing by Party A uniqueid */
00781 static int cdr_object_channel_hash_fn(const void *obj, const int flags)
00782 {
00783    const struct cdr_object *cdr;
00784    const char *key;
00785 
00786    switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
00787    case OBJ_KEY:
00788       key = obj;
00789       break;
00790    case OBJ_POINTER:
00791       cdr = obj;
00792       key = cdr->uniqueid;
00793       break;
00794    default:
00795       ast_assert(0);
00796       return 0;
00797    }
00798    return ast_str_case_hash(key);
00799 }
00800 
00801 /*! \internal
00802  * \brief Comparison function for containers of CDRs indexing by Party A uniqueid
00803  */
00804 static int cdr_object_channel_cmp_fn(void *obj, void *arg, int flags)
00805 {
00806     struct cdr_object *left = obj;
00807     struct cdr_object *right = arg;
00808     const char *right_key = arg;
00809     int cmp;
00810 
00811     switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
00812     case OBJ_POINTER:
00813         right_key = right->uniqueid;
00814         /* Fall through */
00815     case OBJ_KEY:
00816         cmp = strcmp(left->uniqueid, right_key);
00817         break;
00818     case OBJ_PARTIAL_KEY:
00819         /*
00820          * We could also use a partial key struct containing a length
00821          * so strlen() does not get called for every comparison instead.
00822          */
00823         cmp = strncmp(left->uniqueid, right_key, strlen(right_key));
00824         break;
00825     default:
00826         /* Sort can only work on something with a full or partial key. */
00827         ast_assert(0);
00828         cmp = 0;
00829         break;
00830     }
00831     return cmp ? 0 : CMP_MATCH;
00832 }
00833 
00834 /*!
00835  * \brief \ref cdr_object Destructor
00836  */
00837 static void cdr_object_dtor(void *obj)
00838 {
00839    struct cdr_object *cdr = obj;
00840    struct ast_var_t *it_var;
00841 
00842    ao2_cleanup(cdr->party_a.snapshot);
00843    ao2_cleanup(cdr->party_b.snapshot);
00844    while ((it_var = AST_LIST_REMOVE_HEAD(&cdr->party_a.variables, entries))) {
00845       ast_var_delete(it_var);
00846    }
00847    while ((it_var = AST_LIST_REMOVE_HEAD(&cdr->party_b.variables, entries))) {
00848       ast_var_delete(it_var);
00849    }
00850    ast_string_field_free_memory(cdr);
00851 
00852    ao2_cleanup(cdr->next);
00853 }
00854 
00855 /*!
00856  * \brief \ref cdr_object constructor
00857  * \param chan The \ref ast_channel_snapshot that is the CDR's Party A
00858  *
00859  * This implicitly sets the state of the newly created CDR to the Single state
00860  * (\ref single_state_fn_table)
00861  */
00862 static struct cdr_object *cdr_object_alloc(struct ast_channel_snapshot *chan)
00863 {
00864    RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
00865    struct cdr_object *cdr;
00866 
00867    ast_assert(chan != NULL);
00868 
00869    cdr = ao2_alloc(sizeof(*cdr), cdr_object_dtor);
00870    if (!cdr) {
00871       return NULL;
00872    }
00873    cdr->last = cdr;
00874    if (ast_string_field_init(cdr, 64)) {
00875       ao2_cleanup(cdr);
00876       return NULL;
00877    }
00878    ast_string_field_set(cdr, uniqueid, chan->uniqueid);
00879    ast_string_field_set(cdr, name, chan->name);
00880    ast_string_field_set(cdr, linkedid, chan->linkedid);
00881    cdr->disposition = AST_CDR_NULL;
00882    cdr->sequence = ast_atomic_fetchadd_int(&global_cdr_sequence, +1);
00883 
00884    cdr->party_a.snapshot = chan;
00885    ao2_t_ref(cdr->party_a.snapshot, +1, "bump snapshot during CDR creation");
00886 
00887    CDR_DEBUG(mod_cfg, "%p - Created CDR for channel %s\n", cdr, chan->name);
00888 
00889    cdr_object_transition_state(cdr, &single_state_fn_table);
00890 
00891    return cdr;
00892 }
00893 
00894 /*!
00895  * \brief Create a new \ref cdr_object and append it to an existing chain
00896  * \param cdr The \ref cdr_object to append to
00897  */
00898 static struct cdr_object *cdr_object_create_and_append(struct cdr_object *cdr)
00899 {
00900    struct cdr_object *new_cdr;
00901    struct cdr_object *it_cdr;
00902    struct cdr_object *cdr_last;
00903 
00904    cdr_last = cdr->last;
00905    new_cdr = cdr_object_alloc(cdr_last->party_a.snapshot);
00906    if (!new_cdr) {
00907       return NULL;
00908    }
00909    new_cdr->disposition = AST_CDR_NULL;
00910 
00911    /* Copy over the linkedid, as it may have changed */
00912    ast_string_field_set(new_cdr, linkedid, cdr_last->linkedid);
00913    ast_string_field_set(new_cdr, appl, cdr_last->appl);
00914    ast_string_field_set(new_cdr, data, cdr_last->data);
00915 
00916    /* Copy over other Party A information */
00917    cdr_object_snapshot_copy(&new_cdr->party_a, &cdr_last->party_a);
00918 
00919    /* Append the CDR to the end of the list */
00920    for (it_cdr = cdr; it_cdr->next; it_cdr = it_cdr->next) {
00921       it_cdr->last = new_cdr;
00922    }
00923    it_cdr->last = new_cdr;
00924    it_cdr->next = new_cdr;
00925 
00926    return new_cdr;
00927 }
00928 
00929 /*!
00930  * \brief Return whether or not a channel has changed its state in the dialplan, subject
00931  * to endbeforehexten logic
00932  *
00933  * \param old_snapshot The previous state
00934  * \param new_snapshot The new state
00935  *
00936  * \retval 0 if the state has not changed
00937  * \retval 1 if the state changed
00938  */
00939 static int snapshot_cep_changed(struct ast_channel_snapshot *old_snapshot,
00940    struct ast_channel_snapshot *new_snapshot)
00941 {
00942    RAII_VAR(struct module_config *, mod_cfg,
00943       ao2_global_obj_ref(module_configs), ao2_cleanup);
00944 
00945    /* If we ignore hangup logic, don't indicate that we're executing anything new */
00946    if (ast_test_flag(&mod_cfg->general->settings, CDR_END_BEFORE_H_EXTEN)
00947       && ast_test_flag(&new_snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)) {
00948       return 0;
00949    }
00950 
00951    /* When Party A is originated to an application and the application exits, the stack
00952     * will attempt to clear the application and restore the dummy originate application
00953     * of "AppDialX". Ignore application changes to AppDialX as a result.
00954     */
00955    if (strcmp(new_snapshot->appl, old_snapshot->appl) && strncasecmp(new_snapshot->appl, "appdial", 7)
00956       && (strcmp(new_snapshot->context, old_snapshot->context)
00957       || strcmp(new_snapshot->exten, old_snapshot->exten)
00958       || new_snapshot->priority != old_snapshot->priority)) {
00959       return 1;
00960    }
00961 
00962    return 0;
00963 }
00964 
00965 /*!
00966  * \brief Return whether or not a \ref ast_channel_snapshot is for a channel
00967  * that was created as the result of a dial operation
00968  *
00969  * \retval 0 the channel was not created as the result of a dial
00970  * \retval 1 the channel was created as the result of a dial
00971  */
00972 static int snapshot_is_dialed(struct ast_channel_snapshot *snapshot)
00973 {
00974    return (ast_test_flag(&snapshot->flags, AST_FLAG_OUTGOING)
00975          && !(ast_test_flag(&snapshot->flags, AST_FLAG_ORIGINATED)));
00976 }
00977 
00978 /*!
00979  * \brief Given two CDR snapshots, figure out who should be Party A for the
00980  * resulting CDR
00981  * \param left One of the snapshots
00982  * \param right The other snapshot
00983  * \retval The snapshot that won
00984  */
00985 static struct cdr_object_snapshot *cdr_object_pick_party_a(struct cdr_object_snapshot *left, struct cdr_object_snapshot *right)
00986 {
00987    /* Check whether or not the party is dialed. A dialed party is never the
00988     * Party A with a party that was not dialed.
00989     */
00990    if (!snapshot_is_dialed(left->snapshot) && snapshot_is_dialed(right->snapshot)) {
00991       return left;
00992    } else if (snapshot_is_dialed(left->snapshot) && !snapshot_is_dialed(right->snapshot)) {
00993       return right;
00994    }
00995 
00996    /* Try the Party A flag */
00997    if (ast_test_flag(left, AST_CDR_FLAG_PARTY_A) && !ast_test_flag(right, AST_CDR_FLAG_PARTY_A)) {
00998       return left;
00999    } else if (!ast_test_flag(right, AST_CDR_FLAG_PARTY_A) && ast_test_flag(right, AST_CDR_FLAG_PARTY_A)) {
01000       return right;
01001    }
01002 
01003    /* Neither party is dialed and neither has the Party A flag - defer to
01004     * creation time */
01005    if (left->snapshot->creationtime.tv_sec < right->snapshot->creationtime.tv_sec) {
01006       return left;
01007    } else if (left->snapshot->creationtime.tv_sec > right->snapshot->creationtime.tv_sec) {
01008       return right;
01009    } else if (left->snapshot->creationtime.tv_usec > right->snapshot->creationtime.tv_usec) {
01010       return right;
01011    } else {
01012       /* Okay, fine, take the left one */
01013       return left;
01014    }
01015 }
01016 
01017 /*!
01018  * Compute the duration for a \ref cdr_object
01019  */
01020 static long cdr_object_get_duration(struct cdr_object *cdr)
01021 {
01022    return (long)(ast_tvdiff_ms(ast_tvzero(cdr->end) ? ast_tvnow() : cdr->end, cdr->start) / 1000);
01023 }
01024 
01025 /*!
01026  * \brief Compute the billsec for a \ref cdr_object
01027  */
01028 static long cdr_object_get_billsec(struct cdr_object *cdr)
01029 {
01030    RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
01031    long int ms;
01032 
01033    if (ast_tvzero(cdr->answer)) {
01034       return 0;
01035    }
01036    ms = ast_tvdiff_ms(ast_tvzero(cdr->end) ? ast_tvnow() : cdr->end, cdr->answer);
01037    if (ast_test_flag(&mod_cfg->general->settings, CDR_INITIATED_SECONDS)
01038       && (ms % 1000 >= 500)) {
01039       ms = (ms / 1000) + 1;
01040    } else {
01041       ms = ms / 1000;
01042    }
01043 
01044    return ms;
01045 }
01046 
01047 /*!
01048  * \internal
01049  * \brief Set a variable on a CDR object
01050  *
01051  * \param headp The header pointer to the variable to set
01052  * \param name The name of the variable
01053  * \param value The value of the variable
01054  */
01055 static void set_variable(struct varshead *headp, const char *name, const char *value)
01056 {
01057    struct ast_var_t *newvariable;
01058 
01059    AST_LIST_TRAVERSE_SAFE_BEGIN(headp, newvariable, entries) {
01060       if (!strcasecmp(ast_var_name(newvariable), name)) {
01061          AST_LIST_REMOVE_CURRENT(entries);
01062          ast_var_delete(newvariable);
01063          break;
01064       }
01065    }
01066    AST_LIST_TRAVERSE_SAFE_END;
01067 
01068    if (value && (newvariable = ast_var_assign(name, value))) {
01069       AST_LIST_INSERT_HEAD(headp, newvariable, entries);
01070    }
01071 }
01072 
01073 /*!
01074  * \brief Create a chain of \ref ast_cdr objects from a chain of \ref cdr_object
01075  * suitable for consumption by the registered CDR backends
01076  * \param cdr The \ref cdr_object to convert to a public record
01077  * \retval A chain of \ref ast_cdr objects on success
01078  * \retval NULL on failure
01079  */
01080 static struct ast_cdr *cdr_object_create_public_records(struct cdr_object *cdr)
01081 {
01082    struct ast_cdr *pub_cdr = NULL, *cdr_prev = NULL;
01083    struct cdr_object *it_cdr;
01084    struct ast_var_t *it_var, *it_copy_var;
01085    struct ast_channel_snapshot *party_a;
01086    struct ast_channel_snapshot *party_b;
01087 
01088    for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
01089       struct ast_cdr *cdr_copy;
01090 
01091       /* Don't create records for CDRs where the party A was a dialed channel */
01092       if (snapshot_is_dialed(it_cdr->party_a.snapshot) && !it_cdr->party_b.snapshot) {
01093          ast_debug(1, "CDR for %s is dialed and has no Party B; discarding\n",
01094             it_cdr->party_a.snapshot->name);
01095          continue;
01096       }
01097 
01098       cdr_copy = ast_calloc(1, sizeof(*cdr_copy));
01099       if (!cdr_copy) {
01100          ast_free(pub_cdr);
01101          return NULL;
01102       }
01103 
01104       party_a = it_cdr->party_a.snapshot;
01105       party_b = it_cdr->party_b.snapshot;
01106 
01107       /* Party A */
01108       ast_assert(party_a != NULL);
01109       ast_copy_string(cdr_copy->accountcode, party_a->accountcode, sizeof(cdr_copy->accountcode));
01110       cdr_copy->amaflags = party_a->amaflags;
01111       ast_copy_string(cdr_copy->channel, party_a->name, sizeof(cdr_copy->channel));
01112       ast_callerid_merge(cdr_copy->clid, sizeof(cdr_copy->clid), party_a->caller_name, party_a->caller_number, "");
01113       ast_copy_string(cdr_copy->src, party_a->caller_number, sizeof(cdr_copy->src));
01114       ast_copy_string(cdr_copy->uniqueid, party_a->uniqueid, sizeof(cdr_copy->uniqueid));
01115       ast_copy_string(cdr_copy->lastapp, it_cdr->appl, sizeof(cdr_copy->lastapp));
01116       ast_copy_string(cdr_copy->lastdata, it_cdr->data, sizeof(cdr_copy->lastdata));
01117       ast_copy_string(cdr_copy->dst, it_cdr->exten, sizeof(cdr_copy->dst));
01118       ast_copy_string(cdr_copy->dcontext, it_cdr->context, sizeof(cdr_copy->dcontext));
01119 
01120       /* Party B */
01121       if (party_b) {
01122          ast_copy_string(cdr_copy->dstchannel, party_b->name, sizeof(cdr_copy->dstchannel));
01123          ast_copy_string(cdr_copy->peeraccount, party_b->accountcode, sizeof(cdr_copy->peeraccount));
01124          if (!ast_strlen_zero(it_cdr->party_b.userfield)) {
01125             snprintf(cdr_copy->userfield, sizeof(cdr_copy->userfield), "%s;%s", it_cdr->party_a.userfield, it_cdr->party_b.userfield);
01126          }
01127       }
01128       if (ast_strlen_zero(cdr_copy->userfield) && !ast_strlen_zero(it_cdr->party_a.userfield)) {
01129          ast_copy_string(cdr_copy->userfield, it_cdr->party_a.userfield, sizeof(cdr_copy->userfield));
01130       }
01131 
01132       /* Timestamps/durations */
01133       cdr_copy->start = it_cdr->start;
01134       cdr_copy->answer = it_cdr->answer;
01135       cdr_copy->end = it_cdr->end;
01136       cdr_copy->billsec = cdr_object_get_billsec(it_cdr);
01137       cdr_copy->duration = cdr_object_get_duration(it_cdr);
01138 
01139       /* Flags and IDs */
01140       ast_copy_flags(cdr_copy, &it_cdr->flags, AST_FLAGS_ALL);
01141       ast_copy_string(cdr_copy->linkedid, it_cdr->linkedid, sizeof(cdr_copy->linkedid));
01142       cdr_copy->disposition = it_cdr->disposition;
01143       cdr_copy->sequence = it_cdr->sequence;
01144 
01145       /* Variables */
01146       copy_variables(&cdr_copy->varshead, &it_cdr->party_a.variables);
01147       AST_LIST_TRAVERSE(&it_cdr->party_b.variables, it_var, entries) {
01148          int found = 0;
01149          struct ast_var_t *newvariable;
01150          AST_LIST_TRAVERSE(&cdr_copy->varshead, it_copy_var, entries) {
01151             if (!strcasecmp(ast_var_name(it_var), ast_var_name(it_copy_var))) {
01152                found = 1;
01153                break;
01154             }
01155          }
01156          if (!found && (newvariable = ast_var_assign(ast_var_name(it_var), ast_var_value(it_var)))) {
01157             AST_LIST_INSERT_TAIL(&cdr_copy->varshead, newvariable, entries);
01158          }
01159       }
01160 
01161       if (!pub_cdr) {
01162          pub_cdr = cdr_copy;
01163          cdr_prev = pub_cdr;
01164       } else {
01165          cdr_prev->next = cdr_copy;
01166          cdr_prev = cdr_copy;
01167       }
01168    }
01169 
01170    return pub_cdr;
01171 }
01172 
01173 /*!
01174  * \brief Dispatch a CDR.
01175  * \param cdr The \ref cdr_object to dispatch
01176  *
01177  * This will create a \ref ast_cdr object and publish it to the various backends
01178  */
01179 static void cdr_object_dispatch(struct cdr_object *cdr)
01180 {
01181    RAII_VAR(struct module_config *, mod_cfg,
01182          ao2_global_obj_ref(module_configs), ao2_cleanup);
01183    struct ast_cdr *pub_cdr;
01184 
01185    CDR_DEBUG(mod_cfg, "%p - Dispatching CDR for Party A %s, Party B %s\n", cdr,
01186          cdr->party_a.snapshot->name,
01187          cdr->party_b.snapshot ? cdr->party_b.snapshot->name : "<none>");
01188    pub_cdr = cdr_object_create_public_records(cdr);
01189    cdr_detach(pub_cdr);
01190 }
01191 
01192 /*!
01193  * \brief Set the disposition on a \ref cdr_object based on a hangupcause code
01194  * \param cdr The \ref cdr_object
01195  * \param hangupcause The Asterisk hangup cause code
01196  */
01197 static void cdr_object_set_disposition(struct cdr_object *cdr, int hangupcause)
01198 {
01199    RAII_VAR(struct module_config *, mod_cfg,
01200          ao2_global_obj_ref(module_configs), ao2_cleanup);
01201 
01202    /* Change the disposition based on the hang up cause */
01203    switch (hangupcause) {
01204    case AST_CAUSE_BUSY:
01205       cdr->disposition = AST_CDR_BUSY;
01206       break;
01207    case AST_CAUSE_CONGESTION:
01208       if (!ast_test_flag(&mod_cfg->general->settings, CDR_CONGESTION)) {
01209          cdr->disposition = AST_CDR_FAILED;
01210       } else {
01211          cdr->disposition = AST_CDR_CONGESTION;
01212       }
01213       break;
01214    case AST_CAUSE_NO_ROUTE_DESTINATION:
01215    case AST_CAUSE_UNREGISTERED:
01216       cdr->disposition = AST_CDR_FAILED;
01217       break;
01218    case AST_CAUSE_NORMAL_CLEARING:
01219    case AST_CAUSE_NO_ANSWER:
01220       cdr->disposition = AST_CDR_NOANSWER;
01221       break;
01222    default:
01223       break;
01224    }
01225 }
01226 
01227 /*!
01228  * \brief Finalize a CDR.
01229  *
01230  * This function is safe to call multiple times. Note that you can call this
01231  * explicitly before going to the finalized state if there's a chance the CDR
01232  * will be re-activated, in which case the \ref cdr_object's end time should be
01233  * cleared. This function is implicitly called when a CDR transitions to the
01234  * finalized state and right before it is dispatched
01235  *
01236  * \param cdr_object The CDR to finalize
01237  */
01238 static void cdr_object_finalize(struct cdr_object *cdr)
01239 {
01240    if (!ast_tvzero(cdr->end)) {
01241       return;
01242    }
01243    cdr->end = ast_tvnow();
01244 
01245    if (cdr->disposition == AST_CDR_NULL) {
01246       if (!ast_tvzero(cdr->answer)) {
01247          cdr->disposition = AST_CDR_ANSWERED;
01248       } else if (cdr->party_a.snapshot->hangupcause) {
01249          cdr_object_set_disposition(cdr, cdr->party_a.snapshot->hangupcause);
01250       } else if (cdr->party_b.snapshot && cdr->party_b.snapshot->hangupcause) {
01251          cdr_object_set_disposition(cdr, cdr->party_b.snapshot->hangupcause);
01252       } else {
01253          cdr->disposition = AST_CDR_FAILED;
01254       }
01255    }
01256 
01257    /* tv_usec is suseconds_t, which could be int or long */
01258    ast_debug(1, "Finalized CDR for %s - start %ld.%06ld answer %ld.%06ld end %ld.%06ld dispo %s\n",
01259          cdr->party_a.snapshot->name,
01260          (long)cdr->start.tv_sec,
01261          (long)cdr->start.tv_usec,
01262          (long)cdr->answer.tv_sec,
01263          (long)cdr->answer.tv_usec,
01264          (long)cdr->end.tv_sec,
01265          (long)cdr->end.tv_usec,
01266          ast_cdr_disp2str(cdr->disposition));
01267 }
01268 
01269 /*!
01270  * \brief Check to see if a CDR needs to move to the finalized state because
01271  * its Party A hungup.
01272  */
01273 static void cdr_object_check_party_a_hangup(struct cdr_object *cdr)
01274 {
01275    RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
01276 
01277    if (ast_test_flag(&mod_cfg->general->settings, CDR_END_BEFORE_H_EXTEN)
01278       && ast_test_flag(&cdr->party_a.snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)) {
01279       cdr_object_finalize(cdr);
01280    }
01281 
01282    if (ast_test_flag(&cdr->party_a.snapshot->flags, AST_FLAG_DEAD)
01283       && cdr->fn_table != &finalized_state_fn_table) {
01284       cdr_object_transition_state(cdr, &finalized_state_fn_table);
01285    }
01286 }
01287 
01288 /*!
01289  * \brief Check to see if a CDR needs to be answered based on its Party A.
01290  * Note that this is safe to call as much as you want - we won't answer twice
01291  */
01292 static void cdr_object_check_party_a_answer(struct cdr_object *cdr) {
01293    RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
01294 
01295    if (cdr->party_a.snapshot->state == AST_STATE_UP && ast_tvzero(cdr->answer)) {
01296       cdr->answer = ast_tvnow();
01297       /* tv_usec is suseconds_t, which could be int or long */
01298       CDR_DEBUG(mod_cfg, "%p - Set answered time to %ld.%06ld\n", cdr,
01299          (long)cdr->answer.tv_sec,
01300          (long)cdr->answer.tv_usec);
01301    }
01302 }
01303 
01304 /* \brief Set Caller ID information on a CDR */
01305 static void cdr_object_update_cid(struct cdr_object_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot)
01306 {
01307    if (!old_snapshot->snapshot) {
01308       set_variable(&old_snapshot->variables, "dnid", new_snapshot->caller_dnid);
01309       set_variable(&old_snapshot->variables, "callingsubaddr", new_snapshot->caller_subaddr);
01310       set_variable(&old_snapshot->variables, "calledsubaddr", new_snapshot->dialed_subaddr);
01311       return;
01312    }
01313    if (!strcmp(old_snapshot->snapshot->caller_dnid, new_snapshot->caller_dnid)) {
01314       set_variable(&old_snapshot->variables, "dnid", new_snapshot->caller_dnid);
01315    }
01316    if (!strcmp(old_snapshot->snapshot->caller_subaddr, new_snapshot->caller_subaddr)) {
01317       set_variable(&old_snapshot->variables, "callingsubaddr", new_snapshot->caller_subaddr);
01318    }
01319    if (!strcmp(old_snapshot->snapshot->dialed_subaddr, new_snapshot->dialed_subaddr)) {
01320       set_variable(&old_snapshot->variables, "calledsubaddr", new_snapshot->dialed_subaddr);
01321    }
01322 }
01323 
01324 /*!
01325  * \brief Swap an old \ref cdr_object_snapshot's \ref ast_channel_snapshot for
01326  * a new \ref ast_channel_snapshot
01327  * \param old_snapshot The old \ref cdr_object_snapshot
01328  * \param new_snapshot The new \ref ast_channel_snapshot for old_snapshot
01329  */
01330 static void cdr_object_swap_snapshot(struct cdr_object_snapshot *old_snapshot,
01331       struct ast_channel_snapshot *new_snapshot)
01332 {
01333    cdr_object_update_cid(old_snapshot, new_snapshot);
01334    if (old_snapshot->snapshot) {
01335       ao2_t_ref(old_snapshot->snapshot, -1, "Drop ref for swap");
01336    }
01337    ao2_t_ref(new_snapshot, +1, "Bump ref for swap");
01338    old_snapshot->snapshot = new_snapshot;
01339 }
01340 
01341 /* BASE METHOD IMPLEMENTATIONS */
01342 
01343 static int base_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
01344 {
01345    RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
01346 
01347    ast_assert(strcasecmp(snapshot->name, cdr->party_a.snapshot->name) == 0);
01348 
01349    /* Ignore any snapshots from a dead or dying channel */
01350    if (ast_test_flag(&snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)
01351          && ast_test_flag(&mod_cfg->general->settings, CDR_END_BEFORE_H_EXTEN)) {
01352       cdr_object_check_party_a_hangup(cdr);
01353       return 0;
01354    }
01355 
01356    /*
01357     * Only record the context and extension if we aren't in a subroutine, or if
01358     * we are executing hangup logic.
01359     */
01360    if (!ast_test_flag(&snapshot->flags, AST_FLAG_SUBROUTINE_EXEC)
01361       || ast_test_flag(&snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)) {
01362       ast_string_field_set(cdr, context, snapshot->context);
01363       ast_string_field_set(cdr, exten, snapshot->exten);
01364    }
01365 
01366    cdr_object_swap_snapshot(&cdr->party_a, snapshot);
01367 
01368    /* When Party A is originated to an application and the application exits, the stack
01369     * will attempt to clear the application and restore the dummy originate application
01370     * of "AppDialX". Prevent that, and any other application changes we might not want
01371     * here.
01372     */
01373    if (!ast_strlen_zero(snapshot->appl)
01374          && (strncasecmp(snapshot->appl, "appdial", 7) || ast_strlen_zero(cdr->appl))
01375          && !ast_test_flag(&cdr->flags, AST_CDR_LOCK_APP)) {
01376       ast_string_field_set(cdr, appl, snapshot->appl);
01377       ast_string_field_set(cdr, data, snapshot->data);
01378 
01379       /* Dial (app_dial) is a special case. Because pre-dial handlers, which
01380        * execute before the dial begins, will alter the application/data to
01381        * something people typically don't want to see, if we see a channel enter
01382        * into Dial here, we set the appl/data accordingly and lock it.
01383        */
01384       if (!strcmp(snapshot->appl, "Dial")) {
01385          ast_set_flag(&cdr->flags, AST_CDR_LOCK_APP);
01386       }
01387    }
01388 
01389    ast_string_field_set(cdr, linkedid, snapshot->linkedid);
01390    cdr_object_check_party_a_answer(cdr);
01391    cdr_object_check_party_a_hangup(cdr);
01392 
01393    return 0;
01394 }
01395 
01396 static int base_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
01397 {
01398    /* In general, most things shouldn't get a bridge leave */
01399    ast_assert(0);
01400    return 1;
01401 }
01402 
01403 static int base_process_dial_end(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer, const char *dial_status)
01404 {
01405    /* In general, most things shouldn't get a dial end. */
01406    ast_assert(0);
01407    return 0;
01408 }
01409 
01410 static enum process_bridge_enter_results base_process_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
01411 {
01412    /* Base process bridge enter simply indicates that we can't handle it */
01413    return BRIDGE_ENTER_NEED_CDR;
01414 }
01415 
01416 static int base_process_parked_channel(struct cdr_object *cdr, struct ast_parked_call_payload *parking_info)
01417 {
01418    char park_info[128];
01419 
01420    ast_assert(!strcasecmp(parking_info->parkee->name, cdr->party_a.snapshot->name));
01421 
01422    /* Update Party A information regardless */
01423    cdr->fn_table->process_party_a(cdr, parking_info->parkee);
01424 
01425    /* Fake out where we're parked */
01426    ast_string_field_set(cdr, appl, "Park");
01427    snprintf(park_info, sizeof(park_info), "%s:%u", parking_info->parkinglot, parking_info->parkingspace);
01428    ast_string_field_set(cdr, data, park_info);
01429 
01430    /* Prevent any further changes to the App/Data fields for this record */
01431    ast_set_flag(&cdr->flags, AST_CDR_LOCK_APP);
01432 
01433    return 0;
01434 }
01435 
01436 /* SINGLE STATE */
01437 
01438 static void single_state_init_function(struct cdr_object *cdr) {
01439    cdr->start = ast_tvnow();
01440    cdr_object_check_party_a_answer(cdr);
01441 }
01442 
01443 static void single_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
01444 {
01445    /* This should never happen! */
01446    ast_assert(cdr->party_b.snapshot == NULL);
01447    ast_assert(0);
01448    return;
01449 }
01450 
01451 static int single_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer)
01452 {
01453    RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
01454 
01455    if (caller && !strcasecmp(cdr->party_a.snapshot->name, caller->name)) {
01456       base_process_party_a(cdr, caller);
01457       CDR_DEBUG(mod_cfg, "%p - Updated Party A %s snapshot\n", cdr,
01458             cdr->party_a.snapshot->name);
01459       cdr_object_swap_snapshot(&cdr->party_b, peer);
01460       CDR_DEBUG(mod_cfg, "%p - Updated Party B %s snapshot\n", cdr,
01461             cdr->party_b.snapshot->name);
01462 
01463       /* If we have two parties, lock the application that caused the
01464        * two parties to be associated. This prevents mid-call event
01465        * macros/gosubs from perturbing the CDR application/data
01466        */
01467       ast_set_flag(&cdr->flags, AST_CDR_LOCK_APP);
01468    } else if (!strcasecmp(cdr->party_a.snapshot->name, peer->name)) {
01469       /* We're the entity being dialed, i.e., outbound origination */
01470       base_process_party_a(cdr, peer);
01471       CDR_DEBUG(mod_cfg, "%p - Updated Party A %s snapshot\n", cdr,
01472             cdr->party_a.snapshot->name);
01473    }
01474 
01475    cdr_object_transition_state(cdr, &dial_state_fn_table);
01476    return 0;
01477 }
01478 
01479 /*!
01480  * \brief Handle a comparison between our \ref cdr_object and a \ref cdr_object
01481  * already in the bridge while in the Single state. The goal of this is to find
01482  * a Party B for our CDR.
01483  *
01484  * \param cdr Our \ref cdr_object in the Single state
01485  * \param cand_cdr The \ref cdr_object already in the Bridge state
01486  *
01487  * \retval 0 The cand_cdr had a Party A or Party B that we could use as our
01488  * Party B
01489  * \retval 1 No party in the cand_cdr could be used as our Party B
01490  */
01491 static int single_state_bridge_enter_comparison(struct cdr_object *cdr,
01492       struct cdr_object *cand_cdr)
01493 {
01494    RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
01495    struct cdr_object_snapshot *party_a;
01496 
01497    /* Don't match on ourselves */
01498    if (!strcasecmp(cdr->party_a.snapshot->name, cand_cdr->party_a.snapshot->name)) {
01499       return 1;
01500    }
01501 
01502    /* Try the candidate CDR's Party A first */
01503    party_a = cdr_object_pick_party_a(&cdr->party_a, &cand_cdr->party_a);
01504    if (!strcasecmp(party_a->snapshot->name, cdr->party_a.snapshot->name)) {
01505       CDR_DEBUG(mod_cfg, "%p - Party A %s has new Party B %s\n",
01506          cdr, cdr->party_a.snapshot->name, cand_cdr->party_a.snapshot->name);
01507       cdr_object_snapshot_copy(&cdr->party_b, &cand_cdr->party_a);
01508       if (!cand_cdr->party_b.snapshot) {
01509          /* We just stole them - finalize their CDR. Note that this won't
01510           * transition their state, it just sets the end time and the
01511           * disposition - if we need to re-activate them later, we can.
01512           */
01513          cdr_object_finalize(cand_cdr);
01514       }
01515       return 0;
01516    }
01517 
01518    /* Try their Party B, unless it's us */
01519    if (!cand_cdr->party_b.snapshot
01520       || !strcasecmp(cdr->party_a.snapshot->name, cand_cdr->party_b.snapshot->name)) {
01521       return 1;
01522    }
01523    party_a = cdr_object_pick_party_a(&cdr->party_a, &cand_cdr->party_b);
01524    if (!strcasecmp(party_a->snapshot->name, cdr->party_a.snapshot->name)) {
01525       CDR_DEBUG(mod_cfg, "%p - Party A %s has new Party B %s\n",
01526          cdr, cdr->party_a.snapshot->name, cand_cdr->party_b.snapshot->name);
01527       cdr_object_snapshot_copy(&cdr->party_b, &cand_cdr->party_b);
01528       return 0;
01529    }
01530 
01531    return 1;
01532 }
01533 
01534 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)
01535 {
01536    struct ao2_iterator it_cdrs;
01537    char *channel_id;
01538    int success = 0;
01539 
01540    ast_string_field_set(cdr, bridge, bridge->uniqueid);
01541 
01542    if (ao2_container_count(bridge->channels) == 1) {
01543       /* No one in the bridge yet but us! */
01544       cdr_object_transition_state(cdr, &bridge_state_fn_table);
01545       return BRIDGE_ENTER_ONLY_PARTY;
01546    }
01547 
01548    for (it_cdrs = ao2_iterator_init(bridge->channels, 0);
01549       !success && (channel_id = ao2_iterator_next(&it_cdrs));
01550       ao2_ref(channel_id, -1)) {
01551       RAII_VAR(struct cdr_object *, cand_cdr_master,
01552          ao2_find(active_cdrs_by_channel, channel_id, OBJ_KEY),
01553          ao2_cleanup);
01554       struct cdr_object *cand_cdr;
01555 
01556       if (!cand_cdr_master) {
01557          continue;
01558       }
01559 
01560       ao2_lock(cand_cdr_master);
01561       for (cand_cdr = cand_cdr_master; cand_cdr; cand_cdr = cand_cdr->next) {
01562          /* Skip any records that are not in a bridge or in this bridge.
01563           * I'm not sure how that would happen, but it pays to be careful. */
01564          if (cand_cdr->fn_table != &bridge_state_fn_table ||
01565                strcmp(cdr->bridge, cand_cdr->bridge)) {
01566             continue;
01567          }
01568 
01569          if (single_state_bridge_enter_comparison(cdr, cand_cdr)) {
01570             continue;
01571          }
01572          /* We successfully got a party B - break out */
01573          success = 1;
01574          break;
01575       }
01576       ao2_unlock(cand_cdr_master);
01577    }
01578    ao2_iterator_destroy(&it_cdrs);
01579 
01580    /* We always transition state, even if we didn't get a peer */
01581    cdr_object_transition_state(cdr, &bridge_state_fn_table);
01582 
01583    /* Success implies that we have a Party B */
01584    if (success) {
01585       return BRIDGE_ENTER_OBTAINED_PARTY_B;
01586    }
01587 
01588    return BRIDGE_ENTER_NO_PARTY_B;
01589 }
01590 
01591 static int single_state_process_parking_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
01592 {
01593    cdr_object_transition_state(cdr, &parked_state_fn_table);
01594    return 0;
01595 }
01596 
01597 
01598 /* DIAL STATE */
01599 
01600 static void dial_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
01601 {
01602    ast_assert(snapshot != NULL);
01603 
01604    if (!cdr->party_b.snapshot
01605       || strcasecmp(cdr->party_b.snapshot->name, snapshot->name)) {
01606       return;
01607    }
01608    cdr_object_swap_snapshot(&cdr->party_b, snapshot);
01609 
01610    /* If party B hangs up, finalize this CDR */
01611    if (ast_test_flag(&cdr->party_b.snapshot->flags, AST_FLAG_DEAD)) {
01612       cdr_object_transition_state(cdr, &finalized_state_fn_table);
01613    }
01614 }
01615 
01616 static int dial_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer)
01617 {
01618    /* Don't process a begin dial here. A party A already in the dial state will
01619     * who receives a dial begin for something else will be handled by the
01620     * message router callback and will add a new CDR for the party A */
01621    return 1;
01622 }
01623 
01624 /*!
01625  * \internal
01626  * \brief Convert a dial status to a CDR disposition
01627  */
01628 static enum ast_cdr_disposition dial_status_to_disposition(const char *dial_status)
01629 {
01630    RAII_VAR(struct module_config *, mod_cfg,
01631       ao2_global_obj_ref(module_configs), ao2_cleanup);
01632 
01633    if (!strcmp(dial_status, "ANSWER")) {
01634       return AST_CDR_ANSWERED;
01635    } else if (!strcmp(dial_status, "BUSY")) {
01636       return AST_CDR_BUSY;
01637    } else if (!strcmp(dial_status, "CANCEL") || !strcmp(dial_status, "NOANSWER")) {
01638       return AST_CDR_NOANSWER;
01639    } else if (!strcmp(dial_status, "CONGESTION")) {
01640       if (!ast_test_flag(&mod_cfg->general->settings, CDR_CONGESTION)) {
01641          return AST_CDR_FAILED;
01642       } else {
01643          return AST_CDR_CONGESTION;
01644       }
01645    } else if (!strcmp(dial_status, "FAILED")) {
01646       return AST_CDR_FAILED;
01647    }
01648    return AST_CDR_FAILED;
01649 }
01650 
01651 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)
01652 {
01653    struct ast_channel_snapshot *party_a;
01654 
01655    if (caller) {
01656       party_a = caller;
01657    } else {
01658       party_a = peer;
01659    }
01660    ast_assert(!strcasecmp(cdr->party_a.snapshot->name, party_a->name));
01661    cdr_object_swap_snapshot(&cdr->party_a, party_a);
01662 
01663    if (cdr->party_b.snapshot) {
01664       if (strcasecmp(cdr->party_b.snapshot->name, peer->name)) {
01665          /* Not the status for this CDR - defer back to the message router */
01666          return 1;
01667       }
01668       cdr_object_swap_snapshot(&cdr->party_b, peer);
01669    }
01670 
01671    /* Set the disposition based on the dial string. */
01672    cdr->disposition = dial_status_to_disposition(dial_status);
01673    if (cdr->disposition == AST_CDR_ANSWERED) {
01674       /* Switch to dial pending to wait and see what the caller does */
01675       cdr_object_transition_state(cdr, &dialed_pending_state_fn_table);
01676    } else {
01677       cdr_object_transition_state(cdr, &finalized_state_fn_table);
01678    }
01679 
01680    return 0;
01681 }
01682 
01683 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)
01684 {
01685    struct ao2_iterator it_cdrs;
01686    char *channel_id;
01687    int success = 0;
01688 
01689    ast_string_field_set(cdr, bridge, bridge->uniqueid);
01690 
01691    /* Get parties in the bridge */
01692    if (ao2_container_count(bridge->channels) == 1) {
01693       /* No one in the bridge yet but us! */
01694       cdr_object_transition_state(cdr, &bridge_state_fn_table);
01695       return BRIDGE_ENTER_ONLY_PARTY;
01696    }
01697 
01698    for (it_cdrs = ao2_iterator_init(bridge->channels, 0);
01699       !success && (channel_id = ao2_iterator_next(&it_cdrs));
01700       ao2_ref(channel_id, -1)) {
01701       RAII_VAR(struct cdr_object *, cand_cdr_master,
01702          ao2_find(active_cdrs_by_channel, channel_id, OBJ_KEY),
01703          ao2_cleanup);
01704       struct cdr_object *cand_cdr;
01705 
01706       if (!cand_cdr_master) {
01707          continue;
01708       }
01709 
01710       ao2_lock(cand_cdr_master);
01711       for (cand_cdr = cand_cdr_master; cand_cdr; cand_cdr = cand_cdr->next) {
01712          /* Skip any records that are not in a bridge or in this bridge.
01713           * I'm not sure how that would happen, but it pays to be careful. */
01714          if (cand_cdr->fn_table != &bridge_state_fn_table ||
01715                strcmp(cdr->bridge, cand_cdr->bridge)) {
01716             continue;
01717          }
01718 
01719          /* If we don't have a Party B (originated channel), skip it */
01720          if (!cdr->party_b.snapshot) {
01721             continue;
01722          }
01723 
01724          /* Skip any records that aren't our Party B */
01725          if (strcasecmp(cdr->party_b.snapshot->name, cand_cdr->party_a.snapshot->name)) {
01726             continue;
01727          }
01728          cdr_object_snapshot_copy(&cdr->party_b, &cand_cdr->party_a);
01729          /* If they have a Party B, they joined up with someone else as their
01730           * Party A. Don't finalize them as they're active. Otherwise, we
01731           * have stolen them so they need to be finalized.
01732           */
01733          if (!cand_cdr->party_b.snapshot) {
01734             cdr_object_finalize(cand_cdr);
01735          }
01736          success = 1;
01737          break;
01738       }
01739       ao2_unlock(cand_cdr_master);
01740    }
01741    ao2_iterator_destroy(&it_cdrs);
01742 
01743    /* We always transition state, even if we didn't get a peer */
01744    cdr_object_transition_state(cdr, &bridge_state_fn_table);
01745 
01746    /* Success implies that we have a Party B */
01747    if (success) {
01748       return BRIDGE_ENTER_OBTAINED_PARTY_B;
01749    }
01750    return BRIDGE_ENTER_NO_PARTY_B;
01751 }
01752 
01753 /* DIALED PENDING STATE */
01754 
01755 static int dialed_pending_state_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
01756 {
01757    /* If we get a CEP change, we're executing dialplan. If we have a Party B
01758     * that means we need a new CDR; otherwise, switch us over to single.
01759     */
01760    if (snapshot_cep_changed(cdr->party_a.snapshot, snapshot)) {
01761       if (cdr->party_b.snapshot) {
01762          cdr_object_transition_state(cdr, &finalized_state_fn_table);
01763          cdr->fn_table->process_party_a(cdr, snapshot);
01764          return 1;
01765       } else {
01766          cdr_object_transition_state(cdr, &single_state_fn_table);
01767          cdr->fn_table->process_party_a(cdr, snapshot);
01768          return 0;
01769       }
01770    }
01771    base_process_party_a(cdr, snapshot);
01772    return 0;
01773 }
01774 
01775 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)
01776 {
01777    cdr_object_transition_state(cdr, &dial_state_fn_table);
01778    return cdr->fn_table->process_bridge_enter(cdr, bridge, channel);
01779 }
01780 
01781 static int dialed_pending_state_process_parking_bridge_enter(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
01782 {
01783    if (cdr->party_b.snapshot) {
01784       /* We can't handle this as we have a Party B - ask for a new one */
01785       return 1;
01786    }
01787    cdr_object_transition_state(cdr, &parked_state_fn_table);
01788    return 0;
01789 }
01790 
01791 static int dialed_pending_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer)
01792 {
01793    cdr_object_transition_state(cdr, &finalized_state_fn_table);
01794 
01795    /* Ask for a new CDR */
01796    return 1;
01797 }
01798 
01799 /* BRIDGE STATE */
01800 
01801 static void bridge_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
01802 {
01803    if (!cdr->party_b.snapshot
01804       || strcasecmp(cdr->party_b.snapshot->name, snapshot->name)) {
01805       return;
01806    }
01807    cdr_object_swap_snapshot(&cdr->party_b, snapshot);
01808 
01809    /* If party B hangs up, finalize this CDR */
01810    if (ast_test_flag(&cdr->party_b.snapshot->flags, AST_FLAG_DEAD)) {
01811       cdr_object_transition_state(cdr, &finalized_state_fn_table);
01812    }
01813 }
01814 
01815 static int bridge_state_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
01816 {
01817    if (strcmp(cdr->bridge, bridge->uniqueid)) {
01818       return 1;
01819    }
01820    if (strcasecmp(cdr->party_a.snapshot->name, channel->name)
01821       && cdr->party_b.snapshot
01822       && strcasecmp(cdr->party_b.snapshot->name, channel->name)) {
01823       return 1;
01824    }
01825    cdr_object_transition_state(cdr, &finalized_state_fn_table);
01826 
01827    return 0;
01828 }
01829 
01830 /* PARKED STATE */
01831 
01832 static int parked_state_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
01833 {
01834    if (strcasecmp(cdr->party_a.snapshot->name, channel->name)) {
01835       return 1;
01836    }
01837    cdr_object_transition_state(cdr, &finalized_state_fn_table);
01838 
01839    return 0;
01840 }
01841 
01842 /* FINALIZED STATE */
01843 
01844 static void finalized_state_init_function(struct cdr_object *cdr)
01845 {
01846    cdr_object_finalize(cdr);
01847 }
01848 
01849 static int finalized_state_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
01850 {
01851    RAII_VAR(struct module_config *, mod_cfg,
01852       ao2_global_obj_ref(module_configs), ao2_cleanup);
01853 
01854    if (ast_test_flag(&snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)
01855          && ast_test_flag(&mod_cfg->general->settings, CDR_END_BEFORE_H_EXTEN)) {
01856       return 0;
01857    }
01858 
01859    /* Indicate that, if possible, we should get a new CDR */
01860    return 1;
01861 }
01862 
01863 /*!
01864  * \internal
01865  * \brief Filter channel snapshots by technology
01866  */
01867 static int filter_channel_snapshot(struct ast_channel_snapshot *snapshot)
01868 {
01869    return snapshot->tech_properties & AST_CHAN_TP_INTERNAL;
01870 }
01871 
01872 /*!
01873  * \internal
01874  * \brief Filter a channel cache update
01875  */
01876 static int filter_channel_cache_message(struct ast_channel_snapshot *old_snapshot,
01877       struct ast_channel_snapshot *new_snapshot)
01878 {
01879    int ret = 0;
01880 
01881    /* Drop cache updates from certain channel technologies */
01882    if (old_snapshot) {
01883       ret |= filter_channel_snapshot(old_snapshot);
01884    }
01885    if (new_snapshot) {
01886       ret |= filter_channel_snapshot(new_snapshot);
01887    }
01888 
01889    return ret;
01890 }
01891 
01892 /* TOPIC ROUTER CALLBACKS */
01893 
01894 /*!
01895  * \brief Handler for Stasis-Core dial messages
01896  * \param data Passed on
01897  * \param sub The stasis subscription for this message callback
01898  * \param topic The topic this message was published for
01899  * \param message The message
01900  */
01901 static void handle_dial_message(void *data, struct stasis_subscription *sub, struct stasis_message *message)
01902 {
01903    RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
01904    RAII_VAR(struct cdr_object *, cdr, NULL, ao2_cleanup);
01905    struct ast_multi_channel_blob *payload = stasis_message_data(message);
01906    struct ast_channel_snapshot *caller;
01907    struct ast_channel_snapshot *peer;
01908    struct cdr_object *it_cdr;
01909    struct ast_json *dial_status_blob;
01910    const char *dial_status = NULL;
01911    int res = 1;
01912 
01913    caller = ast_multi_channel_blob_get_channel(payload, "caller");
01914    peer = ast_multi_channel_blob_get_channel(payload, "peer");
01915    if (!peer && !caller) {
01916       return;
01917    }
01918    dial_status_blob = ast_json_object_get(ast_multi_channel_blob_get_json(payload), "dialstatus");
01919    if (dial_status_blob) {
01920       dial_status = ast_json_string_get(dial_status_blob);
01921    }
01922 
01923    CDR_DEBUG(mod_cfg, "Dial %s message for %s, %s: %u.%08u\n",
01924          ast_strlen_zero(dial_status) ? "Begin" : "End",
01925          caller ? caller->name : "(none)",
01926          peer ? peer->name : "(none)",
01927          (unsigned int)stasis_message_timestamp(message)->tv_sec,
01928          (unsigned int)stasis_message_timestamp(message)->tv_usec);
01929 
01930    if (filter_channel_snapshot(peer) || (caller && filter_channel_snapshot(caller))) {
01931       return;
01932    }
01933 
01934    /* Figure out who is running this show */
01935    if (caller) {
01936       cdr = ao2_find(active_cdrs_by_channel, caller->uniqueid, OBJ_KEY);
01937    } else {
01938       cdr = ao2_find(active_cdrs_by_channel, peer->uniqueid, OBJ_KEY);
01939    }
01940 
01941    if (!cdr) {
01942       ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", caller ? caller->name : peer->name);
01943       ast_assert(0);
01944       return;
01945    }
01946 
01947    ao2_lock(cdr);
01948    for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
01949       if (ast_strlen_zero(dial_status)) {
01950          if (!it_cdr->fn_table->process_dial_begin) {
01951             continue;
01952          }
01953          CDR_DEBUG(mod_cfg, "%p - Processing Dial Begin message for channel %s, peer %s\n",
01954                it_cdr,
01955                caller ? caller->name : "(none)",
01956                peer ? peer->name : "(none)");
01957          res &= it_cdr->fn_table->process_dial_begin(it_cdr,
01958                caller,
01959                peer);
01960       } else {
01961          if (!it_cdr->fn_table->process_dial_end) {
01962             continue;
01963          }
01964          CDR_DEBUG(mod_cfg, "%p - Processing Dial End message for channel %s, peer %s\n",
01965                it_cdr,
01966                caller ? caller->name : "(none)",
01967                peer ? peer->name : "(none)");
01968          it_cdr->fn_table->process_dial_end(it_cdr,
01969                caller,
01970                peer,
01971                dial_status);
01972       }
01973    }
01974 
01975    /* If no CDR handled a dial begin message, make a new one */
01976    if (res && ast_strlen_zero(dial_status)) {
01977       struct cdr_object *new_cdr;
01978 
01979       new_cdr = cdr_object_create_and_append(cdr);
01980       if (!new_cdr) {
01981          ao2_unlock(cdr);
01982          return;
01983       }
01984       new_cdr->fn_table->process_dial_begin(new_cdr,
01985             caller,
01986             peer);
01987    }
01988    ao2_unlock(cdr);
01989 }
01990 
01991 static int cdr_object_finalize_party_b(void *obj, void *arg, int flags)
01992 {
01993    struct cdr_object *cdr = obj;
01994    struct ast_channel_snapshot *party_b = arg;
01995    struct cdr_object *it_cdr;
01996    for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
01997       if (it_cdr->party_b.snapshot
01998          && !strcasecmp(it_cdr->party_b.snapshot->name, party_b->name)) {
01999          /* Don't transition to the finalized state - let the Party A do
02000           * that when its ready
02001           */
02002          cdr_object_finalize(it_cdr);
02003       }
02004    }
02005    return 0;
02006 }
02007 
02008 static int cdr_object_update_party_b(void *obj, void *arg, int flags)
02009 {
02010    struct cdr_object *cdr = obj;
02011    struct ast_channel_snapshot *party_b = arg;
02012    struct cdr_object *it_cdr;
02013    for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
02014       if (!it_cdr->fn_table->process_party_b) {
02015          continue;
02016       }
02017       if (it_cdr->party_b.snapshot
02018          && !strcasecmp(it_cdr->party_b.snapshot->name, party_b->name)) {
02019          it_cdr->fn_table->process_party_b(it_cdr, party_b);
02020       }
02021    }
02022    return 0;
02023 }
02024 
02025 /*! \brief Determine if we need to add a new CDR based on snapshots */
02026 static int check_new_cdr_needed(struct ast_channel_snapshot *old_snapshot,
02027       struct ast_channel_snapshot *new_snapshot)
02028 {
02029    RAII_VAR(struct module_config *, mod_cfg,
02030          ao2_global_obj_ref(module_configs), ao2_cleanup);
02031 
02032    /* If we're dead, we don't need a new CDR */
02033    if (!new_snapshot
02034       || (ast_test_flag(&new_snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)
02035          && ast_test_flag(&mod_cfg->general->settings, CDR_END_BEFORE_H_EXTEN))) {
02036       return 0;
02037    }
02038 
02039    /* Auto-fall through will increment the priority but have no application */
02040    if (ast_strlen_zero(new_snapshot->appl)) {
02041       return 0;
02042    }
02043 
02044    if (old_snapshot && !snapshot_cep_changed(old_snapshot, new_snapshot)) {
02045       return 0;
02046    }
02047 
02048    return 1;
02049 }
02050 
02051 /*!
02052  * \brief Handler for Stasis-Core channel cache update messages
02053  * \param data Passed on
02054  * \param sub The stasis subscription for this message callback
02055  * \param topic The topic this message was published for
02056  * \param message The message
02057  */
02058 static void handle_channel_cache_message(void *data, struct stasis_subscription *sub, struct stasis_message *message)
02059 {
02060    RAII_VAR(struct cdr_object *, cdr, NULL, ao2_cleanup);
02061    RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
02062    struct stasis_cache_update *update = stasis_message_data(message);
02063    struct ast_channel_snapshot *old_snapshot;
02064    struct ast_channel_snapshot *new_snapshot;
02065    const char *uniqueid;
02066    const char *name;
02067    struct cdr_object *it_cdr;
02068 
02069    ast_assert(update != NULL);
02070    ast_assert(ast_channel_snapshot_type() == update->type);
02071 
02072    old_snapshot = stasis_message_data(update->old_snapshot);
02073    new_snapshot = stasis_message_data(update->new_snapshot);
02074    uniqueid = new_snapshot ? new_snapshot->uniqueid : old_snapshot->uniqueid;
02075    name = new_snapshot ? new_snapshot->name : old_snapshot->name;
02076 
02077    if (filter_channel_cache_message(old_snapshot, new_snapshot)) {
02078       return;
02079    }
02080 
02081    if (new_snapshot && !old_snapshot) {
02082       cdr = cdr_object_alloc(new_snapshot);
02083       if (!cdr) {
02084          return;
02085       }
02086       ao2_link(active_cdrs_by_channel, cdr);
02087    }
02088 
02089    /* Handle Party A */
02090    if (!cdr) {
02091       cdr = ao2_find(active_cdrs_by_channel, uniqueid, OBJ_KEY);
02092    }
02093    if (!cdr) {
02094       ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", name);
02095       ast_assert(0);
02096    } else {
02097       ao2_lock(cdr);
02098       if (new_snapshot) {
02099          int all_reject = 1;
02100          for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
02101             if (!it_cdr->fn_table->process_party_a) {
02102                continue;
02103             }
02104             all_reject &= it_cdr->fn_table->process_party_a(it_cdr, new_snapshot);
02105          }
02106          if (all_reject && check_new_cdr_needed(old_snapshot, new_snapshot)) {
02107             /* We're not hung up and we have a new snapshot - we need a new CDR */
02108             struct cdr_object *new_cdr;
02109             new_cdr = cdr_object_create_and_append(cdr);
02110             if (new_cdr) {
02111                new_cdr->fn_table->process_party_a(new_cdr, new_snapshot);
02112             }
02113          }
02114       } else {
02115          CDR_DEBUG(mod_cfg, "%p - Beginning finalize/dispatch for %s\n", cdr, old_snapshot->name);
02116          for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
02117             cdr_object_finalize(it_cdr);
02118          }
02119          cdr_object_dispatch(cdr);
02120          ao2_unlink(active_cdrs_by_channel, cdr);
02121       }
02122       ao2_unlock(cdr);
02123    }
02124 
02125    /* Handle Party B */
02126    if (new_snapshot) {
02127       ao2_callback(active_cdrs_by_channel, OBJ_NODATA, cdr_object_update_party_b,
02128          new_snapshot);
02129    } else {
02130       ao2_callback(active_cdrs_by_channel, OBJ_NODATA, cdr_object_finalize_party_b,
02131          old_snapshot);
02132    }
02133 
02134 }
02135 
02136 struct bridge_leave_data {
02137    struct ast_bridge_snapshot *bridge;
02138    struct ast_channel_snapshot *channel;
02139 };
02140 
02141 /*! \brief Callback used to notify CDRs of a Party B leaving the bridge */
02142 static int cdr_object_party_b_left_bridge_cb(void *obj, void *arg, int flags)
02143 {
02144    struct cdr_object *cdr = obj;
02145    struct bridge_leave_data *leave_data = arg;
02146    struct cdr_object *it_cdr;
02147 
02148    if (strcmp(cdr->bridge, leave_data->bridge->uniqueid)) {
02149       return 0;
02150    }
02151    for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
02152       if (it_cdr->fn_table != &bridge_state_fn_table) {
02153          continue;
02154       }
02155       if (!it_cdr->party_b.snapshot) {
02156          continue;
02157       }
02158       if (strcasecmp(it_cdr->party_b.snapshot->name, leave_data->channel->name)) {
02159          continue;
02160       }
02161       /* It is our Party B, in our bridge. Set the end time and let the handler
02162        * transition our CDR appropriately when we leave the bridge.
02163        */
02164       cdr_object_finalize(it_cdr);
02165    }
02166    return 0;
02167 }
02168 
02169 /*! \brief Filter bridge messages based on bridge technology */
02170 static int filter_bridge_messages(struct ast_bridge_snapshot *bridge)
02171 {
02172    /* Ignore holding bridge technology messages. We treat this simply as an application
02173     * that a channel enters into.
02174     */
02175    if (!strcmp(bridge->technology, "holding_bridge") && strcmp(bridge->subclass, "parking")) {
02176       return 1;
02177    }
02178    return 0;
02179 }
02180 
02181 /*!
02182  * \brief Handler for when a channel leaves a bridge
02183  * \param data Passed on
02184  * \param sub The stasis subscription for this message callback
02185  * \param topic The topic this message was published for
02186  * \param message The message - hopefully a bridge one!
02187  */
02188 static void handle_bridge_leave_message(void *data, struct stasis_subscription *sub,
02189       struct stasis_message *message)
02190 {
02191    struct ast_bridge_blob *update = stasis_message_data(message);
02192    struct ast_bridge_snapshot *bridge = update->bridge;
02193    struct ast_channel_snapshot *channel = update->channel;
02194    RAII_VAR(struct module_config *, mod_cfg,
02195          ao2_global_obj_ref(module_configs), ao2_cleanup);
02196    RAII_VAR(struct cdr_object *, cdr,
02197          ao2_find(active_cdrs_by_channel, channel->uniqueid, OBJ_KEY),
02198          ao2_cleanup);
02199    struct cdr_object *it_cdr;
02200    struct bridge_leave_data leave_data = {
02201       .bridge = bridge,
02202       .channel = channel,
02203    };
02204    int left_bridge = 0;
02205 
02206    if (filter_bridge_messages(bridge)) {
02207       return;
02208    }
02209 
02210    if (filter_channel_snapshot(channel)) {
02211       return;
02212    }
02213 
02214    CDR_DEBUG(mod_cfg, "Bridge Leave message for %s: %u.%08u\n",
02215          channel->name,
02216          (unsigned int)stasis_message_timestamp(message)->tv_sec,
02217          (unsigned int)stasis_message_timestamp(message)->tv_usec);
02218 
02219    if (!cdr) {
02220       ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", channel->name);
02221       ast_assert(0);
02222       return;
02223    }
02224 
02225    /* Party A */
02226    ao2_lock(cdr);
02227    for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
02228       if (!it_cdr->fn_table->process_bridge_leave) {
02229          continue;
02230       }
02231       CDR_DEBUG(mod_cfg, "%p - Processing Bridge Leave for %s\n",
02232             it_cdr, channel->name);
02233       if (!it_cdr->fn_table->process_bridge_leave(it_cdr, bridge, channel)) {
02234          ast_string_field_set(it_cdr, bridge, "");
02235          left_bridge = 1;
02236       }
02237    }
02238    ao2_unlock(cdr);
02239    if (!left_bridge) {
02240       return;
02241    }
02242 
02243    if (strcmp(bridge->subclass, "parking")) {
02244       /* Party B */
02245       ao2_callback(active_cdrs_by_channel, OBJ_NODATA,
02246             cdr_object_party_b_left_bridge_cb,
02247             &leave_data);
02248    }
02249 }
02250 
02251 /*!
02252  * \internal
02253  * \brief Create a new CDR, append it to an existing CDR, and update its snapshots
02254  *
02255  * \note The new CDR will be automatically transitioned to the bridge state
02256  */
02257 static void bridge_candidate_add_to_cdr(struct cdr_object *cdr,
02258       struct cdr_object_snapshot *party_b)
02259 {
02260    RAII_VAR(struct module_config *,  mod_cfg,
02261       ao2_global_obj_ref(module_configs), ao2_cleanup);
02262    struct cdr_object *new_cdr;
02263 
02264    new_cdr = cdr_object_create_and_append(cdr);
02265    if (!new_cdr) {
02266       return;
02267    }
02268    cdr_object_snapshot_copy(&new_cdr->party_b, party_b);
02269    cdr_object_check_party_a_answer(new_cdr);
02270    ast_string_field_set(new_cdr, bridge, cdr->bridge);
02271    cdr_object_transition_state(new_cdr, &bridge_state_fn_table);
02272    CDR_DEBUG(mod_cfg, "%p - Party A %s has new Party B %s\n",
02273       new_cdr, new_cdr->party_a.snapshot->name,
02274       party_b->snapshot->name);
02275 }
02276 
02277 /*!
02278  * \brief Process a single \ref bridge_candidate
02279  *
02280  * When a CDR enters a bridge, it needs to make pairings with everyone else
02281  * that it is not currently paired with. This function determines, for the
02282  * CDR for the channel that entered the bridge and the CDR for every other
02283  * channel currently in the bridge, who is Party A and makes new CDRs.
02284  *
02285  * \param cdr The \ref cdr_obj being processed
02286  * \param cand_cdr The \ref cdr_object that is a candidate
02287  *
02288  */
02289 static int bridge_candidate_process(struct cdr_object *cdr, struct cdr_object *base_cand_cdr)
02290 {
02291    RAII_VAR(struct module_config *, mod_cfg,
02292       ao2_global_obj_ref(module_configs), ao2_cleanup);
02293    struct cdr_object_snapshot *party_a;
02294    struct cdr_object *cand_cdr;
02295 
02296    SCOPED_AO2LOCK(lock, base_cand_cdr);
02297 
02298    for (cand_cdr = base_cand_cdr; cand_cdr; cand_cdr = cand_cdr->next) {
02299       /* Skip any records that are not in this bridge */
02300       if (strcmp(cand_cdr->bridge, cdr->bridge)) {
02301          continue;
02302       }
02303 
02304       /* If the candidate is us or someone we've taken on, pass on by */
02305       if (!strcasecmp(cdr->party_a.snapshot->name, cand_cdr->party_a.snapshot->name)
02306          || (cdr->party_b.snapshot
02307             && !strcasecmp(cdr->party_b.snapshot->name, cand_cdr->party_a.snapshot->name))) {
02308          return 0;
02309       }
02310 
02311       party_a = cdr_object_pick_party_a(&cdr->party_a, &cand_cdr->party_a);
02312       /* We're party A - make a new CDR, append it to us, and set the candidate as
02313        * Party B */
02314       if (!strcasecmp(party_a->snapshot->name, cdr->party_a.snapshot->name)) {
02315          bridge_candidate_add_to_cdr(cdr, &cand_cdr->party_a);
02316          return 0;
02317       }
02318 
02319       /* We're Party B. Check if we can add ourselves immediately or if we need
02320        * a new CDR for them (they already have a Party B) */
02321       if (cand_cdr->party_b.snapshot
02322          && strcasecmp(cand_cdr->party_b.snapshot->name, cdr->party_a.snapshot->name)) {
02323          bridge_candidate_add_to_cdr(cand_cdr, &cdr->party_a);
02324       } else {
02325          CDR_DEBUG(mod_cfg, "%p - Party A %s has new Party B %s\n",
02326             cand_cdr, cand_cdr->party_a.snapshot->name,
02327             cdr->party_a.snapshot->name);
02328          cdr_object_snapshot_copy(&cand_cdr->party_b, &cdr->party_a);
02329          /* It's possible that this joined at one point and was never chosen
02330           * as party A. Clear their end time, as it would be set in such a
02331           * case.
02332           */
02333          memset(&cand_cdr->end, 0, sizeof(cand_cdr->end));
02334       }
02335       return 0;
02336    }
02337    return 0;
02338 }
02339 
02340 /*!
02341  * \brief Handle creating bridge pairings for the \ref cdr_object that just
02342  * entered a bridge
02343  * \param cdr The \ref cdr_object that just entered the bridge
02344  * \param bridge The \ref ast_bridge_snapshot representing the bridge it just entered
02345  */
02346 static void handle_bridge_pairings(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge)
02347 {
02348    struct ao2_iterator it_channels;
02349    char *channel_id;
02350 
02351    it_channels = ao2_iterator_init(bridge->channels, 0);
02352    while ((channel_id = ao2_iterator_next(&it_channels))) {
02353       RAII_VAR(struct cdr_object *, cand_cdr,
02354          ao2_find(active_cdrs_by_channel, channel_id, OBJ_KEY),
02355          ao2_cleanup);
02356 
02357       if (!cand_cdr) {
02358          ao2_ref(channel_id, -1);
02359          continue;
02360       }
02361 
02362       bridge_candidate_process(cdr, cand_cdr);
02363 
02364       ao2_ref(channel_id, -1);
02365    }
02366    ao2_iterator_destroy(&it_channels);
02367 }
02368 
02369 /*! \brief Handle entering into a parking bridge
02370  * \param cdr The CDR to operate on
02371  * \param bridge The bridge the channel just entered
02372  * \param channel The channel snapshot
02373  */
02374 static void handle_parking_bridge_enter_message(struct cdr_object *cdr,
02375       struct ast_bridge_snapshot *bridge,
02376       struct ast_channel_snapshot *channel)
02377 {
02378    RAII_VAR(struct module_config *, mod_cfg,
02379          ao2_global_obj_ref(module_configs), ao2_cleanup);
02380    int res = 1;
02381    struct cdr_object *it_cdr;
02382    struct cdr_object *new_cdr;
02383 
02384    ao2_lock(cdr);
02385 
02386    for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
02387       if (it_cdr->fn_table->process_parking_bridge_enter) {
02388          res &= it_cdr->fn_table->process_parking_bridge_enter(it_cdr, bridge, channel);
02389       }
02390       if (it_cdr->fn_table->process_party_a) {
02391          CDR_DEBUG(mod_cfg, "%p - Updating Party A %s snapshot\n", it_cdr,
02392                channel->name);
02393          it_cdr->fn_table->process_party_a(it_cdr, channel);
02394       }
02395    }
02396 
02397    if (res) {
02398       /* No one handled it - we need a new one! */
02399       new_cdr = cdr_object_create_and_append(cdr);
02400       if (new_cdr) {
02401          /* Let the single state transition us to Parked */
02402          cdr_object_transition_state(new_cdr, &single_state_fn_table);
02403          new_cdr->fn_table->process_parking_bridge_enter(new_cdr, bridge, channel);
02404       }
02405    }
02406    ao2_unlock(cdr);
02407 }
02408 
02409 /*! \brief Handle a bridge enter message for a 'normal' bridge
02410  * \param cdr The CDR to operate on
02411  * \param bridge The bridge the channel just entered
02412  * \param channel The channel snapshot
02413  */
02414 static void handle_standard_bridge_enter_message(struct cdr_object *cdr,
02415       struct ast_bridge_snapshot *bridge,
02416       struct ast_channel_snapshot *channel)
02417 {
02418    RAII_VAR(struct module_config *, mod_cfg,
02419          ao2_global_obj_ref(module_configs), ao2_cleanup);
02420    enum process_bridge_enter_results result;
02421    struct cdr_object *it_cdr;
02422    struct cdr_object *new_cdr;
02423    struct cdr_object *handled_cdr = NULL;
02424 
02425    ao2_lock(cdr);
02426 
02427    for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
02428       if (it_cdr->fn_table->process_party_a) {
02429          CDR_DEBUG(mod_cfg, "%p - Updating Party A %s snapshot\n", it_cdr,
02430                channel->name);
02431          it_cdr->fn_table->process_party_a(it_cdr, channel);
02432       }
02433 
02434       /* Notify all states that they have entered a bridge */
02435       if (it_cdr->fn_table->process_bridge_enter) {
02436          CDR_DEBUG(mod_cfg, "%p - Processing bridge enter for %s\n", it_cdr,
02437                channel->name);
02438          result = it_cdr->fn_table->process_bridge_enter(it_cdr, bridge, channel);
02439          switch (result) {
02440          case BRIDGE_ENTER_ONLY_PARTY:
02441             /* Fall through */
02442          case BRIDGE_ENTER_OBTAINED_PARTY_B:
02443             if (!handled_cdr) {
02444                handled_cdr = it_cdr;
02445             }
02446             break;
02447          case BRIDGE_ENTER_NEED_CDR:
02448             /* Pass */
02449             break;
02450          case BRIDGE_ENTER_NO_PARTY_B:
02451             /* We didn't win on any - end this CDR. If someone else comes in later
02452              * that is Party B to this CDR, it can re-activate this CDR.
02453              */
02454             if (!handled_cdr) {
02455                handled_cdr = it_cdr;
02456             }
02457             cdr_object_finalize(cdr);
02458             break;
02459          }
02460       }
02461    }
02462 
02463    /* Create the new matchings, but only for either:
02464     *  * The first CDR in the chain that handled it. This avoids issues with
02465     *    forked CDRs.
02466     *  * If no one handled it, the last CDR in the chain. This would occur if
02467     *    a CDR joined a bridge and it wasn't Party A for anyone. We still need
02468     *    to make pairings with everyone in the bridge.
02469     */
02470    if (handled_cdr) {
02471       handle_bridge_pairings(handled_cdr, bridge);
02472    } else {
02473       /* Nothing handled it - we need a new one! */
02474       new_cdr = cdr_object_create_and_append(cdr);
02475       if (new_cdr) {
02476          /* This is guaranteed to succeed: the new CDR is created in the single state
02477           * and will be able to handle the bridge enter message
02478           */
02479          handle_standard_bridge_enter_message(cdr, bridge, channel);
02480       }
02481    }
02482    ao2_unlock(cdr);
02483 }
02484 
02485 /*!
02486  * \internal
02487  * \brief Handler for Stasis-Core bridge enter messages
02488  * \param data Passed on
02489  * \param sub The stasis subscription for this message callback
02490  * \param topic The topic this message was published for
02491  * \param message The message - hopefully a bridge one!
02492  */
02493 static void handle_bridge_enter_message(void *data, struct stasis_subscription *sub,
02494       struct stasis_message *message)
02495 {
02496    struct ast_bridge_blob *update = stasis_message_data(message);
02497    struct ast_bridge_snapshot *bridge = update->bridge;
02498    struct ast_channel_snapshot *channel = update->channel;
02499    RAII_VAR(struct cdr_object *, cdr,
02500          ao2_find(active_cdrs_by_channel, channel->uniqueid, OBJ_KEY),
02501          ao2_cleanup);
02502    RAII_VAR(struct module_config *, mod_cfg,
02503          ao2_global_obj_ref(module_configs), ao2_cleanup);
02504 
02505    if (filter_bridge_messages(bridge)) {
02506       return;
02507    }
02508 
02509    if (filter_channel_snapshot(channel)) {
02510       return;
02511    }
02512 
02513    CDR_DEBUG(mod_cfg, "Bridge Enter message for channel %s: %u.%08u\n",
02514          channel->name,
02515          (unsigned int)stasis_message_timestamp(message)->tv_sec,
02516          (unsigned int)stasis_message_timestamp(message)->tv_usec);
02517 
02518    if (!cdr) {
02519       ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", channel->name);
02520       ast_assert(0);
02521       return;
02522    }
02523 
02524    if (!strcmp(bridge->subclass, "parking")) {
02525       handle_parking_bridge_enter_message(cdr, bridge, channel);
02526    } else {
02527       handle_standard_bridge_enter_message(cdr, bridge, channel);
02528    }
02529 }
02530 
02531 /*!
02532  * \brief Handler for when a channel is parked
02533  * \param data Passed on
02534  * \param sub The stasis subscription for this message callback
02535  * \param topic The topic this message was published for
02536  * \param message The message about who got parked
02537  * */
02538 static void handle_parked_call_message(void *data, struct stasis_subscription *sub,
02539       struct stasis_message *message)
02540 {
02541    struct ast_parked_call_payload *payload = stasis_message_data(message);
02542    struct ast_channel_snapshot *channel = payload->parkee;
02543    RAII_VAR(struct cdr_object *, cdr, NULL, ao2_cleanup);
02544    RAII_VAR(struct module_config *, mod_cfg,
02545          ao2_global_obj_ref(module_configs), ao2_cleanup);
02546    int unhandled = 1;
02547    struct cdr_object *it_cdr;
02548 
02549    /* Anything other than getting parked will be handled by other updates */
02550    if (payload->event_type != PARKED_CALL) {
02551       return;
02552    }
02553 
02554    /* No one got parked? */
02555    if (!channel) {
02556       return;
02557    }
02558 
02559    if (filter_channel_snapshot(channel)) {
02560       return;
02561    }
02562 
02563    CDR_DEBUG(mod_cfg, "Parked Call message for channel %s: %u.%08u\n",
02564          channel->name,
02565          (unsigned int)stasis_message_timestamp(message)->tv_sec,
02566          (unsigned int)stasis_message_timestamp(message)->tv_usec);
02567 
02568    cdr = ao2_find(active_cdrs_by_channel, channel->uniqueid, OBJ_KEY);
02569    if (!cdr) {
02570       ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", channel->name);
02571       ast_assert(0);
02572       return;
02573    }
02574 
02575    ao2_lock(cdr);
02576 
02577    for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
02578       if (it_cdr->fn_table->process_parked_channel) {
02579          unhandled &= it_cdr->fn_table->process_parked_channel(it_cdr, payload);
02580       }
02581    }
02582 
02583    if (unhandled) {
02584       /* Nothing handled the messgae - we need a new one! */
02585       struct cdr_object *new_cdr = cdr_object_create_and_append(cdr);
02586       if (new_cdr) {
02587          /* As the new CDR is created in the single state, it is guaranteed
02588           * to have a function for the parked call message and will handle
02589           * the message */
02590          new_cdr->fn_table->process_parked_channel(new_cdr, payload);
02591       }
02592    }
02593 
02594    ao2_unlock(cdr);
02595 
02596 }
02597 
02598 /*!
02599  * \brief Handler for a synchronization message
02600  * \param data Passed on
02601  * \param sub The stasis subscription for this message callback
02602  * \param topic The topic this message was published for
02603  * \param message A blank ao2 object
02604  * */
02605 static void handle_cdr_sync_message(void *data, struct stasis_subscription *sub,
02606       struct stasis_message *message)
02607 {
02608    return;
02609 }
02610 
02611 struct ast_cdr_config *ast_cdr_get_config(void)
02612 {
02613    RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
02614    ao2_ref(mod_cfg->general, +1);
02615    return mod_cfg->general;
02616 }
02617 
02618 void ast_cdr_set_config(struct ast_cdr_config *config)
02619 {
02620    RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
02621 
02622    ao2_cleanup(mod_cfg->general);
02623    mod_cfg->general = config;
02624    ao2_ref(mod_cfg->general, +1);
02625 
02626    cdr_toggle_runtime_options();
02627 }
02628 
02629 int ast_cdr_is_enabled(void)
02630 {
02631    RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
02632    return ast_test_flag(&mod_cfg->general->settings, CDR_ENABLED);
02633 }
02634 
02635 int ast_cdr_backend_suspend(const char *name)
02636 {
02637    int success = -1;
02638    struct cdr_beitem *i = NULL;
02639 
02640    AST_RWLIST_WRLOCK(&be_list);
02641    AST_RWLIST_TRAVERSE(&be_list, i, list) {
02642       if (!strcasecmp(name, i->name)) {
02643          ast_debug(3, "Suspending CDR backend %s\n", i->name);
02644          i->suspended = 1;
02645          success = 0;
02646       }
02647    }
02648    AST_RWLIST_UNLOCK(&be_list);
02649 
02650    return success;
02651 }
02652 
02653 int ast_cdr_backend_unsuspend(const char *name)
02654 {
02655    int success = -1;
02656    struct cdr_beitem *i = NULL;
02657 
02658    AST_RWLIST_WRLOCK(&be_list);
02659    AST_RWLIST_TRAVERSE(&be_list, i, list) {
02660       if (!strcasecmp(name, i->name)) {
02661          ast_debug(3, "Unsuspending CDR backend %s\n", i->name);
02662          i->suspended = 0;
02663          success = 0;
02664       }
02665    }
02666    AST_RWLIST_UNLOCK(&be_list);
02667 
02668    return success;
02669 }
02670 
02671 int ast_cdr_register(const char *name, const char *desc, ast_cdrbe be)
02672 {
02673    struct cdr_beitem *i = NULL;
02674 
02675    if (!name)
02676       return -1;
02677 
02678    if (!be) {
02679       ast_log(LOG_WARNING, "CDR engine '%s' lacks backend\n", name);
02680       return -1;
02681    }
02682 
02683    AST_RWLIST_WRLOCK(&be_list);
02684    AST_RWLIST_TRAVERSE(&be_list, i, list) {
02685       if (!strcasecmp(name, i->name)) {
02686          ast_log(LOG_WARNING, "Already have a CDR backend called '%s'\n", name);
02687          AST_RWLIST_UNLOCK(&be_list);
02688          return -1;
02689       }
02690    }
02691 
02692    if (!(i = ast_calloc(1, sizeof(*i))))
02693       return -1;
02694 
02695    i->be = be;
02696    ast_copy_string(i->name, name, sizeof(i->name));
02697    ast_copy_string(i->desc, desc, sizeof(i->desc));
02698 
02699    AST_RWLIST_INSERT_HEAD(&be_list, i, list);
02700    AST_RWLIST_UNLOCK(&be_list);
02701 
02702    return 0;
02703 }
02704 
02705 int ast_cdr_unregister(const char *name)
02706 {
02707    struct cdr_beitem *match = NULL;
02708    int active_count;
02709 
02710    AST_RWLIST_WRLOCK(&be_list);
02711    AST_RWLIST_TRAVERSE(&be_list, match, list) {
02712       if (!strcasecmp(name, match->name)) {
02713          break;
02714       }
02715    }
02716 
02717    if (!match) {
02718       AST_RWLIST_UNLOCK(&be_list);
02719       return 0;
02720    }
02721 
02722    active_count = ao2_container_count(active_cdrs_by_channel);
02723 
02724    if (!match->suspended && active_count != 0) {
02725       AST_RWLIST_UNLOCK(&be_list);
02726       ast_log(AST_LOG_WARNING, "Unable to unregister CDR backend %s; %d CDRs are still active\n",
02727          name, active_count);
02728       return -1;
02729    }
02730 
02731    AST_RWLIST_REMOVE(&be_list, match, list);
02732    AST_RWLIST_UNLOCK(&be_list);
02733 
02734    ast_verb(2, "Unregistered '%s' CDR backend\n", name);
02735    ast_free(match);
02736 
02737    return 0;
02738 }
02739 
02740 struct ast_cdr *ast_cdr_dup(struct ast_cdr *cdr)
02741 {
02742    struct ast_cdr *newcdr;
02743 
02744    if (!cdr) {
02745       return NULL;
02746    }
02747    newcdr = ast_cdr_alloc();
02748    if (!newcdr) {
02749       return NULL;
02750    }
02751 
02752    *newcdr = *cdr;
02753    AST_LIST_HEAD_INIT_NOLOCK(&newcdr->varshead);
02754    copy_variables(&newcdr->varshead, &cdr->varshead);
02755    newcdr->next = NULL;
02756 
02757    return newcdr;
02758 }
02759 
02760 static const char *cdr_format_var_internal(struct ast_cdr *cdr, const char *name)
02761 {
02762    struct ast_var_t *variables;
02763 
02764    if (ast_strlen_zero(name)) {
02765       return NULL;
02766    }
02767 
02768    AST_LIST_TRAVERSE(&cdr->varshead, variables, entries) {
02769       if (!strcasecmp(name, ast_var_name(variables))) {
02770          return ast_var_value(variables);
02771       }
02772    }
02773 
02774    return NULL;
02775 }
02776 
02777 static void cdr_get_tv(struct timeval when, const char *fmt, char *buf, int bufsize)
02778 {
02779    if (fmt == NULL) {   /* raw mode */
02780       snprintf(buf, bufsize, "%ld.%06ld", (long)when.tv_sec, (long)when.tv_usec);
02781    } else {
02782       buf[0] = '\0';/* Ensure the buffer is initialized. */
02783       if (when.tv_sec) {
02784          struct ast_tm tm;
02785 
02786          ast_localtime(&when, &tm, NULL);
02787          ast_strftime(buf, bufsize, fmt, &tm);
02788       }
02789    }
02790 }
02791 
02792 void ast_cdr_format_var(struct ast_cdr *cdr, const char *name, char **ret, char *workspace, int workspacelen, int raw)
02793 {
02794    const char *fmt = "%Y-%m-%d %T";
02795    const char *varbuf;
02796 
02797    if (!cdr) {
02798       return;
02799    }
02800 
02801    *ret = NULL;
02802 
02803    if (!strcasecmp(name, "clid")) {
02804       ast_copy_string(workspace, cdr->clid, workspacelen);
02805    } else if (!strcasecmp(name, "src")) {
02806       ast_copy_string(workspace, cdr->src, workspacelen);
02807    } else if (!strcasecmp(name, "dst")) {
02808       ast_copy_string(workspace, cdr->dst, workspacelen);
02809    } else if (!strcasecmp(name, "dcontext")) {
02810       ast_copy_string(workspace, cdr->dcontext, workspacelen);
02811    } else if (!strcasecmp(name, "channel")) {
02812       ast_copy_string(workspace, cdr->channel, workspacelen);
02813    } else if (!strcasecmp(name, "dstchannel")) {
02814       ast_copy_string(workspace, cdr->dstchannel, workspacelen);
02815    } else if (!strcasecmp(name, "lastapp")) {
02816       ast_copy_string(workspace, cdr->lastapp, workspacelen);
02817    } else if (!strcasecmp(name, "lastdata")) {
02818       ast_copy_string(workspace, cdr->lastdata, workspacelen);
02819    } else if (!strcasecmp(name, "start")) {
02820       cdr_get_tv(cdr->start, raw ? NULL : fmt, workspace, workspacelen);
02821    } else if (!strcasecmp(name, "answer")) {
02822       cdr_get_tv(cdr->answer, raw ? NULL : fmt, workspace, workspacelen);
02823    } else if (!strcasecmp(name, "end")) {
02824       cdr_get_tv(cdr->end, raw ? NULL : fmt, workspace, workspacelen);
02825    } else if (!strcasecmp(name, "duration")) {
02826       snprintf(workspace, workspacelen, "%ld", cdr->end.tv_sec != 0 ? cdr->duration : (long)ast_tvdiff_ms(ast_tvnow(), cdr->start) / 1000);
02827    } else if (!strcasecmp(name, "billsec")) {
02828       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);
02829    } else if (!strcasecmp(name, "disposition")) {
02830       if (raw) {
02831          snprintf(workspace, workspacelen, "%ld", cdr->disposition);
02832       } else {
02833          ast_copy_string(workspace, ast_cdr_disp2str(cdr->disposition), workspacelen);
02834       }
02835    } else if (!strcasecmp(name, "amaflags")) {
02836       if (raw) {
02837          snprintf(workspace, workspacelen, "%ld", cdr->amaflags);
02838       } else {
02839          ast_copy_string(workspace, ast_channel_amaflags2string(cdr->amaflags), workspacelen);
02840       }
02841    } else if (!strcasecmp(name, "accountcode")) {
02842       ast_copy_string(workspace, cdr->accountcode, workspacelen);
02843    } else if (!strcasecmp(name, "peeraccount")) {
02844       ast_copy_string(workspace, cdr->peeraccount, workspacelen);
02845    } else if (!strcasecmp(name, "uniqueid")) {
02846       ast_copy_string(workspace, cdr->uniqueid, workspacelen);
02847    } else if (!strcasecmp(name, "linkedid")) {
02848       ast_copy_string(workspace, cdr->linkedid, workspacelen);
02849    } else if (!strcasecmp(name, "userfield")) {
02850       ast_copy_string(workspace, cdr->userfield, workspacelen);
02851    } else if (!strcasecmp(name, "sequence")) {
02852       snprintf(workspace, workspacelen, "%d", cdr->sequence);
02853    } else if ((varbuf = cdr_format_var_internal(cdr, name))) {
02854       ast_copy_string(workspace, varbuf, workspacelen);
02855    } else {
02856       workspace[0] = '\0';
02857    }
02858 
02859    if (!ast_strlen_zero(workspace)) {
02860       *ret = workspace;
02861    }
02862 }
02863 
02864 /*
02865  * \internal
02866  * \brief Callback that finds all CDRs that reference a particular channel by name
02867  */
02868 static int cdr_object_select_all_by_name_cb(void *obj, void *arg, int flags)
02869 {
02870    struct cdr_object *cdr = obj;
02871    const char *name = arg;
02872 
02873    if (!strcasecmp(cdr->party_a.snapshot->name, name) ||
02874          (cdr->party_b.snapshot && !strcasecmp(cdr->party_b.snapshot->name, name))) {
02875       return CMP_MATCH;
02876    }
02877    return 0;
02878 }
02879 
02880 /*
02881  * \internal
02882  * \brief Callback that finds a CDR by channel name
02883  */
02884 static int cdr_object_get_by_name_cb(void *obj, void *arg, int flags)
02885 {
02886    struct cdr_object *cdr = obj;
02887    const char *name = arg;
02888 
02889    if (!strcasecmp(cdr->party_a.snapshot->name, name)) {
02890       return CMP_MATCH;
02891    }
02892    return 0;
02893 }
02894 
02895 /* Read Only CDR variables */
02896 static const char * const cdr_readonly_vars[] = {
02897    "clid",
02898    "src",
02899    "dst",
02900    "dcontext",
02901    "channel",
02902    "dstchannel",
02903    "lastapp",
02904    "lastdata",
02905    "start",
02906    "answer",
02907    "end",
02908    "duration",
02909    "billsec",
02910    "disposition",
02911    "amaflags",
02912    "accountcode",
02913    "uniqueid",
02914    "linkedid",
02915    "userfield",
02916    "sequence",
02917    NULL
02918 };
02919 
02920 int ast_cdr_setvar(const char *channel_name, const char *name, const char *value)
02921 {
02922    struct cdr_object *cdr;
02923    struct cdr_object *it_cdr;
02924    struct ao2_iterator *it_cdrs;
02925    char *arg = ast_strdupa(channel_name);
02926    int x;
02927 
02928    for (x = 0; cdr_readonly_vars[x]; x++) {
02929       if (!strcasecmp(name, cdr_readonly_vars[x])) {
02930          ast_log(LOG_ERROR, "Attempt to set the '%s' read-only variable!\n", name);
02931          return -1;
02932       }
02933    }
02934 
02935    it_cdrs = ao2_callback(active_cdrs_by_channel, OBJ_MULTIPLE, cdr_object_select_all_by_name_cb, arg);
02936    if (!it_cdrs) {
02937       ast_log(AST_LOG_ERROR, "Unable to find CDR for channel %s\n", channel_name);
02938       return -1;
02939    }
02940 
02941    for (; (cdr = ao2_iterator_next(it_cdrs)); ao2_unlock(cdr), ao2_cleanup(cdr)) {
02942       ao2_lock(cdr);
02943       for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
02944          struct varshead *headp = NULL;
02945 
02946          if (it_cdr->fn_table == &finalized_state_fn_table) {
02947             continue;
02948          }
02949          if (!strcasecmp(channel_name, it_cdr->party_a.snapshot->name)) {
02950             headp = &it_cdr->party_a.variables;
02951          } else if (it_cdr->party_b.snapshot
02952             && !strcasecmp(channel_name, it_cdr->party_b.snapshot->name)) {
02953             headp = &it_cdr->party_b.variables;
02954          }
02955          if (headp) {
02956             set_variable(headp, name, value);
02957          }
02958       }
02959    }
02960    ao2_iterator_destroy(it_cdrs);
02961 
02962    return 0;
02963 }
02964 
02965 /*!
02966  * \brief Format a variable on a \ref cdr_object
02967  */
02968 static void cdr_object_format_var_internal(struct cdr_object *cdr, const char *name, char *value, size_t length)
02969 {
02970    struct ast_var_t *variable;
02971 
02972    AST_LIST_TRAVERSE(&cdr->party_a.variables, variable, entries) {
02973       if (!strcasecmp(name, ast_var_name(variable))) {
02974          ast_copy_string(value, ast_var_value(variable), length);
02975          return;
02976       }
02977    }
02978 
02979    *value = '\0';
02980 }
02981 
02982 /*!
02983  * \brief Format one of the standard properties on a \ref cdr_object
02984  */
02985 static int cdr_object_format_property(struct cdr_object *cdr_obj, const char *name, char *value, size_t length)
02986 {
02987    struct ast_channel_snapshot *party_a = cdr_obj->party_a.snapshot;
02988    struct ast_channel_snapshot *party_b = cdr_obj->party_b.snapshot;
02989 
02990    if (!strcasecmp(name, "clid")) {
02991       ast_callerid_merge(value, length, party_a->caller_name, party_a->caller_number, "");
02992    } else if (!strcasecmp(name, "src")) {
02993       ast_copy_string(value, party_a->caller_number, length);
02994    } else if (!strcasecmp(name, "dst")) {
02995       ast_copy_string(value, party_a->exten, length);
02996    } else if (!strcasecmp(name, "dcontext")) {
02997       ast_copy_string(value, party_a->context, length);
02998    } else if (!strcasecmp(name, "channel")) {
02999       ast_copy_string(value, party_a->name, length);
03000    } else if (!strcasecmp(name, "dstchannel")) {
03001       if (party_b) {
03002          ast_copy_string(value, party_b->name, length);
03003       } else {
03004          ast_copy_string(value, "", length);
03005       }
03006    } else if (!strcasecmp(name, "lastapp")) {
03007       ast_copy_string(value, party_a->appl, length);
03008    } else if (!strcasecmp(name, "lastdata")) {
03009       ast_copy_string(value, party_a->data, length);
03010    } else if (!strcasecmp(name, "start")) {
03011       cdr_get_tv(cdr_obj->start, NULL, value, length);
03012    } else if (!strcasecmp(name, "answer")) {
03013       cdr_get_tv(cdr_obj->answer, NULL, value, length);
03014    } else if (!strcasecmp(name, "end")) {
03015       cdr_get_tv(cdr_obj->end, NULL, value, length);
03016    } else if (!strcasecmp(name, "duration")) {
03017       snprintf(value, length, "%ld", cdr_object_get_duration(cdr_obj));
03018    } else if (!strcasecmp(name, "billsec")) {
03019       snprintf(value, length, "%ld", cdr_object_get_billsec(cdr_obj));
03020    } else if (!strcasecmp(name, "disposition")) {
03021       snprintf(value, length, "%u", cdr_obj->disposition);
03022    } else if (!strcasecmp(name, "amaflags")) {
03023       snprintf(value, length, "%d", party_a->amaflags);
03024    } else if (!strcasecmp(name, "accountcode")) {
03025       ast_copy_string(value, party_a->accountcode, length);
03026    } else if (!strcasecmp(name, "peeraccount")) {
03027       if (party_b) {
03028          ast_copy_string(value, party_b->accountcode, length);
03029       } else {
03030          ast_copy_string(value, "", length);
03031       }
03032    } else if (!strcasecmp(name, "uniqueid")) {
03033       ast_copy_string(value, party_a->uniqueid, length);
03034    } else if (!strcasecmp(name, "linkedid")) {
03035       ast_copy_string(value, cdr_obj->linkedid, length);
03036    } else if (!strcasecmp(name, "userfield")) {
03037       ast_copy_string(value, cdr_obj->party_a.userfield, length);
03038    } else if (!strcasecmp(name, "sequence")) {
03039       snprintf(value, length, "%u", cdr_obj->sequence);
03040    } else {
03041       return 1;
03042    }
03043 
03044    return 0;
03045 }
03046 
03047 /*! \internal
03048  * \brief Look up and retrieve a CDR object by channel name
03049  * \param name The name of the channel
03050  * \retval NULL on error
03051  * \retval The \ref cdr_object for the channel on success, with the reference
03052  * count bumped by one.
03053  */
03054 static struct cdr_object *cdr_object_get_by_name(const char *name)
03055 {
03056    char *param;
03057 
03058    if (ast_strlen_zero(name)) {
03059       return NULL;
03060    }
03061 
03062    param = ast_strdupa(name);
03063    return ao2_callback(active_cdrs_by_channel, 0, cdr_object_get_by_name_cb, param);
03064 }
03065 
03066 int ast_cdr_getvar(const char *channel_name, const char *name, char *value, size_t length)
03067 {
03068    RAII_VAR(struct cdr_object *, cdr, cdr_object_get_by_name(channel_name), ao2_cleanup);
03069    struct cdr_object *cdr_obj;
03070 
03071    if (!cdr) {
03072       ast_log(AST_LOG_ERROR, "Unable to find CDR for channel %s\n", channel_name);
03073       return 1;
03074    }
03075 
03076    if (ast_strlen_zero(name)) {
03077       return 1;
03078    }
03079 
03080    ao2_lock(cdr);
03081 
03082    cdr_obj = cdr->last;
03083    if (cdr_object_format_property(cdr_obj, name, value, length)) {
03084       /* Property failed; attempt variable */
03085       cdr_object_format_var_internal(cdr_obj, name, value, length);
03086    }
03087 
03088    ao2_unlock(cdr);
03089 
03090    return 0;
03091 }
03092 
03093 int ast_cdr_serialize_variables(const char *channel_name, struct ast_str **buf, char delim, char sep)
03094 {
03095    RAII_VAR(struct cdr_object *, cdr, cdr_object_get_by_name(channel_name), ao2_cleanup);
03096    struct cdr_object *it_cdr;
03097    struct ast_var_t *variable;
03098    const char *var;
03099    RAII_VAR(char *, workspace, ast_malloc(256), ast_free);
03100    int total = 0, x = 0, i;
03101 
03102    if (!workspace) {
03103       return 0;
03104    }
03105 
03106    if (!cdr) {
03107       RAII_VAR(struct module_config *, mod_cfg,
03108           ao2_global_obj_ref(module_configs), ao2_cleanup);
03109 
03110       if (ast_test_flag(&mod_cfg->general->settings, CDR_ENABLED)) {
03111          ast_log(AST_LOG_ERROR, "Unable to find CDR for channel %s\n", channel_name);
03112       }
03113 
03114       return 0;
03115    }
03116 
03117    ast_str_reset(*buf);
03118 
03119    ao2_lock(cdr);
03120    for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
03121       if (++x > 1)
03122          ast_str_append(buf, 0, "\n");
03123 
03124       AST_LIST_TRAVERSE(&it_cdr->party_a.variables, variable, entries) {
03125          if (!(var = ast_var_name(variable))) {
03126             continue;
03127          }
03128 
03129          if (ast_str_append(buf, 0, "level %d: %s%c%s%c", x, var, delim, S_OR(ast_var_value(variable), ""), sep) < 0) {
03130             ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
03131             break;
03132          }
03133 
03134          total++;
03135       }
03136 
03137       for (i = 0; cdr_readonly_vars[i]; i++) {
03138          if (cdr_object_format_property(it_cdr, cdr_readonly_vars[i], workspace, sizeof(workspace))) {
03139             /* Unhandled read-only CDR variable. */
03140             ast_assert(0);
03141             continue;
03142          }
03143 
03144          if (!ast_strlen_zero(workspace)
03145             && ast_str_append(buf, 0, "level %d: %s%c%s%c", x, cdr_readonly_vars[i], delim, workspace, sep) < 0) {
03146             ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
03147             break;
03148          }
03149          total++;
03150       }
03151    }
03152    ao2_unlock(cdr);
03153    return total;
03154 }
03155 
03156 void ast_cdr_free(struct ast_cdr *cdr)
03157 {
03158    while (cdr) {
03159       struct ast_cdr *next = cdr->next;
03160 
03161       free_variables(&cdr->varshead);
03162       ast_free(cdr);
03163       cdr = next;
03164    }
03165 }
03166 
03167 struct ast_cdr *ast_cdr_alloc(void)
03168 {
03169    struct ast_cdr *x;
03170 
03171    x = ast_calloc(1, sizeof(*x));
03172    return x;
03173 }
03174 
03175 const char *ast_cdr_disp2str(int disposition)
03176 {
03177    switch (disposition) {
03178    case AST_CDR_NULL:
03179       return "NO ANSWER"; /* by default, for backward compatibility */
03180    case AST_CDR_NOANSWER:
03181       return "NO ANSWER";
03182    case AST_CDR_FAILED:
03183       return "FAILED";
03184    case AST_CDR_BUSY:
03185       return "BUSY";
03186    case AST_CDR_ANSWERED:
03187       return "ANSWERED";
03188    case AST_CDR_CONGESTION:
03189       return "CONGESTION";
03190    }
03191    return "UNKNOWN";
03192 }
03193 
03194 struct party_b_userfield_update {
03195    const char *channel_name;
03196    const char *userfield;
03197 };
03198 
03199 /*! \brief Callback used to update the userfield on Party B on all CDRs */
03200 static int cdr_object_update_party_b_userfield_cb(void *obj, void *arg, int flags)
03201 {
03202    struct cdr_object *cdr = obj;
03203    struct party_b_userfield_update *info = arg;
03204    struct cdr_object *it_cdr;
03205    for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
03206       if (it_cdr->fn_table == &finalized_state_fn_table) {
03207          continue;
03208       }
03209       if (it_cdr->party_b.snapshot
03210          && !strcasecmp(it_cdr->party_b.snapshot->name, info->channel_name)) {
03211          strcpy(it_cdr->party_b.userfield, info->userfield);
03212       }
03213    }
03214    return 0;
03215 }
03216 
03217 void ast_cdr_setuserfield(const char *channel_name, const char *userfield)
03218 {
03219    RAII_VAR(struct cdr_object *, cdr, cdr_object_get_by_name(channel_name), ao2_cleanup);
03220    struct party_b_userfield_update party_b_info = {
03221          .channel_name = channel_name,
03222          .userfield = userfield,
03223    };
03224    struct cdr_object *it_cdr;
03225 
03226    /* Handle Party A */
03227    if (cdr) {
03228       ao2_lock(cdr);
03229       for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
03230          if (it_cdr->fn_table == &finalized_state_fn_table) {
03231             continue;
03232          }
03233          strcpy(it_cdr->party_a.userfield, userfield);
03234       }
03235       ao2_unlock(cdr);
03236    }
03237 
03238    /* Handle Party B */
03239    ao2_callback(active_cdrs_by_channel, OBJ_NODATA,
03240          cdr_object_update_party_b_userfield_cb,
03241          &party_b_info);
03242 
03243 }
03244 
03245 static void post_cdr(struct ast_cdr *cdr)
03246 {
03247    RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
03248    struct cdr_beitem *i;
03249 
03250    for (; cdr ; cdr = cdr->next) {
03251       /* For people, who don't want to see unanswered single-channel events */
03252       if (!ast_test_flag(&mod_cfg->general->settings, CDR_UNANSWERED) &&
03253             cdr->disposition < AST_CDR_ANSWERED &&
03254             (ast_strlen_zero(cdr->channel) || ast_strlen_zero(cdr->dstchannel))) {
03255          ast_debug(1, "Skipping CDR  for %s since we weren't answered\n", cdr->channel);
03256          continue;
03257       }
03258 
03259       if (ast_test_flag(cdr, AST_CDR_FLAG_DISABLE)) {
03260          continue;
03261       }
03262       AST_RWLIST_RDLOCK(&be_list);
03263       AST_RWLIST_TRAVERSE(&be_list, i, list) {
03264          if (!i->suspended) {
03265             i->be(cdr);
03266          }
03267       }
03268       AST_RWLIST_UNLOCK(&be_list);
03269    }
03270 }
03271 
03272 int ast_cdr_set_property(const char *channel_name, enum ast_cdr_options option)
03273 {
03274    RAII_VAR(struct cdr_object *, cdr, cdr_object_get_by_name(channel_name), ao2_cleanup);
03275    struct cdr_object *it_cdr;
03276 
03277    if (!cdr) {
03278       return -1;
03279    }
03280 
03281    ao2_lock(cdr);
03282    for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
03283       if (it_cdr->fn_table == &finalized_state_fn_table) {
03284          continue;
03285       }
03286       /* Note: in general, set the flags on both the CDR record as well as the
03287        * Party A. Sometimes all we have is the Party A to look at.
03288        */
03289       ast_set_flag(&it_cdr->flags, option);
03290       ast_set_flag(&it_cdr->party_a, option);
03291    }
03292    ao2_unlock(cdr);
03293 
03294    return 0;
03295 }
03296 
03297 int ast_cdr_clear_property(const char *channel_name, enum ast_cdr_options option)
03298 {
03299    RAII_VAR(struct cdr_object *, cdr, cdr_object_get_by_name(channel_name), ao2_cleanup);
03300    struct cdr_object *it_cdr;
03301 
03302    if (!cdr) {
03303       return -1;
03304    }
03305 
03306    ao2_lock(cdr);
03307    for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
03308       if (it_cdr->fn_table == &finalized_state_fn_table) {
03309          continue;
03310       }
03311       ast_clear_flag(&it_cdr->flags, option);
03312    }
03313    ao2_unlock(cdr);
03314 
03315    return 0;
03316 }
03317 
03318 int ast_cdr_reset(const char *channel_name, int keep_variables)
03319 {
03320    RAII_VAR(struct cdr_object *, cdr, cdr_object_get_by_name(channel_name), ao2_cleanup);
03321    struct ast_var_t *vardata;
03322    struct cdr_object *it_cdr;
03323 
03324    if (!cdr) {
03325       return -1;
03326    }
03327 
03328    ao2_lock(cdr);
03329    for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
03330       /* clear variables */
03331       if (!keep_variables) {
03332          while ((vardata = AST_LIST_REMOVE_HEAD(&it_cdr->party_a.variables, entries))) {
03333             ast_var_delete(vardata);
03334          }
03335          if (cdr->party_b.snapshot) {
03336             while ((vardata = AST_LIST_REMOVE_HEAD(&it_cdr->party_b.variables, entries))) {
03337                ast_var_delete(vardata);
03338             }
03339          }
03340       }
03341 
03342       /* Reset to initial state */
03343       memset(&it_cdr->start, 0, sizeof(it_cdr->start));
03344       memset(&it_cdr->end, 0, sizeof(it_cdr->end));
03345       memset(&it_cdr->answer, 0, sizeof(it_cdr->answer));
03346       it_cdr->start = ast_tvnow();
03347       cdr_object_check_party_a_answer(it_cdr);
03348    }
03349    ao2_unlock(cdr);
03350 
03351    return 0;
03352 }
03353 
03354 int ast_cdr_fork(const char *channel_name, struct ast_flags *options)
03355 {
03356    RAII_VAR(struct cdr_object *, cdr, cdr_object_get_by_name(channel_name), ao2_cleanup);
03357    struct cdr_object *new_cdr;
03358    struct cdr_object *it_cdr;
03359    struct cdr_object *cdr_obj;
03360 
03361    if (!cdr) {
03362       return -1;
03363    }
03364 
03365    {
03366       SCOPED_AO2LOCK(lock, cdr);
03367 
03368       cdr_obj = cdr->last;
03369       if (cdr_obj->fn_table == &finalized_state_fn_table) {
03370          /* If the last CDR in the chain is finalized, don't allow a fork -
03371           * things are already dying at this point
03372           */
03373          return -1;
03374       }
03375 
03376       /* Copy over the basic CDR information. The Party A information is
03377        * copied over automatically as part of the append
03378        */
03379       ast_debug(1, "Forking CDR for channel %s\n", cdr->party_a.snapshot->name);
03380       new_cdr = cdr_object_create_and_append(cdr);
03381       if (!new_cdr) {
03382          return -1;
03383       }
03384       new_cdr->fn_table = cdr_obj->fn_table;
03385       ast_string_field_set(new_cdr, bridge, cdr->bridge);
03386       ast_string_field_set(new_cdr, appl, cdr->appl);
03387       ast_string_field_set(new_cdr, data, cdr->data);
03388       ast_string_field_set(new_cdr, context, cdr->context);
03389       ast_string_field_set(new_cdr, exten, cdr->exten);
03390       new_cdr->flags = cdr->flags;
03391       /* Explicitly clear the AST_CDR_LOCK_APP flag - we want
03392        * the application to be changed on the new CDR if the
03393        * dialplan demands it
03394        */
03395       ast_clear_flag(&new_cdr->flags, AST_CDR_LOCK_APP);
03396 
03397       /* If there's a Party B, copy it over as well */
03398       if (cdr_obj->party_b.snapshot) {
03399          new_cdr->party_b.snapshot = cdr_obj->party_b.snapshot;
03400          ao2_ref(new_cdr->party_b.snapshot, +1);
03401          strcpy(new_cdr->party_b.userfield, cdr_obj->party_b.userfield);
03402          new_cdr->party_b.flags = cdr_obj->party_b.flags;
03403          if (ast_test_flag(options, AST_CDR_FLAG_KEEP_VARS)) {
03404             copy_variables(&new_cdr->party_b.variables, &cdr_obj->party_b.variables);
03405          }
03406       }
03407       new_cdr->start = cdr_obj->start;
03408       new_cdr->answer = cdr_obj->answer;
03409 
03410       /* Modify the times based on the flags passed in */
03411       if (ast_test_flag(options, AST_CDR_FLAG_SET_ANSWER)
03412             && new_cdr->party_a.snapshot->state == AST_STATE_UP) {
03413          new_cdr->answer = ast_tvnow();
03414       }
03415       if (ast_test_flag(options, AST_CDR_FLAG_RESET)) {
03416          new_cdr->answer = ast_tvnow();
03417          new_cdr->start = ast_tvnow();
03418       }
03419 
03420       /* Create and append, by default, copies over the variables */
03421       if (!ast_test_flag(options, AST_CDR_FLAG_KEEP_VARS)) {
03422          free_variables(&new_cdr->party_a.variables);
03423       }
03424 
03425       /* Finalize any current CDRs */
03426       if (ast_test_flag(options, AST_CDR_FLAG_FINALIZE)) {
03427          for (it_cdr = cdr; it_cdr != new_cdr; it_cdr = it_cdr->next) {
03428             if (it_cdr->fn_table == &finalized_state_fn_table) {
03429                continue;
03430             }
03431             /* Force finalization on the CDR. This will bypass any checks for
03432              * end before 'h' extension.
03433              */
03434             cdr_object_finalize(it_cdr);
03435             cdr_object_transition_state(it_cdr, &finalized_state_fn_table);
03436          }
03437       }
03438    }
03439 
03440    return 0;
03441 }
03442 
03443 /*! \note Don't call without cdr_batch_lock */
03444 static void reset_batch(void)
03445 {
03446    batch->size = 0;
03447    batch->head = NULL;
03448    batch->tail = NULL;
03449 }
03450 
03451 /*! \note Don't call without cdr_batch_lock */
03452 static int init_batch(void)
03453 {
03454    /* This is the single meta-batch used to keep track of all CDRs during the entire life of the program */
03455    if (!(batch = ast_malloc(sizeof(*batch))))
03456       return -1;
03457 
03458    reset_batch();
03459 
03460    return 0;
03461 }
03462 
03463 static void *do_batch_backend_process(void *data)
03464 {
03465    struct cdr_batch_item *processeditem;
03466    struct cdr_batch_item *batchitem = data;
03467 
03468    /* Push each CDR into storage mechanism(s) and free all the memory */
03469    while (batchitem) {
03470       post_cdr(batchitem->cdr);
03471       ast_cdr_free(batchitem->cdr);
03472       processeditem = batchitem;
03473       batchitem = batchitem->next;
03474       ast_free(processeditem);
03475    }
03476 
03477    return NULL;
03478 }
03479 
03480 static void cdr_submit_batch(int do_shutdown)
03481 {
03482    RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
03483    struct cdr_batch_item *oldbatchitems = NULL;
03484    pthread_t batch_post_thread = AST_PTHREADT_NULL;
03485 
03486    /* if there's no batch, or no CDRs in the batch, then there's nothing to do */
03487    if (!batch || !batch->head) {
03488       return;
03489    }
03490 
03491    /* move the old CDRs aside, and prepare a new CDR batch */
03492    ast_mutex_lock(&cdr_batch_lock);
03493    oldbatchitems = batch->head;
03494    reset_batch();
03495    ast_mutex_unlock(&cdr_batch_lock);
03496 
03497    /* if configured, spawn a new thread to post these CDRs,
03498       also try to save as much as possible if we are shutting down safely */
03499    if (ast_test_flag(&mod_cfg->general->batch_settings.settings, BATCH_MODE_SCHEDULER_ONLY) || do_shutdown) {
03500       ast_debug(1, "CDR single-threaded batch processing begins now\n");
03501       do_batch_backend_process(oldbatchitems);
03502    } else {
03503       if (ast_pthread_create_detached_background(&batch_post_thread, NULL, do_batch_backend_process, oldbatchitems)) {
03504          ast_log(LOG_WARNING, "CDR processing thread could not detach, now trying in this thread\n");
03505          do_batch_backend_process(oldbatchitems);
03506       } else {
03507          ast_debug(1, "CDR multi-threaded batch processing begins now\n");
03508       }
03509    }
03510 }
03511 
03512 static int submit_scheduled_batch(const void *data)
03513 {
03514    RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
03515    cdr_submit_batch(0);
03516    /* manually reschedule from this point in time */
03517 
03518    ast_mutex_lock(&cdr_sched_lock);
03519    cdr_sched = ast_sched_add(sched, mod_cfg->general->batch_settings.time * 1000, submit_scheduled_batch, NULL);
03520    ast_mutex_unlock(&cdr_sched_lock);
03521    /* returning zero so the scheduler does not automatically reschedule */
03522    return 0;
03523 }
03524 
03525 /*! Do not hold the batch lock while calling this function */
03526 static void submit_unscheduled_batch(void)
03527 {
03528    /* Prevent two deletes from happening at the same time */
03529    ast_mutex_lock(&cdr_sched_lock);
03530    /* this is okay since we are not being called from within the scheduler */
03531    AST_SCHED_DEL(sched, cdr_sched);
03532    /* schedule the submission to occur ASAP (1 ms) */
03533    cdr_sched = ast_sched_add(sched, 1, submit_scheduled_batch, NULL);
03534    ast_mutex_unlock(&cdr_sched_lock);
03535 
03536    /* signal the do_cdr thread to wakeup early and do some work (that lazy thread ;) */
03537    ast_mutex_lock(&cdr_pending_lock);
03538    ast_cond_signal(&cdr_pending_cond);
03539    ast_mutex_unlock(&cdr_pending_lock);
03540 }
03541 
03542 static void cdr_detach(struct ast_cdr *cdr)
03543 {
03544    struct cdr_batch_item *newtail;
03545    int curr;
03546    RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
03547    int submit_batch = 0;
03548 
03549    if (!cdr) {
03550       return;
03551    }
03552 
03553    /* maybe they disabled CDR stuff completely, so just drop it */
03554    if (!ast_test_flag(&mod_cfg->general->settings, CDR_ENABLED)) {
03555       ast_debug(1, "Dropping CDR !\n");
03556       ast_cdr_free(cdr);
03557       return;
03558    }
03559 
03560    /* post stuff immediately if we are not in batch mode, this is legacy behaviour */
03561    if (!ast_test_flag(&mod_cfg->general->settings, CDR_BATCHMODE)) {
03562       post_cdr(cdr);
03563       ast_cdr_free(cdr);
03564       return;
03565    }
03566 
03567    /* otherwise, each CDR gets put into a batch list (at the end) */
03568    ast_debug(1, "CDR detaching from this thread\n");
03569 
03570    /* we'll need a new tail for every CDR */
03571    if (!(newtail = ast_calloc(1, sizeof(*newtail)))) {
03572       post_cdr(cdr);
03573       ast_cdr_free(cdr);
03574       return;
03575    }
03576 
03577    /* don't traverse a whole list (just keep track of the tail) */
03578    ast_mutex_lock(&cdr_batch_lock);
03579    if (!batch)
03580       init_batch();
03581    if (!batch->head) {
03582       /* new batch is empty, so point the head at the new tail */
03583       batch->head = newtail;
03584    } else {
03585       /* already got a batch with something in it, so just append a new tail */
03586       batch->tail->next = newtail;
03587    }
03588    newtail->cdr = cdr;
03589    batch->tail = newtail;
03590    curr = batch->size++;
03591 
03592    /* if we have enough stuff to post, then do it */
03593    if (curr >= (mod_cfg->general->batch_settings.size - 1)) {
03594       submit_batch = 1;
03595    }
03596    ast_mutex_unlock(&cdr_batch_lock);
03597 
03598    /* Don't call submit_unscheduled_batch with the cdr_batch_lock held */
03599    if (submit_batch) {
03600       submit_unscheduled_batch();
03601    }
03602 }
03603 
03604 static void *do_cdr(void *data)
03605 {
03606    struct timespec timeout;
03607    int schedms;
03608    int numevents = 0;
03609 
03610    for (;;) {
03611       struct timeval now;
03612       schedms = ast_sched_wait(sched);
03613       /* this shouldn't happen, but provide a 1 second default just in case */
03614       if (schedms <= 0)
03615          schedms = 1000;
03616       now = ast_tvadd(ast_tvnow(), ast_samp2tv(schedms, 1000));
03617       timeout.tv_sec = now.tv_sec;
03618       timeout.tv_nsec = now.tv_usec * 1000;
03619       /* prevent stuff from clobbering cdr_pending_cond, then wait on signals sent to it until the timeout expires */
03620       ast_mutex_lock(&cdr_pending_lock);
03621       ast_cond_timedwait(&cdr_pending_cond, &cdr_pending_lock, &timeout);
03622       numevents = ast_sched_runq(sched);
03623       ast_mutex_unlock(&cdr_pending_lock);
03624       ast_debug(2, "Processed %d scheduled CDR batches from the run queue\n", numevents);
03625    }
03626 
03627    return NULL;
03628 }
03629 
03630 static char *handle_cli_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03631 {
03632    RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
03633 
03634    switch (cmd) {
03635    case CLI_INIT:
03636       e->command = "cdr set debug [on|off]";
03637       e->usage = "Enable or disable extra debugging in the CDR Engine. Note\n"
03638             "that this will dump debug information to the VERBOSE setting\n"
03639             "and should only be used when debugging information from the\n"
03640             "CDR engine is needed.\n";
03641       return NULL;
03642    case CLI_GENERATE:
03643       return NULL;
03644    }
03645 
03646    if (a->argc != 4) {
03647       return CLI_SHOWUSAGE;
03648    }
03649 
03650    if (!strcasecmp(a->argv[3], "on")
03651       && !ast_test_flag(&mod_cfg->general->settings, CDR_DEBUG)) {
03652       ast_set_flag(&mod_cfg->general->settings, CDR_DEBUG);
03653       ast_cli(a->fd, "CDR debugging enabled\n");
03654    } else if (!strcasecmp(a->argv[3], "off")
03655       && ast_test_flag(&mod_cfg->general->settings, CDR_DEBUG)) {
03656       ast_clear_flag(&mod_cfg->general->settings, CDR_DEBUG);
03657       ast_cli(a->fd, "CDR debugging disabled\n");
03658    }
03659 
03660    return CLI_SUCCESS;
03661 }
03662 
03663 /*! \brief Complete user input for 'cdr show' */
03664 static char *cli_complete_show(struct ast_cli_args *a)
03665 {
03666    char *result = NULL;
03667    int wordlen = strlen(a->word);
03668    int which = 0;
03669    struct ao2_iterator it_cdrs;
03670    struct cdr_object *cdr;
03671 
03672    it_cdrs = ao2_iterator_init(active_cdrs_by_channel, 0);
03673    while ((cdr = ao2_iterator_next(&it_cdrs))) {
03674       if (!strncasecmp(a->word, cdr->party_a.snapshot->name, wordlen) &&
03675          (++which > a->n)) {
03676          result = ast_strdup(cdr->party_a.snapshot->name);
03677          if (result) {
03678             ao2_ref(cdr, -1);
03679             break;
03680          }
03681       }
03682       ao2_ref(cdr, -1);
03683    }
03684    ao2_iterator_destroy(&it_cdrs);
03685    return result;
03686 }
03687 
03688 static void cli_show_channels(struct ast_cli_args *a)
03689 {
03690    struct ao2_iterator it_cdrs;
03691    struct cdr_object *cdr;
03692    char start_time_buffer[64];
03693    char answer_time_buffer[64];
03694    char end_time_buffer[64];
03695 
03696 #define TITLE_STRING "%-25.25s %-25.25s %-15.15s %-8.8s %-8.8s %-8.8s %-8.8s %-8.8s\n"
03697 #define FORMAT_STRING "%-25.25s %-25.25s %-15.15s %-8.8s %-8.8s %-8.8s %-8.8ld %-8.8ld\n"
03698 
03699    ast_cli(a->fd, "\n");
03700    ast_cli(a->fd, "Channels with Call Detail Record (CDR) Information\n");
03701    ast_cli(a->fd, "--------------------------------------------------\n");
03702    ast_cli(a->fd, TITLE_STRING, "Channel", "Dst. Channel", "LastApp", "Start", "Answer", "End", "Billsec", "Duration");
03703 
03704    it_cdrs = ao2_iterator_init(active_cdrs_by_channel, 0);
03705    for (; (cdr = ao2_iterator_next(&it_cdrs)); ao2_cleanup(cdr)) {
03706       struct cdr_object *it_cdr;
03707       struct timeval start_time = { 0, };
03708       struct timeval answer_time = { 0, };
03709       struct timeval end_time = { 0, };
03710 
03711       SCOPED_AO2LOCK(lock, cdr);
03712 
03713       /* Calculate the start, end, answer, billsec, and duration over the
03714        * life of all of the CDR entries
03715        */
03716       for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
03717          if (snapshot_is_dialed(it_cdr->party_a.snapshot)) {
03718             continue;
03719          }
03720          if (ast_tvzero(start_time)) {
03721             start_time = it_cdr->start;
03722          }
03723          if (!ast_tvzero(it_cdr->answer) && ast_tvzero(answer_time)) {
03724             answer_time = it_cdr->answer;
03725          }
03726       }
03727 
03728       /* If there was no start time, then all CDRs were for a dialed channel; skip */
03729       if (ast_tvzero(start_time)) {
03730          continue;
03731       }
03732       it_cdr = cdr->last;
03733 
03734       end_time = ast_tvzero(it_cdr->end) ? ast_tvnow() : it_cdr->end;
03735       cdr_get_tv(start_time, "%T", start_time_buffer, sizeof(start_time_buffer));
03736       cdr_get_tv(answer_time, "%T", answer_time_buffer, sizeof(answer_time_buffer));
03737       cdr_get_tv(end_time, "%T", end_time_buffer, sizeof(end_time_buffer));
03738       ast_cli(a->fd, FORMAT_STRING, it_cdr->party_a.snapshot->name,
03739             it_cdr->party_b.snapshot ? it_cdr->party_b.snapshot->name : "<none>",
03740             it_cdr->appl,
03741             start_time_buffer,
03742             answer_time_buffer,
03743             end_time_buffer,
03744             ast_tvzero(answer_time) ? 0 : (long)ast_tvdiff_ms(end_time, answer_time) / 1000,
03745             (long)ast_tvdiff_ms(end_time, start_time) / 1000);
03746    }
03747    ao2_iterator_destroy(&it_cdrs);
03748 #undef FORMAT_STRING
03749 #undef TITLE_STRING
03750 }
03751 
03752 static void cli_show_channel(struct ast_cli_args *a)
03753 {
03754    struct cdr_object *it_cdr;
03755    char clid[64];
03756    char start_time_buffer[64];
03757    char answer_time_buffer[64];
03758    char end_time_buffer[64];
03759    const char *channel_name = a->argv[3];
03760    RAII_VAR(struct cdr_object *, cdr, NULL, ao2_cleanup);
03761 
03762 #define TITLE_STRING "%-10.10s %-20.20s %-25.25s %-15.15s %-15.15s %-8.8s %-8.8s %-8.8s %-8.8s %-8.8s\n"
03763 #define FORMAT_STRING "%-10.10s %-20.20s %-25.25s %-15.15s %-15.15s %-8.8s %-8.8s %-8.8s %-8.8ld %-8.8ld\n"
03764 
03765    cdr = cdr_object_get_by_name(channel_name);
03766    if (!cdr) {
03767       ast_cli(a->fd, "Unknown channel: %s\n", channel_name);
03768       return;
03769    }
03770 
03771    ast_cli(a->fd, "\n");
03772    ast_cli(a->fd, "Call Detail Record (CDR) Information for %s\n", channel_name);
03773    ast_cli(a->fd, "--------------------------------------------------\n");
03774    ast_cli(a->fd, TITLE_STRING, "AccountCode", "CallerID", "Dst. Channel", "LastApp", "Data", "Start", "Answer", "End", "Billsec", "Duration");
03775 
03776    ao2_lock(cdr);
03777    for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
03778       struct timeval end;
03779       if (snapshot_is_dialed(it_cdr->party_a.snapshot)) {
03780          continue;
03781       }
03782       ast_callerid_merge(clid, sizeof(clid), it_cdr->party_a.snapshot->caller_name, it_cdr->party_a.snapshot->caller_number, "");
03783       if (ast_tvzero(it_cdr->end)) {
03784          end = ast_tvnow();
03785       } else {
03786          end = it_cdr->end;
03787       }
03788       cdr_get_tv(it_cdr->start, "%T", start_time_buffer, sizeof(start_time_buffer));
03789       cdr_get_tv(it_cdr->answer, "%T", answer_time_buffer, sizeof(answer_time_buffer));
03790       cdr_get_tv(end, "%T", end_time_buffer, sizeof(end_time_buffer));
03791       ast_cli(a->fd, FORMAT_STRING,
03792             it_cdr->party_a.snapshot->accountcode,
03793             clid,
03794             it_cdr->party_b.snapshot ? it_cdr->party_b.snapshot->name : "<none>",
03795             it_cdr->appl,
03796             it_cdr->data,
03797             start_time_buffer,
03798             answer_time_buffer,
03799             end_time_buffer,
03800             (long)ast_tvdiff_ms(end, it_cdr->answer) / 1000,
03801             (long)ast_tvdiff_ms(end, it_cdr->start) / 1000);
03802    }
03803    ao2_unlock(cdr);
03804 #undef FORMAT_STRING
03805 #undef TITLE_STRING
03806 }
03807 
03808 static char *handle_cli_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03809 {
03810    switch (cmd) {
03811    case CLI_INIT:
03812          e->command = "cdr show active";
03813          e->usage =
03814             "Usage: cdr show active [channel]\n"
03815             "  Displays a summary of all Call Detail Records when [channel]\n"
03816             "  is omitted; displays all of the Call Detail Records\n"
03817             "  currently in flight for a given [channel] when [channel] is\n"
03818             "  specified.\n\n"
03819             "  Note that this will not display Call Detail Records that\n"
03820             "  have already been dispatched to a backend storage, nor for\n"
03821             "  channels that are no longer active.\n";
03822          return NULL;
03823    case CLI_GENERATE:
03824       return cli_complete_show(a);
03825    }
03826 
03827    if (a->argc > 4) {
03828       return CLI_SHOWUSAGE;
03829    } else if (a->argc < 4) {
03830       cli_show_channels(a);
03831    } else {
03832       cli_show_channel(a);
03833    }
03834 
03835    return CLI_SUCCESS;
03836 }
03837 
03838 static char *handle_cli_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03839 {
03840    struct cdr_beitem *beitem = NULL;
03841    RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
03842    int cnt = 0;
03843    long nextbatchtime = 0;
03844 
03845    switch (cmd) {
03846    case CLI_INIT:
03847       e->command = "cdr show status";
03848       e->usage =
03849          "Usage: cdr show status\n"
03850          "  Displays the Call Detail Record engine system status.\n";
03851       return NULL;
03852    case CLI_GENERATE:
03853       return NULL;
03854    }
03855 
03856    if (a->argc > 3) {
03857       return CLI_SHOWUSAGE;
03858    }
03859 
03860    ast_cli(a->fd, "\n");
03861    ast_cli(a->fd, "Call Detail Record (CDR) settings\n");
03862    ast_cli(a->fd, "----------------------------------\n");
03863    ast_cli(a->fd, "  Logging:                    %s\n", ast_test_flag(&mod_cfg->general->settings, CDR_ENABLED) ? "Enabled" : "Disabled");
03864    ast_cli(a->fd, "  Mode:                       %s\n", ast_test_flag(&mod_cfg->general->settings, CDR_BATCHMODE) ? "Batch" : "Simple");
03865    if (ast_test_flag(&mod_cfg->general->settings, CDR_ENABLED)) {
03866       ast_cli(a->fd, "  Log unanswered calls:       %s\n", ast_test_flag(&mod_cfg->general->settings, CDR_UNANSWERED) ? "Yes" : "No");
03867       ast_cli(a->fd, "  Log congestion:             %s\n\n", ast_test_flag(&mod_cfg->general->settings, CDR_CONGESTION) ? "Yes" : "No");
03868       if (ast_test_flag(&mod_cfg->general->settings, CDR_BATCHMODE)) {
03869          ast_cli(a->fd, "* Batch Mode Settings\n");
03870          ast_cli(a->fd, "  -------------------\n");
03871          if (batch)
03872             cnt = batch->size;
03873          if (cdr_sched > -1)
03874             nextbatchtime = ast_sched_when(sched, cdr_sched);
03875          ast_cli(a->fd, "  Safe shutdown:              %s\n", ast_test_flag(&mod_cfg->general->batch_settings.settings, BATCH_MODE_SAFE_SHUTDOWN) ? "Enabled" : "Disabled");
03876          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");
03877          ast_cli(a->fd, "  Current batch size:         %d record%s\n", cnt, ESS(cnt));
03878          ast_cli(a->fd, "  Maximum batch size:         %u record%s\n", mod_cfg->general->batch_settings.size, ESS(mod_cfg->general->batch_settings.size));
03879          ast_cli(a->fd, "  Maximum batch time:         %u second%s\n", mod_cfg->general->batch_settings.time, ESS(mod_cfg->general->batch_settings.time));
03880          ast_cli(a->fd, "  Next batch processing time: %ld second%s\n\n", nextbatchtime, ESS(nextbatchtime));
03881       }
03882       ast_cli(a->fd, "* Registered Backends\n");
03883       ast_cli(a->fd, "  -------------------\n");
03884       AST_RWLIST_RDLOCK(&be_list);
03885       if (AST_RWLIST_EMPTY(&be_list)) {
03886          ast_cli(a->fd, "    (none)\n");
03887       } else {
03888          AST_RWLIST_TRAVERSE(&be_list, beitem, list) {
03889             ast_cli(a->fd, "    %s%s\n", beitem->name, beitem->suspended ? " (suspended) " : "");
03890          }
03891       }
03892       AST_RWLIST_UNLOCK(&be_list);
03893       ast_cli(a->fd, "\n");
03894    }
03895 
03896    return CLI_SUCCESS;
03897 }
03898 
03899 static char *handle_cli_submit(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03900 {
03901    RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
03902 
03903    switch (cmd) {
03904    case CLI_INIT:
03905       e->command = "cdr submit";
03906       e->usage =
03907          "Usage: cdr submit\n"
03908          "Posts all pending batched CDR data to the configured CDR\n"
03909          "backend engine modules.\n";
03910       return NULL;
03911    case CLI_GENERATE:
03912       return NULL;
03913    }
03914    if (a->argc > 2) {
03915       return CLI_SHOWUSAGE;
03916    }
03917 
03918    if (!ast_test_flag(&mod_cfg->general->settings, CDR_ENABLED)) {
03919       ast_cli(a->fd, "Cannot submit CDR batch: CDR engine disabled.\n");
03920       return CLI_SUCCESS;
03921    }
03922 
03923    if (ast_test_flag(&mod_cfg->general->settings, CDR_BATCHMODE)) {
03924       ast_cli(a->fd, "Cannot submit CDR batch: batch mode not enabled.\n");
03925       return CLI_SUCCESS;
03926    }
03927 
03928    submit_unscheduled_batch();
03929    ast_cli(a->fd, "Submitted CDRs to backend engines for processing.  This may take a while.\n");
03930 
03931    return CLI_SUCCESS;
03932 }
03933 
03934 static struct ast_cli_entry cli_commands[] = {
03935    AST_CLI_DEFINE(handle_cli_submit, "Posts all pending batched CDR data"),
03936    AST_CLI_DEFINE(handle_cli_status, "Display the CDR status"),
03937    AST_CLI_DEFINE(handle_cli_show, "Display active CDRs for channels"),
03938    AST_CLI_DEFINE(handle_cli_debug, "Enable debugging in the CDR engine"),
03939 };
03940 
03941 /*!
03942  * \brief This dispatches *all* \ref cdr_objects. It should only be used during
03943  * shutdown, so that we get billing records for everything that we can.
03944  */
03945 static int cdr_object_dispatch_all_cb(void *obj, void *arg, int flags)
03946 {
03947    struct cdr_object *cdr = obj;
03948    struct cdr_object *it_cdr;
03949 
03950    ao2_lock(cdr);
03951    for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
03952       cdr_object_transition_state(it_cdr, &finalized_state_fn_table);
03953    }
03954    cdr_object_dispatch(cdr);
03955    ao2_unlock(cdr);
03956 
03957    return 0;
03958 }
03959 
03960 static void finalize_batch_mode(void)
03961 {
03962    if (cdr_thread == AST_PTHREADT_NULL) {
03963       return;
03964    }
03965    /* wake up the thread so it will exit */
03966    pthread_cancel(cdr_thread);
03967    pthread_kill(cdr_thread, SIGURG);
03968    pthread_join(cdr_thread, NULL);
03969    cdr_thread = AST_PTHREADT_NULL;
03970    ast_cond_destroy(&cdr_pending_cond);
03971    ast_cdr_engine_term();
03972 }
03973 
03974 struct stasis_message_router *ast_cdr_message_router(void)
03975 {
03976    if (!stasis_router) {
03977       return NULL;
03978    }
03979 
03980    ao2_bump(stasis_router);
03981    return stasis_router;
03982 }
03983 
03984 /*!
03985  * \brief Destroy the active Stasis subscriptions
03986  */
03987 static void destroy_subscriptions(void)
03988 {
03989    channel_subscription = stasis_forward_cancel(channel_subscription);
03990    bridge_subscription = stasis_forward_cancel(bridge_subscription);
03991    parking_subscription = stasis_forward_cancel(parking_subscription);
03992 }
03993 
03994 /*!
03995  * \brief Create the Stasis subcriptions for CDRs
03996  */
03997 static int create_subscriptions(void)
03998 {
03999    if (!cdr_topic) {
04000       return -1;
04001    }
04002 
04003    if (channel_subscription || bridge_subscription || parking_subscription) {
04004       return 0;
04005    }
04006 
04007    channel_subscription = stasis_forward_all(ast_channel_topic_all_cached(), cdr_topic);
04008    if (!channel_subscription) {
04009       return -1;
04010    }
04011    bridge_subscription = stasis_forward_all(ast_bridge_topic_all_cached(), cdr_topic);
04012    if (!bridge_subscription) {
04013       return -1;
04014    }
04015    parking_subscription = stasis_forward_all(ast_parking_topic(), cdr_topic);
04016    if (!parking_subscription) {
04017       return -1;
04018    }
04019 
04020    return 0;
04021 }
04022 
04023 static int process_config(int reload)
04024 {
04025    RAII_VAR(struct module_config *, mod_cfg, module_config_alloc(), ao2_cleanup);
04026 
04027    if (!reload) {
04028       if (aco_info_init(&cfg_info)) {
04029          return 1;
04030       }
04031 
04032       aco_option_register(&cfg_info, "enable", ACO_EXACT, general_options, DEFAULT_ENABLED, OPT_BOOLFLAG_T, 1, FLDSET(struct ast_cdr_config, settings), CDR_ENABLED);
04033       aco_option_register(&cfg_info, "debug", ACO_EXACT, general_options, 0, OPT_BOOLFLAG_T, 1, FLDSET(struct ast_cdr_config, settings), CDR_DEBUG);
04034       aco_option_register(&cfg_info, "unanswered", ACO_EXACT, general_options, DEFAULT_UNANSWERED, OPT_BOOLFLAG_T, 1, FLDSET(struct ast_cdr_config, settings), CDR_UNANSWERED);
04035       aco_option_register(&cfg_info, "congestion", ACO_EXACT, general_options, 0, OPT_BOOLFLAG_T, 1, FLDSET(struct ast_cdr_config, settings), CDR_CONGESTION);
04036       aco_option_register(&cfg_info, "batch", ACO_EXACT, general_options, DEFAULT_BATCHMODE, OPT_BOOLFLAG_T, 1, FLDSET(struct ast_cdr_config, settings), CDR_BATCHMODE);
04037       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);
04038       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);
04039       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);
04040       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);
04041       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);
04042       aco_option_register(&cfg_info, "time", ACO_EXACT, general_options, DEFAULT_BATCH_TIME, OPT_UINT_T, PARSE_IN_RANGE, FLDSET(struct ast_cdr_config, batch_settings.time), 0, MAX_BATCH_TIME);
04043    }
04044 
04045    if (aco_process_config(&cfg_info, reload)) {
04046       if (!mod_cfg) {
04047          return 1;
04048       }
04049       /* If we couldn't process the configuration and this wasn't a reload,
04050        * create a default config
04051        */
04052       if (!reload && !(aco_set_defaults(&general_option, "general", mod_cfg->general))) {
04053          ast_log(LOG_NOTICE, "Failed to process CDR configuration; using defaults\n");
04054          ao2_global_obj_replace_unref(module_configs, mod_cfg);
04055          return 0;
04056       }
04057       return 1;
04058    }
04059 
04060    return 0;
04061 }
04062 
04063 static void cdr_engine_cleanup(void)
04064 {
04065    destroy_subscriptions();
04066 }
04067 
04068 static void cdr_engine_shutdown(void)
04069 {
04070    stasis_message_router_unsubscribe_and_join(stasis_router);
04071    stasis_router = NULL;
04072 
04073    ao2_cleanup(cdr_topic);
04074    cdr_topic = NULL;
04075 
04076    STASIS_MESSAGE_TYPE_CLEANUP(cdr_sync_message_type);
04077 
04078    ao2_callback(active_cdrs_by_channel, OBJ_NODATA, cdr_object_dispatch_all_cb,
04079       NULL);
04080    finalize_batch_mode();
04081    ast_cli_unregister_multiple(cli_commands, ARRAY_LEN(cli_commands));
04082    ast_sched_context_destroy(sched);
04083    sched = NULL;
04084    ast_free(batch);
04085    batch = NULL;
04086 
04087    aco_info_destroy(&cfg_info);
04088    ao2_global_obj_release(module_configs);
04089 
04090    ao2_container_unregister("cdrs_by_channel");
04091    ao2_ref(active_cdrs_by_channel, -1);
04092    active_cdrs_by_channel = NULL;
04093 }
04094 
04095 static void cdr_enable_batch_mode(struct ast_cdr_config *config)
04096 {
04097    SCOPED_LOCK(batch, &cdr_batch_lock, ast_mutex_lock, ast_mutex_unlock);
04098 
04099    /* Only create the thread level portions once */
04100    if (cdr_thread == AST_PTHREADT_NULL) {
04101       ast_cond_init(&cdr_pending_cond, NULL);
04102       if (ast_pthread_create_background(&cdr_thread, NULL, do_cdr, NULL) < 0) {
04103          ast_log(LOG_ERROR, "Unable to start CDR thread.\n");
04104          return;
04105       }
04106    }
04107 
04108    /* Kill the currently scheduled item */
04109    AST_SCHED_DEL(sched, cdr_sched);
04110    cdr_sched = ast_sched_add(sched, config->batch_settings.time * 1000, submit_scheduled_batch, NULL);
04111    ast_log(LOG_NOTICE, "CDR batch mode logging enabled, first of either size %u or time %u seconds.\n",
04112          config->batch_settings.size, config->batch_settings.time);
04113 }
04114 
04115 /*!
04116  * \internal
04117  * \brief Print channel object key (name).
04118  * \since 12.0.0
04119  *
04120  * \param v_obj A pointer to the object we want the key printed.
04121  * \param where User data needed by prnt to determine where to put output.
04122  * \param prnt Print output callback function to use.
04123  *
04124  * \return Nothing
04125  */
04126 static void cdr_container_print_fn(void *v_obj, void *where, ao2_prnt_fn *prnt)
04127 {
04128    struct cdr_object *cdr = v_obj;
04129    struct cdr_object *it_cdr;
04130    if (!cdr) {
04131       return;
04132    }
04133    for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
04134       prnt(where, "Party A: %s; Party B: %s; Bridge %s\n", it_cdr->party_a.snapshot->name, it_cdr->party_b.snapshot ? it_cdr->party_b.snapshot->name : "<unknown>",
04135             it_cdr->bridge);
04136    }
04137 }
04138 
04139 /*!
04140  * \brief Checks if CDRs are enabled and enables/disables the necessary options
04141  */
04142 static int cdr_toggle_runtime_options(void)
04143 {
04144    RAII_VAR(struct module_config *, mod_cfg,
04145       ao2_global_obj_ref(module_configs), ao2_cleanup);
04146 
04147    if (ast_test_flag(&mod_cfg->general->settings, CDR_ENABLED)) {
04148       if (create_subscriptions()) {
04149          destroy_subscriptions();
04150          ast_log(AST_LOG_ERROR, "Failed to create Stasis subscriptions\n");
04151          return -1;
04152       }
04153       if (ast_test_flag(&mod_cfg->general->settings, CDR_BATCHMODE)) {
04154          cdr_enable_batch_mode(mod_cfg->general);
04155       } else {
04156          ast_log(LOG_NOTICE, "CDR simple logging enabled.\n");
04157       }
04158    } else {
04159       destroy_subscriptions();
04160       ast_log(LOG_NOTICE, "CDR logging disabled.\n");
04161    }
04162 
04163    return 0;
04164 }
04165 
04166 int ast_cdr_engine_init(void)
04167 {
04168    if (process_config(0)) {
04169       return -1;
04170    }
04171 
04172    cdr_topic = stasis_topic_create("cdr_engine");
04173    if (!cdr_topic) {
04174       return -1;
04175    }
04176 
04177    stasis_router = stasis_message_router_create(cdr_topic);
04178    if (!stasis_router) {
04179       return -1;
04180    }
04181 
04182    if (STASIS_MESSAGE_TYPE_INIT(cdr_sync_message_type)) {
04183       return -1;
04184    }
04185 
04186    stasis_message_router_add_cache_update(stasis_router, ast_channel_snapshot_type(), handle_channel_cache_message, NULL);
04187    stasis_message_router_add(stasis_router, ast_channel_dial_type(), handle_dial_message, NULL);
04188    stasis_message_router_add(stasis_router, ast_channel_entered_bridge_type(), handle_bridge_enter_message, NULL);
04189    stasis_message_router_add(stasis_router, ast_channel_left_bridge_type(), handle_bridge_leave_message, NULL);
04190    stasis_message_router_add(stasis_router, ast_parked_call_type(), handle_parked_call_message, NULL);
04191    stasis_message_router_add(stasis_router, cdr_sync_message_type(), handle_cdr_sync_message, NULL);
04192 
04193    active_cdrs_by_channel = ao2_container_alloc(NUM_CDR_BUCKETS,
04194       cdr_object_channel_hash_fn, cdr_object_channel_cmp_fn);
04195    if (!active_cdrs_by_channel) {
04196       return -1;
04197    }
04198    ao2_container_register("cdrs_by_channel", active_cdrs_by_channel, cdr_container_print_fn);
04199 
04200    sched = ast_sched_context_create();
04201    if (!sched) {
04202       ast_log(LOG_ERROR, "Unable to create schedule context.\n");
04203       return -1;
04204    }
04205 
04206    ast_cli_register_multiple(cli_commands, ARRAY_LEN(cli_commands));
04207    ast_register_cleanup(cdr_engine_cleanup);
04208    ast_register_atexit(cdr_engine_shutdown);
04209 
04210    return cdr_toggle_runtime_options();
04211 }
04212 
04213 void ast_cdr_engine_term(void)
04214 {
04215    RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
04216    RAII_VAR(void *, payload, NULL, ao2_cleanup);
04217    RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
04218 
04219    /* Since this is called explicitly during process shutdown, we might not have ever
04220     * been initialized. If so, the config object will be NULL.
04221     */
04222    if (!mod_cfg) {
04223       return;
04224    }
04225 
04226    if (cdr_sync_message_type()) {
04227       /* Make sure we have the needed items */
04228       payload = ao2_alloc(sizeof(*payload), NULL);
04229       if (!stasis_router || !payload) {
04230          return;
04231       }
04232 
04233       ast_debug(1, "CDR Engine termination request received; waiting on messages...\n");
04234 
04235       message = stasis_message_create(cdr_sync_message_type(), payload);
04236       if (message) {
04237          stasis_message_router_publish_sync(stasis_router, message);
04238       }
04239    }
04240 
04241    if (ast_test_flag(&mod_cfg->general->settings, CDR_BATCHMODE)) {
04242       cdr_submit_batch(ast_test_flag(&mod_cfg->general->batch_settings.settings, BATCH_MODE_SAFE_SHUTDOWN));
04243    }
04244 }
04245 
04246 int ast_cdr_engine_reload(void)
04247 {
04248    RAII_VAR(struct module_config *, old_mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
04249    RAII_VAR(struct module_config *, mod_cfg, NULL, ao2_cleanup);
04250 
04251    if (process_config(1)) {
04252       return -1;
04253    }
04254 
04255    mod_cfg = ao2_global_obj_ref(module_configs);
04256 
04257    if (!ast_test_flag(&mod_cfg->general->settings, CDR_ENABLED) ||
04258          !(ast_test_flag(&mod_cfg->general->settings, CDR_BATCHMODE))) {
04259       /* If batch mode used to be enabled, finalize the batch */
04260       if (ast_test_flag(&old_mod_cfg->general->settings, CDR_BATCHMODE)) {
04261          finalize_batch_mode();
04262       }
04263    }
04264 
04265    return cdr_toggle_runtime_options();
04266 }
04267 
04268 

Generated on Thu Apr 16 06:27:17 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6