features.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2012, Digium, Inc.
00005  * Copyright (C) 2012, Russell Bryant
00006  *
00007  * Mark Spencer <markster@digium.com>
00008  *
00009  * See http://www.asterisk.org for more information about
00010  * the Asterisk project. Please do not directly contact
00011  * any of the maintainers of this project for assistance;
00012  * the project provides a web site, mailing lists and IRC
00013  * channels for your use.
00014  *
00015  * This program is free software, distributed under the terms of
00016  * the GNU General Public License Version 2. See the LICENSE file
00017  * at the top of the source tree.
00018  */
00019 
00020 /*! \file
00021  *
00022  * \brief Routines implementing call features as call pickup, parking and transfer
00023  *
00024  * \author Mark Spencer <markster@digium.com>
00025  */
00026 
00027 /*! \li \ref features.c uses the configuration file \ref features.conf
00028  * \addtogroup configuration_file Configuration Files
00029  */
00030 
00031 /*!
00032  * \page features.conf features.conf
00033  * \verbinclude features.conf.sample
00034  */
00035 
00036 /*** MODULEINFO
00037    <support_level>core</support_level>
00038  ***/
00039 
00040 #include "asterisk.h"
00041 
00042 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 433695 $")
00043 
00044 #include "asterisk/_private.h"
00045 
00046 #include <pthread.h>
00047 #include <signal.h>
00048 #include <sys/time.h>
00049 #include <sys/signal.h>
00050 #include <netinet/in.h>
00051 
00052 #include "asterisk/lock.h"
00053 #include "asterisk/file.h"
00054 #include "asterisk/channel.h"
00055 #include "asterisk/pbx.h"
00056 #include "asterisk/causes.h"
00057 #include "asterisk/module.h"
00058 #include "asterisk/translate.h"
00059 #include "asterisk/app.h"
00060 #include "asterisk/say.h"
00061 #include "asterisk/features.h"
00062 #include "asterisk/musiconhold.h"
00063 #include "asterisk/config.h"
00064 #include "asterisk/cli.h"
00065 #include "asterisk/manager.h"
00066 #include "asterisk/utils.h"
00067 #include "asterisk/adsi.h"
00068 #include "asterisk/devicestate.h"
00069 #include "asterisk/monitor.h"
00070 #include "asterisk/audiohook.h"
00071 #include "asterisk/global_datastores.h"
00072 #include "asterisk/astobj2.h"
00073 #include "asterisk/test.h"
00074 #include "asterisk/bridge.h"
00075 #include "asterisk/bridge_features.h"
00076 #include "asterisk/bridge_basic.h"
00077 #include "asterisk/bridge_after.h"
00078 #include "asterisk/stasis.h"
00079 #include "asterisk/stasis_channels.h"
00080 #include "asterisk/features_config.h"
00081 
00082 /*** DOCUMENTATION
00083    <application name="Bridge" language="en_US">
00084       <synopsis>
00085          Bridge two channels.
00086       </synopsis>
00087       <syntax>
00088          <parameter name="channel" required="true">
00089             <para>The current channel is bridged to the specified <replaceable>channel</replaceable>.</para>
00090          </parameter>
00091          <parameter name="options">
00092             <optionlist>
00093                <option name="p">
00094                   <para>Play a courtesy tone to <replaceable>channel</replaceable>.</para>
00095                </option>
00096                <option name="F" argsep="^">
00097                   <argument name="context" required="false" />
00098                   <argument name="exten" required="false" />
00099                   <argument name="priority" required="true" />
00100                   <para>When the bridger hangs up, transfer the <emphasis>bridged</emphasis> party
00101                   to the specified destination and <emphasis>start</emphasis> execution at that location.</para>
00102                   <note>
00103                      <para>Any channel variables you want the called channel to inherit from the caller channel must be
00104                      prefixed with one or two underbars ('_').</para>
00105                   </note>
00106                   <note>
00107                      <para>This option will override the 'x' option</para>
00108                   </note>
00109                </option>
00110                <option name="F">
00111                   <para>When the bridger hangs up, transfer the <emphasis>bridged</emphasis> party
00112                   to the next priority of the current extension and <emphasis>start</emphasis> execution
00113                   at that location.</para>
00114                   <note>
00115                      <para>Any channel variables you want the called channel to inherit from the caller channel must be
00116                      prefixed with one or two underbars ('_').</para>
00117                   </note>
00118                   <note>
00119                      <para>Using this option from a Macro() or GoSub() might not make sense as there would be no return points.</para>
00120                   </note>
00121                   <note>
00122                      <para>This option will override the 'x' option</para>
00123                   </note>
00124                </option>
00125 
00126                <option name="h">
00127                   <para>Allow the called party to hang up by sending the
00128                   <replaceable>*</replaceable> DTMF digit.</para>
00129                </option>
00130                <option name="H">
00131                   <para>Allow the calling party to hang up by pressing the
00132                   <replaceable>*</replaceable> DTMF digit.</para>
00133                </option>
00134                <option name="k">
00135                   <para>Allow the called party to enable parking of the call by sending
00136                   the DTMF sequence defined for call parking in <filename>features.conf</filename>.</para>
00137                </option>
00138                <option name="K">
00139                   <para>Allow the calling party to enable parking of the call by sending
00140                    the DTMF sequence defined for call parking in <filename>features.conf</filename>.</para>
00141                </option>
00142                <option name="L(x[:y][:z])">
00143                   <para>Limit the call to <replaceable>x</replaceable> ms. Play a warning
00144                   when <replaceable>y</replaceable> ms are left. Repeat the warning every
00145                   <replaceable>z</replaceable> ms. The following special variables can be
00146                   used with this option:</para>
00147                   <variablelist>
00148                      <variable name="LIMIT_PLAYAUDIO_CALLER">
00149                         <para>Play sounds to the caller. yes|no (default yes)</para>
00150                      </variable>
00151                      <variable name="LIMIT_PLAYAUDIO_CALLEE">
00152                         <para>Play sounds to the callee. yes|no</para>
00153                      </variable>
00154                      <variable name="LIMIT_TIMEOUT_FILE">
00155                         <para>File to play when time is up.</para>
00156                      </variable>
00157                      <variable name="LIMIT_CONNECT_FILE">
00158                         <para>File to play when call begins.</para>
00159                      </variable>
00160                      <variable name="LIMIT_WARNING_FILE">
00161                         <para>File to play as warning if <replaceable>y</replaceable> is
00162                         defined. The default is to say the time remaining.</para>
00163                      </variable>
00164                   </variablelist>
00165                </option>
00166                <option name="S(x)">
00167                   <para>Hang up the call after <replaceable>x</replaceable> seconds *after* the called party has answered the call.</para>
00168                </option>
00169                <option name="t">
00170                   <para>Allow the called party to transfer the calling party by sending the
00171                   DTMF sequence defined in <filename>features.conf</filename>.</para>
00172                </option>
00173                <option name="T">
00174                   <para>Allow the calling party to transfer the called party by sending the
00175                   DTMF sequence defined in <filename>features.conf</filename>.</para>
00176                </option>
00177                <option name="w">
00178                   <para>Allow the called party to enable recording of the call by sending
00179                   the DTMF sequence defined for one-touch recording in <filename>features.conf</filename>.</para>
00180                </option>
00181                <option name="W">
00182                   <para>Allow the calling party to enable recording of the call by sending
00183                   the DTMF sequence defined for one-touch recording in <filename>features.conf</filename>.</para>
00184                </option>
00185                <option name="x">
00186                   <para>Cause the called party to be hung up after the bridge, instead of being
00187                   restarted in the dialplan.</para>
00188                </option>
00189             </optionlist>
00190          </parameter>
00191       </syntax>
00192       <description>
00193          <para>Allows the ability to bridge two channels via the dialplan.</para>
00194          <para>This application sets the following channel variable upon completion:</para>
00195          <variablelist>
00196             <variable name="BRIDGERESULT">
00197                <para>The result of the bridge attempt as a text string.</para>
00198                <value name="SUCCESS" />
00199                <value name="FAILURE" />
00200                <value name="LOOP" />
00201                <value name="NONEXISTENT" />
00202                <value name="INCOMPATIBLE" />
00203             </variable>
00204          </variablelist>
00205       </description>
00206    </application>
00207    <manager name="Bridge" language="en_US">
00208       <synopsis>
00209          Bridge two channels already in the PBX.
00210       </synopsis>
00211       <syntax>
00212          <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
00213          <parameter name="Channel1" required="true">
00214             <para>Channel to Bridge to Channel2.</para>
00215          </parameter>
00216          <parameter name="Channel2" required="true">
00217             <para>Channel to Bridge to Channel1.</para>
00218          </parameter>
00219          <parameter name="Tone">
00220             <para>Play courtesy tone to Channel 2.</para>
00221             <enumlist>
00222                <enum name="no" />
00223                <enum name="Channel1" />
00224                <enum name="Channel2" />
00225                <enum name="Both" />
00226             </enumlist>
00227          </parameter>
00228       </syntax>
00229       <description>
00230          <para>Bridge together two channels already in the PBX.</para>
00231       </description>
00232    </manager>
00233  ***/
00234 
00235 typedef enum {
00236    FEATURE_INTERPRET_DETECT, /* Used by ast_feature_detect */
00237    FEATURE_INTERPRET_DO,     /* Used by feature_interpret */
00238    FEATURE_INTERPRET_CHECK,  /* Used by feature_check */
00239 } feature_interpret_op;
00240 
00241 struct ast_dial_features {
00242    /*! Channel's feature flags. */
00243    struct ast_flags my_features;
00244    /*! Bridge peer's feature flags. */
00245    struct ast_flags peer_features;
00246 };
00247 
00248 static void *dial_features_duplicate(void *data)
00249 {
00250    struct ast_dial_features *df = data, *df_copy;
00251 
00252    if (!(df_copy = ast_calloc(1, sizeof(*df)))) {
00253       return NULL;
00254    }
00255 
00256    memcpy(df_copy, df, sizeof(*df));
00257 
00258    return df_copy;
00259 }
00260 
00261 static const struct ast_datastore_info dial_features_info = {
00262    .type = "dial-features",
00263    .destroy = ast_free_ptr,
00264    .duplicate = dial_features_duplicate,
00265 };
00266 
00267 /*!
00268  * \internal
00269  * \brief Set the features datastore if it doesn't exist.
00270  *
00271  * \param chan Channel to add features datastore
00272  * \param my_features The channel's feature flags
00273  * \param peer_features The channel's bridge peer feature flags
00274  *
00275  * \retval TRUE if features datastore already existed.
00276  */
00277 static int add_features_datastore(struct ast_channel *chan, const struct ast_flags *my_features, const struct ast_flags *peer_features)
00278 {
00279    struct ast_datastore *datastore;
00280    struct ast_dial_features *dialfeatures;
00281 
00282    ast_channel_lock(chan);
00283    datastore = ast_channel_datastore_find(chan, &dial_features_info, NULL);
00284    ast_channel_unlock(chan);
00285    if (datastore) {
00286       /* Already exists. */
00287       return 1;
00288    }
00289 
00290    /* Create a new datastore with specified feature flags. */
00291    datastore = ast_datastore_alloc(&dial_features_info, NULL);
00292    if (!datastore) {
00293       ast_log(LOG_WARNING, "Unable to create channel features datastore.\n");
00294       return 0;
00295    }
00296    dialfeatures = ast_calloc(1, sizeof(*dialfeatures));
00297    if (!dialfeatures) {
00298       ast_log(LOG_WARNING, "Unable to allocate memory for feature flags.\n");
00299       ast_datastore_free(datastore);
00300       return 0;
00301    }
00302    ast_copy_flags(&dialfeatures->my_features, my_features, AST_FLAGS_ALL);
00303    ast_copy_flags(&dialfeatures->peer_features, peer_features, AST_FLAGS_ALL);
00304    datastore->inheritance = DATASTORE_INHERIT_FOREVER;
00305    datastore->data = dialfeatures;
00306    ast_channel_lock(chan);
00307    ast_channel_datastore_add(chan, datastore);
00308    ast_channel_unlock(chan);
00309    return 0;
00310 }
00311 
00312 struct ast_bridge_thread_obj
00313 {
00314    struct ast_bridge_config bconfig;
00315    struct ast_channel *chan;
00316    struct ast_channel *peer;
00317    unsigned int return_to_pbx:1;
00318 };
00319 
00320 static void set_config_flags(struct ast_channel *chan, struct ast_bridge_config *config)
00321 {
00322    ast_clear_flag(config, AST_FLAGS_ALL);
00323 
00324    if (ast_test_flag(&config->features_caller, AST_FEATURE_DTMF_MASK)) {
00325       ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
00326    }
00327    if (ast_test_flag(&config->features_callee, AST_FEATURE_DTMF_MASK)) {
00328       ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
00329    }
00330 
00331    if (!(ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_0) && ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_1))) {
00332       RAII_VAR(struct ao2_container *, applicationmap, NULL, ao2_cleanup);
00333 
00334       ast_channel_lock(chan);
00335       applicationmap = ast_get_chan_applicationmap(chan);
00336       ast_channel_unlock(chan);
00337 
00338       if (!applicationmap) {
00339          return;
00340       }
00341 
00342       /* If an applicationmap exists for this channel at all, then the channel needs the DTMF flag set */
00343       ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
00344    }
00345 }
00346 
00347 void ast_channel_log(char *title, struct ast_channel *chan);
00348 
00349 void ast_channel_log(char *title, struct ast_channel *chan) /* for debug, this is handy enough to justify keeping it in the source */
00350 {
00351    ast_log(LOG_NOTICE, "______ %s (%lx)______\n", title, (unsigned long) chan);
00352    ast_log(LOG_NOTICE, "CHAN: name: %s;  appl: %s; data: %s; contxt: %s;  exten: %s; pri: %d;\n",
00353       ast_channel_name(chan), ast_channel_appl(chan), ast_channel_data(chan),
00354       ast_channel_context(chan), ast_channel_exten(chan), ast_channel_priority(chan));
00355    ast_log(LOG_NOTICE, "CHAN: acctcode: %s;  dialcontext: %s; amaflags: %x; maccontxt: %s;  macexten: %s; macpri: %d;\n",
00356       ast_channel_accountcode(chan), ast_channel_dialcontext(chan), ast_channel_amaflags(chan),
00357       ast_channel_macrocontext(chan), ast_channel_macroexten(chan), ast_channel_macropriority(chan));
00358    ast_log(LOG_NOTICE, "CHAN: masq: %p;  masqr: %p; uniqueID: %s; linkedID:%s\n",
00359       ast_channel_masq(chan), ast_channel_masqr(chan),
00360       ast_channel_uniqueid(chan), ast_channel_linkedid(chan));
00361    if (ast_channel_masqr(chan)) {
00362       ast_log(LOG_NOTICE, "CHAN: masquerading as: %s;  cdr: %p;\n",
00363          ast_channel_name(ast_channel_masqr(chan)), ast_channel_cdr(ast_channel_masqr(chan)));
00364    }
00365 
00366    ast_log(LOG_NOTICE, "===== done ====\n");
00367 }
00368 
00369 static void set_bridge_features_on_config(struct ast_bridge_config *config, const char *features)
00370 {
00371    const char *feature;
00372 
00373    if (ast_strlen_zero(features)) {
00374       return;
00375    }
00376 
00377    for (feature = features; *feature; feature++) {
00378       struct ast_flags *party;
00379 
00380       if (isupper(*feature)) {
00381          party = &config->features_caller;
00382       } else {
00383          party = &config->features_callee;
00384       }
00385 
00386       switch (tolower(*feature)) {
00387       case 't' :
00388          ast_set_flag(party, AST_FEATURE_REDIRECT);
00389          break;
00390       case 'k' :
00391          ast_set_flag(party, AST_FEATURE_PARKCALL);
00392          break;
00393       case 'h' :
00394          ast_set_flag(party, AST_FEATURE_DISCONNECT);
00395          break;
00396       case 'w' :
00397          ast_set_flag(party, AST_FEATURE_AUTOMON);
00398          break;
00399       case 'x' :
00400          ast_set_flag(party, AST_FEATURE_AUTOMIXMON);
00401          break;
00402       default :
00403          ast_log(LOG_WARNING, "Skipping unknown feature code '%c'\n", *feature);
00404          break;
00405       }
00406    }
00407 }
00408 
00409 static void add_features_datastores(struct ast_channel *caller, struct ast_channel *callee, struct ast_bridge_config *config)
00410 {
00411    if (add_features_datastore(caller, &config->features_caller, &config->features_callee)) {
00412       /*
00413        * If we don't return here, then when we do a builtin_atxfer we
00414        * will copy the disconnect flags over from the atxfer to the
00415        * callee (Party C).
00416        */
00417       return;
00418    }
00419 
00420    add_features_datastore(callee, &config->features_callee, &config->features_caller);
00421 }
00422 
00423 static void clear_dialed_interfaces(struct ast_channel *chan)
00424 {
00425    struct ast_datastore *di_datastore;
00426 
00427    ast_channel_lock(chan);
00428    if ((di_datastore = ast_channel_datastore_find(chan, &dialed_interface_info, NULL))) {
00429       if (option_debug) {
00430          ast_log(LOG_DEBUG, "Removing dialed interfaces datastore on %s since we're bridging\n", ast_channel_name(chan));
00431       }
00432       if (!ast_channel_datastore_remove(chan, di_datastore)) {
00433          ast_datastore_free(di_datastore);
00434       }
00435    }
00436    ast_channel_unlock(chan);
00437 }
00438 
00439 static void bridge_config_set_limits_warning_values(struct ast_bridge_config *config, struct ast_bridge_features_limits *limits)
00440 {
00441    if (config->end_sound) {
00442       ast_string_field_set(limits, duration_sound, config->end_sound);
00443    }
00444 
00445    if (config->warning_sound) {
00446       ast_string_field_set(limits, warning_sound, config->warning_sound);
00447    }
00448 
00449    if (config->start_sound) {
00450       ast_string_field_set(limits, connect_sound, config->start_sound);
00451    }
00452 
00453    limits->frequency = config->warning_freq;
00454    limits->warning = config->play_warning;
00455 }
00456 
00457 /*!
00458  * \internal brief Setup limit hook structures on calls that need limits
00459  *
00460  * \param config ast_bridge_config which provides the limit data
00461  * \param caller_limits pointer to an ast_bridge_features_limits struct which will store the caller side limits
00462  * \param callee_limits pointer to an ast_bridge_features_limits struct which will store the callee side limits
00463  */
00464 static void bridge_config_set_limits(struct ast_bridge_config *config, struct ast_bridge_features_limits *caller_limits, struct ast_bridge_features_limits *callee_limits)
00465 {
00466    if (ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING)) {
00467       bridge_config_set_limits_warning_values(config, caller_limits);
00468    }
00469 
00470    if (ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING)) {
00471       bridge_config_set_limits_warning_values(config, callee_limits);
00472    }
00473 
00474    caller_limits->duration = config->timelimit;
00475    callee_limits->duration = config->timelimit;
00476 }
00477 
00478 /*!
00479  * \internal
00480  * \brief Check if Monitor needs to be started on a channel.
00481  * \since 12.0.0
00482  *
00483  * \param chan The bridge considers this channel the caller.
00484  * \param peer The bridge considers this channel the callee.
00485  *
00486  * \return Nothing
00487  */
00488 static void bridge_check_monitor(struct ast_channel *chan, struct ast_channel *peer)
00489 {
00490    const char *value;
00491    const char *monitor_args = NULL;
00492    struct ast_channel *monitor_chan = NULL;
00493 
00494    ast_channel_lock(chan);
00495    value = pbx_builtin_getvar_helper(chan, "AUTO_MONITOR");
00496    if (!ast_strlen_zero(value)) {
00497       monitor_args = ast_strdupa(value);
00498       monitor_chan = chan;
00499    }
00500    ast_channel_unlock(chan);
00501    if (!monitor_chan) {
00502       ast_channel_lock(peer);
00503       value = pbx_builtin_getvar_helper(peer, "AUTO_MONITOR");
00504       if (!ast_strlen_zero(value)) {
00505          monitor_args = ast_strdupa(value);
00506          monitor_chan = peer;
00507       }
00508       ast_channel_unlock(peer);
00509    }
00510    if (monitor_chan) {
00511       struct ast_app *monitor_app;
00512 
00513       monitor_app = pbx_findapp("Monitor");
00514       if (monitor_app) {
00515          pbx_exec(monitor_chan, monitor_app, monitor_args);
00516       }
00517    }
00518 }
00519 
00520 /*!
00521  * \internal
00522  * \brief Send the peer channel on its way on bridge start failure.
00523  * \since 12.0.0
00524  *
00525  * \param chan Chan to put into autoservice.
00526  * \param peer Chan to send to after bridge goto or run hangup handlers and hangup.
00527  *
00528  * \return Nothing
00529  */
00530 static void bridge_failed_peer_goto(struct ast_channel *chan, struct ast_channel *peer)
00531 {
00532    if (ast_bridge_setup_after_goto(peer)
00533       || ast_pbx_start(peer)) {
00534       ast_autoservice_chan_hangup_peer(chan, peer);
00535    }
00536 }
00537 
00538 static int pre_bridge_setup(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config,
00539       struct ast_bridge_features *chan_features, struct ast_bridge_features *peer_features)
00540 {
00541    int res;
00542 
00543    set_bridge_features_on_config(config, pbx_builtin_getvar_helper(chan, "BRIDGE_FEATURES"));
00544    add_features_datastores(chan, peer, config);
00545 
00546    /*
00547     * This is an interesting case.  One example is if a ringing
00548     * channel gets redirected to an extension that picks up a
00549     * parked call.  This will make sure that the call taken out of
00550     * parking gets told that the channel it just got bridged to is
00551     * still ringing.
00552     */
00553    if (ast_channel_state(chan) == AST_STATE_RINGING
00554       && ast_channel_visible_indication(peer) != AST_CONTROL_RINGING) {
00555       ast_indicate(peer, AST_CONTROL_RINGING);
00556    }
00557 
00558    bridge_check_monitor(chan, peer);
00559 
00560    set_config_flags(chan, config);
00561 
00562    /* Answer if need be */
00563    if (ast_channel_state(chan) != AST_STATE_UP) {
00564       if (ast_raw_answer(chan)) {
00565          return -1;
00566       }
00567    }
00568 
00569 #ifdef FOR_DEBUG
00570    /* show the two channels and cdrs involved in the bridge for debug & devel purposes */
00571    ast_channel_log("Pre-bridge CHAN Channel info", chan);
00572    ast_channel_log("Pre-bridge PEER Channel info", peer);
00573 #endif
00574 
00575    /*
00576     * If we are bridging a call, stop worrying about forwarding
00577     * loops.  We presume that if a call is being bridged, that the
00578     * humans in charge know what they're doing.  If they don't,
00579     * well, what can we do about that?
00580     */
00581    clear_dialed_interfaces(chan);
00582    clear_dialed_interfaces(peer);
00583 
00584    res = 0;
00585    ast_channel_lock(chan);
00586    res |= ast_bridge_features_ds_append(chan, &config->features_caller);
00587    ast_channel_unlock(chan);
00588    ast_channel_lock(peer);
00589    res |= ast_bridge_features_ds_append(peer, &config->features_callee);
00590    ast_channel_unlock(peer);
00591 
00592    if (res) {
00593       return -1;
00594    }
00595 
00596    if (config->timelimit) {
00597       struct ast_bridge_features_limits call_duration_limits_chan;
00598       struct ast_bridge_features_limits call_duration_limits_peer;
00599       int abandon_call = 0; /* TRUE if set limits fails so we can abandon the call. */
00600 
00601       if (ast_bridge_features_limits_construct(&call_duration_limits_chan)) {
00602          ast_log(LOG_ERROR, "Could not construct caller duration limits. Bridge canceled.\n");
00603 
00604          return -1;
00605       }
00606 
00607       if (ast_bridge_features_limits_construct(&call_duration_limits_peer)) {
00608          ast_log(LOG_ERROR, "Could not construct callee duration limits. Bridge canceled.\n");
00609          ast_bridge_features_limits_destroy(&call_duration_limits_chan);
00610 
00611          return -1;
00612       }
00613 
00614       bridge_config_set_limits(config, &call_duration_limits_chan, &call_duration_limits_peer);
00615 
00616       if (ast_bridge_features_set_limits(chan_features, &call_duration_limits_chan, 0)) {
00617          abandon_call = 1;
00618       }
00619       if (ast_bridge_features_set_limits(peer_features, &call_duration_limits_peer, 0)) {
00620          abandon_call = 1;
00621       }
00622 
00623       /* At this point we are done with the limits structs since they have been copied to the individual feature sets. */
00624       ast_bridge_features_limits_destroy(&call_duration_limits_chan);
00625       ast_bridge_features_limits_destroy(&call_duration_limits_peer);
00626 
00627       if (abandon_call) {
00628          ast_log(LOG_ERROR, "Could not set duration limits on one or more sides of the call. Bridge canceled.\n");
00629          return -1;
00630       }
00631    }
00632 
00633    return 0;
00634 }
00635 
00636 int ast_bridge_call_with_flags(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, unsigned int flags)
00637 {
00638    int res;
00639    struct ast_bridge *bridge;
00640    struct ast_bridge_features chan_features;
00641    struct ast_bridge_features *peer_features;
00642 
00643    /* Setup features. */
00644    res = ast_bridge_features_init(&chan_features);
00645    peer_features = ast_bridge_features_new();
00646    if (res || !peer_features) {
00647       ast_bridge_features_destroy(peer_features);
00648       ast_bridge_features_cleanup(&chan_features);
00649       bridge_failed_peer_goto(chan, peer);
00650       return -1;
00651    }
00652 
00653    if (pre_bridge_setup(chan, peer, config, &chan_features, peer_features)) {
00654       ast_bridge_features_destroy(peer_features);
00655       ast_bridge_features_cleanup(&chan_features);
00656       bridge_failed_peer_goto(chan, peer);
00657       return -1;
00658    }
00659 
00660    /* Create bridge */
00661    bridge = ast_bridge_basic_new();
00662    if (!bridge) {
00663       ast_bridge_features_destroy(peer_features);
00664       ast_bridge_features_cleanup(&chan_features);
00665       bridge_failed_peer_goto(chan, peer);
00666       return -1;
00667    }
00668 
00669    ast_bridge_basic_set_flags(bridge, flags);
00670 
00671    /* Put peer into the bridge */
00672    if (ast_bridge_impart(bridge, peer, NULL, peer_features,
00673       AST_BRIDGE_IMPART_CHAN_INDEPENDENT | AST_BRIDGE_IMPART_INHIBIT_JOIN_COLP)) {
00674       ast_bridge_destroy(bridge, 0);
00675       ast_bridge_features_cleanup(&chan_features);
00676       bridge_failed_peer_goto(chan, peer);
00677       return -1;
00678    }
00679 
00680    /* Join bridge */
00681    ast_bridge_join(bridge, chan, NULL, &chan_features, NULL,
00682       AST_BRIDGE_JOIN_PASS_REFERENCE | AST_BRIDGE_JOIN_INHIBIT_JOIN_COLP);
00683 
00684    /*
00685     * If the bridge was broken for a hangup that isn't real, then
00686     * don't run the h extension, because the channel isn't really
00687     * hung up.  This should really only happen with
00688     * AST_SOFTHANGUP_ASYNCGOTO.
00689     */
00690    res = -1;
00691    ast_channel_lock(chan);
00692    if (ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_ASYNCGOTO) {
00693       res = 0;
00694    }
00695    ast_channel_unlock(chan);
00696 
00697    ast_bridge_features_cleanup(&chan_features);
00698 
00699    if (res && config->end_bridge_callback) {
00700       config->end_bridge_callback(config->end_bridge_callback_data);
00701    }
00702 
00703    return res;
00704 }
00705 
00706 /*!
00707  * \brief bridge the call and set CDR
00708  *
00709  * \param chan The bridge considers this channel the caller.
00710  * \param peer The bridge considers this channel the callee.
00711  * \param config Configuration for this bridge.
00712  *
00713  * Set start time, check for two channels,check if monitor on
00714  * check for feature activation, create new CDR
00715  * \retval res on success.
00716  * \retval -1 on failure to bridge.
00717  */
00718 int ast_bridge_call(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config)
00719 {
00720    return ast_bridge_call_with_flags(chan, peer, config, 0);
00721 }
00722 
00723 enum play_tone_action {
00724    PLAYTONE_NONE = 0,
00725    PLAYTONE_CHANNEL1 = (1 << 0),
00726    PLAYTONE_CHANNEL2 = (1 << 1),
00727    PLAYTONE_BOTH = PLAYTONE_CHANNEL1 | PLAYTONE_CHANNEL2,
00728 };
00729 
00730 static enum play_tone_action parse_playtone(const char *playtone_val)
00731 {
00732    if (ast_strlen_zero(playtone_val) || ast_false(playtone_val)) {
00733       return PLAYTONE_NONE;
00734    } if (!strcasecmp(playtone_val, "channel1")) {
00735       return PLAYTONE_CHANNEL1;
00736    } else if (!strcasecmp(playtone_val, "channel2") || ast_true(playtone_val)) {
00737       return PLAYTONE_CHANNEL2;
00738    } else if (!strcasecmp(playtone_val, "both")) {
00739       return PLAYTONE_BOTH;
00740    } else {
00741       /* Invalid input. Assume none */
00742       return PLAYTONE_NONE;
00743    }
00744 }
00745 
00746 /*!
00747  * \brief Bridge channels together
00748  * \param s
00749  * \param m
00750  *
00751  * Make sure valid channels were specified,
00752  * send errors if any of the channels could not be found/locked, answer channels if needed,
00753  * create the placeholder channels and grab the other channels
00754  * make the channels compatible, send error if we fail doing so
00755  * setup the bridge thread object and start the bridge.
00756  *
00757  * \retval 0
00758  */
00759 static int action_bridge(struct mansession *s, const struct message *m)
00760 {
00761    const char *channela = astman_get_header(m, "Channel1");
00762    const char *channelb = astman_get_header(m, "Channel2");
00763    enum play_tone_action playtone = parse_playtone(astman_get_header(m, "Tone"));
00764    RAII_VAR(struct ast_channel *, chana, NULL, ao2_cleanup);
00765    RAII_VAR(struct ast_channel *, chanb, NULL, ao2_cleanup);
00766    const char *chana_exten;
00767    const char *chana_context;
00768    int chana_priority;
00769    const char *chanb_exten;
00770    const char *chanb_context;
00771    int chanb_priority;
00772    struct ast_bridge *bridge;
00773    char buf[256];
00774    RAII_VAR(struct ast_features_xfer_config *, xfer_cfg_a, NULL, ao2_cleanup);
00775    RAII_VAR(struct ast_features_xfer_config *, xfer_cfg_b, NULL, ao2_cleanup);
00776 
00777    /* make sure valid channels were specified */
00778    if (ast_strlen_zero(channela) || ast_strlen_zero(channelb)) {
00779       astman_send_error(s, m, "Missing channel parameter in request");
00780       return 0;
00781    }
00782 
00783    ast_debug(1, "Performing Bridge action on %s and %s\n", channela, channelb);
00784 
00785    /* Start with chana */
00786    chana = ast_channel_get_by_name_prefix(channela, strlen(channela));
00787    if (!chana) {
00788       snprintf(buf, sizeof(buf), "Channel1 does not exist: %s", channela);
00789       astman_send_error(s, m, buf);
00790       return 0;
00791    }
00792    xfer_cfg_a = ast_get_chan_features_xfer_config(chana);
00793    ast_channel_lock(chana);
00794    chana_exten = ast_strdupa(ast_channel_exten(chana));
00795    chana_context = ast_strdupa(ast_channel_context(chana));
00796    chana_priority = ast_channel_priority(chana);
00797    if (!ast_test_flag(ast_channel_flags(chana), AST_FLAG_IN_AUTOLOOP)) {
00798       chana_priority++;
00799    }
00800    ast_channel_unlock(chana);
00801 
00802    chanb = ast_channel_get_by_name_prefix(channelb, strlen(channelb));
00803    if (!chanb) {
00804       snprintf(buf, sizeof(buf), "Channel2 does not exist: %s", channelb);
00805       astman_send_error(s, m, buf);
00806       return 0;
00807    }
00808    xfer_cfg_b = ast_get_chan_features_xfer_config(chanb);
00809    ast_channel_lock(chanb);
00810    chanb_exten = ast_strdupa(ast_channel_exten(chanb));
00811    chanb_context = ast_strdupa(ast_channel_context(chanb));
00812    chanb_priority = ast_channel_priority(chanb);
00813    if (!ast_test_flag(ast_channel_flags(chanb), AST_FLAG_IN_AUTOLOOP)) {
00814       chanb_priority++;
00815    }
00816    ast_channel_unlock(chanb);
00817 
00818    bridge = ast_bridge_basic_new();
00819    if (!bridge) {
00820       astman_send_error(s, m, "Unable to create bridge\n");
00821       return 0;
00822    }
00823 
00824    ast_bridge_set_after_go_on(chana, chana_context, chana_exten, chana_priority, NULL);
00825    if (ast_bridge_add_channel(bridge, chana, NULL, playtone & PLAYTONE_CHANNEL1, xfer_cfg_a ? xfer_cfg_a->xfersound : NULL)) {
00826       snprintf(buf, sizeof(buf), "Unable to add Channel1 to bridge: %s", ast_channel_name(chana));
00827       astman_send_error(s, m, buf);
00828       ast_bridge_destroy(bridge, 0);
00829       return 0;
00830    }
00831 
00832    ast_bridge_set_after_go_on(chanb, chanb_context, chanb_exten, chanb_priority, NULL);
00833    if (ast_bridge_add_channel(bridge, chanb, NULL, playtone & PLAYTONE_CHANNEL2, xfer_cfg_b ? xfer_cfg_b->xfersound : NULL)) {
00834       snprintf(buf, sizeof(buf), "Unable to add Channel2 to bridge: %s", ast_channel_name(chanb));
00835       astman_send_error(s, m, buf);
00836       ast_bridge_destroy(bridge, 0);
00837       return 0;
00838    }
00839 
00840    astman_send_ack(s, m, "Channels have been bridged");
00841    ao2_cleanup(bridge);
00842 
00843    return 0;
00844 }
00845 
00846 static char *app_bridge = "Bridge";
00847 
00848 enum {
00849    BRIDGE_OPT_PLAYTONE = (1 << 0),
00850    OPT_CALLEE_HANGUP =  (1 << 1),
00851    OPT_CALLER_HANGUP =  (1 << 2),
00852    OPT_DURATION_LIMIT = (1 << 3),
00853    OPT_DURATION_STOP =  (1 << 4),
00854    OPT_CALLEE_TRANSFER = (1 << 5),
00855    OPT_CALLER_TRANSFER = (1 << 6),
00856    OPT_CALLEE_MONITOR = (1 << 7),
00857    OPT_CALLER_MONITOR = (1 << 8),
00858    OPT_CALLEE_PARK = (1 << 9),
00859    OPT_CALLER_PARK = (1 << 10),
00860    OPT_CALLEE_KILL = (1 << 11),
00861    OPT_CALLEE_GO_ON = (1 << 12),
00862 };
00863 
00864 enum {
00865    OPT_ARG_DURATION_LIMIT = 0,
00866    OPT_ARG_DURATION_STOP,
00867    OPT_ARG_CALLEE_GO_ON,
00868    /* note: this entry _MUST_ be the last one in the enum */
00869    OPT_ARG_ARRAY_SIZE,
00870 };
00871 
00872 AST_APP_OPTIONS(bridge_exec_options, BEGIN_OPTIONS
00873    AST_APP_OPTION('p', BRIDGE_OPT_PLAYTONE),
00874    AST_APP_OPTION_ARG('F', OPT_CALLEE_GO_ON, OPT_ARG_CALLEE_GO_ON),
00875    AST_APP_OPTION('h', OPT_CALLEE_HANGUP),
00876    AST_APP_OPTION('H', OPT_CALLER_HANGUP),
00877    AST_APP_OPTION('k', OPT_CALLEE_PARK),
00878    AST_APP_OPTION('K', OPT_CALLER_PARK),
00879    AST_APP_OPTION_ARG('L', OPT_DURATION_LIMIT, OPT_ARG_DURATION_LIMIT),
00880    AST_APP_OPTION_ARG('S', OPT_DURATION_STOP, OPT_ARG_DURATION_STOP),
00881    AST_APP_OPTION('t', OPT_CALLEE_TRANSFER),
00882    AST_APP_OPTION('T', OPT_CALLER_TRANSFER),
00883    AST_APP_OPTION('w', OPT_CALLEE_MONITOR),
00884    AST_APP_OPTION('W', OPT_CALLER_MONITOR),
00885    AST_APP_OPTION('x', OPT_CALLEE_KILL),
00886 END_OPTIONS );
00887 
00888 int ast_bridge_timelimit(struct ast_channel *chan, struct ast_bridge_config *config,
00889    char *parse, struct timeval *calldurationlimit)
00890 {
00891    char *stringp = ast_strdupa(parse);
00892    char *limit_str, *warning_str, *warnfreq_str;
00893    const char *var;
00894    int play_to_caller = 0, play_to_callee = 0;
00895    int delta;
00896 
00897    limit_str = strsep(&stringp, ":");
00898    warning_str = strsep(&stringp, ":");
00899    warnfreq_str = strsep(&stringp, ":");
00900 
00901    config->timelimit = atol(limit_str);
00902    if (warning_str)
00903       config->play_warning = atol(warning_str);
00904    if (warnfreq_str)
00905       config->warning_freq = atol(warnfreq_str);
00906 
00907    if (!config->timelimit) {
00908       ast_log(LOG_WARNING, "Bridge does not accept L(%s), hanging up.\n", limit_str);
00909       config->timelimit = config->play_warning = config->warning_freq = 0;
00910       config->warning_sound = NULL;
00911       return -1; /* error */
00912    } else if ( (delta = config->play_warning - config->timelimit) > 0) {
00913       int w = config->warning_freq;
00914 
00915       /*
00916        * If the first warning is requested _after_ the entire call
00917        * would end, and no warning frequency is requested, then turn
00918        * off the warning. If a warning frequency is requested, reduce
00919        * the 'first warning' time by that frequency until it falls
00920        * within the call's total time limit.
00921        *
00922        * Graphically:
00923        *                timelim->|    delta        |<-playwarning
00924        *      0__________________|_________________|
00925        *                       | w  |    |    |    |
00926        *
00927        * so the number of intervals to cut is 1+(delta-1)/w
00928        */
00929       if (w == 0) {
00930          config->play_warning = 0;
00931       } else {
00932          config->play_warning -= w * ( 1 + (delta-1)/w );
00933          if (config->play_warning < 1)
00934             config->play_warning = config->warning_freq = 0;
00935       }
00936    }
00937 
00938    ast_channel_lock(chan);
00939 
00940    var = pbx_builtin_getvar_helper(chan, "LIMIT_PLAYAUDIO_CALLER");
00941    play_to_caller = var ? ast_true(var) : 1;
00942 
00943    var = pbx_builtin_getvar_helper(chan, "LIMIT_PLAYAUDIO_CALLEE");
00944    play_to_callee = var ? ast_true(var) : 0;
00945 
00946    if (!play_to_caller && !play_to_callee)
00947       play_to_caller = 1;
00948 
00949    var = pbx_builtin_getvar_helper(chan, "LIMIT_WARNING_FILE");
00950    config->warning_sound = !ast_strlen_zero(var) ? ast_strdup(var) : ast_strdup("timeleft");
00951 
00952    /* The code looking at config wants a NULL, not just "", to decide
00953     * that the message should not be played, so we replace "" with NULL.
00954     * Note, pbx_builtin_getvar_helper _can_ return NULL if the variable is
00955     * not found.
00956     */
00957 
00958    var = pbx_builtin_getvar_helper(chan, "LIMIT_TIMEOUT_FILE");
00959    config->end_sound = !ast_strlen_zero(var) ? ast_strdup(var) : NULL;
00960 
00961    var = pbx_builtin_getvar_helper(chan, "LIMIT_CONNECT_FILE");
00962    config->start_sound = !ast_strlen_zero(var) ? ast_strdup(var) : NULL;
00963 
00964    ast_channel_unlock(chan);
00965 
00966    /* undo effect of S(x) in case they are both used */
00967    calldurationlimit->tv_sec = 0;
00968    calldurationlimit->tv_usec = 0;
00969 
00970    /* more efficient to do it like S(x) does since no advanced opts */
00971    if (!config->play_warning && !config->start_sound && !config->end_sound && config->timelimit) {
00972       calldurationlimit->tv_sec = config->timelimit / 1000;
00973       calldurationlimit->tv_usec = (config->timelimit % 1000) * 1000;
00974       ast_verb(3, "Setting call duration limit to %.3lf seconds.\n",
00975          calldurationlimit->tv_sec + calldurationlimit->tv_usec / 1000000.0);
00976       play_to_caller = 0;
00977       play_to_callee = 0;
00978       config->timelimit = 0;
00979       config->play_warning = 0;
00980       config->warning_freq = 0;
00981    } else {
00982       ast_verb(4, "Limit Data for this call:\n");
00983       ast_verb(4, "timelimit      = %ld ms (%.3lf s)\n", config->timelimit, config->timelimit / 1000.0);
00984       ast_verb(4, "play_warning   = %ld ms (%.3lf s)\n", config->play_warning, config->play_warning / 1000.0);
00985       ast_verb(4, "play_to_caller = %s\n", play_to_caller ? "yes" : "no");
00986       ast_verb(4, "play_to_callee = %s\n", play_to_callee ? "yes" : "no");
00987       ast_verb(4, "warning_freq   = %ld ms (%.3lf s)\n", config->warning_freq, config->warning_freq / 1000.0);
00988       ast_verb(4, "start_sound    = %s\n", S_OR(config->start_sound, ""));
00989       ast_verb(4, "warning_sound  = %s\n", config->warning_sound);
00990       ast_verb(4, "end_sound      = %s\n", S_OR(config->end_sound, ""));
00991    }
00992    if (play_to_caller)
00993       ast_set_flag(&(config->features_caller), AST_FEATURE_PLAY_WARNING);
00994    if (play_to_callee)
00995       ast_set_flag(&(config->features_callee), AST_FEATURE_PLAY_WARNING);
00996    return 0;
00997 }
00998 
00999 
01000 /*!
01001  * \brief Bridge channels
01002  * \param chan
01003  * \param data channel to bridge with.
01004  *
01005  * Split data, check we aren't bridging with ourself, check valid channel,
01006  * answer call if not already, check compatible channels, setup bridge config
01007  * now bridge call, if transferred party hangs up return to PBX extension.
01008  */
01009 static int bridge_exec(struct ast_channel *chan, const char *data)
01010 {
01011    struct ast_channel *current_dest_chan;
01012    char *tmp_data  = NULL;
01013    struct ast_flags opts = { 0, };
01014    struct ast_bridge_config bconfig = { { 0, }, };
01015    char *opt_args[OPT_ARG_ARRAY_SIZE];
01016    struct timeval calldurationlimit = { 0, };
01017    const char *context;
01018    const char *extension;
01019    int priority;
01020    int bridge_add_failed;
01021    struct ast_bridge_features chan_features;
01022    struct ast_bridge_features *peer_features;
01023    struct ast_bridge *bridge;
01024    struct ast_features_xfer_config *xfer_cfg;
01025 
01026    AST_DECLARE_APP_ARGS(args,
01027       AST_APP_ARG(dest_chan);
01028       AST_APP_ARG(options);
01029    );
01030 
01031    if (ast_strlen_zero(data)) {
01032       ast_log(LOG_WARNING, "Bridge require at least 1 argument specifying the other end of the bridge\n");
01033       return -1;
01034    }
01035 
01036    tmp_data = ast_strdupa(data);
01037    AST_STANDARD_APP_ARGS(args, tmp_data);
01038    if (!ast_strlen_zero(args.options))
01039       ast_app_parse_options(bridge_exec_options, &opts, opt_args, args.options);
01040 
01041    /* make sure we have a valid end point */
01042    current_dest_chan = ast_channel_get_by_name_prefix(args.dest_chan,
01043       strlen(args.dest_chan));
01044    if (!current_dest_chan) {
01045       ast_log(LOG_WARNING, "Bridge failed because channel %s does not exist\n",
01046          args.dest_chan);
01047       return 0;
01048    }
01049 
01050    /* avoid bridge with ourselves */
01051    if (chan == current_dest_chan) {
01052       ast_channel_unref(current_dest_chan);
01053       ast_log(LOG_WARNING, "Unable to bridge channel %s with itself\n", ast_channel_name(chan));
01054       return 0;
01055    }
01056 
01057    if (ast_test_flag(&opts, OPT_DURATION_LIMIT)
01058       && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_LIMIT])
01059       && ast_bridge_timelimit(chan, &bconfig, opt_args[OPT_ARG_DURATION_LIMIT], &calldurationlimit)) {
01060       pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "FAILURE");
01061       goto done;
01062    }
01063 
01064    if (ast_test_flag(&opts, OPT_CALLEE_TRANSFER))
01065       ast_set_flag(&(bconfig.features_callee), AST_FEATURE_REDIRECT);
01066    if (ast_test_flag(&opts, OPT_CALLER_TRANSFER))
01067       ast_set_flag(&(bconfig.features_caller), AST_FEATURE_REDIRECT);
01068    if (ast_test_flag(&opts, OPT_CALLEE_HANGUP))
01069       ast_set_flag(&(bconfig.features_callee), AST_FEATURE_DISCONNECT);
01070    if (ast_test_flag(&opts, OPT_CALLER_HANGUP))
01071       ast_set_flag(&(bconfig.features_caller), AST_FEATURE_DISCONNECT);
01072    if (ast_test_flag(&opts, OPT_CALLEE_MONITOR))
01073       ast_set_flag(&(bconfig.features_callee), AST_FEATURE_AUTOMON);
01074    if (ast_test_flag(&opts, OPT_CALLER_MONITOR))
01075       ast_set_flag(&(bconfig.features_caller), AST_FEATURE_AUTOMON);
01076    if (ast_test_flag(&opts, OPT_CALLEE_PARK))
01077       ast_set_flag(&(bconfig.features_callee), AST_FEATURE_PARKCALL);
01078    if (ast_test_flag(&opts, OPT_CALLER_PARK))
01079       ast_set_flag(&(bconfig.features_caller), AST_FEATURE_PARKCALL);
01080 
01081    /* Setup after bridge goto location. */
01082    if (ast_test_flag(&opts, OPT_CALLEE_GO_ON)) {
01083       ast_channel_lock(chan);
01084       context = ast_strdupa(ast_channel_context(chan));
01085       extension = ast_strdupa(ast_channel_exten(chan));
01086       priority = ast_channel_priority(chan);
01087       ast_channel_unlock(chan);
01088       ast_bridge_set_after_go_on(current_dest_chan, context, extension, priority,
01089          opt_args[OPT_ARG_CALLEE_GO_ON]);
01090    } else if (!ast_test_flag(&opts, OPT_CALLEE_KILL)) {
01091       ast_channel_lock(current_dest_chan);
01092       context = ast_strdupa(ast_channel_context(current_dest_chan));
01093       extension = ast_strdupa(ast_channel_exten(current_dest_chan));
01094       priority = ast_channel_priority(current_dest_chan);
01095       ast_channel_unlock(current_dest_chan);
01096       ast_bridge_set_after_go_on(current_dest_chan, context, extension, priority, NULL);
01097    }
01098 
01099    if (ast_bridge_features_init(&chan_features)) {
01100       ast_bridge_features_cleanup(&chan_features);
01101       goto done;
01102    }
01103 
01104    peer_features = ast_bridge_features_new();
01105    if (!peer_features) {
01106       ast_bridge_features_cleanup(&chan_features);
01107       goto done;
01108    }
01109 
01110    if (pre_bridge_setup(chan, current_dest_chan, &bconfig, &chan_features, peer_features)) {
01111       ast_bridge_features_destroy(peer_features);
01112       ast_bridge_features_cleanup(&chan_features);
01113       goto done;
01114    }
01115 
01116    bridge = ast_bridge_basic_new();
01117    if (!bridge) {
01118       ast_bridge_features_destroy(peer_features);
01119       ast_bridge_features_cleanup(&chan_features);
01120       goto done;
01121    }
01122 
01123    xfer_cfg = ast_get_chan_features_xfer_config(current_dest_chan);
01124    bridge_add_failed = ast_bridge_add_channel(bridge, current_dest_chan, peer_features,
01125       ast_test_flag(&opts, BRIDGE_OPT_PLAYTONE),
01126       xfer_cfg ? xfer_cfg->xfersound : NULL);
01127    ao2_cleanup(xfer_cfg);
01128    if (bridge_add_failed) {
01129       ast_bridge_features_destroy(peer_features);
01130       ast_bridge_features_cleanup(&chan_features);
01131       ast_bridge_destroy(bridge, 0);
01132       goto done;
01133    }
01134 
01135    /* Don't keep the channel ref in case it was not already in a bridge. */
01136    current_dest_chan = ast_channel_unref(current_dest_chan);
01137 
01138    ast_bridge_join(bridge, chan, NULL, &chan_features, NULL,
01139       AST_BRIDGE_JOIN_PASS_REFERENCE);
01140 
01141    ast_bridge_features_cleanup(&chan_features);
01142 
01143    /* The bridge has ended, set BRIDGERESULT to SUCCESS. */
01144    pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "SUCCESS");
01145 done:
01146    ast_free((char *) bconfig.warning_sound);
01147    ast_free((char *) bconfig.end_sound);
01148    ast_free((char *) bconfig.start_sound);
01149 
01150    ast_channel_cleanup(current_dest_chan);
01151    return 0;
01152 }
01153 
01154 /*!
01155  * \internal
01156  * \brief Clean up resources on Asterisk shutdown
01157  */
01158 static void features_shutdown(void)
01159 {
01160    ast_features_config_shutdown();
01161 
01162    ast_manager_unregister("Bridge");
01163 
01164    ast_unregister_application(app_bridge);
01165 
01166 }
01167 
01168 int ast_features_init(void)
01169 {
01170    int res;
01171 
01172    res = ast_features_config_init();
01173    if (res) {
01174       return res;
01175    }
01176    res |= ast_register_application2(app_bridge, bridge_exec, NULL, NULL, NULL);
01177    res |= ast_manager_register_xml_core("Bridge", EVENT_FLAG_CALL, action_bridge);
01178 
01179    if (res) {
01180       features_shutdown();
01181    } else {
01182       ast_register_cleanup(features_shutdown);
01183    }
01184 
01185    return res;
01186 }

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