Sun Oct 16 2011 08:41:39

Asterisk developer's documentation


features.c
Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2008, 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 Routines implementing call features as call pickup, parking and transfer
00022  *
00023  * \author Mark Spencer <markster@digium.com> 
00024  */
00025 
00026 /*** MODULEINFO
00027    <support_level>core</support_level>
00028  ***/
00029 
00030 #include "asterisk.h"
00031 
00032 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 332100 $")
00033 
00034 #include "asterisk/_private.h"
00035 
00036 #include <pthread.h>
00037 #include <signal.h>
00038 #include <sys/time.h>
00039 #include <sys/signal.h>
00040 #include <netinet/in.h>
00041 
00042 #include "asterisk/lock.h"
00043 #include "asterisk/file.h"
00044 #include "asterisk/channel.h"
00045 #include "asterisk/pbx.h"
00046 #include "asterisk/causes.h"
00047 #include "asterisk/module.h"
00048 #include "asterisk/translate.h"
00049 #include "asterisk/app.h"
00050 #include "asterisk/say.h"
00051 #include "asterisk/features.h"
00052 #include "asterisk/musiconhold.h"
00053 #include "asterisk/config.h"
00054 #include "asterisk/cli.h"
00055 #include "asterisk/manager.h"
00056 #include "asterisk/utils.h"
00057 #include "asterisk/adsi.h"
00058 #include "asterisk/devicestate.h"
00059 #include "asterisk/monitor.h"
00060 #include "asterisk/audiohook.h"
00061 #include "asterisk/global_datastores.h"
00062 #include "asterisk/astobj2.h"
00063 #include "asterisk/cel.h"
00064 #include "asterisk/test.h"
00065 
00066 /*
00067  * Party A - transferee
00068  * Party B - transferer
00069  * Party C - target of transfer
00070  *
00071  * DTMF attended transfer works within the channel bridge.
00072  * Unfortunately, when either party A or B in the channel bridge
00073  * hangs up, that channel is not completely hung up until the
00074  * transfer completes.  This is a real problem depending upon
00075  * the channel technology involved.
00076  *
00077  * For chan_dahdi, the channel is crippled until the hangup is
00078  * complete.  Either the channel is not useable (analog) or the
00079  * protocol disconnect messages are held up (PRI/BRI/SS7) and
00080  * the media is not released.
00081  *
00082  * For chan_sip, a call limit of one is going to block that
00083  * endpoint from any further calls until the hangup is complete.
00084  *
00085  * For party A this is a minor problem.  The party A channel
00086  * will only be in this condition while party B is dialing and
00087  * when party B and C are conferring.  The conversation between
00088  * party B and C is expected to be a short one.  Party B is
00089  * either asking a question of party C or announcing party A.
00090  * Also party A does not have much incentive to hangup at this
00091  * point.
00092  *
00093  * For party B this can be a major problem during a blonde
00094  * transfer.  (A blonde transfer is our term for an attended
00095  * transfer that is converted into a blind transfer. :))  Party
00096  * B could be the operator.  When party B hangs up, he assumes
00097  * that he is out of the original call entirely.  The party B
00098  * channel will be in this condition while party C is ringing,
00099  * while attempting to recall party B, and while waiting between
00100  * call attempts.
00101  *
00102  * WARNING:
00103  * The ATXFER_NULL_TECH conditional is a hack to fix the
00104  * problem.  It will replace the party B channel technology with
00105  * a NULL channel driver.  The consequences of this code is that
00106  * the 'h' extension will not be able to access any channel
00107  * technology specific information like SIP statistics for the
00108  * call.
00109  *
00110  * Uncomment the ATXFER_NULL_TECH define below to replace the
00111  * party B channel technology in the channel bridge to complete
00112  * hanging up the channel technology.
00113  */
00114 //#define ATXFER_NULL_TECH 1
00115 
00116 /*** DOCUMENTATION
00117    <application name="Bridge" language="en_US">
00118       <synopsis>
00119          Bridge two channels.
00120       </synopsis>
00121       <syntax>
00122          <parameter name="channel" required="true">
00123             <para>The current channel is bridged to the specified <replaceable>channel</replaceable>.</para>
00124          </parameter>
00125          <parameter name="options">
00126             <optionlist>
00127                <option name="p">
00128                   <para>Play a courtesy tone to <replaceable>channel</replaceable>.</para>
00129                </option>
00130                <option name="h">
00131                   <para>Allow the called party to hang up by sending the
00132                   <replaceable>*</replaceable> DTMF digit.</para>
00133                </option>
00134                <option name="H">
00135                   <para>Allow the calling party to hang up by pressing the
00136                   <replaceable>*</replaceable> DTMF digit.</para>
00137                </option>
00138                <option name="k">
00139                   <para>Allow the called 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="K">
00143                   <para>Allow the calling party to enable parking of the call by sending
00144                    the DTMF sequence defined for call parking in <filename>features.conf</filename>.</para>
00145                </option>
00146                <option name="L(x[:y][:z])">
00147                   <para>Limit the call to <replaceable>x</replaceable> ms. Play a warning
00148                   when <replaceable>y</replaceable> ms are left. Repeat the warning every
00149                   <replaceable>z</replaceable> ms. The following special variables can be
00150                   used with this option:</para>
00151                   <variablelist>
00152                      <variable name="LIMIT_PLAYAUDIO_CALLER">
00153                         <para>Play sounds to the caller. yes|no (default yes)</para>
00154                      </variable>
00155                      <variable name="LIMIT_PLAYAUDIO_CALLEE">   
00156                         <para>Play sounds to the callee. yes|no</para>
00157                      </variable>
00158                      <variable name="LIMIT_TIMEOUT_FILE">
00159                         <para>File to play when time is up.</para>
00160                      </variable>
00161                      <variable name="LIMIT_CONNECT_FILE">
00162                         <para>File to play when call begins.</para>
00163                      </variable>
00164                      <variable name="LIMIT_WARNING_FILE">
00165                         <para>File to play as warning if <replaceable>y</replaceable> is
00166                         defined. The default is to say the time remaining.</para>
00167                      </variable>
00168                   </variablelist>
00169                </option>
00170                <option name="S(x)">
00171                   <para>Hang up the call after <replaceable>x</replaceable> seconds *after* the called party has answered the call.</para>
00172                </option>
00173                <option name="t">
00174                   <para>Allow the called party to transfer the calling party by sending the
00175                   DTMF sequence defined in <filename>features.conf</filename>.</para>
00176                </option>
00177                <option name="T">
00178                   <para>Allow the calling party to transfer the called party by sending the
00179                   DTMF sequence defined in <filename>features.conf</filename>.</para>
00180                </option>
00181                <option name="w">
00182                   <para>Allow the called 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="W">
00186                   <para>Allow the calling party to enable recording of the call by sending
00187                   the DTMF sequence defined for one-touch recording in <filename>features.conf</filename>.</para>
00188                </option>
00189                <option name="x">
00190                   <para>Cause the called party to be hung up after the bridge, instead of being
00191                   restarted in the dialplan.</para>
00192                </option>
00193             </optionlist>
00194          </parameter>
00195       </syntax>
00196       <description>
00197          <para>Allows the ability to bridge two channels via the dialplan.</para>
00198          <para>This application sets the following channel variable upon completion:</para>
00199          <variablelist>
00200             <variable name="BRIDGERESULT">
00201                <para>The result of the bridge attempt as a text string.</para>
00202                <value name="SUCCESS" />
00203                <value name="FAILURE" />
00204                <value name="LOOP" />
00205                <value name="NONEXISTENT" />
00206                <value name="INCOMPATIBLE" />
00207             </variable>
00208          </variablelist>
00209       </description>
00210    </application>
00211    <application name="ParkedCall" language="en_US">
00212       <synopsis>
00213          Retrieve a parked call.
00214       </synopsis>
00215       <syntax>
00216          <parameter name="exten">
00217             <para>Parking space extension to retrieve a parked call.
00218             If not provided then the first available parked call in the
00219             parking lot will be retrieved.</para>
00220          </parameter>
00221          <parameter name="parking_lot_name">
00222             <para>Specify from which parking lot to retrieve a parked call.</para>
00223             <para>The parking lot used is selected in the following order:</para>
00224             <para>1) parking_lot_name option</para>
00225             <para>2) <variable>PARKINGLOT</variable> variable</para>
00226             <para>3) <literal>CHANNEL(parkinglot)</literal> function
00227             (Possibly preset by the channel driver.)</para>
00228             <para>4) Default parking lot.</para>
00229          </parameter>
00230       </syntax>
00231       <description>
00232          <para>Used to retrieve a parked call from a parking lot.</para>
00233          <note>
00234             <para>Parking lots automatically create and manage dialplan extensions in
00235             the parking lot context.  You do not need to explicitly use this
00236             application in your dialplan.  Instead, all you should do is include the
00237             parking lot context in your dialplan.</para>
00238          </note>
00239       </description>
00240       <see-also>
00241          <ref type="application">Park</ref>
00242          <ref type="application">ParkAndAnnounce</ref>
00243       </see-also>
00244    </application>
00245    <application name="Park" language="en_US">
00246       <synopsis>
00247          Park yourself.
00248       </synopsis>
00249       <syntax>
00250          <parameter name="timeout">
00251             <para>A custom parking timeout for this parked call. Value in milliseconds.</para>
00252          </parameter>
00253          <parameter name="return_context">
00254             <para>The context to return the call to after it times out.</para>
00255          </parameter>
00256          <parameter name="return_exten">
00257             <para>The extension to return the call to after it times out.</para>
00258          </parameter>
00259          <parameter name="return_priority">
00260             <para>The priority to return the call to after it times out.</para>
00261          </parameter>
00262          <parameter name="options">
00263             <para>A list of options for this parked call.</para>
00264             <optionlist>
00265                <option name="r">
00266                   <para>Send ringing instead of MOH to the parked call.</para>
00267                </option>
00268                <option name="R">
00269                   <para>Randomize the selection of a parking space.</para>
00270                </option>
00271                <option name="s">
00272                   <para>Silence announcement of the parking space number.</para>
00273                </option>
00274             </optionlist>
00275          </parameter>
00276          <parameter name="parking_lot_name">
00277             <para>Specify in which parking lot to park a call.</para>
00278             <para>The parking lot used is selected in the following order:</para>
00279             <para>1) parking_lot_name option</para>
00280             <para>2) <variable>PARKINGLOT</variable> variable</para>
00281             <para>3) <literal>CHANNEL(parkinglot)</literal> function
00282             (Possibly preset by the channel driver.)</para>
00283             <para>4) Default parking lot.</para>
00284          </parameter>
00285       </syntax>
00286       <description>
00287          <para>Used to park yourself (typically in combination with a supervised
00288          transfer to know the parking space).</para>
00289          <para>If you set the <variable>PARKINGEXTEN</variable> variable to a
00290          parking space extension in the parking lot, Park() will attempt to park the call
00291          on that extension.  If the extension is already is in use then execution
00292          will continue at the next priority.</para>
00293          <para>If the <literal>parkeddynamic</literal> option is enabled in <filename>features.conf</filename>
00294          the following variables can be used to dynamically create new parking lots.</para>
00295          <para>If you set the <variable>PARKINGDYNAMIC</variable> variable and this parking lot
00296          exists then it will be used as a template for the newly created dynamic lot.  Otherwise,
00297          the default parking lot will be used.</para>
00298          <para>If you set the <variable>PARKINGDYNCONTEXT</variable> variable then the newly created dynamic
00299          parking lot will use this context.</para>
00300          <para>If you set the <variable>PARKINGDYNEXTEN</variable> variable then the newly created dynamic
00301          parking lot will use this extension to access the parking lot.</para>
00302          <para>If you set the <variable>PARKINGDYNPOS</variable> variable then the newly created dynamic parking lot
00303          will use those parking postitions.</para>
00304          <note>
00305             <para>This application must be used as the first extension priority
00306             to be recognized as a parking access extension.  DTMF transfers
00307             and some channel drivers need this distinction to operate properly.
00308             The parking access extension in this case is treated like a dialplan
00309             hint.</para>
00310          </note>
00311          <note>
00312             <para>Parking lots automatically create and manage dialplan extensions in
00313             the parking lot context.  You do not need to explicitly use this
00314             application in your dialplan.  Instead, all you should do is include the
00315             parking lot context in your dialplan.</para>
00316          </note>
00317       </description>
00318       <see-also>
00319          <ref type="application">ParkAndAnnounce</ref>
00320          <ref type="application">ParkedCall</ref>
00321       </see-also>
00322    </application>
00323    <manager name="ParkedCalls" language="en_US">
00324       <synopsis>
00325          List parked calls.
00326       </synopsis>
00327       <syntax>
00328          <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
00329       </syntax>
00330       <description>
00331          <para>List parked calls.</para>
00332       </description>
00333    </manager>
00334    <manager name="Park" language="en_US">
00335       <synopsis>
00336          Park a channel.
00337       </synopsis>
00338       <syntax>
00339          <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
00340          <parameter name="Channel" required="true">
00341             <para>Channel name to park.</para>
00342          </parameter>
00343          <parameter name="Channel2" required="true">
00344             <para>Channel to announce park info to (and return to if timeout).</para>
00345          </parameter>
00346          <parameter name="Timeout">
00347             <para>Number of milliseconds to wait before callback.</para>
00348          </parameter>
00349          <parameter name="Parkinglot">
00350             <para>Specify in which parking lot to park the channel.</para>
00351          </parameter>
00352       </syntax>
00353       <description>
00354          <para>Park a channel.</para>
00355       </description>
00356    </manager>
00357    <manager name="Bridge" language="en_US">
00358       <synopsis>
00359          Bridge two channels already in the PBX.
00360       </synopsis>
00361       <syntax>
00362          <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
00363          <parameter name="Channel1" required="true">
00364             <para>Channel to Bridge to Channel2.</para>
00365          </parameter>
00366          <parameter name="Channel2" required="true">
00367             <para>Channel to Bridge to Channel1.</para>
00368          </parameter>
00369          <parameter name="Tone">
00370             <para>Play courtesy tone to Channel 2.</para>
00371             <enumlist>
00372                <enum name="yes" />
00373                <enum name="no" />
00374             </enumlist>
00375          </parameter>
00376       </syntax>
00377       <description>
00378          <para>Bridge together two channels already in the PBX.</para>
00379       </description>
00380    </manager>
00381  ***/
00382 
00383 #define DEFAULT_PARK_TIME                    45000 /*!< ms */
00384 #define DEFAULT_PARK_EXTENSION                  "700"
00385 #define DEFAULT_TRANSFER_DIGIT_TIMEOUT          3000  /*!< ms */
00386 #define DEFAULT_FEATURE_DIGIT_TIMEOUT           1000  /*!< ms */
00387 #define DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER 15000 /*!< ms */
00388 #define DEFAULT_ATXFER_DROP_CALL             0     /*!< Do not drop call. */
00389 #define DEFAULT_ATXFER_LOOP_DELAY               10000 /*!< ms */
00390 #define DEFAULT_ATXFER_CALLBACK_RETRIES            2
00391 
00392 #define AST_MAX_WATCHERS 256
00393 #define MAX_DIAL_FEATURE_OPTIONS 30
00394 
00395 struct feature_group_exten {
00396    AST_LIST_ENTRY(feature_group_exten) entry;
00397    AST_DECLARE_STRING_FIELDS(
00398       AST_STRING_FIELD(exten);
00399    );
00400    struct ast_call_feature *feature;
00401 };
00402 
00403 struct feature_group {
00404    AST_LIST_ENTRY(feature_group) entry;
00405    AST_DECLARE_STRING_FIELDS(
00406       AST_STRING_FIELD(gname);
00407    );
00408    AST_LIST_HEAD_NOLOCK(, feature_group_exten) features;
00409 };
00410 
00411 static AST_RWLIST_HEAD_STATIC(feature_groups, feature_group);
00412 
00413 typedef enum {
00414    FEATURE_INTERPRET_DETECT, /* Used by ast_feature_detect */
00415    FEATURE_INTERPRET_DO,     /* Used by feature_interpret */
00416    FEATURE_INTERPRET_CHECK,  /* Used by feature_check */
00417 } feature_interpret_op;
00418 
00419 static char *parkedcall = "ParkedCall";
00420 
00421 static char pickup_ext[AST_MAX_EXTENSION];                 /*!< Call pickup extension */
00422 
00423 /*! Parking lot access ramp dialplan usage entry. */
00424 struct parking_dp_ramp {
00425    /*! Next node in the parking lot spaces dialplan list. */
00426    AST_LIST_ENTRY(parking_dp_ramp) node;
00427    /*! TRUE if the parking lot access extension is exclusive. */
00428    unsigned int exclusive:1;
00429    /*! Parking lot access extension */
00430    char exten[1];
00431 };
00432 
00433 /*! Parking lot dialplan access ramp map */
00434 AST_LIST_HEAD_NOLOCK(parking_dp_ramp_map, parking_dp_ramp);
00435 
00436 /*! Parking lot spaces dialplan usage entry. */
00437 struct parking_dp_spaces {
00438    /*! Next node in the parking lot spaces dialplan list. */
00439    AST_LIST_ENTRY(parking_dp_spaces) node;
00440    /*! First parking space */
00441    int start;
00442    /*! Last parking space */
00443    int stop;
00444 };
00445 
00446 /*! Parking lot dialplan context space map */
00447 AST_LIST_HEAD_NOLOCK(parking_dp_space_map, parking_dp_spaces);
00448 
00449 /*! Parking lot context dialplan usage entry. */
00450 struct parking_dp_context {
00451    /*! Next node in the parking lot contexts dialplan list. */
00452    AST_LIST_ENTRY(parking_dp_context) node;
00453    /*! Parking access extensions defined in this context. */
00454    struct parking_dp_ramp_map access_extens;
00455    /*! Parking spaces defined in this context. */
00456    struct parking_dp_space_map spaces;
00457    /*! Parking hints defined in this context. */
00458    struct parking_dp_space_map hints;
00459    /*! Parking lot context name */
00460    char context[1];
00461 };
00462 
00463 /*! Parking lot dialplan usage map. */
00464 AST_LIST_HEAD_NOLOCK(parking_dp_map, parking_dp_context);
00465 
00466 /*!
00467  * \brief Description of one parked call, added to a list while active, then removed.
00468  * The list belongs to a parkinglot.
00469  */
00470 struct parkeduser {
00471    struct ast_channel *chan;                   /*!< Parked channel */
00472    struct timeval start;                       /*!< Time the park started */
00473    int parkingnum;                             /*!< Parking lot space used */
00474    char parkingexten[AST_MAX_EXTENSION];       /*!< If set beforehand, parking extension used for this call */
00475    char context[AST_MAX_CONTEXT];              /*!< Where to go if our parking time expires */
00476    char exten[AST_MAX_EXTENSION];
00477    int priority;
00478    int parkingtime;                            /*!< Maximum length in parking lot before return */
00479    /*! Method to entertain the caller when parked: AST_CONTROL_RINGING, AST_CONTROL_HOLD, or 0(none) */
00480    enum ast_control_frame_type hold_method;
00481    unsigned int notquiteyet:1;
00482    unsigned int options_specified:1;
00483    char peername[1024];
00484    unsigned char moh_trys;
00485    /*! Parking lot this entry belongs to.  Holds a parking lot reference. */
00486    struct ast_parkinglot *parkinglot;
00487    AST_LIST_ENTRY(parkeduser) list;
00488 };
00489 
00490 /*! Parking lot configuration options. */
00491 struct parkinglot_cfg {
00492    /*! Music class used for parking */
00493    char mohclass[MAX_MUSICCLASS];
00494    /*! Extension to park calls in this parking lot. */
00495    char parkext[AST_MAX_EXTENSION];
00496    /*! Context for which parking is made accessible */
00497    char parking_con[AST_MAX_EXTENSION];
00498    /*! First available extension for parking */
00499    int parking_start;
00500    /*! Last available extension for parking */
00501    int parking_stop;
00502    /*! Default parking time in ms. */
00503    int parkingtime;
00504    /*!
00505     * \brief Enable DTMF based transfers on bridge when picking up parked calls.
00506     *
00507     * \details
00508     * none(0)
00509     * AST_FEATURE_FLAG_BYCALLEE
00510     * AST_FEATURE_FLAG_BYCALLER
00511     * AST_FEATURE_FLAG_BYBOTH
00512     */
00513    int parkedcalltransfers;
00514    /*!
00515     * \brief Enable DTMF based parking on bridge when picking up parked calls.
00516     *
00517     * \details
00518     * none(0)
00519     * AST_FEATURE_FLAG_BYCALLEE
00520     * AST_FEATURE_FLAG_BYCALLER
00521     * AST_FEATURE_FLAG_BYBOTH
00522     */
00523    int parkedcallreparking;
00524    /*!
00525     * \brief Enable DTMF based hangup on a bridge when pickup up parked calls.
00526     *
00527     * \details
00528     * none(0)
00529     * AST_FEATURE_FLAG_BYCALLEE
00530     * AST_FEATURE_FLAG_BYCALLER
00531     * AST_FEATURE_FLAG_BYBOTH
00532     */
00533    int parkedcallhangup;
00534    /*!
00535     * \brief Enable DTMF based recording on a bridge when picking up parked calls.
00536     *
00537     * \details
00538     * none(0)
00539     * AST_FEATURE_FLAG_BYCALLEE
00540     * AST_FEATURE_FLAG_BYCALLER
00541     * AST_FEATURE_FLAG_BYBOTH
00542     */
00543    int parkedcallrecording;
00544 
00545    /*! TRUE if findslot is set to next */
00546    unsigned int parkfindnext:1;
00547    /*! TRUE if the parking lot is exclusively accessed by parkext */
00548    unsigned int parkext_exclusive:1;
00549    /*! Add parking hints automatically */
00550    unsigned int parkaddhints:1;
00551    /*! TRUE if configuration is invalid and the parking lot should not be used. */
00552    unsigned int is_invalid:1;
00553 };
00554 
00555 /*! \brief Structure for parking lots which are put in a container. */
00556 struct ast_parkinglot {
00557    /*! Name of the parking lot. */
00558    char name[AST_MAX_CONTEXT];
00559    /*! Parking lot user configuration. */
00560    struct parkinglot_cfg cfg;
00561 
00562    /*! Parking space to start next park search. */
00563    int next_parking_space;
00564 
00565    /*! That which bears the_mark shall be deleted if parking lot empty! (Used during reloads.) */
00566    unsigned int the_mark:1;
00567    /*! TRUE if the parking lot is disabled. */
00568    unsigned int disabled:1;
00569 
00570    /*! List of active parkings in this parkinglot */
00571    AST_LIST_HEAD(parkinglot_parklist, parkeduser) parkings;
00572 };
00573 
00574 /*! \brief The configured parking lots container. Always at least one  - the default parking lot */
00575 static struct ao2_container *parkinglots;
00576 
00577 /*!
00578  * \brief Default parking lot.
00579  * \note Holds a parkinglot reference.
00580  * \note Will not be NULL while running.
00581  */
00582 static struct ast_parkinglot *default_parkinglot;
00583 
00584 /*! Force a config reload to reload regardless of config file timestamp. */
00585 static int force_reload_load;
00586 
00587 static int parkedplay = 0;                                 /*!< Who to play courtesytone to when someone picks up a parked call. */
00588 static int parkeddynamic = 0;                              /*!< Enable creation of parkinglots dynamically */
00589 static char courtesytone[256];                             /*!< Courtesy tone used to pickup parked calls and on-touch-record */
00590 static char xfersound[256];                                /*!< Call transfer sound */
00591 static char xferfailsound[256];                            /*!< Call transfer failure sound */
00592 static char pickupsound[256];                              /*!< Pickup sound */
00593 static char pickupfailsound[256];                          /*!< Pickup failure sound */
00594 
00595 /*!
00596  * \brief Context for parking dialback to parker.
00597  * \note The need for the context is a KLUDGE.
00598  *
00599  * \todo Might be able to eliminate the parking_con_dial context
00600  * kludge by running app_dial directly in its own thread to
00601  * simulate a PBX.
00602  */
00603 static char parking_con_dial[] = "park-dial";
00604 
00605 /*! Ensure that features.conf reloads on one thread at a time. */
00606 AST_MUTEX_DEFINE_STATIC(features_reload_lock);
00607 
00608 static int adsipark;
00609 
00610 static int transferdigittimeout;
00611 static int featuredigittimeout;
00612 static int comebacktoorigin = 1;
00613 
00614 static int atxfernoanswertimeout;
00615 static unsigned int atxferdropcall;
00616 static unsigned int atxferloopdelay;
00617 static unsigned int atxfercallbackretries;
00618 
00619 static char *registrar = "features";         /*!< Registrar for operations */
00620 
00621 /*! PARK_APP_NAME application arguments */
00622 AST_DEFINE_APP_ARGS_TYPE(park_app_args,
00623    AST_APP_ARG(timeout);      /*!< Time in ms to remain in the parking lot. */
00624    AST_APP_ARG(return_con);   /*!< Context to return parked call if timeout. */
00625    AST_APP_ARG(return_ext);   /*!< Exten to return parked call if timeout. */
00626    AST_APP_ARG(return_pri);   /*!< Priority to return parked call if timeout. */
00627    AST_APP_ARG(options);      /*!< Parking option flags. */
00628    AST_APP_ARG(pl_name);      /*!< Parking lot name to use if present. */
00629    AST_APP_ARG(dummy);        /*!< Place to put any remaining args string. */
00630    );
00631 
00632 /* module and CLI command definitions */
00633 static char *parkcall = PARK_APP_NAME;
00634 
00635 static struct ast_app *monitor_app = NULL;
00636 static int monitor_ok = 1;
00637 
00638 static struct ast_app *mixmonitor_app = NULL;
00639 static int mixmonitor_ok = 1;
00640 
00641 static struct ast_app *stopmixmonitor_app = NULL;
00642 static int stopmixmonitor_ok = 1;
00643 
00644 static pthread_t parking_thread;
00645 struct ast_dial_features {
00646    struct ast_flags features_caller;
00647    struct ast_flags features_callee;
00648    int is_caller;
00649 };
00650 
00651 #if defined(ATXFER_NULL_TECH)
00652 /*!
00653  * \internal
00654  * \brief Set the channel technology to the kill technology.
00655  *
00656  * \param chan Channel to change technology.
00657  *
00658  * \return Nothing
00659  */
00660 static void set_kill_chan_tech(struct ast_channel *chan)
00661 {
00662    int idx;
00663 
00664    ast_channel_lock(chan);
00665 
00666    /* Hangup the channel's physical side */
00667    if (chan->tech->hangup) {
00668       chan->tech->hangup(chan);
00669    }
00670    if (chan->tech_pvt) {
00671       ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n",
00672          chan->name);
00673       ast_free(chan->tech_pvt);
00674       chan->tech_pvt = NULL;
00675    }
00676 
00677    /* Install the kill technology and wake up anyone waiting on it. */
00678    chan->tech = &ast_kill_tech;
00679    for (idx = 0; idx < AST_MAX_FDS; ++idx) {
00680       switch (idx) {
00681       case AST_ALERT_FD:
00682       case AST_TIMING_FD:
00683       case AST_GENERATOR_FD:
00684          /* Don't clear these fd's. */
00685          break;
00686       default:
00687          ast_channel_set_fd(chan, idx, -1);
00688          break;
00689       }
00690    }
00691    ast_queue_frame(chan, &ast_null_frame);
00692 
00693    ast_channel_unlock(chan);
00694 }
00695 #endif   /* defined(ATXFER_NULL_TECH) */
00696 
00697 #if defined(ATXFER_NULL_TECH)
00698 /*!
00699  * \internal
00700  * \brief Set the channel name to something unique.
00701  *
00702  * \param chan Channel to change name.
00703  *
00704  * \return Nothing
00705  */
00706 static void set_new_chan_name(struct ast_channel *chan)
00707 {
00708    static int seq_num_last;
00709    int seq_num;
00710    int len;
00711    char *chan_name;
00712    char dummy[1];
00713 
00714    /* Create the new channel name string. */
00715    ast_channel_lock(chan);
00716    seq_num = ast_atomic_fetchadd_int(&seq_num_last, +1);
00717    len = snprintf(dummy, sizeof(dummy), "%s<XFER_%x>", chan->name, seq_num) + 1;
00718    chan_name = alloca(len);
00719    snprintf(chan_name, len, "%s<XFER_%x>", chan->name, seq_num);
00720    ast_channel_unlock(chan);
00721 
00722    ast_change_name(chan, chan_name);
00723 }
00724 #endif   /* defined(ATXFER_NULL_TECH) */
00725 
00726 static void *dial_features_duplicate(void *data)
00727 {
00728    struct ast_dial_features *df = data, *df_copy;
00729  
00730    if (!(df_copy = ast_calloc(1, sizeof(*df)))) {
00731       return NULL;
00732    }
00733  
00734    memcpy(df_copy, df, sizeof(*df));
00735  
00736    return df_copy;
00737 }
00738 
00739 static void dial_features_destroy(void *data)
00740 {
00741    struct ast_dial_features *df = data;
00742    if (df) {
00743       ast_free(df);
00744    }
00745 }
00746 
00747 static const struct ast_datastore_info dial_features_info = {
00748    .type = "dial-features",
00749    .destroy = dial_features_destroy,
00750    .duplicate = dial_features_duplicate,
00751 };
00752  
00753 /* Forward declarations */
00754 static struct ast_parkinglot *parkinglot_addref(struct ast_parkinglot *parkinglot);
00755 static void parkinglot_unref(struct ast_parkinglot *parkinglot);
00756 static struct ast_parkinglot *find_parkinglot(const char *name);
00757 static struct ast_parkinglot *create_parkinglot(const char *name);
00758 static struct ast_parkinglot *copy_parkinglot(const char *name, const struct ast_parkinglot *parkinglot);
00759 static int parkinglot_activate(struct ast_parkinglot *parkinglot);
00760 static int play_message_on_chan(struct ast_channel *play_to, struct ast_channel *other, const char *msg, const char *audiofile);
00761 
00762 /*!
00763  * \internal
00764  * \brief Get the parking extension if it exists.
00765  *
00766  * \param exten_str Parking extension to see if exists.
00767  * \param chan Channel to autoservice while looking for exten.  (Could be NULL)
00768  * \param context Parking context to look in for exten.
00769  *
00770  * \retval exten on success.
00771  * \retval NULL on error or exten does not exist.
00772  */
00773 static struct ast_exten *get_parking_exten(const char *exten_str, struct ast_channel *chan, const char *context)
00774 {
00775    struct ast_exten *exten;
00776    struct pbx_find_info q = { .stacklen = 0 }; /* the rest is reset in pbx_find_extension */
00777    const char *app_at_exten;
00778 
00779    exten = pbx_find_extension(chan, NULL, &q, context, exten_str, 1, NULL, NULL,
00780       E_MATCH);
00781    if (!exten) {
00782       return NULL;
00783    }
00784 
00785    app_at_exten = ast_get_extension_app(exten);
00786    if (!app_at_exten || strcasecmp(PARK_APP_NAME, app_at_exten)) {
00787       return NULL;
00788    }
00789 
00790    return exten;
00791 }
00792 
00793 int ast_parking_ext_valid(const char *exten_str, struct ast_channel *chan, const char *context)
00794 {
00795    return get_parking_exten(exten_str, chan, context) ? 1 : 0;
00796 }
00797 
00798 const char *ast_pickup_ext(void)
00799 {
00800    return pickup_ext;
00801 }
00802 
00803 struct ast_bridge_thread_obj 
00804 {
00805    struct ast_bridge_config bconfig;
00806    struct ast_channel *chan;
00807    struct ast_channel *peer;
00808    unsigned int return_to_pbx:1;
00809 };
00810 
00811 static int parkinglot_hash_cb(const void *obj, const int flags)
00812 {
00813    const struct ast_parkinglot *parkinglot = obj;
00814 
00815    return ast_str_case_hash(parkinglot->name);
00816 }
00817 
00818 static int parkinglot_cmp_cb(void *obj, void *arg, int flags)
00819 {
00820    struct ast_parkinglot *parkinglot = obj;
00821    struct ast_parkinglot *parkinglot2 = arg;
00822 
00823    return !strcasecmp(parkinglot->name, parkinglot2->name) ? CMP_MATCH | CMP_STOP : 0;
00824 }
00825 
00826 /*!
00827  * \brief store context, extension and priority 
00828  * \param chan, context, ext, pri
00829  */
00830 static void set_c_e_p(struct ast_channel *chan, const char *context, const char *ext, int pri)
00831 {
00832    ast_copy_string(chan->context, context, sizeof(chan->context));
00833    ast_copy_string(chan->exten, ext, sizeof(chan->exten));
00834    chan->priority = pri;
00835 }
00836 
00837 /*!
00838  * \brief Check goto on transfer
00839  * \param chan
00840  *
00841  * Check if channel has 'GOTO_ON_BLINDXFR' set, if not exit.
00842  * When found make sure the types are compatible. Check if channel is valid
00843  * if so start the new channel else hangup the call. 
00844  */
00845 static void check_goto_on_transfer(struct ast_channel *chan) 
00846 {
00847    struct ast_channel *xferchan;
00848    const char *val = pbx_builtin_getvar_helper(chan, "GOTO_ON_BLINDXFR");
00849    char *x, *goto_on_transfer;
00850    struct ast_frame *f;
00851 
00852    if (ast_strlen_zero(val))
00853       return;
00854 
00855    goto_on_transfer = ast_strdupa(val);
00856 
00857    if (!(xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", chan->linkedid, 0, "%s", chan->name)))
00858       return;
00859 
00860    for (x = goto_on_transfer; x && *x; x++) {
00861       if (*x == '^')
00862          *x = ',';
00863    }
00864    /* Make formats okay */
00865    xferchan->readformat = chan->readformat;
00866    xferchan->writeformat = chan->writeformat;
00867    ast_channel_masquerade(xferchan, chan);
00868    ast_parseable_goto(xferchan, goto_on_transfer);
00869    xferchan->_state = AST_STATE_UP;
00870    ast_clear_flag(xferchan, AST_FLAGS_ALL);  
00871    ast_channel_clear_softhangup(xferchan, AST_SOFTHANGUP_ALL);
00872    if ((f = ast_read(xferchan))) {
00873       ast_frfree(f);
00874       f = NULL;
00875       ast_pbx_start(xferchan);
00876    } else {
00877       ast_hangup(xferchan);
00878    }
00879 }
00880 
00881 static struct ast_channel *feature_request_and_dial(struct ast_channel *caller,
00882    const char *caller_name, struct ast_channel *requestor,
00883    struct ast_channel *transferee, const char *type, format_t format, void *data,
00884    int timeout, int *outstate, const char *language);
00885 
00886 /*!
00887  * \brief bridge the call 
00888  * \param data thread bridge.
00889  *
00890  * Set Last Data for respective channels, reset cdr for channels
00891  * bridge call, check if we're going back to dialplan
00892  * if not hangup both legs of the call
00893  */
00894 static void *bridge_call_thread(void *data)
00895 {
00896    struct ast_bridge_thread_obj *tobj = data;
00897    int res;
00898 
00899    tobj->chan->appl = !tobj->return_to_pbx ? "Transferred Call" : "ManagerBridge";
00900    tobj->chan->data = tobj->peer->name;
00901    tobj->peer->appl = !tobj->return_to_pbx ? "Transferred Call" : "ManagerBridge";
00902    tobj->peer->data = tobj->chan->name;
00903 
00904    ast_bridge_call(tobj->peer, tobj->chan, &tobj->bconfig);
00905 
00906    if (tobj->return_to_pbx) {
00907       if (!ast_check_hangup(tobj->peer)) {
00908          ast_log(LOG_VERBOSE, "putting peer %s into PBX again\n", tobj->peer->name);
00909          res = ast_pbx_start(tobj->peer);
00910          if (res != AST_PBX_SUCCESS)
00911             ast_log(LOG_WARNING, "FAILED continuing PBX on peer %s\n", tobj->peer->name);
00912       } else
00913          ast_hangup(tobj->peer);
00914       if (!ast_check_hangup(tobj->chan)) {
00915          ast_log(LOG_VERBOSE, "putting chan %s into PBX again\n", tobj->chan->name);
00916          res = ast_pbx_start(tobj->chan);
00917          if (res != AST_PBX_SUCCESS)
00918             ast_log(LOG_WARNING, "FAILED continuing PBX on chan %s\n", tobj->chan->name);
00919       } else
00920          ast_hangup(tobj->chan);
00921    } else {
00922       ast_hangup(tobj->chan);
00923       ast_hangup(tobj->peer);
00924    }
00925 
00926    ast_free(tobj);
00927 
00928    return NULL;
00929 }
00930 
00931 /*!
00932  * \brief create thread for the parked call
00933  * \param data
00934  *
00935  * Create thread and attributes, call bridge_call_thread
00936  */
00937 static void bridge_call_thread_launch(void *data) 
00938 {
00939    pthread_t thread;
00940    pthread_attr_t attr;
00941    struct sched_param sched;
00942 
00943    pthread_attr_init(&attr);
00944    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
00945    ast_pthread_create(&thread, &attr, bridge_call_thread, data);
00946    pthread_attr_destroy(&attr);
00947    memset(&sched, 0, sizeof(sched));
00948    pthread_setschedparam(thread, SCHED_RR, &sched);
00949 }
00950 
00951 /*!
00952  * \brief Announce call parking by ADSI
00953  * \param chan .
00954  * \param parkingexten .
00955  * Create message to show for ADSI, display message.
00956  * \retval 0 on success.
00957  * \retval -1 on failure.
00958  */
00959 static int adsi_announce_park(struct ast_channel *chan, char *parkingexten)
00960 {
00961    int res;
00962    int justify[5] = {ADSI_JUST_CENT, ADSI_JUST_CENT, ADSI_JUST_CENT, ADSI_JUST_CENT};
00963    char tmp[256];
00964    char *message[5] = {NULL, NULL, NULL, NULL, NULL};
00965 
00966    snprintf(tmp, sizeof(tmp), "Parked on %s", parkingexten);
00967    message[0] = tmp;
00968    res = ast_adsi_load_session(chan, NULL, 0, 1);
00969    if (res == -1)
00970       return res;
00971    return ast_adsi_print(chan, message, justify, 1);
00972 }
00973 
00974 /*!
00975  * \brief Find parking lot name from channel
00976  * \note Channel needs to be locked while the returned string is in use.
00977  */
00978 static const char *findparkinglotname(struct ast_channel *chan)
00979 {
00980    const char *name;
00981 
00982    /* The channel variable overrides everything */
00983    name = pbx_builtin_getvar_helper(chan, "PARKINGLOT");
00984    if (!name && !ast_strlen_zero(chan->parkinglot)) {
00985       /* Use the channel's parking lot. */
00986       name = chan->parkinglot;
00987    }
00988    return name;
00989 }
00990 
00991 /*! \brief Notify metermaids that we've changed an extension */
00992 static void notify_metermaids(const char *exten, char *context, enum ast_device_state state)
00993 {
00994    ast_debug(4, "Notification of state change to metermaids %s@%s\n to state '%s'", 
00995       exten, context, ast_devstate2str(state));
00996 
00997    ast_devstate_changed(state, "park:%s@%s", exten, context);
00998 }
00999 
01000 /*! \brief metermaids callback from devicestate.c */
01001 static enum ast_device_state metermaidstate(const char *data)
01002 {
01003    char *context;
01004    char *exten;
01005 
01006    context = ast_strdupa(data);
01007 
01008    exten = strsep(&context, "@");
01009    if (!context)
01010       return AST_DEVICE_INVALID;
01011    
01012    ast_debug(4, "Checking state of exten %s in context %s\n", exten, context);
01013 
01014    if (!ast_exists_extension(NULL, context, exten, 1, NULL))
01015       return AST_DEVICE_NOT_INUSE;
01016 
01017    return AST_DEVICE_INUSE;
01018 }
01019 
01020 /*! Options to pass to park_call_full */
01021 enum ast_park_call_options {
01022    /*! Provide ringing to the parked caller instead of music on hold */
01023    AST_PARK_OPT_RINGING =   (1 << 0),
01024    /*! Randomly choose a parking spot for the caller instead of choosing
01025     *  the first one that is available. */
01026    AST_PARK_OPT_RANDOMIZE = (1 << 1),
01027    /*! Do not announce the parking number */
01028    AST_PARK_OPT_SILENCE = (1 << 2),
01029 };
01030 
01031 /*! Optional additional parking options when parking a call. */
01032 struct ast_park_call_args {
01033    /*! How long to wait in the parking lot before the call gets sent back
01034     *  to the specified return extension (or a best guess at where it came
01035     *  from if not explicitly specified). */
01036    int timeout;
01037    /*! An output parameter to store the parking space where the parked caller
01038     *  was placed. */
01039    int *extout;
01040    const char *orig_chan_name;
01041    const char *return_con;
01042    const char *return_ext;
01043    int return_pri;
01044    uint32_t flags;
01045    /*! Parked user that has already obtained a parking space */
01046    struct parkeduser *pu;
01047    /*! \brief Parkinglot to be parked in */
01048    struct ast_parkinglot *parkinglot;
01049 };
01050 
01051 /*!
01052  * \internal
01053  * \brief Create a dynamic parking lot.
01054  *
01055  * \param name Dynamic parking lot name to create.
01056  * \param chan Channel to get dynamic parking lot parameters.
01057  *
01058  * \retval parkinglot on success.
01059  * \retval NULL on error.
01060  */
01061 static struct ast_parkinglot *create_dynamic_parkinglot(const char *name, struct ast_channel *chan)
01062 {
01063    const char *dyn_context;
01064    const char *dyn_exten;
01065    const char *dyn_range;
01066    const char *template_name;
01067    struct ast_parkinglot *template_parkinglot = NULL;
01068    struct ast_parkinglot *parkinglot;
01069    int dyn_start;
01070    int dyn_end;
01071 
01072    ast_channel_lock(chan);
01073    template_name = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGDYNAMIC"), ""));
01074    dyn_context = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGDYNCONTEXT"), ""));
01075    dyn_exten = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGDYNEXTEN"), ""));
01076    dyn_range = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGDYNPOS"), ""));
01077    ast_channel_unlock(chan);
01078 
01079    if (!ast_strlen_zero(template_name)) {
01080       template_parkinglot = find_parkinglot(template_name);
01081       if (!template_parkinglot) {
01082          ast_debug(1, "PARKINGDYNAMIC lot %s does not exist.\n",
01083             template_name);
01084       } else if (template_parkinglot->cfg.is_invalid) {
01085          ast_debug(1, "PARKINGDYNAMIC lot %s has invalid config.\n",
01086             template_name);
01087          parkinglot_unref(template_parkinglot);
01088          template_parkinglot = NULL;
01089       }
01090    }
01091    if (!template_parkinglot) {
01092       template_parkinglot = parkinglot_addref(default_parkinglot);
01093       ast_debug(1, "Using default parking lot for template\n");
01094    }
01095 
01096    parkinglot = copy_parkinglot(name, template_parkinglot);
01097    if (!parkinglot) {
01098       ast_log(LOG_ERROR, "Could not build dynamic parking lot!\n");
01099    } else {
01100       /* Configure the dynamic parking lot. */
01101       if (!ast_strlen_zero(dyn_context)) {
01102          ast_copy_string(parkinglot->cfg.parking_con, dyn_context,
01103             sizeof(parkinglot->cfg.parking_con));
01104       }
01105       if (!ast_strlen_zero(dyn_exten)) {
01106          ast_copy_string(parkinglot->cfg.parkext, dyn_exten,
01107             sizeof(parkinglot->cfg.parkext));
01108       }
01109       if (!ast_strlen_zero(dyn_range)) {
01110          if (sscanf(dyn_range, "%30d-%30d", &dyn_start, &dyn_end) != 2) {
01111             ast_log(LOG_WARNING,
01112                "Format for parking positions is a-b, where a and b are numbers\n");
01113          } else if (dyn_end < dyn_start || dyn_start <= 0 || dyn_end <= 0) {
01114             ast_log(LOG_WARNING,
01115                "Format for parking positions is a-b, where a <= b\n");
01116          } else {
01117             parkinglot->cfg.parking_start = dyn_start;
01118             parkinglot->cfg.parking_stop = dyn_end;
01119          }
01120       }
01121 
01122       /*
01123        * Sanity check for dynamic parking lot configuration.
01124        *
01125        * XXX It may be desirable to instead check if the dynamic
01126        * parking lot overlaps any existing lots like what is done for
01127        * a reload.
01128        */
01129       if (!strcmp(parkinglot->cfg.parking_con, template_parkinglot->cfg.parking_con)) {
01130          if (!strcmp(parkinglot->cfg.parkext, template_parkinglot->cfg.parkext)
01131             && parkinglot->cfg.parkext_exclusive) {
01132             ast_log(LOG_WARNING,
01133                "Parking lot '%s' conflicts with template parking lot '%s'!\n"
01134                "Change either PARKINGDYNCONTEXT or PARKINGDYNEXTEN.\n",
01135                parkinglot->name, template_parkinglot->name);
01136          }
01137          if ((template_parkinglot->cfg.parking_start <= parkinglot->cfg.parking_start
01138                && parkinglot->cfg.parking_start <= template_parkinglot->cfg.parking_stop)
01139             || (template_parkinglot->cfg.parking_start <= parkinglot->cfg.parking_stop
01140                && parkinglot->cfg.parking_stop <= template_parkinglot->cfg.parking_stop)
01141             || (parkinglot->cfg.parking_start < template_parkinglot->cfg.parking_start
01142                && template_parkinglot->cfg.parking_stop < parkinglot->cfg.parking_stop)) {
01143             ast_log(LOG_WARNING,
01144                "Parking lot '%s' parking spaces overlap template parking lot '%s'!\n"
01145                "Change PARKINGDYNPOS.\n",
01146                parkinglot->name, template_parkinglot->name);
01147          }
01148       }
01149 
01150       parkinglot_activate(parkinglot);
01151       ao2_link(parkinglots, parkinglot);
01152    }
01153    parkinglot_unref(template_parkinglot);
01154 
01155    return parkinglot;
01156 }
01157 
01158 /*!
01159  * \internal
01160  * \brief Reserve a parking space in a parking lot for a call being parked.
01161  *
01162  * \param park_me Channel being parked.
01163  * \param parker Channel parking the call.
01164  * \param args Optional additional parking options when parking a call.
01165  *
01166  * \return Parked call descriptor or NULL if failed.
01167  * \note The parking lot list is locked if successful.
01168  */
01169 static struct parkeduser *park_space_reserve(struct ast_channel *park_me, struct ast_channel *parker, struct ast_park_call_args *args)
01170 {
01171    struct parkeduser *pu;
01172    int i;
01173    int parking_space = -1;
01174    const char *parkinglotname;
01175    const char *parkingexten;
01176    struct parkeduser *cur;
01177    struct ast_parkinglot *parkinglot = NULL;
01178 
01179    if (args->parkinglot) {
01180       parkinglot = parkinglot_addref(args->parkinglot);
01181       parkinglotname = parkinglot->name;
01182    } else {
01183       if (parker) {
01184          parkinglotname = findparkinglotname(parker);
01185       } else { /* parker was NULL, check park_me (ParkAndAnnounce / res_agi) */
01186          parkinglotname = findparkinglotname(park_me);
01187       }
01188       if (!ast_strlen_zero(parkinglotname)) {
01189          parkinglot = find_parkinglot(parkinglotname);
01190       } else {
01191          /* Parking lot is not specified, so use the default parking lot. */
01192          ast_debug(4, "This could be an indication channel driver needs updating, using default lot.\n");
01193          parkinglot = parkinglot_addref(default_parkinglot);
01194       }
01195    }
01196 
01197    /* Dynamically create parkinglot */
01198    if (!parkinglot && parkeddynamic && !ast_strlen_zero(parkinglotname)) {
01199       parkinglot = create_dynamic_parkinglot(parkinglotname, park_me);
01200    }
01201 
01202    if (!parkinglot) {
01203       ast_log(LOG_WARNING, "Parking lot not available to park %s.\n", park_me->name);
01204       return NULL;
01205    }
01206 
01207    ast_debug(1, "Parking lot: %s\n", parkinglot->name);
01208    if (parkinglot->disabled || parkinglot->cfg.is_invalid) {
01209       ast_log(LOG_WARNING, "Parking lot %s is not in a useable state.\n",
01210          parkinglot->name);
01211       parkinglot_unref(parkinglot);
01212       return NULL;
01213    }
01214 
01215    /* Allocate memory for parking data */
01216    if (!(pu = ast_calloc(1, sizeof(*pu)))) {
01217       parkinglot_unref(parkinglot);
01218       return NULL;
01219    }
01220 
01221    /* Lock parking list */
01222    AST_LIST_LOCK(&parkinglot->parkings);
01223 
01224    /* Check for channel variable PARKINGEXTEN */
01225    parkingexten = ast_strdupa(S_OR(pbx_builtin_getvar_helper(park_me, "PARKINGEXTEN"), ""));
01226    if (!ast_strlen_zero(parkingexten)) {
01227       /*!
01228        * \note The API forces us to specify a numeric parking slot, even
01229        * though the architecture would tend to support non-numeric extensions
01230        * (as are possible with SIP, for example).  Hence, we enforce that
01231        * limitation here.  If extout was not numeric, we could permit
01232        * arbitrary non-numeric extensions.
01233        */
01234       if (sscanf(parkingexten, "%30d", &parking_space) != 1 || parking_space <= 0) {
01235          ast_log(LOG_WARNING, "PARKINGEXTEN='%s' is not a valid parking space.\n",
01236             parkingexten);
01237          AST_LIST_UNLOCK(&parkinglot->parkings);
01238          parkinglot_unref(parkinglot);
01239          ast_free(pu);
01240          return NULL;
01241       }
01242 
01243       if (parking_space < parkinglot->cfg.parking_start
01244          || parkinglot->cfg.parking_stop < parking_space) {
01245          /*
01246           * Cannot allow park because parking lots are not setup for
01247           * spaces outside of the lot.  (Things like dialplan hints don't
01248           * exist for outside lot space.)
01249           */
01250          ast_log(LOG_WARNING, "PARKINGEXTEN=%d is not in %s (%d-%d).\n",
01251             parking_space, parkinglot->name, parkinglot->cfg.parking_start,
01252             parkinglot->cfg.parking_stop);
01253          AST_LIST_UNLOCK(&parkinglot->parkings);
01254          parkinglot_unref(parkinglot);
01255          ast_free(pu);
01256          return NULL;
01257       }
01258 
01259       /* Check if requested parking space is in use. */
01260       AST_LIST_TRAVERSE(&parkinglot->parkings, cur, list) {
01261          if (cur->parkingnum == parking_space) {
01262             ast_log(LOG_WARNING, "PARKINGEXTEN=%d is already in use in %s\n",
01263                parking_space, parkinglot->name);
01264             AST_LIST_UNLOCK(&parkinglot->parkings);
01265             parkinglot_unref(parkinglot);
01266             ast_free(pu);
01267             return NULL;
01268          }
01269       }
01270    } else {
01271       /* PARKINGEXTEN is empty, so find a usable extension in the lot to park the call */
01272       int start; /* The first slot we look in the parkinglot. It can be randomized. */
01273       int start_checked = 0; /* flag raised once the first slot is checked */
01274 
01275       /* If using randomize mode, set start to random position on parking range */
01276       if (ast_test_flag(args, AST_PARK_OPT_RANDOMIZE)) {
01277          start = ast_random() % (parkinglot->cfg.parking_stop - parkinglot->cfg.parking_start + 1);
01278          start += parkinglot->cfg.parking_start;
01279       } else if (parkinglot->cfg.parkfindnext
01280          && parkinglot->cfg.parking_start <= parkinglot->next_parking_space
01281          && parkinglot->next_parking_space <= parkinglot->cfg.parking_stop) {
01282          /* Start looking with the next parking space in the lot. */
01283          start = parkinglot->next_parking_space;
01284       } else {
01285          /* Otherwise, just set it to the start position. */
01286          start = parkinglot->cfg.parking_start;
01287       }
01288 
01289       /* free parking extension linear search: O(n^2) */
01290       for (i = start; ; i++) {
01291          /* If we are past the end, wrap around to the first parking slot*/
01292          if (i == parkinglot->cfg.parking_stop + 1) {
01293             i = parkinglot->cfg.parking_start;
01294          }
01295 
01296          if (i == start) {
01297             /* At this point, if start_checked, we've exhausted all the possible slots. */
01298             if (start_checked) {
01299                break;
01300             } else {
01301                start_checked = 1;
01302             }
01303          }
01304 
01305          /* Search the list of parked calls already in use for i. If we find it, it's in use. */
01306          AST_LIST_TRAVERSE(&parkinglot->parkings, cur, list) {
01307             if (cur->parkingnum == i) {
01308                break;
01309             }
01310          }
01311          if (!cur) {
01312             /* We found a parking space. */
01313             parking_space = i;
01314             break;
01315          }
01316       }
01317       if (parking_space == -1) {
01318          /* We did not find a parking space.  Lot is full. */
01319          ast_log(LOG_WARNING, "No more parking spaces in %s\n", parkinglot->name);
01320          AST_LIST_UNLOCK(&parkinglot->parkings);
01321          parkinglot_unref(parkinglot);
01322          ast_free(pu);
01323          return NULL;
01324       }
01325    }
01326 
01327    /* Prepare for next parking space search. */
01328    parkinglot->next_parking_space = parking_space + 1;
01329 
01330    snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", parking_space);
01331    pu->notquiteyet = 1;
01332    pu->parkingnum = parking_space;
01333    pu->parkinglot = parkinglot;
01334    AST_LIST_INSERT_TAIL(&parkinglot->parkings, pu, list);
01335 
01336    return pu;
01337 }
01338 
01339 /* Park a call */
01340 static int park_call_full(struct ast_channel *chan, struct ast_channel *peer, struct ast_park_call_args *args)
01341 {
01342    struct parkeduser *pu = args->pu;
01343    const char *event_from;
01344    char app_data[AST_MAX_EXTENSION + AST_MAX_CONTEXT];
01345 
01346    if (pu == NULL) {
01347       args->pu = pu = park_space_reserve(chan, peer, args);
01348       if (pu == NULL) {
01349          return -1;
01350       }
01351    }
01352 
01353    chan->appl = "Parked Call";
01354    chan->data = NULL;
01355 
01356    pu->chan = chan;
01357 
01358    /* Put the parked channel on hold if we have two different channels */
01359    if (chan != peer) {
01360       if (ast_test_flag(args, AST_PARK_OPT_RINGING)) {
01361          pu->hold_method = AST_CONTROL_RINGING;
01362          ast_indicate(pu->chan, AST_CONTROL_RINGING);
01363       } else {
01364          pu->hold_method = AST_CONTROL_HOLD;
01365          ast_indicate_data(pu->chan, AST_CONTROL_HOLD, 
01366             S_OR(pu->parkinglot->cfg.mohclass, NULL),
01367             !ast_strlen_zero(pu->parkinglot->cfg.mohclass) ? strlen(pu->parkinglot->cfg.mohclass) + 1 : 0);
01368       }
01369    }
01370    
01371    pu->start = ast_tvnow();
01372    pu->parkingtime = (args->timeout > 0) ? args->timeout : pu->parkinglot->cfg.parkingtime;
01373    if (args->extout)
01374       *(args->extout) = pu->parkingnum;
01375 
01376    if (peer) { 
01377       /*
01378        * This is so ugly that it hurts, but implementing
01379        * get_base_channel() on local channels could have ugly side
01380        * effects.  We could have
01381        * transferer<->local,1<->local,2<->parking and we need the
01382        * callback name to be that of transferer.  Since local,1/2 have
01383        * the same name we can be tricky and just grab the bridged
01384        * channel from the other side of the local.
01385        */
01386       if (!strcasecmp(peer->tech->type, "Local")) {
01387          struct ast_channel *tmpchan, *base_peer;
01388          char other_side[AST_CHANNEL_NAME];
01389          char *c;
01390 
01391          ast_copy_string(other_side, S_OR(args->orig_chan_name, peer->name), sizeof(other_side));
01392          if ((c = strrchr(other_side, ';'))) {
01393             *++c = '1';
01394          }
01395          if ((tmpchan = ast_channel_get_by_name(other_side))) {
01396             ast_channel_lock(tmpchan);
01397             if ((base_peer = ast_bridged_channel(tmpchan))) {
01398                ast_copy_string(pu->peername, base_peer->name, sizeof(pu->peername));
01399             }
01400             ast_channel_unlock(tmpchan);
01401             tmpchan = ast_channel_unref(tmpchan);
01402          }
01403       } else {
01404          ast_copy_string(pu->peername, S_OR(args->orig_chan_name, peer->name), sizeof(pu->peername));
01405       }
01406    }
01407 
01408    /*
01409     * Remember what had been dialed, so that if the parking
01410     * expires, we try to come back to the same place
01411     */
01412    pu->options_specified = (!ast_strlen_zero(args->return_con) || !ast_strlen_zero(args->return_ext) || args->return_pri);
01413 
01414    /*
01415     * If extension has options specified, they override all other
01416     * possibilities such as the returntoorigin flag and transferred
01417     * context.  Information on extension options is lost here, so
01418     * we set a flag
01419     */
01420    ast_copy_string(pu->context, 
01421       S_OR(args->return_con, S_OR(chan->macrocontext, chan->context)), 
01422       sizeof(pu->context));
01423    ast_copy_string(pu->exten, 
01424       S_OR(args->return_ext, S_OR(chan->macroexten, chan->exten)), 
01425       sizeof(pu->exten));
01426    pu->priority = args->return_pri ? args->return_pri : 
01427       (chan->macropriority ? chan->macropriority : chan->priority);
01428 
01429    /*
01430     * If parking a channel directly, don't quite yet get parking
01431     * running on it.  All parking lot entries are put into the
01432     * parking lot with notquiteyet on.
01433     */
01434    if (peer != chan) {
01435       pu->notquiteyet = 0;
01436    }
01437 
01438    /* Wake up the (presumably select()ing) thread */
01439    pthread_kill(parking_thread, SIGURG);
01440    ast_verb(2, "Parked %s on %d (lot %s). Will timeout back to extension [%s] %s, %d in %d seconds\n",
01441       pu->chan->name, pu->parkingnum, pu->parkinglot->name,
01442       pu->context, pu->exten, pu->priority, (pu->parkingtime / 1000));
01443 
01444    ast_cel_report_event(pu->chan, AST_CEL_PARK_START, NULL, pu->parkinglot->name, peer);
01445 
01446    if (peer) {
01447       event_from = peer->name;
01448    } else {
01449       event_from = pbx_builtin_getvar_helper(chan, "BLINDTRANSFER");
01450    }
01451 
01452    ast_manager_event(pu->chan, EVENT_FLAG_CALL, "ParkedCall",
01453       "Exten: %s\r\n"
01454       "Channel: %s\r\n"
01455       "Parkinglot: %s\r\n"
01456       "From: %s\r\n"
01457       "Timeout: %ld\r\n"
01458       "CallerIDNum: %s\r\n"
01459       "CallerIDName: %s\r\n"
01460       "ConnectedLineNum: %s\r\n"
01461       "ConnectedLineName: %s\r\n"
01462       "Uniqueid: %s\r\n",
01463       pu->parkingexten, pu->chan->name, pu->parkinglot->name, event_from ? event_from : "",
01464       (long)pu->start.tv_sec + (long)(pu->parkingtime/1000) - (long)time(NULL),
01465       S_COR(pu->chan->caller.id.number.valid, pu->chan->caller.id.number.str, "<unknown>"),
01466       S_COR(pu->chan->caller.id.name.valid, pu->chan->caller.id.name.str, "<unknown>"),
01467       S_COR(pu->chan->connected.id.number.valid, pu->chan->connected.id.number.str, "<unknown>"),
01468       S_COR(pu->chan->connected.id.name.valid, pu->chan->connected.id.name.str, "<unknown>"),
01469       pu->chan->uniqueid
01470       );
01471 
01472    if (peer && adsipark && ast_adsi_available(peer)) {
01473       adsi_announce_park(peer, pu->parkingexten);  /* Only supports parking numbers */
01474       ast_adsi_unload_session(peer);
01475    }
01476 
01477    snprintf(app_data, sizeof(app_data), "%s,%s", pu->parkingexten,
01478       pu->parkinglot->name);
01479    if (ast_add_extension(pu->parkinglot->cfg.parking_con, 1, pu->parkingexten, 1,
01480       NULL, NULL, parkedcall, ast_strdup(app_data), ast_free_ptr, registrar)) {
01481       ast_log(LOG_ERROR, "Could not create parked call exten: %s@%s\n",
01482          pu->parkingexten, pu->parkinglot->cfg.parking_con);
01483    } else {
01484       notify_metermaids(pu->parkingexten, pu->parkinglot->cfg.parking_con, AST_DEVICE_INUSE);
01485    }
01486 
01487    AST_LIST_UNLOCK(&pu->parkinglot->parkings);
01488 
01489    /* Only say number if it's a number and the channel hasn't been masqueraded away */
01490    if (peer && !ast_test_flag(args, AST_PARK_OPT_SILENCE)
01491       && (ast_strlen_zero(args->orig_chan_name) || !strcasecmp(peer->name, args->orig_chan_name))) {
01492       /*
01493        * If a channel is masqueraded into peer while playing back the
01494        * parking space number do not continue playing it back.  This
01495        * is the case if an attended transfer occurs.
01496        */
01497       ast_set_flag(peer, AST_FLAG_MASQ_NOSTREAM);
01498       /* Tell the peer channel the number of the parking space */
01499       ast_say_digits(peer, pu->parkingnum, "", peer->language);
01500       ast_clear_flag(peer, AST_FLAG_MASQ_NOSTREAM);
01501    }
01502    if (peer == chan) { /* pu->notquiteyet = 1 */
01503       /* Wake up parking thread if we're really done */
01504       pu->hold_method = AST_CONTROL_HOLD;
01505       ast_indicate_data(pu->chan, AST_CONTROL_HOLD, 
01506          S_OR(pu->parkinglot->cfg.mohclass, NULL),
01507          !ast_strlen_zero(pu->parkinglot->cfg.mohclass) ? strlen(pu->parkinglot->cfg.mohclass) + 1 : 0);
01508       pu->notquiteyet = 0;
01509       pthread_kill(parking_thread, SIGURG);
01510    }
01511    return 0;
01512 }
01513 
01514 /*! \brief Park a call */
01515 int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeout, const char *parkexten, int *extout)
01516 {
01517    struct ast_park_call_args args = {
01518       .timeout = timeout,
01519       .extout = extout,
01520    };
01521 
01522    return park_call_full(chan, peer, &args);
01523 }
01524 
01525 /*!
01526  * \param rchan the real channel to be parked
01527  * \param peer the channel to have the parking read to.
01528  * \param timeout is a timeout in milliseconds
01529  * \param extout is a parameter to an int that will hold the parked location, or NULL if you want.
01530  * \param play_announcement TRUE if to play which parking space call parked in to peer.
01531  * \param args Optional additional parking options when parking a call.
01532  *
01533  * \retval 0 on success.
01534  * \retval -1 on failure.
01535  */
01536 static int masq_park_call(struct ast_channel *rchan, struct ast_channel *peer, int timeout, int *extout, int play_announcement, struct ast_park_call_args *args)
01537 {
01538    struct ast_channel *chan;
01539    struct ast_park_call_args park_args = {0,};
01540 
01541    if (!args) {
01542       args = &park_args;
01543       args->timeout = timeout;
01544       args->extout = extout;
01545    }
01546 
01547    /* Make a new, channel that we'll use to masquerade in the real one */
01548    chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, rchan->accountcode, rchan->exten,
01549       rchan->context, rchan->linkedid, rchan->amaflags, "Parked/%s", rchan->name);
01550    if (!chan) {
01551       ast_log(LOG_WARNING, "Unable to create parked channel\n");
01552       if (peer == rchan) {
01553          /* Only have one channel to worry about. */
01554          ast_stream_and_wait(peer, "pbx-parkingfailed", "");
01555       } else if (peer) {
01556          /* Have two different channels to worry about. */
01557          play_message_on_chan(peer, rchan, "failure message", "pbx-parkingfailed");
01558       }
01559       return -1;
01560    }
01561 
01562    args->pu = park_space_reserve(rchan, peer, args);
01563    if (!args->pu) {
01564       chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
01565       ast_hangup(chan);
01566       if (peer == rchan) {
01567          /* Only have one channel to worry about. */
01568          ast_stream_and_wait(peer, "pbx-parkingfailed", "");
01569       } else if (peer) {
01570          /* Have two different channels to worry about. */
01571          play_message_on_chan(peer, rchan, "failure message", "pbx-parkingfailed");
01572       }
01573       return -1;
01574    }
01575 
01576    /* Make formats okay */
01577    chan->readformat = rchan->readformat;
01578    chan->writeformat = rchan->writeformat;
01579    ast_channel_masquerade(chan, rchan);
01580 
01581    /* Setup the extensions and such */
01582    set_c_e_p(chan, rchan->context, rchan->exten, rchan->priority);
01583 
01584    /* Setup the macro extension and such */
01585    ast_copy_string(chan->macrocontext,rchan->macrocontext,sizeof(chan->macrocontext));
01586    ast_copy_string(chan->macroexten,rchan->macroexten,sizeof(chan->macroexten));
01587    chan->macropriority = rchan->macropriority;
01588 
01589    /* Manually do the masquerade to make sure it is complete. */
01590    ast_do_masquerade(chan);
01591 
01592    if (peer == rchan) {
01593       peer = chan;
01594    }
01595 
01596    if (peer && (!play_announcement && args == &park_args)) {
01597       args->orig_chan_name = ast_strdupa(peer->name);
01598    }
01599 
01600    /* parking space reserved, return code check unnecessary */
01601    park_call_full(chan, peer, args);
01602 
01603    return 0;
01604 }
01605 
01606 int ast_masq_park_call(struct ast_channel *rchan, struct ast_channel *peer, int timeout, int *extout)
01607 {
01608    return masq_park_call(rchan, peer, timeout, extout, 0, NULL);
01609 }
01610 
01611 /*!
01612  * \brief Park call via masqueraded channel and announce parking spot on peer channel.
01613  *
01614  * \param rchan the real channel to be parked
01615  * \param peer the channel to have the parking read to.
01616  * \param args Optional additional parking options when parking a call.
01617  *
01618  * \retval 0 on success.
01619  * \retval -1 on failure.
01620  */
01621 static int masq_park_call_announce(struct ast_channel *rchan, struct ast_channel *peer, struct ast_park_call_args *args)
01622 {
01623    return masq_park_call(rchan, peer, 0, NULL, 1, args);
01624 }
01625 
01626 static int finishup(struct ast_channel *chan)
01627 {
01628    ast_indicate(chan, AST_CONTROL_UNHOLD);
01629 
01630    return ast_autoservice_stop(chan);
01631 }
01632 
01633 /*!
01634  * \internal
01635  * \brief Builtin transfer park call helper.
01636  *
01637  * \param park_me Channel to be parked.
01638  * \param parker Channel parking the call.
01639  * \param park_exten Parking lot dialplan access ramp extension.
01640  *
01641  * \note Assumes park_me is on hold and in autoservice.
01642  *
01643  * \retval -1 on successful park.
01644  * \retval -1 on park_me hangup.
01645  * \retval AST_FEATURE_RETURN_SUCCESS on error to keep the bridge connected.
01646  */
01647 static int xfer_park_call_helper(struct ast_channel *park_me, struct ast_channel *parker, struct ast_exten *park_exten)
01648 {
01649    char *parse;
01650    const char *app_data;
01651    const char *pl_name;
01652    struct ast_park_call_args args = { 0, };
01653    struct park_app_args app_args;
01654    int res;
01655 
01656    app_data = ast_get_extension_app_data(park_exten);
01657    if (!app_data) {
01658       app_data = "";
01659    }
01660    parse = ast_strdupa(app_data);
01661    AST_STANDARD_APP_ARGS(app_args, parse);
01662 
01663    /* Find the parking lot */
01664    if (!ast_strlen_zero(app_args.pl_name)) {
01665       pl_name = app_args.pl_name;
01666    } else {
01667       pl_name = findparkinglotname(parker);
01668    }
01669    if (ast_strlen_zero(pl_name)) {
01670       /* Parking lot is not specified, so use the default parking lot. */
01671       args.parkinglot = parkinglot_addref(default_parkinglot);
01672    } else {
01673       args.parkinglot = find_parkinglot(pl_name);
01674       if (!args.parkinglot && parkeddynamic) {
01675          args.parkinglot = create_dynamic_parkinglot(pl_name, park_me);
01676       }
01677    }
01678 
01679    if (args.parkinglot) {
01680       /* Park the call */
01681       res = finishup(park_me);
01682       if (res) {
01683          /* park_me hungup on us. */
01684          parkinglot_unref(args.parkinglot);
01685          return -1;
01686       }
01687       res = masq_park_call_announce(park_me, parker, &args);
01688       parkinglot_unref(args.parkinglot);
01689    } else {
01690       /* Parking failed because parking lot does not exist. */
01691       ast_stream_and_wait(parker, "pbx-parkingfailed", "");
01692       finishup(park_me);
01693       res = -1;
01694    }
01695 
01696    return res ? AST_FEATURE_RETURN_SUCCESS : -1;
01697 }
01698 
01699 /*!
01700  * \brief set caller and callee according to the direction
01701  * \param caller, callee, peer, chan, sense
01702  *
01703  * Detect who triggered feature and set callee/caller variables accordingly
01704  */
01705 static void set_peers(struct ast_channel **caller, struct ast_channel **callee,
01706    struct ast_channel *peer, struct ast_channel *chan, int sense)
01707 {
01708    if (sense == FEATURE_SENSE_PEER) {
01709       *caller = peer;
01710       *callee = chan;
01711    } else {
01712       *callee = peer;
01713       *caller = chan;
01714    }
01715 }
01716 
01717 /*!
01718  * \brief support routing for one touch call parking
01719  * \param chan channel parking call
01720  * \param peer channel to be parked
01721  * \param config unsed
01722  * \param code unused
01723  * \param sense feature options
01724  * \param data unused
01725  *
01726  * \retval -1 on successful park.
01727  * \retval -1 on chan hangup.
01728  * \retval AST_FEATURE_RETURN_SUCCESS on error to keep the bridge connected.
01729  */
01730 static int builtin_parkcall(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
01731 {
01732    struct ast_channel *parker;
01733    struct ast_channel *parkee;
01734 
01735    /*
01736     * We used to set chan's exten and priority to "s" and 1 here,
01737     * but this generates (in some cases) an invalid extension, and
01738     * if "s" exists, could errantly cause execution of extensions
01739     * you don't expect.  It makes more sense to let nature take its
01740     * course when chan finishes, and let the pbx do its thing and
01741     * hang up when the park is over.
01742     */
01743 
01744    /* Answer if call is not up */
01745    if (chan->_state != AST_STATE_UP) {
01746       /*
01747        * XXX Why are we doing this?  Both of the channels should be up
01748        * since you cannot do DTMF features unless you are bridged.
01749        */
01750       if (ast_answer(chan)) {
01751          return -1;
01752       }
01753 
01754       /* Sleep to allow VoIP streams to settle down */
01755       if (ast_safe_sleep(chan, 1000)) {
01756          return -1;
01757       }
01758    }
01759 
01760    /* one direction used to call park_call.... */
01761    set_peers(&parker, &parkee, peer, chan, sense);
01762    return masq_park_call_announce(parkee, parker, NULL)
01763       ? AST_FEATURE_RETURN_SUCCESS : -1;
01764 }
01765 
01766 /*!
01767  * \internal
01768  * \brief Play file to specified channel.
01769  *
01770  * \param play_to Channel to play audiofile to.
01771  * \param other Channel to put in autoservice while playing file.
01772  * \param msg Descriptive name of message type being played.
01773  * \param audiofile Audio file to play.
01774  *
01775  * \retval 0 on success.
01776  * \retval -1 on error. (Couldn't play file, a channel hung up,...)
01777  */
01778 static int play_message_on_chan(struct ast_channel *play_to, struct ast_channel *other, const char *msg, const char *audiofile)
01779 {
01780    /* Put other channel in autoservice. */
01781    if (ast_autoservice_start(other)) {
01782       return -1;
01783    }
01784    ast_autoservice_ignore(other, AST_FRAME_DTMF_BEGIN);
01785    ast_autoservice_ignore(other, AST_FRAME_DTMF_END);
01786    if (ast_stream_and_wait(play_to, audiofile, "")) {
01787       ast_log(LOG_WARNING, "Failed to play %s '%s'!\n", msg, audiofile);
01788       ast_autoservice_stop(other);
01789       return -1;
01790    }
01791    if (ast_autoservice_stop(other)) {
01792       return -1;
01793    }
01794    return 0;
01795 }
01796 
01797 /*!
01798  * \internal
01799  * \brief Play file to specified channels.
01800  *
01801  * \param left Channel on left to play file.
01802  * \param right Channel on right to play file.
01803  * \param which Play file on indicated channels: which < 0 play left, which == 0 play both, which > 0 play right
01804  * \param msg Descriptive name of message type being played.
01805  * \param audiofile Audio file to play to channels.
01806  *
01807  * \note Plays file to the indicated channels in turn so please
01808  * don't use this for very long messages.
01809  *
01810  * \retval 0 on success.
01811  * \retval -1 on error. (Couldn't play file, channel hung up,...)
01812  */
01813 static int play_message_to_chans(struct ast_channel *left, struct ast_channel *right, int which, const char *msg, const char *audiofile)
01814 {
01815    /* First play the file to the left channel if requested. */
01816    if (which <= 0 && play_message_on_chan(left, right, msg, audiofile)) {
01817       return -1;
01818    }
01819 
01820    /* Then play the file to the right channel if requested. */
01821    if (which >= 0 && play_message_on_chan(right, left, msg, audiofile)) {
01822       return -1;
01823    }
01824 
01825    return 0;
01826 }
01827 
01828 /*!
01829  * \brief Play message to both caller and callee in bridged call, plays synchronously, autoservicing the
01830  * other channel during the message, so please don't use this for very long messages
01831  */
01832 static int play_message_in_bridged_call(struct ast_channel *caller_chan, struct ast_channel *callee_chan, const char *audiofile)
01833 {
01834    return play_message_to_chans(caller_chan, callee_chan, 0, "automon message",
01835       audiofile);
01836 }
01837 
01838 /*!
01839  * \brief Monitor a channel by DTMF
01840  * \param chan channel requesting monitor
01841  * \param peer channel to be monitored
01842  * \param config
01843  * \param code
01844  * \param sense feature options
01845  *
01846  * \param data
01847  * Check monitor app enabled, setup channels, both caller/callee chans not null
01848  * get TOUCH_MONITOR variable for filename if exists, exec monitor app.
01849  * \retval AST_FEATURE_RETURN_SUCCESS on success.
01850  * \retval -1 on error.
01851  */
01852 static int builtin_automonitor(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
01853 {
01854    char *caller_chan_id = NULL, *callee_chan_id = NULL, *args = NULL, *touch_filename = NULL;
01855    int x = 0;
01856    size_t len;
01857    struct ast_channel *caller_chan, *callee_chan;
01858    const char *automon_message_start = NULL;
01859    const char *automon_message_stop = NULL;
01860 
01861    if (!monitor_ok) {
01862       ast_log(LOG_ERROR,"Cannot record the call. The monitor application is disabled.\n");
01863       return -1;
01864    }
01865 
01866    if (!monitor_app && !(monitor_app = pbx_findapp("Monitor"))) {
01867       monitor_ok = 0;
01868       ast_log(LOG_ERROR,"Cannot record the call. The monitor application is disabled.\n");
01869       return -1;
01870    }
01871 
01872    set_peers(&caller_chan, &callee_chan, peer, chan, sense);
01873    if (caller_chan) {   /* Find extra messages */
01874       automon_message_start = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_MESSAGE_START");
01875       automon_message_stop = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_MESSAGE_STOP");
01876    }
01877 
01878    if (!ast_strlen_zero(courtesytone)) {  /* Play courtesy tone if configured */
01879       if(play_message_in_bridged_call(caller_chan, callee_chan, courtesytone) == -1) {
01880          return -1;
01881       }
01882    }
01883    
01884    if (callee_chan->monitor) {
01885       ast_verb(4, "User hit '%s' to stop recording call.\n", code);
01886       if (!ast_strlen_zero(automon_message_stop)) {
01887          play_message_in_bridged_call(caller_chan, callee_chan, automon_message_stop);
01888       }
01889       callee_chan->monitor->stop(callee_chan, 1);
01890       return AST_FEATURE_RETURN_SUCCESS;
01891    }
01892 
01893    if (caller_chan && callee_chan) {
01894       const char *touch_format = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_FORMAT");
01895       const char *touch_monitor = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR");
01896       const char *touch_monitor_prefix = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_PREFIX");
01897 
01898       if (!touch_format)
01899          touch_format = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR_FORMAT");
01900 
01901       if (!touch_monitor)
01902          touch_monitor = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR");
01903    
01904       if (!touch_monitor_prefix)
01905          touch_monitor_prefix = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR_PREFIX");
01906    
01907       if (touch_monitor) {
01908          len = strlen(touch_monitor) + 50;
01909          args = alloca(len);
01910          touch_filename = alloca(len);
01911          snprintf(touch_filename, len, "%s-%ld-%s", S_OR(touch_monitor_prefix, "auto"), (long)time(NULL), touch_monitor);
01912          snprintf(args, len, "%s,%s,m", S_OR(touch_format, "wav"), touch_filename);
01913       } else {
01914          caller_chan_id = ast_strdupa(S_COR(caller_chan->caller.id.number.valid,
01915             caller_chan->caller.id.number.str, caller_chan->name));
01916          callee_chan_id = ast_strdupa(S_COR(callee_chan->caller.id.number.valid,
01917             callee_chan->caller.id.number.str, callee_chan->name));
01918          len = strlen(caller_chan_id) + strlen(callee_chan_id) + 50;
01919          args = alloca(len);
01920          touch_filename = alloca(len);
01921          snprintf(touch_filename, len, "%s-%ld-%s-%s", S_OR(touch_monitor_prefix, "auto"), (long)time(NULL), caller_chan_id, callee_chan_id);
01922          snprintf(args, len, "%s,%s,m", S_OR(touch_format, "wav"), touch_filename);
01923       }
01924 
01925       for(x = 0; x < strlen(args); x++) {
01926          if (args[x] == '/')
01927             args[x] = '-';
01928       }
01929       
01930       ast_verb(4, "User hit '%s' to record call. filename: %s\n", code, args);
01931 
01932       pbx_exec(callee_chan, monitor_app, args);
01933       pbx_builtin_setvar_helper(callee_chan, "TOUCH_MONITOR_OUTPUT", touch_filename);
01934       pbx_builtin_setvar_helper(caller_chan, "TOUCH_MONITOR_OUTPUT", touch_filename);
01935 
01936       if (!ast_strlen_zero(automon_message_start)) {  /* Play start message for both channels */
01937          play_message_in_bridged_call(caller_chan, callee_chan, automon_message_start);
01938       }
01939    
01940       return AST_FEATURE_RETURN_SUCCESS;
01941    }
01942    
01943    ast_log(LOG_NOTICE,"Cannot record the call. One or both channels have gone away.\n");  
01944    return -1;
01945 }
01946 
01947 static int builtin_automixmonitor(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
01948 {
01949    char *caller_chan_id = NULL, *callee_chan_id = NULL, *args = NULL, *touch_filename = NULL;
01950    int x = 0;
01951    size_t len;
01952    struct ast_channel *caller_chan, *callee_chan;
01953    const char *mixmonitor_spy_type = "MixMonitor";
01954    int count = 0;
01955 
01956    if (!mixmonitor_ok) {
01957       ast_log(LOG_ERROR,"Cannot record the call. The mixmonitor application is disabled.\n");
01958       return -1;
01959    }
01960 
01961    if (!(mixmonitor_app = pbx_findapp("MixMonitor"))) {
01962       mixmonitor_ok = 0;
01963       ast_log(LOG_ERROR,"Cannot record the call. The mixmonitor application is disabled.\n");
01964       return -1;
01965    }
01966 
01967    set_peers(&caller_chan, &callee_chan, peer, chan, sense);
01968 
01969    if (!ast_strlen_zero(courtesytone)) {
01970       if (ast_autoservice_start(callee_chan))
01971          return -1;
01972       ast_autoservice_ignore(callee_chan, AST_FRAME_DTMF_END);
01973       if (ast_stream_and_wait(caller_chan, courtesytone, "")) {
01974          ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
01975          ast_autoservice_stop(callee_chan);
01976          return -1;
01977       }
01978       if (ast_autoservice_stop(callee_chan))
01979          return -1;
01980    }
01981 
01982    ast_channel_lock(callee_chan);
01983    count = ast_channel_audiohook_count_by_source(callee_chan, mixmonitor_spy_type, AST_AUDIOHOOK_TYPE_SPY);
01984    ast_channel_unlock(callee_chan);
01985 
01986    /* This means a mixmonitor is attached to the channel, running or not is unknown. */
01987    if (count > 0) {
01988       
01989       ast_verb(3, "User hit '%s' to stop recording call.\n", code);
01990 
01991       /* Make sure they are running */
01992       ast_channel_lock(callee_chan);
01993       count = ast_channel_audiohook_count_by_source_running(callee_chan, mixmonitor_spy_type, AST_AUDIOHOOK_TYPE_SPY);
01994       ast_channel_unlock(callee_chan);
01995       if (count > 0) {
01996          if (!stopmixmonitor_ok) {
01997             ast_log(LOG_ERROR,"Cannot stop recording the call. The stopmixmonitor application is disabled.\n");
01998             return -1;
01999          }
02000          if (!(stopmixmonitor_app = pbx_findapp("StopMixMonitor"))) {
02001             stopmixmonitor_ok = 0;
02002             ast_log(LOG_ERROR,"Cannot stop recording the call. The stopmixmonitor application is disabled.\n");
02003             return -1;
02004          } else {
02005             pbx_exec(callee_chan, stopmixmonitor_app, "");
02006             return AST_FEATURE_RETURN_SUCCESS;
02007          }
02008       }
02009       
02010       ast_log(LOG_WARNING,"Stopped MixMonitors are attached to the channel.\n"); 
02011    }        
02012 
02013    if (caller_chan && callee_chan) {
02014       const char *touch_format = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MIXMONITOR_FORMAT");
02015       const char *touch_monitor = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MIXMONITOR");
02016 
02017       if (!touch_format)
02018          touch_format = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MIXMONITOR_FORMAT");
02019 
02020       if (!touch_monitor)
02021          touch_monitor = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MIXMONITOR");
02022 
02023       if (touch_monitor) {
02024          len = strlen(touch_monitor) + 50;
02025          args = alloca(len);
02026          touch_filename = alloca(len);
02027          snprintf(touch_filename, len, "auto-%ld-%s", (long)time(NULL), touch_monitor);
02028          snprintf(args, len, "%s.%s,b", touch_filename, (touch_format) ? touch_format : "wav");
02029       } else {
02030          caller_chan_id = ast_strdupa(S_COR(caller_chan->caller.id.number.valid,
02031             caller_chan->caller.id.number.str, caller_chan->name));
02032          callee_chan_id = ast_strdupa(S_COR(callee_chan->caller.id.number.valid,
02033             callee_chan->caller.id.number.str, callee_chan->name));
02034          len = strlen(caller_chan_id) + strlen(callee_chan_id) + 50;
02035          args = alloca(len);
02036          touch_filename = alloca(len);
02037          snprintf(touch_filename, len, "auto-%ld-%s-%s", (long)time(NULL), caller_chan_id, callee_chan_id);
02038          snprintf(args, len, "%s.%s,b", touch_filename, S_OR(touch_format, "wav"));
02039       }
02040 
02041       for( x = 0; x < strlen(args); x++) {
02042          if (args[x] == '/')
02043             args[x] = '-';
02044       }
02045 
02046       ast_verb(3, "User hit '%s' to record call. filename: %s\n", code, touch_filename);
02047 
02048       pbx_exec(callee_chan, mixmonitor_app, args);
02049       pbx_builtin_setvar_helper(callee_chan, "TOUCH_MIXMONITOR_OUTPUT", touch_filename);
02050       pbx_builtin_setvar_helper(caller_chan, "TOUCH_MIXMONITOR_OUTPUT", touch_filename);
02051       return AST_FEATURE_RETURN_SUCCESS;
02052    
02053    }
02054 
02055    ast_log(LOG_NOTICE,"Cannot record the call. One or both channels have gone away.\n");
02056    return -1;
02057 
02058 }
02059 
02060 static int builtin_disconnect(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
02061 {
02062    ast_verb(4, "User hit '%s' to disconnect call.\n", code);
02063    return AST_FEATURE_RETURN_HANGUP;
02064 }
02065 
02066 /*!
02067  * \brief Find the context for the transfer
02068  * \param transferer
02069  * \param transferee
02070  * 
02071  * Grab the TRANSFER_CONTEXT, if fails try grabbing macrocontext.
02072  * \return a context string
02073  */
02074 static const char *real_ctx(struct ast_channel *transferer, struct ast_channel *transferee)
02075 {
02076    const char *s = pbx_builtin_getvar_helper(transferer, "TRANSFER_CONTEXT");
02077    if (ast_strlen_zero(s)) {
02078       s = pbx_builtin_getvar_helper(transferee, "TRANSFER_CONTEXT");
02079    }
02080    if (ast_strlen_zero(s)) { /* Use the non-macro context to transfer the call XXX ? */
02081       s = transferer->macrocontext;
02082    }
02083    if (ast_strlen_zero(s)) {
02084       s = transferer->context;
02085    }
02086    return s;  
02087 }
02088 
02089 /*!
02090  * \brief Blind transfer user to another extension
02091  * \param chan channel to be transfered
02092  * \param peer channel initiated blind transfer
02093  * \param config
02094  * \param code
02095  * \param data
02096  * \param sense  feature options
02097  * 
02098  * Place chan on hold, check if transferred to parkinglot extension,
02099  * otherwise check extension exists and transfer caller.
02100  * \retval AST_FEATURE_RETURN_SUCCESS.
02101  * \retval -1 on failure.
02102  */
02103 static int builtin_blindtransfer(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
02104 {
02105    struct ast_channel *transferer;
02106    struct ast_channel *transferee;
02107    struct ast_exten *park_exten;
02108    const char *transferer_real_context;
02109    char xferto[256] = "";
02110    int res;
02111 
02112    set_peers(&transferer, &transferee, peer, chan, sense);
02113    transferer_real_context = real_ctx(transferer, transferee);
02114 
02115    /* Start autoservice on transferee while we talk to the transferer */
02116    ast_autoservice_start(transferee);
02117    ast_indicate(transferee, AST_CONTROL_HOLD);
02118 
02119    /* Transfer */
02120    res = ast_stream_and_wait(transferer, "pbx-transfer", AST_DIGIT_ANY);
02121    if (res < 0) {
02122       finishup(transferee);
02123       return -1; /* error ? */
02124    }
02125    if (res > 0) { /* If they've typed a digit already, handle it */
02126       xferto[0] = (char) res;
02127    }
02128 
02129    res = ast_app_dtget(transferer, transferer_real_context, xferto, sizeof(xferto), 100, transferdigittimeout);
02130    if (res < 0) {  /* hangup or error, (would be 0 for invalid and 1 for valid) */
02131       finishup(transferee);
02132       return -1;
02133    }
02134    if (res == 0) {
02135       if (xferto[0]) {
02136          ast_log(LOG_WARNING, "Extension '%s' does not exist in context '%s'\n",
02137             xferto, transferer_real_context);
02138       } else {
02139          /* Does anyone care about this case? */
02140          ast_log(LOG_WARNING, "No digits dialed.\n");
02141       }
02142       ast_stream_and_wait(transferer, "pbx-invalid", "");
02143       finishup(transferee);
02144       return AST_FEATURE_RETURN_SUCCESS;
02145    }
02146 
02147    park_exten = get_parking_exten(xferto, transferer, transferer_real_context);
02148    if (park_exten) {
02149       /* We are transfering the transferee to a parking lot. */
02150       return xfer_park_call_helper(transferee, transferer, park_exten);
02151    }
02152 
02153    /* Do blind transfer. */
02154    ast_cel_report_event(transferer, AST_CEL_BLINDTRANSFER, NULL, xferto, transferee);
02155    pbx_builtin_setvar_helper(transferer, "BLINDTRANSFER", transferee->name);
02156    pbx_builtin_setvar_helper(transferee, "BLINDTRANSFER", transferer->name);
02157    res = finishup(transferee);
02158    if (!transferer->cdr) { /* this code should never get called (in a perfect world) */
02159       transferer->cdr = ast_cdr_alloc();
02160       if (transferer->cdr) {
02161          ast_cdr_init(transferer->cdr, transferer); /* initialize our channel's cdr */
02162          ast_cdr_start(transferer->cdr);
02163       }
02164    }
02165    if (transferer->cdr) {
02166       struct ast_cdr *swap = transferer->cdr;
02167 
02168       ast_log(LOG_DEBUG,
02169          "transferer=%s; transferee=%s; lastapp=%s; lastdata=%s; chan=%s; dstchan=%s\n",
02170          transferer->name, transferee->name, transferer->cdr->lastapp,
02171          transferer->cdr->lastdata, transferer->cdr->channel,
02172          transferer->cdr->dstchannel);
02173       ast_log(LOG_DEBUG, "TRANSFEREE; lastapp=%s; lastdata=%s, chan=%s; dstchan=%s\n",
02174          transferee->cdr->lastapp, transferee->cdr->lastdata, transferee->cdr->channel,
02175          transferee->cdr->dstchannel);
02176       ast_log(LOG_DEBUG, "transferer_real_context=%s; xferto=%s\n",
02177          transferer_real_context, xferto);
02178       /* swap cdrs-- it will save us some time & work */
02179       transferer->cdr = transferee->cdr;
02180       transferee->cdr = swap;
02181    }
02182    if (!transferee->pbx) {
02183       /* Doh!  Use our handy async_goto functions */
02184       ast_verb(3, "Transferring %s to '%s' (context %s) priority 1\n",
02185          transferee->name, xferto, transferer_real_context);
02186       if (ast_async_goto(transferee, transferer_real_context, xferto, 1)) {
02187          ast_log(LOG_WARNING, "Async goto failed :-(\n");
02188       }
02189    } else {
02190       /* Set the channel's new extension, since it exists, using transferer context */
02191       ast_set_flag(transferee, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */
02192       ast_log(LOG_DEBUG,
02193          "ABOUT TO AST_ASYNC_GOTO, have a pbx... set HANGUP_DONT on chan=%s\n",
02194          transferee->name);
02195       if (ast_channel_connected_line_macro(transferee, transferer, &transferer->connected, 1, 0)) {
02196          ast_channel_update_connected_line(transferer, &transferer->connected, NULL);
02197       }
02198       set_c_e_p(transferee, transferer_real_context, xferto, 0);
02199    }
02200    check_goto_on_transfer(transferer);
02201    return res;
02202 }
02203 
02204 /*!
02205  * \brief make channels compatible
02206  * \param c
02207  * \param newchan
02208  * \retval 0 on success.
02209  * \retval -1 on failure.
02210  */
02211 static int check_compat(struct ast_channel *c, struct ast_channel *newchan)
02212 {
02213    if (ast_channel_make_compatible(c, newchan) < 0) {
02214       ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n",
02215          c->name, newchan->name);
02216       ast_hangup(newchan);
02217       return -1;
02218    }
02219    return 0;
02220 }
02221 
02222 /*!
02223  * \internal
02224  * \brief Builtin attended transfer failed cleanup.
02225  * \since 1.10
02226  *
02227  * \param transferee Party A in the transfer.
02228  * \param transferer Party B in the transfer.
02229  * \param connected_line Saved connected line info about party A.
02230  *
02231  * \note The connected_line data is freed.
02232  *
02233  * \return Nothing
02234  */
02235 static void atxfer_fail_cleanup(struct ast_channel *transferee, struct ast_channel *transferer, struct ast_party_connected_line *connected_line)
02236 {
02237    finishup(transferee);
02238 
02239    /*
02240     * Restore party B connected line info about party A.
02241     *
02242     * Party B was the caller to party C and is the last known mode
02243     * for party B.
02244     */
02245    if (ast_channel_connected_line_macro(transferee, transferer, connected_line, 1, 0)) {
02246       ast_channel_update_connected_line(transferer, connected_line, NULL);
02247    }
02248    ast_party_connected_line_free(connected_line);
02249 }
02250 
02251 /*!
02252  * \brief Attended transfer
02253  * \param chan transfered user
02254  * \param peer person transfering call
02255  * \param config
02256  * \param code
02257  * \param sense feature options
02258  *
02259  * \param data
02260  * Get extension to transfer to, if you cannot generate channel (or find extension)
02261  * return to host channel. After called channel answered wait for hangup of transferer,
02262  * bridge call between transfer peer (taking them off hold) to attended transfer channel.
02263  *
02264  * \return -1 on failure
02265  */
02266 static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
02267 {
02268    struct ast_channel *transferer;/* Party B */
02269    struct ast_channel *transferee;/* Party A */
02270    struct ast_exten *park_exten;
02271    const char *transferer_real_context;
02272    char xferto[256] = "";
02273    int res;
02274    int outstate=0;
02275    struct ast_channel *newchan;
02276    struct ast_channel *xferchan;
02277    struct ast_bridge_thread_obj *tobj;
02278    struct ast_bridge_config bconfig;
02279    int l;
02280    struct ast_party_connected_line connected_line;
02281    struct ast_datastore *features_datastore;
02282    struct ast_dial_features *dialfeatures = NULL;
02283    char *transferer_tech;
02284    char *transferer_name;
02285    char *transferer_name_orig;
02286    char *dash;
02287 
02288    ast_debug(1, "Executing Attended Transfer %s, %s (sense=%d) \n", chan->name, peer->name, sense);
02289    set_peers(&transferer, &transferee, peer, chan, sense);
02290    transferer_real_context = real_ctx(transferer, transferee);
02291 
02292    /* Start autoservice on transferee while we talk to the transferer */
02293    ast_autoservice_start(transferee);
02294    ast_indicate(transferee, AST_CONTROL_HOLD);
02295 
02296    /* Transfer */
02297    res = ast_stream_and_wait(transferer, "pbx-transfer", AST_DIGIT_ANY);
02298    if (res < 0) {
02299       finishup(transferee);
02300       return -1;
02301    }
02302    if (res > 0) { /* If they've typed a digit already, handle it */
02303       xferto[0] = (char) res;
02304    }
02305 
02306    /* this is specific of atxfer */
02307    res = ast_app_dtget(transferer, transferer_real_context, xferto, sizeof(xferto), 100, transferdigittimeout);
02308    if (res < 0) {  /* hangup or error, (would be 0 for invalid and 1 for valid) */
02309       finishup(transferee);
02310       return -1;
02311    }
02312    l = strlen(xferto);
02313    if (res == 0) {
02314       if (l) {
02315          ast_log(LOG_WARNING, "Extension '%s' does not exist in context '%s'\n",
02316             xferto, transferer_real_context);
02317       } else {
02318          /* Does anyone care about this case? */
02319          ast_log(LOG_WARNING, "No digits dialed for atxfer.\n");
02320       }
02321       ast_stream_and_wait(transferer, "pbx-invalid", "");
02322       finishup(transferee);
02323       return AST_FEATURE_RETURN_SUCCESS;
02324    }
02325 
02326    park_exten = get_parking_exten(xferto, transferer, transferer_real_context);
02327    if (park_exten) {
02328       /* We are transfering the transferee to a parking lot. */
02329       return xfer_park_call_helper(transferee, transferer, park_exten);
02330    }
02331 
02332    /* Append context to dialed transfer number. */
02333    snprintf(xferto + l, sizeof(xferto) - l, "@%s/n", transferer_real_context);
02334 
02335    /* If we are performing an attended transfer and we have two channels involved then
02336       copy sound file information to play upon attended transfer completion */
02337    if (transferee) {
02338       const char *chan1_attended_sound = pbx_builtin_getvar_helper(transferer, "ATTENDED_TRANSFER_COMPLETE_SOUND");
02339       const char *chan2_attended_sound = pbx_builtin_getvar_helper(transferee, "ATTENDED_TRANSFER_COMPLETE_SOUND");
02340 
02341       if (!ast_strlen_zero(chan1_attended_sound)) {
02342          pbx_builtin_setvar_helper(transferer, "BRIDGE_PLAY_SOUND", chan1_attended_sound);
02343       }
02344       if (!ast_strlen_zero(chan2_attended_sound)) {
02345          pbx_builtin_setvar_helper(transferee, "BRIDGE_PLAY_SOUND", chan2_attended_sound);
02346       }
02347    }
02348 
02349    /* Extract redial transferer information from the channel name. */
02350    transferer_name_orig = ast_strdupa(transferer->name);
02351    transferer_name = ast_strdupa(transferer_name_orig);
02352    transferer_tech = strsep(&transferer_name, "/");
02353    dash = strrchr(transferer_name, '-');
02354    if (dash) {
02355       /* Trim off channel name sequence/serial number. */
02356       *dash = '\0';
02357    }
02358 
02359    /* Stop autoservice so we can monitor all parties involved in the transfer. */
02360    if (ast_autoservice_stop(transferee) < 0) {
02361       ast_indicate(transferee, AST_CONTROL_UNHOLD);
02362       return -1;
02363    }
02364 
02365    /* Save connected line info for party B about party A in case transfer fails. */
02366    ast_party_connected_line_init(&connected_line);
02367    ast_channel_lock(transferer);
02368    ast_party_connected_line_copy(&connected_line, &transferer->connected);
02369    ast_channel_unlock(transferer);
02370    connected_line.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
02371 
02372    /* Dial party C */
02373    newchan = feature_request_and_dial(transferer, transferer_name_orig, transferer,
02374       transferee, "Local", ast_best_codec(transferer->nativeformats), xferto,
02375       atxfernoanswertimeout, &outstate, transferer->language);
02376    ast_debug(2, "Dial party C result: newchan:%d, outstate:%d\n", !!newchan, outstate);
02377 
02378    if (!ast_check_hangup(transferer)) {
02379       int hangup_dont = 0;
02380 
02381       /* Transferer (party B) is up */
02382       ast_debug(1, "Actually doing an attended transfer.\n");
02383 
02384       /* Start autoservice on transferee while the transferer deals with party C. */
02385       ast_autoservice_start(transferee);
02386 
02387       ast_indicate(transferer, -1);
02388       if (!newchan) {
02389          /* any reason besides user requested cancel and busy triggers the failed sound */
02390          switch (outstate) {
02391          case AST_CONTROL_UNHOLD:/* Caller requested cancel or party C answer timeout. */
02392          case AST_CONTROL_BUSY:
02393          case AST_CONTROL_CONGESTION:
02394             if (ast_stream_and_wait(transferer, xfersound, "")) {
02395                ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
02396             }
02397             break;
02398          default:
02399             if (ast_stream_and_wait(transferer, xferfailsound, "")) {
02400                ast_log(LOG_WARNING, "Failed to play transfer failed sound!\n");
02401             }
02402             break;
02403          }
02404          atxfer_fail_cleanup(transferee, transferer, &connected_line);
02405          return AST_FEATURE_RETURN_SUCCESS;
02406       }
02407 
02408       if (check_compat(transferer, newchan)) {
02409          if (ast_stream_and_wait(transferer, xferfailsound, "")) {
02410             ast_log(LOG_WARNING, "Failed to play transfer failed sound!\n");
02411          }
02412          atxfer_fail_cleanup(transferee, transferer, &connected_line);
02413          return AST_FEATURE_RETURN_SUCCESS;
02414       }
02415       memset(&bconfig,0,sizeof(struct ast_bridge_config));
02416       ast_set_flag(&(bconfig.features_caller), AST_FEATURE_DISCONNECT);
02417       ast_set_flag(&(bconfig.features_callee), AST_FEATURE_DISCONNECT);
02418 
02419       /* ast_bridge_call clears AST_FLAG_BRIDGE_HANGUP_DONT, but we don't
02420          want that to happen here because we're also in another bridge already
02421        */
02422       if (ast_test_flag(chan, AST_FLAG_BRIDGE_HANGUP_DONT)) {
02423          hangup_dont = 1;
02424       }
02425       /* Let party B and party C talk as long as they want. */
02426       ast_bridge_call(transferer, newchan, &bconfig);
02427       if (hangup_dont) {
02428          ast_set_flag(chan, AST_FLAG_BRIDGE_HANGUP_DONT);
02429       }
02430 
02431       if (ast_check_hangup(newchan) || !ast_check_hangup(transferer)) {
02432          ast_hangup(newchan);
02433          if (ast_stream_and_wait(transferer, xfersound, "")) {
02434             ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
02435          }
02436          atxfer_fail_cleanup(transferee, transferer, &connected_line);
02437          return AST_FEATURE_RETURN_SUCCESS;
02438       }
02439 
02440       /* Transferer (party B) is confirmed hung up at this point. */
02441       if (check_compat(transferee, newchan)) {
02442          finishup(transferee);
02443          ast_party_connected_line_free(&connected_line);
02444          return -1;
02445       }
02446 
02447       ast_indicate(transferee, AST_CONTROL_UNHOLD);
02448       if ((ast_autoservice_stop(transferee) < 0)
02449          || (ast_waitfordigit(transferee, 100) < 0)
02450          || (ast_waitfordigit(newchan, 100) < 0)
02451          || ast_check_hangup(transferee)
02452          || ast_check_hangup(newchan)) {
02453          ast_hangup(newchan);
02454          ast_party_connected_line_free(&connected_line);
02455          return -1;
02456       }
02457    } else if (!ast_check_hangup(transferee)) {
02458       /* Transferer (party B) has hung up at this point.  Doing blonde transfer. */
02459       ast_debug(1, "Actually doing a blonde transfer.\n");
02460 
02461       if (!newchan && !atxferdropcall) {
02462          /* Party C is not available, try to call party B back. */
02463          unsigned int tries = 0;
02464 
02465          if (ast_strlen_zero(transferer_name) || ast_strlen_zero(transferer_tech)) {
02466             ast_log(LOG_WARNING,
02467                "Transferer channel name: '%s' cannot be used for callback.\n",
02468                transferer_name_orig);
02469             ast_indicate(transferee, AST_CONTROL_UNHOLD);
02470             ast_party_connected_line_free(&connected_line);
02471             return -1;
02472          }
02473 
02474          tries = 0;
02475          for (;;) {
02476             /* Try to get party B back. */
02477             ast_debug(1, "We're trying to callback %s/%s\n",
02478                transferer_tech, transferer_name);
02479             newchan = feature_request_and_dial(transferer, transferer_name_orig,
02480                transferee, transferee, transferer_tech,
02481                ast_best_codec(transferee->nativeformats), transferer_name,
02482                atxfernoanswertimeout, &outstate, transferer->language);
02483             ast_debug(2, "Dial party B result: newchan:%d, outstate:%d\n",
02484                !!newchan, outstate);
02485             if (newchan || ast_check_hangup(transferee)) {
02486                break;
02487             }
02488 
02489             ++tries;
02490             if (atxfercallbackretries <= tries) {
02491                /* No more callback tries remaining. */
02492                break;
02493             }
02494 
02495             if (atxferloopdelay) {
02496                /* Transfer failed, sleeping */
02497                ast_debug(1, "Sleeping for %d ms before retrying atxfer.\n",
02498                   atxferloopdelay);
02499                ast_safe_sleep(transferee, atxferloopdelay);
02500                if (ast_check_hangup(transferee)) {
02501                   ast_party_connected_line_free(&connected_line);
02502                   return -1;
02503                }
02504             }
02505 
02506             /* Retry dialing party C. */
02507             ast_debug(1, "We're retrying to call %s/%s\n", "Local", xferto);
02508             newchan = feature_request_and_dial(transferer, transferer_name_orig,
02509                transferer, transferee, "Local",
02510                ast_best_codec(transferee->nativeformats), xferto,
02511                atxfernoanswertimeout, &outstate, transferer->language);
02512             ast_debug(2, "Redial party C result: newchan:%d, outstate:%d\n",
02513                !!newchan, outstate);
02514             if (newchan || ast_check_hangup(transferee)) {
02515                break;
02516             }
02517          }
02518       }
02519       ast_indicate(transferee, AST_CONTROL_UNHOLD);
02520       if (!newchan) {
02521          /* No party C or could not callback party B. */
02522          ast_party_connected_line_free(&connected_line);
02523          return -1;
02524       }
02525 
02526       /* newchan is up, we should prepare transferee and bridge them */
02527       if (ast_check_hangup(newchan)) {
02528          ast_hangup(newchan);
02529          ast_party_connected_line_free(&connected_line);
02530          return -1;
02531       }
02532       if (check_compat(transferee, newchan)) {
02533          ast_party_connected_line_free(&connected_line);
02534          return -1;
02535       }
02536    } else {
02537       /*
02538        * Both the transferer and transferee have hungup.  If newchan
02539        * is up, hang it up as it has no one to talk to.
02540        */
02541       ast_debug(1, "Everyone is hungup.\n");
02542       if (newchan) {
02543          ast_hangup(newchan);
02544       }
02545       ast_party_connected_line_free(&connected_line);
02546       return -1;
02547    }
02548 
02549    /* Initiate the channel transfer of party A to party C (or recalled party B). */
02550    ast_cel_report_event(transferee, AST_CEL_ATTENDEDTRANSFER, NULL, NULL, newchan);
02551 
02552    xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", transferee->linkedid, 0, "Transfered/%s", transferee->name);
02553    if (!xferchan) {
02554       ast_hangup(newchan);
02555       ast_party_connected_line_free(&connected_line);
02556       return -1;
02557    }
02558 
02559    /* Give party A a momentary ringback tone during transfer. */
02560    xferchan->visible_indication = AST_CONTROL_RINGING;
02561 
02562    /* Make formats okay */
02563    xferchan->readformat = transferee->readformat;
02564    xferchan->writeformat = transferee->writeformat;
02565 
02566    ast_channel_masquerade(xferchan, transferee);
02567    ast_explicit_goto(xferchan, transferee->context, transferee->exten, transferee->priority);
02568    xferchan->_state = AST_STATE_UP;
02569    ast_clear_flag(xferchan, AST_FLAGS_ALL);
02570 
02571    /* Do the masquerade manually to make sure that is is completed. */
02572    ast_do_masquerade(xferchan);
02573 
02574    newchan->_state = AST_STATE_UP;
02575    ast_clear_flag(newchan, AST_FLAGS_ALL);
02576    tobj = ast_calloc(1, sizeof(*tobj));
02577    if (!tobj) {
02578       ast_hangup(xferchan);
02579       ast_hangup(newchan);
02580       ast_party_connected_line_free(&connected_line);
02581       return -1;
02582    }
02583 
02584    ast_channel_lock(newchan);
02585    if ((features_datastore = ast_channel_datastore_find(newchan, &dial_features_info, NULL))) {
02586       dialfeatures = features_datastore->data;
02587    }
02588    ast_channel_unlock(newchan);
02589 
02590    if (dialfeatures) {
02591       /* newchan should always be the callee and shows up as callee in dialfeatures, but for some reason
02592          I don't currently understand, the abilities of newchan seem to be stored on the caller side */
02593       ast_copy_flags(&(config->features_callee), &(dialfeatures->features_caller), AST_FLAGS_ALL);
02594       dialfeatures = NULL;
02595    }
02596 
02597    ast_channel_lock(xferchan);
02598    if ((features_datastore = ast_channel_datastore_find(xferchan, &dial_features_info, NULL))) {
02599       dialfeatures = features_datastore->data;
02600    }
02601    ast_channel_unlock(xferchan);
02602 
02603    if (dialfeatures) {
02604       ast_copy_flags(&(config->features_caller), &(dialfeatures->features_caller), AST_FLAGS_ALL);
02605    }
02606 
02607    tobj->chan = newchan;
02608    tobj->peer = xferchan;
02609    tobj->bconfig = *config;
02610 
02611    if (tobj->bconfig.end_bridge_callback_data_fixup) {
02612       tobj->bconfig.end_bridge_callback_data_fixup(&tobj->bconfig, tobj->peer, tobj->chan);
02613    }
02614 
02615    /*
02616     * xferchan is transferee, and newchan is the transfer target
02617     * So...in a transfer, who is the caller and who is the callee?
02618     *
02619     * When the call is originally made, it is clear who is caller and callee.
02620     * When a transfer occurs, it is my humble opinion that the transferee becomes
02621     * the caller, and the transfer target is the callee.
02622     *
02623     * The problem is that these macros were set with the intention of the original
02624     * caller and callee taking those roles.  A transfer can totally mess things up,
02625     * to be technical.  What sucks even more is that you can't effectively change
02626     * the macros in the dialplan during the call from the transferer to the transfer
02627     * target because the transferee is stuck with whatever role he originally had.
02628     *
02629     * I think the answer here is just to make sure that it is well documented that
02630     * during a transfer, the transferee is the "caller" and the transfer target
02631     * is the "callee."
02632     *
02633     * This means that if party B calls party A, and party B transfers party A to
02634     * party C, then A has switched roles for the call.  Now party A will have the
02635     * caller macro called on his channel instead of the callee macro.
02636     *
02637     * Luckily, the method by which the party B to party C bridge is
02638     * launched above ensures that the transferee is the "chan" on
02639     * the bridge and the transfer target is the "peer," so my idea
02640     * for the roles post-transfer does not require extensive code
02641     * changes.
02642     */
02643 
02644    /* Transfer party C connected line to party A */
02645    ast_channel_lock(transferer);
02646    /*
02647     * Due to a limitation regarding when callerID is set on a Local channel,
02648     * we use the transferer's connected line information here.
02649     */
02650    ast_party_connected_line_copy(&connected_line, &transferer->connected);
02651    ast_channel_unlock(transferer);
02652    connected_line.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
02653    if (ast_channel_connected_line_macro(newchan, xferchan, &connected_line, 1, 0)) {
02654       ast_channel_update_connected_line(xferchan, &connected_line, NULL);
02655    }
02656 
02657    /* Transfer party A connected line to party C */
02658    ast_channel_lock(xferchan);
02659    ast_connected_line_copy_from_caller(&connected_line, &xferchan->caller);
02660    ast_channel_unlock(xferchan);
02661    connected_line.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
02662    if (ast_channel_connected_line_macro(xferchan, newchan, &connected_line, 0, 0)) {
02663       ast_channel_update_connected_line(newchan, &connected_line, NULL);
02664    }
02665 
02666    if (ast_stream_and_wait(newchan, xfersound, ""))
02667       ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
02668    bridge_call_thread_launch(tobj);
02669 
02670    ast_party_connected_line_free(&connected_line);
02671    return -1;/* The transferee is masqueraded and the original bridged channels can be hungup. */
02672 }
02673 
02674 /* add atxfer and automon as undefined so you can only use em if you configure them */
02675 #define FEATURES_COUNT ARRAY_LEN(builtin_features)
02676 
02677 AST_RWLOCK_DEFINE_STATIC(features_lock);
02678 
02679 static struct ast_call_feature builtin_features[] = {
02680    { AST_FEATURE_REDIRECT, "Blind Transfer", "blindxfer", "#", "#", builtin_blindtransfer, AST_FEATURE_FLAG_NEEDSDTMF, "" },
02681    { AST_FEATURE_REDIRECT, "Attended Transfer", "atxfer", "", "", builtin_atxfer, AST_FEATURE_FLAG_NEEDSDTMF, "" },
02682    { AST_FEATURE_AUTOMON, "One Touch Monitor", "automon", "", "", builtin_automonitor, AST_FEATURE_FLAG_NEEDSDTMF, "" },
02683    { AST_FEATURE_DISCONNECT, "Disconnect Call", "disconnect", "*", "*", builtin_disconnect, AST_FEATURE_FLAG_NEEDSDTMF, "" },
02684    { AST_FEATURE_PARKCALL, "Park Call", "parkcall", "", "", builtin_parkcall, AST_FEATURE_FLAG_NEEDSDTMF, "" },
02685    { AST_FEATURE_AUTOMIXMON, "One Touch MixMonitor", "automixmon", "", "", builtin_automixmonitor, AST_FEATURE_FLAG_NEEDSDTMF, "" },
02686 };
02687 
02688 
02689 static AST_RWLIST_HEAD_STATIC(feature_list, ast_call_feature);
02690 
02691 /*! \brief register new feature into feature_list*/
02692 void ast_register_feature(struct ast_call_feature *feature)
02693 {
02694    if (!feature) {
02695       ast_log(LOG_NOTICE,"You didn't pass a feature!\n");
02696       return;
02697    }
02698   
02699    AST_RWLIST_WRLOCK(&feature_list);
02700    AST_RWLIST_INSERT_HEAD(&feature_list,feature,feature_entry);
02701    AST_RWLIST_UNLOCK(&feature_list);
02702 
02703    ast_verb(2, "Registered Feature '%s'\n",feature->sname);
02704 }
02705 
02706 /*! 
02707  * \brief Add new feature group
02708  * \param fgname feature group name.
02709  *
02710  * Add new feature group to the feature group list insert at head of list.
02711  * \note This function MUST be called while feature_groups is locked.
02712  */
02713 static struct feature_group *register_group(const char *fgname)
02714 {
02715    struct feature_group *fg;
02716 
02717    if (!fgname) {
02718       ast_log(LOG_NOTICE, "You didn't pass a new group name!\n");
02719       return NULL;
02720    }
02721 
02722    if (!(fg = ast_calloc_with_stringfields(1, struct feature_group, 128))) {
02723       return NULL;
02724    }
02725 
02726    ast_string_field_set(fg, gname, fgname);
02727 
02728    AST_LIST_INSERT_HEAD(&feature_groups, fg, entry);
02729 
02730    ast_verb(2, "Registered group '%s'\n", fg->gname);
02731 
02732    return fg;
02733 }
02734 
02735 /*! 
02736  * \brief Add feature to group
02737  * \param fg feature group
02738  * \param exten
02739  * \param feature feature to add.
02740  *
02741  * Check fg and feature specified, add feature to list
02742  * \note This function MUST be called while feature_groups is locked. 
02743  */
02744 static void register_group_feature(struct feature_group *fg, const char *exten, struct ast_call_feature *feature)
02745 {
02746    struct feature_group_exten *fge;
02747 
02748    if (!fg) {
02749       ast_log(LOG_NOTICE, "You didn't pass a group!\n");
02750       return;
02751    }
02752 
02753    if (!feature) {
02754       ast_log(LOG_NOTICE, "You didn't pass a feature!\n");
02755       return;
02756    }
02757 
02758    if (!(fge = ast_calloc_with_stringfields(1, struct feature_group_exten, 128))) {
02759       return;
02760    }
02761 
02762    ast_string_field_set(fge, exten, S_OR(exten, feature->exten));
02763 
02764    fge->feature = feature;
02765 
02766    AST_LIST_INSERT_HEAD(&fg->features, fge, entry);
02767 
02768    ast_verb(2, "Registered feature '%s' for group '%s' at exten '%s'\n",
02769                feature->sname, fg->gname, fge->exten);
02770 }
02771 
02772 void ast_unregister_feature(struct ast_call_feature *feature)
02773 {
02774    if (!feature) {
02775       return;
02776    }
02777 
02778    AST_RWLIST_WRLOCK(&feature_list);
02779    AST_RWLIST_REMOVE(&feature_list, feature, feature_entry);
02780    AST_RWLIST_UNLOCK(&feature_list);
02781 
02782    ast_free(feature);
02783 }
02784 
02785 /*! \brief Remove all features in the list */
02786 static void ast_unregister_features(void)
02787 {
02788    struct ast_call_feature *feature;
02789 
02790    AST_RWLIST_WRLOCK(&feature_list);
02791    while ((feature = AST_RWLIST_REMOVE_HEAD(&feature_list, feature_entry))) {
02792       ast_free(feature);
02793    }
02794    AST_RWLIST_UNLOCK(&feature_list);
02795 }
02796 
02797 /*! \brief find a call feature by name */
02798 static struct ast_call_feature *find_dynamic_feature(const char *name)
02799 {
02800    struct ast_call_feature *tmp;
02801 
02802    AST_RWLIST_TRAVERSE(&feature_list, tmp, feature_entry) {
02803       if (!strcasecmp(tmp->sname, name)) {
02804          break;
02805       }
02806    }
02807 
02808    return tmp;
02809 }
02810 
02811 /*! \brief Remove all feature groups in the list */
02812 static void ast_unregister_groups(void)
02813 {
02814    struct feature_group *fg;
02815    struct feature_group_exten *fge;
02816 
02817    AST_RWLIST_WRLOCK(&feature_groups);
02818    while ((fg = AST_LIST_REMOVE_HEAD(&feature_groups, entry))) {
02819       while ((fge = AST_LIST_REMOVE_HEAD(&fg->features, entry))) {
02820          ast_string_field_free_memory(fge);
02821          ast_free(fge);
02822       }
02823 
02824       ast_string_field_free_memory(fg);
02825       ast_free(fg);
02826    }
02827    AST_RWLIST_UNLOCK(&feature_groups);
02828 }
02829 
02830 /*! 
02831  * \brief Find a group by name 
02832  * \param name feature name
02833  * \retval feature group on success.
02834  * \retval NULL on failure.
02835  */
02836 static struct feature_group *find_group(const char *name)
02837 {
02838    struct feature_group *fg = NULL;
02839 
02840    AST_LIST_TRAVERSE(&feature_groups, fg, entry) {
02841       if (!strcasecmp(fg->gname, name))
02842          break;
02843    }
02844 
02845    return fg;
02846 }
02847 
02848 void ast_rdlock_call_features(void)
02849 {
02850    ast_rwlock_rdlock(&features_lock);
02851 }
02852 
02853 void ast_unlock_call_features(void)
02854 {
02855    ast_rwlock_unlock(&features_lock);
02856 }
02857 
02858 struct ast_call_feature *ast_find_call_feature(const char *name)
02859 {
02860    int x;
02861    for (x = 0; x < FEATURES_COUNT; x++) {
02862       if (!strcasecmp(name, builtin_features[x].sname))
02863          return &builtin_features[x];
02864    }
02865    return NULL;
02866 }
02867 
02868 /*!
02869  * \brief exec an app by feature 
02870  * \param chan,peer,config,code,sense,data
02871  *
02872  * Find a feature, determine which channel activated
02873  * \retval AST_FEATURE_RETURN_NO_HANGUP_PEER
02874  * \retval -1 error.
02875  * \retval -2 when an application cannot be found.
02876  */
02877 static int feature_exec_app(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
02878 {
02879    struct ast_app *app;
02880    struct ast_call_feature *feature = data;
02881    struct ast_channel *work, *idle;
02882    int res;
02883 
02884    if (!feature) { /* shouldn't ever happen! */
02885       ast_log(LOG_NOTICE, "Found feature before, but at execing we've lost it??\n");
02886       return -1; 
02887    }
02888 
02889    if (sense == FEATURE_SENSE_CHAN) {
02890       if (!ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLER))
02891          return AST_FEATURE_RETURN_KEEPTRYING;
02892       if (ast_test_flag(feature, AST_FEATURE_FLAG_ONSELF)) {
02893          work = chan;
02894          idle = peer;
02895       } else {
02896          work = peer;
02897          idle = chan;
02898       }
02899    } else {
02900       if (!ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLEE))
02901          return AST_FEATURE_RETURN_KEEPTRYING;
02902       if (ast_test_flag(feature, AST_FEATURE_FLAG_ONSELF)) {
02903          work = peer;
02904          idle = chan;
02905       } else {
02906          work = chan;
02907          idle = peer;
02908       }
02909    }
02910 
02911    if (!(app = pbx_findapp(feature->app))) {
02912       ast_log(LOG_WARNING, "Could not find application (%s)\n", feature->app);
02913       return -2;
02914    }
02915 
02916    ast_autoservice_start(idle);
02917    ast_autoservice_ignore(idle, AST_FRAME_DTMF_END);
02918    
02919    if(work && idle) {
02920       pbx_builtin_setvar_helper(work, "DYNAMIC_PEERNAME", idle->name);
02921       pbx_builtin_setvar_helper(idle, "DYNAMIC_PEERNAME", work->name);
02922       pbx_builtin_setvar_helper(work, "DYNAMIC_FEATURENAME", feature->sname);
02923       pbx_builtin_setvar_helper(idle, "DYNAMIC_FEATURENAME", feature->sname);
02924    }
02925 
02926    if (!ast_strlen_zero(feature->moh_class))
02927       ast_moh_start(idle, feature->moh_class, NULL);
02928 
02929    res = pbx_exec(work, app, feature->app_args);
02930 
02931    if (!ast_strlen_zero(feature->moh_class))
02932       ast_moh_stop(idle);
02933 
02934    ast_autoservice_stop(idle);
02935 
02936    if (res) {
02937       return AST_FEATURE_RETURN_SUCCESSBREAK;
02938    }
02939    return AST_FEATURE_RETURN_SUCCESS;  /*! \todo XXX should probably return res */
02940 }
02941 
02942 static void unmap_features(void)
02943 {
02944    int x;
02945 
02946    ast_rwlock_wrlock(&features_lock);
02947    for (x = 0; x < FEATURES_COUNT; x++)
02948       strcpy(builtin_features[x].exten, builtin_features[x].default_exten);
02949    ast_rwlock_unlock(&features_lock);
02950 }
02951 
02952 static int remap_feature(const char *name, const char *value)
02953 {
02954    int x, res = -1;
02955 
02956    ast_rwlock_wrlock(&features_lock);
02957    for (x = 0; x < FEATURES_COUNT; x++) {
02958       if (strcasecmp(builtin_features[x].sname, name))
02959          continue;
02960 
02961       ast_copy_string(builtin_features[x].exten, value, sizeof(builtin_features[x].exten));
02962       res = 0;
02963       break;
02964    }
02965    ast_rwlock_unlock(&features_lock);
02966 
02967    return res;
02968 }
02969 
02970 /*!
02971  * \brief Helper function for feature_interpret and ast_feature_detect
02972  * \param chan,peer,config,code,sense,dynamic_features_buf,features,operation,feature
02973  *
02974  * Lock features list, browse for code, unlock list
02975  * If a feature is found and the operation variable is set, that feature's
02976  * operation is executed.  The first feature found is copied to the feature parameter.
02977  * \retval res on success.
02978  * \retval -1 on failure.
02979  */
02980 static int feature_interpret_helper(struct ast_channel *chan, struct ast_channel *peer,
02981    struct ast_bridge_config *config, const char *code, int sense, char *dynamic_features_buf,
02982    struct ast_flags *features, feature_interpret_op operation, struct ast_call_feature *feature)
02983 {
02984    int x;
02985    struct feature_group *fg = NULL;
02986    struct feature_group_exten *fge;
02987    struct ast_call_feature *tmpfeature;
02988    char *tmp, *tok;
02989    int res = AST_FEATURE_RETURN_PASSDIGITS;
02990    int feature_detected = 0;
02991 
02992    if (!(peer && chan && config) && operation == FEATURE_INTERPRET_DO) {
02993       return -1; /* can not run feature operation */
02994    }
02995 
02996    ast_rwlock_rdlock(&features_lock);
02997    for (x = 0; x < FEATURES_COUNT; x++) {
02998       if ((ast_test_flag(features, builtin_features[x].feature_mask)) &&
02999           !ast_strlen_zero(builtin_features[x].exten)) {
03000          /* Feature is up for consideration */
03001          if (!strcmp(builtin_features[x].exten, code)) {
03002             ast_debug(3, "Feature detected: fname=%s sname=%s exten=%s\n", builtin_features[x].fname, builtin_features[x].sname, builtin_features[x].exten);
03003             if (operation == FEATURE_INTERPRET_CHECK) {
03004                res = AST_FEATURE_RETURN_SUCCESS; /* We found something */
03005             } else if (operation == FEATURE_INTERPRET_DO) {
03006                res = builtin_features[x].operation(chan, peer, config, code, sense, NULL);
03007             }
03008             if (feature) {
03009                memcpy(feature, &builtin_features[x], sizeof(feature));
03010             }
03011             feature_detected = 1;
03012             break;
03013          } else if (!strncmp(builtin_features[x].exten, code, strlen(code))) {
03014             if (res == AST_FEATURE_RETURN_PASSDIGITS) {
03015                res = AST_FEATURE_RETURN_STOREDIGITS;
03016             }
03017          }
03018       }
03019    }
03020    ast_rwlock_unlock(&features_lock);
03021 
03022    if (ast_strlen_zero(dynamic_features_buf) || feature_detected) {
03023       return res;
03024    }
03025 
03026    tmp = dynamic_features_buf;
03027 
03028    while ((tok = strsep(&tmp, "#"))) {
03029       AST_RWLIST_RDLOCK(&feature_groups);
03030 
03031       fg = find_group(tok);
03032 
03033       if (fg) {
03034          AST_LIST_TRAVERSE(&fg->features, fge, entry) {
03035             if (!strcmp(fge->exten, code)) {
03036                if (operation) {
03037                   res = fge->feature->operation(chan, peer, config, code, sense, fge->feature);
03038                }
03039                memcpy(feature, fge->feature, sizeof(feature));
03040                if (res != AST_FEATURE_RETURN_KEEPTRYING) {
03041                   AST_RWLIST_UNLOCK(&feature_groups);
03042                   break;
03043                }
03044                res = AST_FEATURE_RETURN_PASSDIGITS;
03045             } else if (!strncmp(fge->exten, code, strlen(code))) {
03046                res = AST_FEATURE_RETURN_STOREDIGITS;
03047             }
03048          }
03049          if (fge) {
03050             break;
03051          }
03052       }
03053 
03054       AST_RWLIST_UNLOCK(&feature_groups);
03055 
03056       AST_RWLIST_RDLOCK(&feature_list);
03057 
03058       if (!(tmpfeature = find_dynamic_feature(tok))) {
03059          AST_RWLIST_UNLOCK(&feature_list);
03060          continue;
03061       }
03062 
03063       /* Feature is up for consideration */
03064       if (!strcmp(tmpfeature->exten, code)) {
03065          ast_verb(3, " Feature Found: %s exten: %s\n",tmpfeature->sname, tok);
03066          if (operation == FEATURE_INTERPRET_CHECK) {
03067             res = AST_FEATURE_RETURN_SUCCESS; /* We found something */
03068          } else if (operation == FEATURE_INTERPRET_DO) {
03069             res = tmpfeature->operation(chan, peer, config, code, sense, tmpfeature);
03070          }
03071          if (feature) {
03072             memcpy(feature, tmpfeature, sizeof(feature));
03073          }
03074          if (res != AST_FEATURE_RETURN_KEEPTRYING) {
03075             AST_RWLIST_UNLOCK(&feature_list);
03076             break;
03077          }
03078          res = AST_FEATURE_RETURN_PASSDIGITS;
03079       } else if (!strncmp(tmpfeature->exten, code, strlen(code)))
03080          res = AST_FEATURE_RETURN_STOREDIGITS;
03081 
03082       AST_RWLIST_UNLOCK(&feature_list);
03083    }
03084 
03085    return res;
03086 }
03087 
03088 /*!
03089  * \brief Check the dynamic features
03090  * \param chan,peer,config,code,sense
03091  *
03092  * \retval res on success.
03093  * \retval -1 on failure.
03094  */
03095 static int feature_interpret(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense) {
03096 
03097    char dynamic_features_buf[128];
03098    const char *peer_dynamic_features, *chan_dynamic_features;
03099    struct ast_flags features;
03100    struct ast_call_feature feature;
03101    if (sense == FEATURE_SENSE_CHAN) {
03102       ast_copy_flags(&features, &(config->features_caller), AST_FLAGS_ALL);
03103    }
03104    else {
03105       ast_copy_flags(&features, &(config->features_callee), AST_FLAGS_ALL);
03106    }
03107 
03108    ast_channel_lock(peer);
03109    peer_dynamic_features = ast_strdupa(S_OR(pbx_builtin_getvar_helper(peer, "DYNAMIC_FEATURES"),""));
03110    ast_channel_unlock(peer);
03111 
03112    ast_channel_lock(chan);
03113    chan_dynamic_features = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "DYNAMIC_FEATURES"),""));
03114    ast_channel_unlock(chan);
03115 
03116    snprintf(dynamic_features_buf, sizeof(dynamic_features_buf), "%s%s%s", S_OR(chan_dynamic_features, ""), chan_dynamic_features && peer_dynamic_features ? "#" : "", S_OR(peer_dynamic_features,""));
03117 
03118    ast_debug(3, "Feature interpret: chan=%s, peer=%s, code=%s, sense=%d, features=%d, dynamic=%s\n", chan->name, peer->name, code, sense, features.flags, dynamic_features_buf);
03119 
03120    return feature_interpret_helper(chan, peer, config, code, sense, dynamic_features_buf, &features, FEATURE_INTERPRET_DO, &feature);
03121 }
03122 
03123 
03124 int ast_feature_detect(struct ast_channel *chan, struct ast_flags *features, const char *code, struct ast_call_feature *feature) {
03125 
03126    return feature_interpret_helper(chan, NULL, NULL, code, 0, NULL, features, FEATURE_INTERPRET_DETECT, feature);
03127 }
03128 
03129 /*! \brief Check if a feature exists */
03130 static int feature_check(struct ast_channel *chan, struct ast_flags *features, char *code) {
03131    char *chan_dynamic_features;
03132    ast_channel_lock(chan);
03133    chan_dynamic_features = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "DYNAMIC_FEATURES"),""));
03134    ast_channel_unlock(chan);
03135 
03136    return feature_interpret_helper(chan, NULL, NULL, code, 0, chan_dynamic_features, features, FEATURE_INTERPRET_CHECK, NULL);
03137 }
03138 
03139 static void set_config_flags(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config)
03140 {
03141    int x;
03142 
03143    ast_clear_flag(config, AST_FLAGS_ALL);
03144 
03145    ast_rwlock_rdlock(&features_lock);
03146    for (x = 0; x < FEATURES_COUNT; x++) {
03147       if (!ast_test_flag(builtin_features + x, AST_FEATURE_FLAG_NEEDSDTMF))
03148          continue;
03149 
03150       if (ast_test_flag(&(config->features_caller), builtin_features[x].feature_mask))
03151          ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
03152 
03153       if (ast_test_flag(&(config->features_callee), builtin_features[x].feature_mask))
03154          ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
03155    }
03156    ast_rwlock_unlock(&features_lock);
03157 
03158    if (chan && peer && !(ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_0) && ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_1))) {
03159       const char *dynamic_features = pbx_builtin_getvar_helper(chan, "DYNAMIC_FEATURES");
03160 
03161       if (dynamic_features) {
03162          char *tmp = ast_strdupa(dynamic_features);
03163          char *tok;
03164          struct ast_call_feature *feature;
03165 
03166          /* while we have a feature */
03167          while ((tok = strsep(&tmp, "#"))) {
03168             struct feature_group *fg;
03169 
03170             AST_RWLIST_RDLOCK(&feature_groups);
03171             AST_RWLIST_TRAVERSE(&feature_groups, fg, entry) {
03172                struct feature_group_exten *fge;
03173 
03174                AST_LIST_TRAVERSE(&fg->features, fge, entry) {
03175                   if (ast_test_flag(fge->feature, AST_FEATURE_FLAG_BYCALLER)) {
03176                      ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
03177                   }
03178                   if (ast_test_flag(fge->feature, AST_FEATURE_FLAG_BYCALLEE)) {
03179                      ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
03180                   }
03181                }
03182             }
03183             AST_RWLIST_UNLOCK(&feature_groups);
03184 
03185             AST_RWLIST_RDLOCK(&feature_list);
03186             if ((feature = find_dynamic_feature(tok)) && ast_test_flag(feature, AST_FEATURE_FLAG_NEEDSDTMF)) {
03187                if (ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLER)) {
03188                   ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
03189                }
03190                if (ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLEE)) {
03191                   ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
03192                }
03193             }
03194             AST_RWLIST_UNLOCK(&feature_list);
03195          }
03196       }
03197    }
03198 }
03199 
03200 /*!
03201  * \internal
03202  * \brief Get feature and dial.
03203  *
03204  * \param caller Channel to represent as the calling channel for the dialed channel.
03205  * \param caller_name Original caller channel name.
03206  * \param requestor Channel to say is requesting the dial (usually the caller).
03207  * \param transferee Channel that the dialed channel will be transferred to.
03208  * \param type Channel technology type to dial.
03209  * \param format Codec formats for dialed channel.
03210  * \param data Dialed channel extra parameters for ast_request() and ast_call().
03211  * \param timeout Time limit for dialed channel to answer in ms. Must be greater than zero.
03212  * \param outstate Status of dialed channel if unsuccessful.
03213  * \param language Language of the caller.
03214  *
03215  * \note
03216  * outstate can be:
03217  * 0, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION,
03218  * AST_CONTROL_ANSWER, or AST_CONTROL_UNHOLD.  If
03219  * AST_CONTROL_UNHOLD then the caller channel cancelled the
03220  * transfer or the dialed channel did not answer before the
03221  * timeout.
03222  *
03223  * \details
03224  * Request channel, set channel variables, initiate call,
03225  * check if they want to disconnect, go into loop, check if timeout has elapsed,
03226  * check if person to be transfered hung up, check for answer break loop,
03227  * set cdr return channel.
03228  *
03229  * \retval Channel Connected channel for transfer.
03230  * \retval NULL on failure to get third party connected.
03231  *
03232  * \note This is similar to __ast_request_and_dial() in channel.c
03233  */
03234 static struct ast_channel *feature_request_and_dial(struct ast_channel *caller,
03235    const char *caller_name, struct ast_channel *requestor,
03236    struct ast_channel *transferee, const char *type, format_t format, void *data,
03237    int timeout, int *outstate, const char *language)
03238 {
03239    int state = 0;
03240    int cause = 0;
03241    int to;
03242    int caller_hungup;
03243    int transferee_hungup;
03244    struct ast_channel *chan;
03245    struct ast_channel *monitor_chans[3];
03246    struct ast_channel *active_channel;
03247    int res;
03248    int ready = 0;
03249    struct timeval started;
03250    int x, len = 0;
03251    char *disconnect_code = NULL, *dialed_code = NULL;
03252    struct ast_frame *f;
03253    AST_LIST_HEAD_NOLOCK(, ast_frame) deferred_frames;
03254 
03255    caller_hungup = ast_check_hangup(caller);
03256 
03257    if (!(chan = ast_request(type, format, requestor, data, &cause))) {
03258       ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
03259       switch (cause) {
03260       case AST_CAUSE_BUSY:
03261          state = AST_CONTROL_BUSY;
03262          break;
03263       case AST_CAUSE_CONGESTION:
03264          state = AST_CONTROL_CONGESTION;
03265          break;
03266       default:
03267          state = 0;
03268          break;
03269       }
03270       goto done;
03271    }
03272 
03273    ast_string_field_set(chan, language, language);
03274    ast_channel_inherit_variables(caller, chan);
03275    pbx_builtin_setvar_helper(chan, "TRANSFERERNAME", caller_name);
03276 
03277    ast_channel_lock(chan);
03278    ast_connected_line_copy_from_caller(&chan->connected, &requestor->caller);
03279    ast_channel_unlock(chan);
03280 
03281    if (ast_call(chan, data, timeout)) {
03282       ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
03283       switch (chan->hangupcause) {
03284       case AST_CAUSE_BUSY:
03285          state = AST_CONTROL_BUSY;
03286          break;
03287       case AST_CAUSE_CONGESTION:
03288          state = AST_CONTROL_CONGESTION;
03289          break;
03290       default:
03291          state = 0;
03292          break;
03293       }
03294       goto done;
03295    }
03296 
03297    /* support dialing of the featuremap disconnect code while performing an attended tranfer */
03298    ast_rwlock_rdlock(&features_lock);
03299    for (x = 0; x < FEATURES_COUNT; x++) {
03300       if (strcasecmp(builtin_features[x].sname, "disconnect"))
03301          continue;
03302 
03303       disconnect_code = builtin_features[x].exten;
03304       len = strlen(disconnect_code) + 1;
03305       dialed_code = alloca(len);
03306       memset(dialed_code, 0, len);
03307       break;
03308    }
03309    ast_rwlock_unlock(&features_lock);
03310    x = 0;
03311    started = ast_tvnow();
03312    to = timeout;
03313    AST_LIST_HEAD_INIT_NOLOCK(&deferred_frames);
03314 
03315    ast_poll_channel_add(caller, chan);
03316 
03317    transferee_hungup = 0;
03318    while (!ast_check_hangup(transferee) && (chan->_state != AST_STATE_UP)) {
03319       int num_chans = 0;
03320 
03321       monitor_chans[num_chans++] = transferee;
03322       monitor_chans[num_chans++] = chan;
03323       if (!caller_hungup) {
03324          if (ast_check_hangup(caller)) {
03325             caller_hungup = 1;
03326 
03327 #if defined(ATXFER_NULL_TECH)
03328             /* Change caller's name to ensure that it will remain unique. */
03329             set_new_chan_name(caller);
03330 
03331             /*
03332              * Get rid of caller's physical technology so it is free for
03333              * other calls.
03334              */
03335             set_kill_chan_tech(caller);
03336 #endif   /* defined(ATXFER_NULL_TECH) */
03337          } else {
03338             /* caller is not hungup so monitor it. */
03339             monitor_chans[num_chans++] = caller;
03340          }
03341       }
03342 
03343       /* see if the timeout has been violated */
03344       if (ast_tvdiff_ms(ast_tvnow(), started) > timeout) {
03345          state = AST_CONTROL_UNHOLD;
03346          ast_log(LOG_NOTICE, "We exceeded our AT-timeout for %s\n", chan->name);
03347          break; /*doh! timeout*/
03348       }
03349 
03350       active_channel = ast_waitfor_n(monitor_chans, num_chans, &to);
03351       if (!active_channel)
03352          continue;
03353 
03354       f = NULL;
03355       if (transferee == active_channel) {
03356          struct ast_frame *dup_f;
03357 
03358          f = ast_read(transferee);
03359          if (f == NULL) { /*doh! where'd he go?*/
03360             transferee_hungup = 1;
03361             state = 0;
03362             break;
03363          }
03364          if (ast_is_deferrable_frame(f)) {
03365             dup_f = ast_frisolate(f);
03366             if (dup_f) {
03367                if (dup_f == f) {
03368                   f = NULL;
03369                }
03370                AST_LIST_INSERT_HEAD(&deferred_frames, dup_f, frame_list);
03371             }
03372          }
03373       } else if (chan == active_channel) {
03374          if (!ast_strlen_zero(chan->call_forward)) {
03375             state = 0;
03376             chan = ast_call_forward(caller, chan, NULL, format, NULL, &state);
03377             if (!chan) {
03378                break;
03379             }
03380             continue;
03381          }
03382          f = ast_read(chan);
03383          if (f == NULL) { /*doh! where'd he go?*/
03384             switch (chan->hangupcause) {
03385             case AST_CAUSE_BUSY:
03386                state = AST_CONTROL_BUSY;
03387                break;
03388             case AST_CAUSE_CONGESTION:
03389                state = AST_CONTROL_CONGESTION;
03390                break;
03391             default:
03392                state = 0;
03393                break;
03394             }
03395             break;
03396          }
03397 
03398          if (f->frametype == AST_FRAME_CONTROL) {
03399             if (f->subclass.integer == AST_CONTROL_RINGING) {
03400                ast_verb(3, "%s is ringing\n", chan->name);
03401                ast_indicate(caller, AST_CONTROL_RINGING);
03402             } else if (f->subclass.integer == AST_CONTROL_BUSY) {
03403                state = f->subclass.integer;
03404                ast_verb(3, "%s is busy\n", chan->name);
03405                ast_indicate(caller, AST_CONTROL_BUSY);
03406                ast_frfree(f);
03407                break;
03408             } else if (f->subclass.integer == AST_CONTROL_CONGESTION) {
03409                state = f->subclass.integer;
03410                ast_verb(3, "%s is congested\n", chan->name);
03411                ast_indicate(caller, AST_CONTROL_CONGESTION);
03412                ast_frfree(f);
03413                break;
03414             } else if (f->subclass.integer == AST_CONTROL_ANSWER) {
03415                /* This is what we are hoping for */
03416                state = f->subclass.integer;
03417                ast_frfree(f);
03418                ready=1;
03419                break;
03420             } else if (f->subclass.integer == AST_CONTROL_CONNECTED_LINE) {
03421                if (caller_hungup) {
03422                   struct ast_party_connected_line connected;
03423 
03424                   /* Just save it for the transfer. */
03425                   ast_party_connected_line_set_init(&connected, &caller->connected);
03426                   res = ast_connected_line_parse_data(f->data.ptr, f->datalen,
03427                      &connected);
03428                   if (!res) {
03429                      ast_channel_set_connected_line(caller, &connected, NULL);
03430                   }
03431                   ast_party_connected_line_free(&connected);
03432                } else {
03433                   ast_autoservice_start(transferee);
03434                   if (ast_channel_connected_line_macro(chan, caller, f, 1, 1)) {
03435                      ast_indicate_data(caller, AST_CONTROL_CONNECTED_LINE,
03436                         f->data.ptr, f->datalen);
03437                   }
03438                   ast_autoservice_stop(transferee);
03439                }
03440             } else if (f->subclass.integer == AST_CONTROL_REDIRECTING) {
03441                if (!caller_hungup) {
03442                   ast_autoservice_start(transferee);
03443                   if (ast_channel_redirecting_macro(chan, caller, f, 1, 1)) {
03444                      ast_indicate_data(caller, AST_CONTROL_REDIRECTING,
03445                         f->data.ptr, f->datalen);
03446                   }
03447                   ast_autoservice_stop(transferee);
03448                }
03449             } else if (f->subclass.integer != -1 && f->subclass.integer != AST_CONTROL_PROGRESS) {
03450                ast_log(LOG_NOTICE, "Don't know what to do about control frame: %d\n", f->subclass.integer);
03451             }
03452             /* else who cares */
03453          } else if (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO) {
03454             ast_write(caller, f);
03455          }
03456       } else if (caller == active_channel) {
03457          f = ast_read(caller);
03458          if (f) {
03459             if (f->frametype == AST_FRAME_DTMF) {
03460                dialed_code[x++] = f->subclass.integer;
03461                dialed_code[x] = '\0';
03462                if (strlen(dialed_code) == len) {
03463                   x = 0;
03464                } else if (x && strncmp(dialed_code, disconnect_code, x)) {
03465                   x = 0;
03466                   dialed_code[x] = '\0';
03467                }
03468                if (*dialed_code && !strcmp(dialed_code, disconnect_code)) {
03469                   /* Caller Canceled the call */
03470                   state = AST_CONTROL_UNHOLD;
03471                   ast_frfree(f);
03472                   break;
03473                }
03474             } else if (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO) {
03475                ast_write(chan, f);
03476             }
03477          }
03478       }
03479       if (f)
03480          ast_frfree(f);
03481    } /* end while */
03482 
03483    ast_poll_channel_del(caller, chan);
03484 
03485    /*
03486     * We need to free all the deferred frames, but we only need to
03487     * queue the deferred frames if no hangup was received.
03488     */
03489    ast_channel_lock(transferee);
03490    transferee_hungup = (transferee_hungup || ast_check_hangup(transferee));
03491    while ((f = AST_LIST_REMOVE_HEAD(&deferred_frames, frame_list))) {
03492       if (!transferee_hungup) {
03493          ast_queue_frame_head(transferee, f);
03494       }
03495       ast_frfree(f);
03496    }
03497    ast_channel_unlock(transferee);
03498 
03499 done:
03500    ast_indicate(caller, -1);
03501    if (chan && (ready || chan->_state == AST_STATE_UP)) {
03502       state = AST_CONTROL_ANSWER;
03503    } else if (chan) {
03504       ast_hangup(chan);
03505       chan = NULL;
03506    }
03507 
03508    if (outstate)
03509       *outstate = state;
03510 
03511    return chan;
03512 }
03513 
03514 void ast_channel_log(char *title, struct ast_channel *chan);
03515 
03516 void ast_channel_log(char *title, struct ast_channel *chan) /* for debug, this is handy enough to justify keeping it in the source */
03517 {
03518        ast_log(LOG_NOTICE, "______ %s (%lx)______\n", title, (unsigned long)chan);
03519        ast_log(LOG_NOTICE, "CHAN: name: %s;  appl: %s; data: %s; contxt: %s;  exten: %s; pri: %d;\n",
03520                        chan->name, chan->appl, chan->data, chan->context, chan->exten, chan->priority);
03521        ast_log(LOG_NOTICE, "CHAN: acctcode: %s;  dialcontext: %s; amaflags: %x; maccontxt: %s;  macexten: %s; macpri: %d;\n",
03522                        chan->accountcode, chan->dialcontext, chan->amaflags, chan->macrocontext, chan->macroexten, chan->macropriority);
03523        ast_log(LOG_NOTICE, "CHAN: masq: %p;  masqr: %p; _bridge: %p; uniqueID: %s; linkedID:%s\n",
03524                        chan->masq, chan->masqr,
03525                        chan->_bridge, chan->uniqueid, chan->linkedid);
03526        if (chan->masqr)
03527                ast_log(LOG_NOTICE, "CHAN: masquerading as: %s;  cdr: %p;\n",
03528                                chan->masqr->name, chan->masqr->cdr);
03529        if (chan->_bridge)
03530                ast_log(LOG_NOTICE, "CHAN: Bridged to %s\n", chan->_bridge->name);
03531 
03532    ast_log(LOG_NOTICE, "===== done ====\n");
03533 }
03534 
03535 /*!
03536  * \brief return the first unlocked cdr in a possible chain
03537  */
03538 static struct ast_cdr *pick_unlocked_cdr(struct ast_cdr *cdr)
03539 {
03540    struct ast_cdr *cdr_orig = cdr;
03541    while (cdr) {
03542       if (!ast_test_flag(cdr,AST_CDR_FLAG_LOCKED))
03543          return cdr;
03544       cdr = cdr->next;
03545    }
03546    return cdr_orig; /* everybody LOCKED or some other weirdness, like a NULL */
03547 }
03548 
03549 static void set_bridge_features_on_config(struct ast_bridge_config *config, const char *features)
03550 {
03551    const char *feature;
03552 
03553    if (ast_strlen_zero(features)) {
03554       return;
03555    }
03556 
03557    for (feature = features; *feature; feature++) {
03558       switch (*feature) {
03559       case 'T' :
03560       case 't' :
03561          ast_set_flag(&(config->features_caller), AST_FEATURE_REDIRECT);
03562          break;
03563       case 'K' :
03564       case 'k' :
03565          ast_set_flag(&(config->features_caller), AST_FEATURE_PARKCALL);
03566          break;
03567       case 'H' :
03568       case 'h' :
03569          ast_set_flag(&(config->features_caller), AST_FEATURE_DISCONNECT);
03570          break;
03571       case 'W' :
03572       case 'w' :
03573          ast_set_flag(&(config->features_caller), AST_FEATURE_AUTOMON);
03574          break;
03575       default :
03576          ast_log(LOG_WARNING, "Skipping unknown feature code '%c'\n", *feature);
03577       }
03578    }
03579 }
03580 
03581 static void add_features_datastores(struct ast_channel *caller, struct ast_channel *callee, struct ast_bridge_config *config)
03582 {
03583    struct ast_datastore *ds_callee_features = NULL, *ds_caller_features = NULL;
03584    struct ast_dial_features *callee_features = NULL, *caller_features = NULL;
03585 
03586    ast_channel_lock(caller);
03587    ds_caller_features = ast_channel_datastore_find(caller, &dial_features_info, NULL);
03588    ast_channel_unlock(caller);
03589    if (!ds_caller_features) {
03590       if (!(ds_caller_features = ast_datastore_alloc(&dial_features_info, NULL))) {
03591          ast_log(LOG_WARNING, "Unable to create channel datastore for caller features. Aborting!\n");
03592          return;
03593       }
03594       if (!(caller_features = ast_calloc(1, sizeof(*caller_features)))) {
03595          ast_log(LOG_WARNING, "Unable to allocate memory for callee feature flags. Aborting!\n");
03596          ast_datastore_free(ds_caller_features);
03597          return;
03598       }
03599       ds_caller_features->inheritance = DATASTORE_INHERIT_FOREVER;
03600       caller_features->is_caller = 1;
03601       ast_copy_flags(&(caller_features->features_callee), &(config->features_callee), AST_FLAGS_ALL);
03602       ast_copy_flags(&(caller_features->features_caller), &(config->features_caller), AST_FLAGS_ALL);
03603       ds_caller_features->data = caller_features;
03604       ast_channel_lock(caller);
03605       ast_channel_datastore_add(caller, ds_caller_features);
03606       ast_channel_unlock(caller);
03607    } else {
03608       /* If we don't return here, then when we do a builtin_atxfer we will copy the disconnect
03609        * flags over from the atxfer to the caller */
03610       return;
03611    }
03612 
03613    ast_channel_lock(callee);
03614    ds_callee_features = ast_channel_datastore_find(callee, &dial_features_info, NULL);
03615    ast_channel_unlock(callee);
03616    if (!ds_callee_features) {
03617       if (!(ds_callee_features = ast_datastore_alloc(&dial_features_info, NULL))) {
03618          ast_log(LOG_WARNING, "Unable to create channel datastore for callee features. Aborting!\n");
03619          return;
03620       }
03621       if (!(callee_features = ast_calloc(1, sizeof(*callee_features)))) {
03622          ast_log(LOG_WARNING, "Unable to allocate memory for callee feature flags. Aborting!\n");
03623          ast_datastore_free(ds_callee_features);
03624          return;
03625       }
03626       ds_callee_features->inheritance = DATASTORE_INHERIT_FOREVER;
03627       callee_features->is_caller = 0;
03628       ast_copy_flags(&(callee_features->features_callee), &(config->features_caller), AST_FLAGS_ALL);
03629       ast_copy_flags(&(callee_features->features_caller), &(config->features_callee), AST_FLAGS_ALL);
03630       ds_callee_features->data = callee_features;
03631       ast_channel_lock(callee);
03632       ast_channel_datastore_add(callee, ds_callee_features);
03633       ast_channel_unlock(callee);
03634    }
03635 
03636    return;
03637 }
03638 
03639 static void clear_dialed_interfaces(struct ast_channel *chan)
03640 {
03641    struct ast_datastore *di_datastore;
03642 
03643    ast_channel_lock(chan);
03644    if ((di_datastore = ast_channel_datastore_find(chan, &dialed_interface_info, NULL))) {
03645       if (option_debug) {
03646          ast_log(LOG_DEBUG, "Removing dialed interfaces datastore on %s since we're bridging\n", chan->name);
03647       }
03648       if (!ast_channel_datastore_remove(chan, di_datastore)) {
03649          ast_datastore_free(di_datastore);
03650       }
03651    }
03652    ast_channel_unlock(chan);
03653 }
03654 
03655 /*!
03656  * \brief bridge the call and set CDR
03657  *
03658  * \param chan The bridge considers this channel the caller.
03659  * \param peer The bridge considers this channel the callee.
03660  * \param config Configuration for this bridge.
03661  *
03662  * Set start time, check for two channels,check if monitor on
03663  * check for feature activation, create new CDR
03664  * \retval res on success.
03665  * \retval -1 on failure to bridge.
03666  */
03667 int ast_bridge_call(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config)
03668 {
03669    /* Copy voice back and forth between the two channels.  Give the peer
03670       the ability to transfer calls with '#<extension' syntax. */
03671    struct ast_frame *f;
03672    struct ast_channel *who;
03673    char chan_featurecode[FEATURE_MAX_LEN + 1]="";
03674    char peer_featurecode[FEATURE_MAX_LEN + 1]="";
03675    char orig_channame[AST_CHANNEL_NAME];
03676    char orig_peername[AST_CHANNEL_NAME];
03677    int res;
03678    int diff;
03679    int hasfeatures=0;
03680    int hadfeatures=0;
03681    int autoloopflag;
03682    int sendingdtmfdigit = 0;
03683    int we_disabled_peer_cdr = 0;
03684    struct ast_option_header *aoh;
03685    struct ast_cdr *bridge_cdr = NULL;
03686    struct ast_cdr *chan_cdr = chan->cdr; /* the proper chan cdr, if there are forked cdrs */
03687    struct ast_cdr *peer_cdr = peer->cdr; /* the proper chan cdr, if there are forked cdrs */
03688    struct ast_cdr *new_chan_cdr = NULL; /* the proper chan cdr, if there are forked cdrs */
03689    struct ast_cdr *new_peer_cdr = NULL; /* the proper chan cdr, if there are forked cdrs */
03690    struct ast_silence_generator *silgen = NULL;
03691    const char *h_context;
03692 
03693    if (chan && peer) {
03694       pbx_builtin_setvar_helper(chan, "BRIDGEPEER", peer->name);
03695       pbx_builtin_setvar_helper(peer, "BRIDGEPEER", chan->name);
03696    } else if (chan) {
03697       pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", NULL);
03698    }
03699 
03700    set_bridge_features_on_config(config, pbx_builtin_getvar_helper(chan, "BRIDGE_FEATURES"));
03701    add_features_datastores(chan, peer, config);
03702 
03703    /* This is an interesting case.  One example is if a ringing channel gets redirected to
03704     * an extension that picks up a parked call.  This will make sure that the call taken
03705     * out of parking gets told that the channel it just got bridged to is still ringing. */
03706    if (chan->_state == AST_STATE_RINGING && peer->visible_indication != AST_CONTROL_RINGING) {
03707       ast_indicate(peer, AST_CONTROL_RINGING);
03708    }
03709 
03710    if (monitor_ok) {
03711       const char *monitor_exec;
03712       struct ast_channel *src = NULL;
03713       if (!monitor_app) {
03714          if (!(monitor_app = pbx_findapp("Monitor")))
03715             monitor_ok=0;
03716       }
03717       if ((monitor_exec = pbx_builtin_getvar_helper(chan, "AUTO_MONITOR"))) 
03718          src = chan;
03719       else if ((monitor_exec = pbx_builtin_getvar_helper(peer, "AUTO_MONITOR")))
03720          src = peer;
03721       if (monitor_app && src) {
03722          char *tmp = ast_strdupa(monitor_exec);
03723          pbx_exec(src, monitor_app, tmp);
03724       }
03725    }
03726 
03727    set_config_flags(chan, peer, config);
03728 
03729    /* Answer if need be */
03730    if (chan->_state != AST_STATE_UP) {
03731       if (ast_raw_answer(chan, 1)) {
03732          return -1;
03733       }
03734    }
03735 
03736 #ifdef FOR_DEBUG
03737    /* show the two channels and cdrs involved in the bridge for debug & devel purposes */
03738    ast_channel_log("Pre-bridge CHAN Channel info", chan);
03739    ast_channel_log("Pre-bridge PEER Channel info", peer);
03740 #endif
03741    /* two channels are being marked as linked here */
03742    ast_channel_set_linkgroup(chan,peer);
03743 
03744    /* copy the userfield from the B-leg to A-leg if applicable */
03745    if (chan->cdr && peer->cdr && !ast_strlen_zero(peer->cdr->userfield)) {
03746       char tmp[256];
03747       if (!ast_strlen_zero(chan->cdr->userfield)) {
03748          snprintf(tmp, sizeof(tmp), "%s;%s", chan->cdr->userfield, peer->cdr->userfield);
03749          ast_cdr_appenduserfield(chan, tmp);
03750       } else
03751          ast_cdr_setuserfield(chan, peer->cdr->userfield);
03752       /* Don't delete the CDR; just disable it. */
03753       ast_set_flag(peer->cdr, AST_CDR_FLAG_POST_DISABLED);
03754       we_disabled_peer_cdr = 1;
03755    }
03756    ast_copy_string(orig_channame,chan->name,sizeof(orig_channame));
03757    ast_copy_string(orig_peername,peer->name,sizeof(orig_peername));
03758 
03759    if (!chan_cdr || (chan_cdr && !ast_test_flag(chan_cdr, AST_CDR_FLAG_POST_DISABLED))) {
03760       
03761       if (chan_cdr) {
03762          ast_set_flag(chan_cdr, AST_CDR_FLAG_MAIN);
03763          ast_cdr_update(chan);
03764          bridge_cdr = ast_cdr_dup_unique_swap(chan_cdr);
03765          /* rip any forked CDR's off of the chan_cdr and attach
03766           * them to the bridge_cdr instead */
03767          bridge_cdr->next = chan_cdr->next;
03768          chan_cdr->next = NULL;
03769          ast_copy_string(bridge_cdr->lastapp, S_OR(chan->appl, ""), sizeof(bridge_cdr->lastapp));
03770          ast_copy_string(bridge_cdr->lastdata, S_OR(chan->data, ""), sizeof(bridge_cdr->lastdata));
03771          if (peer_cdr && !ast_strlen_zero(peer_cdr->userfield)) {
03772             ast_copy_string(bridge_cdr->userfield, peer_cdr->userfield, sizeof(bridge_cdr->userfield));
03773          }
03774          ast_cdr_setaccount(peer, chan->accountcode);
03775 
03776       } else {
03777          /* better yet, in a xfer situation, find out why the chan cdr got zapped (pun unintentional) */
03778          bridge_cdr = ast_cdr_alloc(); /* this should be really, really rare/impossible? */
03779          ast_copy_string(bridge_cdr->channel, chan->name, sizeof(bridge_cdr->channel));
03780          ast_copy_string(bridge_cdr->dstchannel, peer->name, sizeof(bridge_cdr->dstchannel));
03781          ast_copy_string(bridge_cdr->uniqueid, chan->uniqueid, sizeof(bridge_cdr->uniqueid));
03782          ast_copy_string(bridge_cdr->lastapp, S_OR(chan->appl, ""), sizeof(bridge_cdr->lastapp));
03783          ast_copy_string(bridge_cdr->lastdata, S_OR(chan->data, ""), sizeof(bridge_cdr->lastdata));
03784          ast_cdr_setcid(bridge_cdr, chan);
03785          bridge_cdr->disposition = (chan->_state == AST_STATE_UP) ?  AST_CDR_ANSWERED : AST_CDR_NULL;
03786          bridge_cdr->amaflags = chan->amaflags ? chan->amaflags :  ast_default_amaflags;
03787          ast_copy_string(bridge_cdr->accountcode, chan->accountcode, sizeof(bridge_cdr->accountcode));
03788          /* Destination information */
03789          ast_copy_string(bridge_cdr->dst, chan->exten, sizeof(bridge_cdr->dst));
03790          ast_copy_string(bridge_cdr->dcontext, chan->context, sizeof(bridge_cdr->dcontext));
03791          if (peer_cdr) {
03792             bridge_cdr->start = peer_cdr->start;
03793             ast_copy_string(bridge_cdr->userfield, peer_cdr->userfield, sizeof(bridge_cdr->userfield));
03794          } else {
03795             ast_cdr_start(bridge_cdr);
03796          }
03797       }
03798       ast_debug(4,"bridge answer set, chan answer set\n");
03799       /* peer_cdr->answer will be set when a macro runs on the peer;
03800          in that case, the bridge answer will be delayed while the
03801          macro plays on the peer channel. The peer answered the call
03802          before the macro started playing. To the phone system,
03803          this is billable time for the call, even tho the caller
03804          hears nothing but ringing while the macro does its thing. */
03805 
03806       /* Another case where the peer cdr's time will be set, is when
03807          A self-parks by pickup up phone and dialing 700, then B
03808          picks up A by dialing its parking slot; there may be more 
03809          practical paths that get the same result, tho... in which
03810          case you get the previous answer time from the Park... which
03811          is before the bridge's start time, so I added in the 
03812          tvcmp check to the if below */
03813 
03814       if (peer_cdr && !ast_tvzero(peer_cdr->answer) && ast_tvcmp(peer_cdr->answer, bridge_cdr->start) >= 0) {
03815          ast_cdr_setanswer(bridge_cdr, peer_cdr->answer);
03816          ast_cdr_setdisposition(bridge_cdr, peer_cdr->disposition);
03817          if (chan_cdr) {
03818             ast_cdr_setanswer(chan_cdr, peer_cdr->answer);
03819             ast_cdr_setdisposition(chan_cdr, peer_cdr->disposition);
03820          }
03821       } else {
03822          ast_cdr_answer(bridge_cdr);
03823          if (chan_cdr) {
03824             ast_cdr_answer(chan_cdr); /* for the sake of cli status checks */
03825          }
03826       }
03827       if (ast_test_flag(chan,AST_FLAG_BRIDGE_HANGUP_DONT) && (chan_cdr || peer_cdr)) {
03828          if (chan_cdr) {
03829             ast_set_flag(chan_cdr, AST_CDR_FLAG_BRIDGED);
03830          }
03831          if (peer_cdr) {
03832             ast_set_flag(peer_cdr, AST_CDR_FLAG_BRIDGED);
03833          }
03834       }
03835       /* the DIALED flag may be set if a dialed channel is transfered
03836        * and then bridged to another channel.  In order for the
03837        * bridge CDR to be written, the DIALED flag must not be
03838        * present. */
03839       ast_clear_flag(bridge_cdr, AST_CDR_FLAG_DIALED);
03840    }
03841    ast_cel_report_event(chan, AST_CEL_BRIDGE_START, NULL, NULL, NULL);
03842 
03843    /* If we are bridging a call, stop worrying about forwarding loops. We presume that if
03844     * a call is being bridged, that the humans in charge know what they're doing. If they
03845     * don't, well, what can we do about that? */
03846    clear_dialed_interfaces(chan);
03847    clear_dialed_interfaces(peer);
03848 
03849    for (;;) {
03850       struct ast_channel *other; /* used later */
03851    
03852       res = ast_channel_bridge(chan, peer, config, &f, &who);
03853 
03854       if (ast_test_flag(chan, AST_FLAG_ZOMBIE)
03855          || ast_test_flag(peer, AST_FLAG_ZOMBIE)) {
03856          /* Zombies are present time to leave! */
03857          res = -1;
03858          if (f) {
03859             ast_frfree(f);
03860          }
03861          goto before_you_go;
03862       }
03863 
03864       /* When frame is not set, we are probably involved in a situation
03865          where we've timed out.
03866          When frame is set, we'll come this code twice; once for DTMF_BEGIN
03867          and also for DTMF_END. If we flow into the following 'if' for both, then 
03868          our wait times are cut in half, as both will subtract from the
03869          feature_timer. Not good!
03870       */
03871       if (config->feature_timer && (!f || f->frametype == AST_FRAME_DTMF_END)) {
03872          /* Update feature timer for next pass */
03873          diff = ast_tvdiff_ms(ast_tvnow(), config->feature_start_time);
03874          if (res == AST_BRIDGE_RETRY) {
03875             /* The feature fully timed out but has not been updated. Skip
03876              * the potential round error from the diff calculation and
03877              * explicitly set to expired. */
03878             config->feature_timer = -1;
03879          } else {
03880             config->feature_timer -= diff;
03881          }
03882 
03883          if (hasfeatures) {
03884             if (config->feature_timer <= 0) {
03885                /* Not *really* out of time, just out of time for
03886                   digits to come in for features. */
03887                ast_debug(1, "Timed out for feature!\n");
03888                if (!ast_strlen_zero(peer_featurecode)) {
03889                   ast_dtmf_stream(chan, peer, peer_featurecode, 0, 0);
03890                   memset(peer_featurecode, 0, sizeof(peer_featurecode));
03891                }
03892                if (!ast_strlen_zero(chan_featurecode)) {
03893                   ast_dtmf_stream(peer, chan, chan_featurecode, 0, 0);
03894                   memset(chan_featurecode, 0, sizeof(chan_featurecode));
03895                }
03896                if (f)
03897                   ast_frfree(f);
03898                hasfeatures = !ast_strlen_zero(chan_featurecode) || !ast_strlen_zero(peer_featurecode);
03899                if (!hasfeatures) {
03900                   /* No more digits expected - reset the timer */
03901                   config->feature_timer = 0;
03902                }
03903                hadfeatures = hasfeatures;
03904                /* Continue as we were */
03905                continue;
03906             } else if (!f) {
03907                /* The bridge returned without a frame and there is a feature in progress.
03908                 * However, we don't think the feature has quite yet timed out, so just
03909                 * go back into the bridge. */
03910                continue;
03911             }
03912          } else {
03913             if (config->feature_timer <=0) {
03914                /* We ran out of time */
03915                config->feature_timer = 0;
03916                who = chan;
03917                if (f)
03918                   ast_frfree(f);
03919                f = NULL;
03920                res = 0;
03921             }
03922          }
03923       }
03924       if (res < 0) {
03925          if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_test_flag(peer, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan) && !ast_check_hangup(peer)) {
03926             ast_log(LOG_WARNING, "Bridge failed on channels %s and %s\n", chan->name, peer->name);
03927          }
03928          goto before_you_go;
03929       }
03930       
03931       if (!f || (f->frametype == AST_FRAME_CONTROL &&
03932             (f->subclass.integer == AST_CONTROL_HANGUP || f->subclass.integer == AST_CONTROL_BUSY ||
03933                f->subclass.integer == AST_CONTROL_CONGESTION))) {
03934          res = -1;
03935          break;
03936       }
03937       /* many things should be sent to the 'other' channel */
03938       other = (who == chan) ? peer : chan;
03939       if (f->frametype == AST_FRAME_CONTROL) {
03940          switch (f->subclass.integer) {
03941          case AST_CONTROL_RINGING:
03942          case AST_CONTROL_FLASH:
03943          case -1:
03944             ast_indicate(other, f->subclass.integer);
03945             break;
03946          case AST_CONTROL_CONNECTED_LINE:
03947             if (!ast_channel_connected_line_macro(who, other, f, who != chan, 1)) {
03948                break;
03949             }
03950             ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
03951             break;
03952          case AST_CONTROL_REDIRECTING:
03953             if (!ast_channel_redirecting_macro(who, other, f, who != chan, 1)) {
03954                break;
03955             }
03956             ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
03957             break;
03958          case AST_CONTROL_AOC:
03959          case AST_CONTROL_HOLD:
03960          case AST_CONTROL_UNHOLD:
03961             ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
03962             break;
03963          case AST_CONTROL_OPTION:
03964             aoh = f->data.ptr;
03965             /* Forward option Requests, but only ones we know are safe
03966              * These are ONLY sent by chan_iax2 and I'm not convinced that
03967              * they are useful. I haven't deleted them entirely because I
03968              * just am not sure of the ramifications of removing them. */
03969             if (aoh && aoh->flag == AST_OPTION_FLAG_REQUEST) {
03970                   switch (ntohs(aoh->option)) {
03971                case AST_OPTION_TONE_VERIFY:
03972                case AST_OPTION_TDD:
03973                case AST_OPTION_RELAXDTMF:
03974                case AST_OPTION_AUDIO_MODE:
03975                case AST_OPTION_DIGIT_DETECT:
03976                case AST_OPTION_FAX_DETECT:
03977                   ast_channel_setoption(other, ntohs(aoh->option), aoh->data, 
03978                      f->datalen - sizeof(struct ast_option_header), 0);
03979                }
03980             }
03981             break;
03982          }
03983       } else if (f->frametype == AST_FRAME_DTMF_BEGIN) {
03984          struct ast_flags *cfg;
03985          char dtmfcode[2] = { f->subclass.integer, };
03986          size_t featurelen;
03987 
03988          if (who == chan) {
03989             featurelen = strlen(chan_featurecode);
03990             cfg = &(config->features_caller);
03991          } else {
03992             featurelen = strlen(peer_featurecode);
03993             cfg = &(config->features_callee);
03994          }
03995          /* Take a peek if this (possibly) matches a feature. If not, just pass this
03996           * DTMF along untouched. If this is not the first digit of a multi-digit code
03997           * then we need to fall through and stream the characters if it matches */
03998          if (featurelen == 0
03999             && feature_check(chan, cfg, &dtmfcode[0]) == AST_FEATURE_RETURN_PASSDIGITS) {
04000             if (option_debug > 3) {
04001                ast_log(LOG_DEBUG, "Passing DTMF through, since it is not a feature code\n");
04002             }
04003             ast_write(other, f);
04004             sendingdtmfdigit = 1;
04005          } else {
04006             /* If ast_opt_transmit_silence is set, then we need to make sure we are
04007              * transmitting something while we hold on to the DTMF waiting for a
04008              * feature. */
04009             if (!silgen && ast_opt_transmit_silence) {
04010                silgen = ast_channel_start_silence_generator(other);
04011             }
04012             if (option_debug > 3) {
04013                ast_log(LOG_DEBUG, "Not passing DTMF through, since it may be a feature code\n");
04014             }
04015          }
04016       } else if (f->frametype == AST_FRAME_DTMF_END) {
04017          char *featurecode;
04018          int sense;
04019 
04020          hadfeatures = hasfeatures;
04021          /* This cannot overrun because the longest feature is one shorter than our buffer */
04022          if (who == chan) {
04023             sense = FEATURE_SENSE_CHAN;
04024             featurecode = chan_featurecode;
04025          } else  {
04026             sense = FEATURE_SENSE_PEER;
04027             featurecode = peer_featurecode;
04028          }
04029 
04030          if (sendingdtmfdigit == 1) {
04031             /* We let the BEGIN go through happily, so let's not bother with the END,
04032              * since we already know it's not something we bother with */
04033             ast_write(other, f);
04034             sendingdtmfdigit = 0;
04035          } else {
04036             /*! append the event to featurecode. we rely on the string being zero-filled, and
04037              * not overflowing it. 
04038              * \todo XXX how do we guarantee the latter ?
04039              */
04040             featurecode[strlen(featurecode)] = f->subclass.integer;
04041             /* Get rid of the frame before we start doing "stuff" with the channels */
04042             ast_frfree(f);
04043             f = NULL;
04044             if (silgen) {
04045                ast_channel_stop_silence_generator(other, silgen);
04046                silgen = NULL;
04047             }
04048             config->feature_timer = 0;
04049             res = feature_interpret(chan, peer, config, featurecode, sense);
04050             switch(res) {
04051             case AST_FEATURE_RETURN_PASSDIGITS:
04052                ast_dtmf_stream(other, who, featurecode, 0, 0);
04053                /* Fall through */
04054             case AST_FEATURE_RETURN_SUCCESS:
04055                memset(featurecode, 0, sizeof(chan_featurecode));
04056                break;
04057             }
04058             if (res >= AST_FEATURE_RETURN_PASSDIGITS) {
04059                res = 0;
04060             } else {
04061                break;
04062             }
04063             hasfeatures = !ast_strlen_zero(chan_featurecode) || !ast_strlen_zero(peer_featurecode);
04064             if (hadfeatures && !hasfeatures) {
04065                /* Feature completed or timed out */
04066                config->feature_timer = 0;
04067             } else if (hasfeatures) {
04068                if (config->timelimit) {
04069                   /* No warning next time - we are waiting for feature code */
04070                   ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE);
04071                }
04072                config->feature_start_time = ast_tvnow();
04073                config->feature_timer = featuredigittimeout;
04074                ast_debug(1, "Set feature timer to %ld ms\n", config->feature_timer);
04075             }
04076          }
04077       }
04078       if (f)
04079          ast_frfree(f);
04080    }
04081    ast_cel_report_event(chan, AST_CEL_BRIDGE_END, NULL, NULL, NULL);
04082 
04083 before_you_go:
04084    /* Just in case something weird happened and we didn't clean up the silence generator... */
04085    if (silgen) {
04086       ast_channel_stop_silence_generator(who == chan ? peer : chan, silgen);
04087       silgen = NULL;
04088    }
04089 
04090    if (ast_test_flag(chan,AST_FLAG_BRIDGE_HANGUP_DONT)) {
04091       ast_clear_flag(chan,AST_FLAG_BRIDGE_HANGUP_DONT); /* its job is done */
04092       if (bridge_cdr) {
04093          ast_cdr_discard(bridge_cdr);
04094          /* QUESTION: should we copy bridge_cdr fields to the peer before we throw it away? */
04095       }
04096       return res; /* if we shouldn't do the h-exten, we shouldn't do the bridge cdr, either! */
04097    }
04098 
04099    if (config->end_bridge_callback) {
04100       config->end_bridge_callback(config->end_bridge_callback_data);
04101    }
04102 
04103    /* run the hangup exten on the chan object IFF it was NOT involved in a parking situation 
04104     * if it were, then chan belongs to a different thread now, and might have been hung up long
04105      * ago.
04106     */
04107    if (ast_test_flag(&config->features_caller, AST_FEATURE_NO_H_EXTEN)) {
04108       h_context = NULL;
04109    } else if (ast_exists_extension(chan, chan->context, "h", 1,
04110       S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
04111       h_context = chan->context;
04112    } else if (!ast_strlen_zero(chan->macrocontext)
04113       && ast_exists_extension(chan, chan->macrocontext, "h", 1,
04114          S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
04115       h_context = chan->macrocontext;
04116    } else {
04117       h_context = NULL;
04118    }
04119    if (h_context) {
04120       struct ast_cdr *swapper = NULL;
04121       char savelastapp[AST_MAX_EXTENSION];
04122       char savelastdata[AST_MAX_EXTENSION];
04123       char save_context[AST_MAX_CONTEXT];
04124       char save_exten[AST_MAX_EXTENSION];
04125       int  save_prio;
04126       int  found = 0;   /* set if we find at least one match */
04127       int  spawn_error = 0;
04128       
04129       autoloopflag = ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP);
04130       ast_set_flag(chan, AST_FLAG_IN_AUTOLOOP);
04131       if (bridge_cdr && ast_opt_end_cdr_before_h_exten) {
04132          ast_cdr_end(bridge_cdr);
04133       }
04134 
04135       /* swap the bridge cdr and the chan cdr for a moment, and let the endbridge
04136          dialplan code operate on it */
04137       ast_channel_lock(chan);
04138       if (bridge_cdr) {
04139          swapper = chan->cdr;
04140          ast_copy_string(savelastapp, bridge_cdr->lastapp, sizeof(bridge_cdr->lastapp));
04141          ast_copy_string(savelastdata, bridge_cdr->lastdata, sizeof(bridge_cdr->lastdata));
04142          chan->cdr = bridge_cdr;
04143       }
04144       ast_copy_string(save_context, chan->context, sizeof(save_context));
04145       ast_copy_string(save_exten, chan->exten, sizeof(save_exten));
04146       save_prio = chan->priority;
04147       if (h_context != chan->context) {
04148          ast_copy_string(chan->context, h_context, sizeof(chan->context));
04149       }
04150       ast_copy_string(chan->exten, "h", sizeof(chan->exten));
04151       chan->priority = 1;
04152       ast_channel_unlock(chan);
04153 
04154       while ((spawn_error = ast_spawn_extension(chan, chan->context, chan->exten,
04155          chan->priority,
04156          S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL),
04157          &found, 1)) == 0) {
04158          chan->priority++;
04159       }
04160       if (found && spawn_error) {
04161          /* Something bad happened, or a hangup has been requested. */
04162          ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", chan->context, chan->exten, chan->priority, chan->name);
04163          ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", chan->context, chan->exten, chan->priority, chan->name);
04164       }
04165 
04166       /* swap it back */
04167       ast_channel_lock(chan);
04168       ast_copy_string(chan->context, save_context, sizeof(chan->context));
04169       ast_copy_string(chan->exten, save_exten, sizeof(chan->exten));
04170       chan->priority = save_prio;
04171       if (bridge_cdr) {
04172          if (chan->cdr == bridge_cdr) {
04173             chan->cdr = swapper;
04174          } else {
04175             bridge_cdr = NULL;
04176          }
04177       }
04178       /* An "h" exten has been run, so indicate that one has been run. */
04179       ast_set_flag(chan, AST_FLAG_BRIDGE_HANGUP_RUN);
04180       ast_channel_unlock(chan);
04181 
04182       /* protect the lastapp/lastdata against the effects of the hangup/dialplan code */
04183       if (bridge_cdr) {
04184          ast_copy_string(bridge_cdr->lastapp, savelastapp, sizeof(bridge_cdr->lastapp));
04185          ast_copy_string(bridge_cdr->lastdata, savelastdata, sizeof(bridge_cdr->lastdata));
04186       }
04187       ast_set2_flag(chan, autoloopflag, AST_FLAG_IN_AUTOLOOP);
04188    }
04189    
04190    /* obey the NoCDR() wishes. -- move the DISABLED flag to the bridge CDR if it was set on the channel during the bridge... */
04191    new_chan_cdr = pick_unlocked_cdr(chan->cdr); /* the proper chan cdr, if there are forked cdrs */
04192    if (bridge_cdr && new_chan_cdr && ast_test_flag(new_chan_cdr, AST_CDR_FLAG_POST_DISABLED))
04193       ast_set_flag(bridge_cdr, AST_CDR_FLAG_POST_DISABLED);
04194 
04195    /* we can post the bridge CDR at this point */
04196    if (bridge_cdr) {
04197       ast_cdr_end(bridge_cdr);
04198       ast_cdr_detach(bridge_cdr);
04199    }
04200    
04201    /* do a specialized reset on the beginning channel
04202       CDR's, if they still exist, so as not to mess up
04203       issues in future bridges;
04204       
04205       Here are the rules of the game:
04206       1. The chan and peer channel pointers will not change
04207          during the life of the bridge.
04208       2. But, in transfers, the channel names will change.
04209          between the time the bridge is started, and the
04210          time the channel ends. 
04211          Usually, when a channel changes names, it will
04212          also change CDR pointers.
04213       3. Usually, only one of the two channels (chan or peer)
04214          will change names.
04215       4. Usually, if a channel changes names during a bridge,
04216          it is because of a transfer. Usually, in these situations,
04217          it is normal to see 2 bridges running simultaneously, and
04218          it is not unusual to see the two channels that change
04219          swapped between bridges.
04220       5. After a bridge occurs, we have 2 or 3 channels' CDRs
04221          to attend to; if the chan or peer changed names,
04222          we have the before and after attached CDR's.
04223    */
04224 
04225    if (new_chan_cdr) {
04226       struct ast_channel *chan_ptr = NULL;
04227 
04228       if (strcasecmp(orig_channame, chan->name) != 0) { 
04229          /* old channel */
04230          if ((chan_ptr = ast_channel_get_by_name(orig_channame))) {
04231             ast_channel_lock(chan_ptr);
04232             if (!ast_bridged_channel(chan_ptr)) {
04233                struct ast_cdr *cur;
04234                for (cur = chan_ptr->cdr; cur; cur = cur->next) {
04235                   if (cur == chan_cdr) {
04236                      break;
04237                   }
04238                }
04239                if (cur) {
04240                   ast_cdr_specialized_reset(chan_cdr, 0);
04241                }
04242             }
04243             ast_channel_unlock(chan_ptr);
04244             chan_ptr = ast_channel_unref(chan_ptr);
04245          }
04246          /* new channel */
04247          ast_cdr_specialized_reset(new_chan_cdr, 0);
04248       } else {
04249          ast_cdr_specialized_reset(chan->cdr, 0); /* nothing changed, reset the chan cdr  */
04250       }
04251    }
04252 
04253    {
04254       struct ast_channel *chan_ptr = NULL;
04255       new_peer_cdr = pick_unlocked_cdr(peer->cdr); /* the proper chan cdr, if there are forked cdrs */
04256       if (new_chan_cdr && ast_test_flag(new_chan_cdr, AST_CDR_FLAG_POST_DISABLED) && new_peer_cdr && !ast_test_flag(new_peer_cdr, AST_CDR_FLAG_POST_DISABLED))
04257          ast_set_flag(new_peer_cdr, AST_CDR_FLAG_POST_DISABLED); /* DISABLED is viral-- it will propagate across a bridge */
04258       if (strcasecmp(orig_peername, peer->name) != 0) { 
04259          /* old channel */
04260          if ((chan_ptr = ast_channel_get_by_name(orig_peername))) {
04261             ast_channel_lock(chan_ptr);
04262             if (!ast_bridged_channel(chan_ptr)) {
04263                struct ast_cdr *cur;
04264                for (cur = chan_ptr->cdr; cur; cur = cur->next) {
04265                   if (cur == peer_cdr) {
04266                      break;
04267                   }
04268                }
04269                if (cur) {
04270                   ast_cdr_specialized_reset(peer_cdr, 0);
04271                }
04272             }
04273             ast_channel_unlock(chan_ptr);
04274             chan_ptr = ast_channel_unref(chan_ptr);
04275          }
04276          /* new channel */
04277          if (new_peer_cdr) {
04278             ast_cdr_specialized_reset(new_peer_cdr, 0);
04279          }
04280       } else {
04281          if (we_disabled_peer_cdr) {
04282             ast_clear_flag(peer->cdr, AST_CDR_FLAG_POST_DISABLED);
04283          }
04284          ast_cdr_specialized_reset(peer->cdr, 0); /* nothing changed, reset the peer cdr  */
04285       }
04286    }
04287    
04288    return res;
04289 }
04290 
04291 /*! \brief Output parking event to manager */
04292 static void post_manager_event(const char *s, struct parkeduser *pu)
04293 {
04294    manager_event(EVENT_FLAG_CALL, s,
04295       "Exten: %s\r\n"
04296       "Channel: %s\r\n"
04297       "Parkinglot: %s\r\n"
04298       "CallerIDNum: %s\r\n"
04299       "CallerIDName: %s\r\n"
04300       "ConnectedLineNum: %s\r\n"
04301       "ConnectedLineName: %s\r\n"
04302       "UniqueID: %s\r\n",
04303       pu->parkingexten, 
04304       pu->chan->name,
04305       pu->parkinglot->name,
04306       S_COR(pu->chan->caller.id.number.valid, pu->chan->caller.id.number.str, "<unknown>"),
04307       S_COR(pu->chan->caller.id.name.valid, pu->chan->caller.id.name.str, "<unknown>"),
04308       S_COR(pu->chan->connected.id.number.valid, pu->chan->connected.id.number.str, "<unknown>"),
04309       S_COR(pu->chan->connected.id.name.valid, pu->chan->connected.id.name.str, "<unknown>"),
04310       pu->chan->uniqueid
04311       );
04312 }
04313 
04314 static char *callback_dialoptions(struct ast_flags *features_callee, struct ast_flags *features_caller, char *options, size_t len)
04315 {
04316    int i = 0;
04317    enum {
04318       OPT_CALLEE_REDIRECT   = 't',
04319       OPT_CALLER_REDIRECT   = 'T',
04320       OPT_CALLEE_AUTOMON    = 'w',
04321       OPT_CALLER_AUTOMON    = 'W',
04322       OPT_CALLEE_DISCONNECT = 'h',
04323       OPT_CALLER_DISCONNECT = 'H',
04324       OPT_CALLEE_PARKCALL   = 'k',
04325       OPT_CALLER_PARKCALL   = 'K',
04326    };
04327 
04328    memset(options, 0, len);
04329    if (ast_test_flag(features_caller, AST_FEATURE_REDIRECT) && i < len) {
04330       options[i++] = OPT_CALLER_REDIRECT;
04331    }
04332    if (ast_test_flag(features_caller, AST_FEATURE_AUTOMON) && i < len) {
04333       options[i++] = OPT_CALLER_AUTOMON;
04334    }
04335    if (ast_test_flag(features_caller, AST_FEATURE_DISCONNECT) && i < len) {
04336       options[i++] = OPT_CALLER_DISCONNECT;
04337    }
04338    if (ast_test_flag(features_caller, AST_FEATURE_PARKCALL) && i < len) {
04339       options[i++] = OPT_CALLER_PARKCALL;
04340    }
04341 
04342    if (ast_test_flag(features_callee, AST_FEATURE_REDIRECT) && i < len) {
04343       options[i++] = OPT_CALLEE_REDIRECT;
04344    }
04345    if (ast_test_flag(features_callee, AST_FEATURE_AUTOMON) && i < len) {
04346       options[i++] = OPT_CALLEE_AUTOMON;
04347    }
04348    if (ast_test_flag(features_callee, AST_FEATURE_DISCONNECT) && i < len) {
04349       options[i++] = OPT_CALLEE_DISCONNECT;
04350    }
04351    if (ast_test_flag(features_callee, AST_FEATURE_PARKCALL) && i < len) {
04352       options[i++] = OPT_CALLEE_PARKCALL;
04353    }
04354 
04355    return options;
04356 }
04357 
04358 /*!
04359  * \internal
04360  * \brief Run management on a parked call.
04361  *
04362  * \note The parkinglot parkings list is locked on entry.
04363  *
04364  * \retval TRUE if the parking completed.
04365  */
04366 static int manage_parked_call(struct parkeduser *pu, const struct pollfd *pfds, int nfds, struct pollfd **new_pfds, int *new_nfds, int *ms)
04367 {
04368    struct ast_channel *chan = pu->chan;   /* shorthand */
04369    int tms;        /* timeout for this item */
04370    int x;          /* fd index in channel */
04371    int parking_complete = 0;
04372 
04373    tms = ast_tvdiff_ms(ast_tvnow(), pu->start);
04374    if (tms > pu->parkingtime) {
04375       /*
04376        * Call has been parked too long.
04377        * Stop entertaining the caller.
04378        */
04379       switch (pu->hold_method) {
04380       case AST_CONTROL_HOLD:
04381          ast_indicate(pu->chan, AST_CONTROL_UNHOLD);
04382          break;
04383       case AST_CONTROL_RINGING:
04384          ast_indicate(pu->chan, -1);
04385          break;
04386       default:
04387          break;
04388       }
04389       pu->hold_method = 0;
04390 
04391       /* Get chan, exten from derived kludge */
04392       if (pu->peername[0]) {
04393          char *peername;
04394          char *dash;
04395          char *peername_flat; /* using something like DAHDI/52 for an extension name is NOT a good idea */
04396          int i;
04397 
04398          peername = ast_strdupa(pu->peername);
04399          dash = strrchr(peername, '-');
04400          if (dash) {
04401             *dash = '\0';
04402          }
04403 
04404          peername_flat = ast_strdupa(peername);
04405          for (i = 0; peername_flat[i]; i++) {
04406             if (peername_flat[i] == '/') {
04407                peername_flat[i] = '_';
04408             }
04409          }
04410 
04411          if (!ast_context_find_or_create(NULL, NULL, parking_con_dial, registrar)) {
04412             ast_log(LOG_ERROR,
04413                "Parking dial context '%s' does not exist and unable to create\n",
04414                parking_con_dial);
04415          } else {
04416             char returnexten[AST_MAX_EXTENSION];
04417             struct ast_datastore *features_datastore;
04418             struct ast_dial_features *dialfeatures;
04419 
04420             if (!strncmp(peername, "Parked/", 7)) {
04421                peername += 7;
04422             }
04423 
04424             ast_channel_lock(chan);
04425             features_datastore = ast_channel_datastore_find(chan, &dial_features_info,
04426                NULL);
04427             if (features_datastore && (dialfeatures = features_datastore->data)) {
04428                char buf[MAX_DIAL_FEATURE_OPTIONS] = {0,};
04429 
04430                snprintf(returnexten, sizeof(returnexten), "%s,30,%s", peername,
04431                   callback_dialoptions(&(dialfeatures->features_callee),
04432                      &(dialfeatures->features_caller), buf, sizeof(buf)));
04433             } else { /* Existing default */
04434                ast_log(LOG_NOTICE, "Dial features not found on %s, using default!\n",
04435                   chan->name);
04436                snprintf(returnexten, sizeof(returnexten), "%s,30,t", peername);
04437             }
04438             ast_channel_unlock(chan);
04439 
04440             if (ast_add_extension(parking_con_dial, 1, peername_flat, 1, NULL, NULL,
04441                "Dial", ast_strdup(returnexten), ast_free_ptr, registrar)) {
04442                ast_log(LOG_ERROR,
04443                   "Could not create parking return dial exten: %s@%s\n",
04444                   peername_flat, parking_con_dial);
04445             }
04446          }
04447          if (pu->options_specified) {
04448             /*
04449              * Park() was called with overriding return arguments, respect
04450              * those arguments.
04451              */
04452             set_c_e_p(chan, pu->context, pu->exten, pu->priority);
04453          } else if (comebacktoorigin) {
04454             set_c_e_p(chan, parking_con_dial, peername_flat, 1);
04455          } else {
04456             char parkingslot[AST_MAX_EXTENSION];
04457 
04458             snprintf(parkingslot, sizeof(parkingslot), "%d", pu->parkingnum);
04459             pbx_builtin_setvar_helper(chan, "PARKINGSLOT", parkingslot);
04460             set_c_e_p(chan, "parkedcallstimeout", peername_flat, 1);
04461          }
04462       } else {
04463          /*
04464           * They've been waiting too long, send them back to where they
04465           * came.  Theoretically they should have their original
04466           * extensions and such, but we copy to be on the safe side.
04467           */
04468          set_c_e_p(chan, pu->context, pu->exten, pu->priority);
04469       }
04470       post_manager_event("ParkedCallTimeOut", pu);
04471       ast_cel_report_event(pu->chan, AST_CEL_PARK_END, NULL, "ParkedCallTimeOut", NULL);
04472 
04473       ast_verb(2, "Timeout for %s parked on %d (%s). Returning to %s,%s,%d\n",
04474          pu->chan->name, pu->parkingnum, pu->parkinglot->name, pu->chan->context,
04475          pu->chan->exten, pu->chan->priority);
04476 
04477       /* Start up the PBX, or hang them up */
04478       if (ast_pbx_start(chan))  {
04479          ast_log(LOG_WARNING,
04480             "Unable to restart the PBX for user on '%s', hanging them up...\n",
04481             pu->chan->name);
04482          ast_hangup(chan);
04483       }
04484 
04485       /* And take them out of the parking lot */
04486       parking_complete = 1;
04487    } else { /* still within parking time, process descriptors */
04488       for (x = 0; x < AST_MAX_FDS; x++) {
04489          struct ast_frame *f;
04490          int y;
04491 
04492          if (chan->fds[x] == -1) {
04493             continue;   /* nothing on this descriptor */
04494          }
04495 
04496          for (y = 0; y < nfds; y++) {
04497             if (pfds[y].fd == chan->fds[x]) {
04498                /* Found poll record! */
04499                break;
04500             }
04501          }
04502          if (y == nfds) {
04503             /* Not found */
04504             continue;
04505          }
04506 
04507          if (!(pfds[y].revents & (POLLIN | POLLERR | POLLPRI))) {
04508             /* Next x */
04509             continue;
04510          }
04511 
04512          if (pfds[y].revents & POLLPRI) {
04513             ast_set_flag(chan, AST_FLAG_EXCEPTION);
04514          } else {
04515             ast_clear_flag(chan, AST_FLAG_EXCEPTION);
04516          }
04517          chan->fdno = x;
04518 
04519          /* See if they need servicing */
04520          f = ast_read(pu->chan);
04521          /* Hangup? */
04522          if (!f || (f->frametype == AST_FRAME_CONTROL
04523             && f->subclass.integer == AST_CONTROL_HANGUP)) {
04524             if (f) {
04525                ast_frfree(f);
04526             }
04527             post_manager_event("ParkedCallGiveUp", pu);
04528             ast_cel_report_event(pu->chan, AST_CEL_PARK_END, NULL, "ParkedCallGiveUp",
04529                NULL);
04530 
04531             /* There's a problem, hang them up */
04532             ast_verb(2, "%s got tired of being parked\n", chan->name);
04533             ast_hangup(chan);
04534 
04535             /* And take them out of the parking lot */
04536             parking_complete = 1;
04537             break;
04538          } else {
04539             /* XXX Maybe we could do something with packets, like dial "0" for operator or something XXX */
04540             ast_frfree(f);
04541             if (pu->hold_method == AST_CONTROL_HOLD
04542                && pu->moh_trys < 3
04543                && !chan->generatordata) {
04544                ast_debug(1,
04545                   "MOH on parked call stopped by outside source.  Restarting on channel %s.\n",
04546                   chan->name);
04547                ast_indicate_data(chan, AST_CONTROL_HOLD,
04548                   S_OR(pu->parkinglot->cfg.mohclass, NULL),
04549                   (!ast_strlen_zero(pu->parkinglot->cfg.mohclass)
04550                      ? strlen(pu->parkinglot->cfg.mohclass) + 1 : 0));
04551                pu->moh_trys++;
04552             }
04553             goto std;   /* XXX Ick: jumping into an else statement??? XXX */
04554          }
04555       } /* End for */
04556       if (x >= AST_MAX_FDS) {
04557 std:     for (x = 0; x < AST_MAX_FDS; x++) { /* mark fds for next round */
04558             if (chan->fds[x] > -1) {
04559                void *tmp = ast_realloc(*new_pfds,
04560                   (*new_nfds + 1) * sizeof(struct pollfd));
04561 
04562                if (!tmp) {
04563                   continue;
04564                }
04565                *new_pfds = tmp;
04566                (*new_pfds)[*new_nfds].fd = chan->fds[x];
04567                (*new_pfds)[*new_nfds].events = POLLIN | POLLERR | POLLPRI;
04568                (*new_pfds)[*new_nfds].revents = 0;
04569                (*new_nfds)++;
04570             }
04571          }
04572          /* Keep track of our shortest wait */
04573          if (tms < *ms || *ms < 0) {
04574             *ms = tms;
04575          }
04576       }
04577    }
04578 
04579    return parking_complete;
04580 }
04581 
04582 /*! \brief Run management on parkinglots, called once per parkinglot */
04583 static void manage_parkinglot(struct ast_parkinglot *curlot, const struct pollfd *pfds, int nfds, struct pollfd **new_pfds, int *new_nfds, int *ms)
04584 {
04585    struct parkeduser *pu;
04586    struct ast_context *con;
04587 
04588    /* Lock parkings list */
04589    AST_LIST_LOCK(&curlot->parkings);
04590    AST_LIST_TRAVERSE_SAFE_BEGIN(&curlot->parkings, pu, list) {
04591       if (pu->notquiteyet) { /* Pretend this one isn't here yet */
04592          continue;
04593       }
04594       if (manage_parked_call(pu, pfds, nfds, new_pfds, new_nfds, ms)) {
04595          /* Parking is complete for this call so remove it from the parking lot. */
04596          con = ast_context_find(pu->parkinglot->cfg.parking_con);
04597          if (con) {
04598             if (ast_context_remove_extension2(con, pu->parkingexten, 1, NULL, 0)) {
04599                ast_log(LOG_WARNING,
04600                   "Whoa, failed to remove the parking extension %s@%s!\n",
04601                   pu->parkingexten, pu->parkinglot->cfg.parking_con);
04602             }
04603             notify_metermaids(pu->parkingexten, pu->parkinglot->cfg.parking_con,
04604                AST_DEVICE_NOT_INUSE);
04605          } else {
04606             ast_log(LOG_WARNING,
04607                "Whoa, parking lot '%s' context '%s' does not exist.\n",
04608                pu->parkinglot->name, pu->parkinglot->cfg.parking_con);
04609          }
04610          AST_LIST_REMOVE_CURRENT(list);
04611          parkinglot_unref(pu->parkinglot);
04612          ast_free(pu);
04613       }
04614    }
04615    AST_LIST_TRAVERSE_SAFE_END;
04616    AST_LIST_UNLOCK(&curlot->parkings);
04617 }
04618 
04619 /*! 
04620  * \brief Take care of parked calls and unpark them if needed 
04621  * \param ignore unused var.
04622  * 
04623  * Start inf loop, lock parking lot, check if any parked channels have gone above timeout
04624  * if so, remove channel from parking lot and return it to the extension that parked it.
04625  * Check if parked channel decided to hangup, wait until next FD via select().
04626  */
04627 static void *do_parking_thread(void *ignore)
04628 {
04629    struct pollfd *pfds = NULL, *new_pfds = NULL;
04630    int nfds = 0, new_nfds = 0;
04631 
04632    for (;;) {
04633       struct ao2_iterator iter;
04634       struct ast_parkinglot *curlot;
04635       int ms = -1;   /* poll2 timeout, uninitialized */
04636 
04637       iter = ao2_iterator_init(parkinglots, 0);
04638       while ((curlot = ao2_iterator_next(&iter))) {
04639          manage_parkinglot(curlot, pfds, nfds, &new_pfds, &new_nfds, &ms);
04640          ao2_ref(curlot, -1);
04641       }
04642       ao2_iterator_destroy(&iter);
04643 
04644       /* Recycle */
04645       ast_free(pfds);
04646       pfds = new_pfds;
04647       nfds = new_nfds;
04648       new_pfds = NULL;
04649       new_nfds = 0;
04650 
04651       /* Wait for something to happen */
04652       ast_poll(pfds, nfds, ms);
04653       pthread_testcancel();
04654    }
04655    /* If this WERE reached, we'd need to free(pfds) */
04656    return NULL;   /* Never reached */
04657 }
04658 
04659 /*! \brief Find parkinglot by name */
04660 static struct ast_parkinglot *find_parkinglot(const char *name)
04661 {
04662    struct ast_parkinglot *parkinglot;
04663 
04664    if (ast_strlen_zero(name)) {
04665       return NULL;
04666    }
04667 
04668    parkinglot = ao2_find(parkinglots, (void *) name, 0);
04669    if (parkinglot) {
04670       ast_debug(1, "Found Parking lot: %s\n", parkinglot->name);
04671    }
04672 
04673    return parkinglot;
04674 }
04675 
04676 /*! \brief Copy parkinglot and store it with new name */
04677 static struct ast_parkinglot *copy_parkinglot(const char *name, const struct ast_parkinglot *parkinglot)
04678 {
04679    struct ast_parkinglot *copylot;
04680 
04681    if ((copylot = find_parkinglot(name))) { /* Parkinglot with that name already exists */
04682       ao2_ref(copylot, -1);
04683       return NULL;
04684    }
04685 
04686    copylot = create_parkinglot(name);
04687    if (!copylot) {
04688       return NULL;
04689    }
04690 
04691    ast_debug(1, "Building parking lot %s\n", name);
04692 
04693    /* Copy the source parking lot configuration. */
04694    copylot->cfg = parkinglot->cfg;
04695 
04696    return copylot;
04697 }
04698 
04699 AST_APP_OPTIONS(park_call_options, BEGIN_OPTIONS
04700    AST_APP_OPTION('r', AST_PARK_OPT_RINGING),
04701    AST_APP_OPTION('R', AST_PARK_OPT_RANDOMIZE),
04702    AST_APP_OPTION('s', AST_PARK_OPT_SILENCE),
04703 END_OPTIONS );
04704 
04705 /*! \brief Park a call */
04706 static int park_call_exec(struct ast_channel *chan, const char *data)
04707 {
04708    /* Cache the original channel name in case we get masqueraded in the middle
04709     * of a park--it is still theoretically possible for a transfer to happen before
04710     * we get here, but it is _really_ unlikely */
04711    char *orig_chan_name = ast_strdupa(chan->name);
04712    struct ast_park_call_args args = {
04713       .orig_chan_name = orig_chan_name,
04714    };
04715    struct ast_flags flags = { 0 };
04716    char orig_exten[AST_MAX_EXTENSION];
04717    int orig_priority;
04718    int res;
04719    const char *pl_name;
04720    char *parse;
04721    struct park_app_args app_args;
04722 
04723    /* Answer if call is not up */
04724    if (chan->_state != AST_STATE_UP) {
04725       if (ast_answer(chan)) {
04726          return -1;
04727       }
04728 
04729       /* Sleep to allow VoIP streams to settle down */
04730       if (ast_safe_sleep(chan, 1000)) {
04731          return -1;
04732       }
04733    }
04734 
04735    /* Process the dialplan application options. */
04736    parse = ast_strdupa(data);
04737    AST_STANDARD_APP_ARGS(app_args, parse);
04738 
04739    if (!ast_strlen_zero(app_args.timeout)) {
04740       if (sscanf(app_args.timeout, "%30d", &args.timeout) != 1) {
04741          ast_log(LOG_WARNING, "Invalid timeout '%s' provided\n", app_args.timeout);
04742          args.timeout = 0;
04743       }
04744    }
04745    if (!ast_strlen_zero(app_args.return_con)) {
04746       args.return_con = app_args.return_con;
04747    }
04748    if (!ast_strlen_zero(app_args.return_ext)) {
04749       args.return_ext = app_args.return_ext;
04750    }
04751    if (!ast_strlen_zero(app_args.return_pri)) {
04752       if (sscanf(app_args.return_pri, "%30d", &args.return_pri) != 1) {
04753          ast_log(LOG_WARNING, "Invalid priority '%s' specified\n", app_args.return_pri);
04754          args.return_pri = 0;
04755       }
04756    }
04757 
04758    ast_app_parse_options(park_call_options, &flags, NULL, app_args.options);
04759    args.flags = flags.flags;
04760 
04761    /*
04762     * Setup the exten/priority to be s/1 since we don't know where
04763     * this call should return.
04764     */
04765    ast_copy_string(orig_exten, chan->exten, sizeof(orig_exten));
04766    orig_priority = chan->priority;
04767    strcpy(chan->exten, "s");
04768    chan->priority = 1;
04769 
04770    /* Park the call */
04771    if (!ast_strlen_zero(app_args.pl_name)) {
04772       pl_name = app_args.pl_name;
04773    } else {
04774       pl_name = findparkinglotname(chan);
04775    }
04776    if (ast_strlen_zero(pl_name)) {
04777       /* Parking lot is not specified, so use the default parking lot. */
04778       args.parkinglot = parkinglot_addref(default_parkinglot);
04779    } else {
04780       args.parkinglot = find_parkinglot(pl_name);
04781       if (!args.parkinglot && parkeddynamic) {
04782          args.parkinglot = create_dynamic_parkinglot(pl_name, chan);
04783       }
04784    }
04785    if (args.parkinglot) {
04786       res = masq_park_call_announce(chan, chan, &args);
04787       parkinglot_unref(args.parkinglot);
04788    } else {
04789       /* Parking failed because the parking lot does not exist. */
04790       ast_stream_and_wait(chan, "pbx-parkingfailed", "");
04791       res = -1;
04792    }
04793    if (res) {
04794       /* Park failed, try to continue in the dialplan. */
04795       ast_copy_string(chan->exten, orig_exten, sizeof(chan->exten));
04796       chan->priority = orig_priority;
04797       res = 0;
04798    } else {
04799       /* Park succeeded. */
04800       res = 1;
04801    }
04802 
04803    return res;
04804 }
04805 
04806 /*! \brief Pickup parked call */
04807 static int parked_call_exec(struct ast_channel *chan, const char *data)
04808 {
04809    int res = 0;
04810    struct ast_channel *peer = NULL;
04811    struct parkeduser *pu;
04812    struct ast_context *con;
04813    char *parse;
04814    const char *pl_name;
04815    int park = 0;
04816    struct ast_bridge_config config;
04817    struct ast_parkinglot *parkinglot;
04818    AST_DECLARE_APP_ARGS(app_args,
04819       AST_APP_ARG(pl_space);  /*!< Parking lot space to retrieve if present. */
04820       AST_APP_ARG(pl_name);   /*!< Parking lot name to use if present. */
04821       AST_APP_ARG(dummy);     /*!< Place to put any remaining args string. */
04822    );
04823 
04824    parse = ast_strdupa(data);
04825    AST_STANDARD_APP_ARGS(app_args, parse);
04826 
04827    if (!ast_strlen_zero(app_args.pl_space)) {
04828       if (sscanf(app_args.pl_space, "%30u", &park) != 1) {
04829          ast_log(LOG_WARNING, "Specified parking extension not a number: %s\n",
04830             app_args.pl_space);
04831          park = -1;
04832       }
04833    }
04834 
04835    if (!ast_strlen_zero(app_args.pl_name)) {
04836       pl_name = app_args.pl_name;
04837    } else {
04838       pl_name = findparkinglotname(chan);
04839    }
04840    if (ast_strlen_zero(pl_name)) {
04841       /* Parking lot is not specified, so use the default parking lot. */
04842       parkinglot = parkinglot_addref(default_parkinglot);
04843    } else {
04844       parkinglot = find_parkinglot(pl_name);
04845       if (!parkinglot) {
04846          /* It helps to answer the channel if not already up. :) */
04847          if (chan->_state != AST_STATE_UP) {
04848             ast_answer(chan);
04849          }
04850          if (ast_stream_and_wait(chan, "pbx-invalidpark", "")) {
04851             ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n",
04852                "pbx-invalidpark", chan->name);
04853          }
04854          ast_log(LOG_WARNING,
04855             "Channel %s tried to retrieve parked call from unknown parking lot '%s'\n",
04856             chan->name, pl_name);
04857          return -1;
04858       }
04859    }
04860 
04861    AST_LIST_LOCK(&parkinglot->parkings);
04862    AST_LIST_TRAVERSE_SAFE_BEGIN(&parkinglot->parkings, pu, list) {
04863       if ((ast_strlen_zero(app_args.pl_space) || pu->parkingnum == park)
04864          && !pu->notquiteyet && !pu->chan->pbx) {
04865          /* The parking space has a call and can be picked up now. */
04866          AST_LIST_REMOVE_CURRENT(list);
04867          break;
04868       }
04869    }
04870    AST_LIST_TRAVERSE_SAFE_END;
04871    if (pu) {
04872       /* Found a parked call to pickup. */
04873       peer = pu->chan;
04874       con = ast_context_find(parkinglot->cfg.parking_con);
04875       if (con) {
04876          if (ast_context_remove_extension2(con, pu->parkingexten, 1, NULL, 0)) {
04877             ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
04878          } else {
04879             notify_metermaids(pu->parkingexten, parkinglot->cfg.parking_con, AST_DEVICE_NOT_INUSE);
04880          }
04881       } else {
04882          ast_log(LOG_WARNING, "Whoa, no parking context?\n");
04883       }
04884 
04885       ast_cel_report_event(pu->chan, AST_CEL_PARK_END, NULL, "UnParkedCall", chan);
04886       ast_manager_event(pu->chan, EVENT_FLAG_CALL, "UnParkedCall",
04887          "Exten: %s\r\n"
04888          "Channel: %s\r\n"
04889          "From: %s\r\n"
04890          "CallerIDNum: %s\r\n"
04891          "CallerIDName: %s\r\n"
04892          "ConnectedLineNum: %s\r\n"
04893          "ConnectedLineName: %s\r\n",
04894          pu->parkingexten, pu->chan->name, chan->name,
04895          S_COR(pu->chan->caller.id.number.valid, pu->chan->caller.id.number.str, "<unknown>"),
04896          S_COR(pu->chan->caller.id.name.valid, pu->chan->caller.id.name.str, "<unknown>"),
04897          S_COR(pu->chan->connected.id.number.valid, pu->chan->connected.id.number.str, "<unknown>"),
04898          S_COR(pu->chan->connected.id.name.valid, pu->chan->connected.id.name.str, "<unknown>")
04899          );
04900 
04901       /* Stop entertaining the caller. */
04902       switch (pu->hold_method) {
04903       case AST_CONTROL_HOLD:
04904          ast_indicate(pu->chan, AST_CONTROL_UNHOLD);
04905          break;
04906       case AST_CONTROL_RINGING:
04907          ast_indicate(pu->chan, -1);
04908          break;
04909       default:
04910          break;
04911       }
04912       pu->hold_method = 0;
04913 
04914       parkinglot_unref(pu->parkinglot);
04915       ast_free(pu);
04916    }
04917    AST_LIST_UNLOCK(&parkinglot->parkings);
04918 
04919    if (peer) {
04920       /* Update connected line between retrieving call and parked call. */
04921       struct ast_party_connected_line connected;
04922 
04923       ast_party_connected_line_init(&connected);
04924 
04925       /* Send our caller-id to peer. */
04926       ast_channel_lock(chan);
04927       ast_connected_line_copy_from_caller(&connected, &chan->caller);
04928       ast_channel_unlock(chan);
04929       connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
04930       if (ast_channel_connected_line_macro(chan, peer, &connected, 0, 0)) {
04931          ast_channel_update_connected_line(peer, &connected, NULL);
04932       }
04933 
04934       /*
04935        * Get caller-id from peer.
04936        *
04937        * Update the retrieving call before it is answered if possible
04938        * for best results.  Some phones do not support updating the
04939        * connected line information after connection.
04940        */
04941       ast_channel_lock(peer);
04942       ast_connected_line_copy_from_caller(&connected, &peer->caller);
04943       ast_channel_unlock(peer);
04944       connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
04945       if (ast_channel_connected_line_macro(peer, chan, &connected, 1, 0)) {
04946          ast_channel_update_connected_line(chan, &connected, NULL);
04947       }
04948 
04949       ast_party_connected_line_free(&connected);
04950    }
04951 
04952    /* JK02: it helps to answer the channel if not already up */
04953    if (chan->_state != AST_STATE_UP) {
04954       ast_answer(chan);
04955    }
04956 
04957    if (peer) {
04958       struct ast_datastore *features_datastore;
04959       struct ast_dial_features *dialfeatures = NULL;
04960 
04961       /* Play a courtesy to the source(s) configured to prefix the bridge connecting */
04962       if (!ast_strlen_zero(courtesytone)) {
04963          static const char msg[] = "courtesy tone";
04964 
04965          switch (parkedplay) {
04966          case 0:/* Courtesy tone to pickup chan */
04967             res = play_message_to_chans(chan, peer, -1, msg, courtesytone);
04968             break;
04969          case 1:/* Courtesy tone to parked chan */
04970             res = play_message_to_chans(chan, peer, 1, msg, courtesytone);
04971             break;
04972          case 2:/* Courtesy tone to both chans */
04973             res = play_message_to_chans(chan, peer, 0, msg, courtesytone);
04974             break;
04975          default:
04976             res = 0;
04977             break;
04978          }
04979          if (res) {
04980             ast_hangup(peer);
04981             parkinglot_unref(parkinglot);
04982             return -1;
04983          }
04984       }
04985 
04986       res = ast_channel_make_compatible(chan, peer);
04987       if (res < 0) {
04988          ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for bridge\n", chan->name, peer->name);
04989          ast_hangup(peer);
04990          parkinglot_unref(parkinglot);
04991          return -1;
04992       }
04993       /* This runs sorta backwards, since we give the incoming channel control, as if it
04994          were the person called. */
04995       ast_verb(3, "Channel %s connected to parked call %d\n", chan->name, park);
04996 
04997       pbx_builtin_setvar_helper(chan, "PARKEDCHANNEL", peer->name);
04998       ast_cdr_setdestchan(chan->cdr, peer->name);
04999       memset(&config, 0, sizeof(struct ast_bridge_config));
05000 
05001       /* Get datastore for peer and apply it's features to the callee side of the bridge config */
05002       ast_channel_lock(peer);
05003       if ((features_datastore = ast_channel_datastore_find(peer, &dial_features_info, NULL))) {
05004          dialfeatures = features_datastore->data;
05005       }
05006 
05007       /*
05008        * When the datastores for both caller and callee are created,
05009        * both the callee and caller channels use the features_caller
05010        * flag variable to represent themselves.  With that said, the
05011        * config.features_callee flags should be copied from the
05012        * datastore's caller feature flags regardless if peer was a
05013        * callee or caller.
05014        */
05015       if (dialfeatures) {
05016          ast_copy_flags(&(config.features_callee), &(dialfeatures->features_caller), AST_FLAGS_ALL);
05017       }
05018       ast_channel_unlock(peer);
05019 
05020       if ((parkinglot->cfg.parkedcalltransfers == AST_FEATURE_FLAG_BYCALLEE) || (parkinglot->cfg.parkedcalltransfers == AST_FEATURE_FLAG_BYBOTH)) {
05021          ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
05022       }
05023       if ((parkinglot->cfg.parkedcalltransfers == AST_FEATURE_FLAG_BYCALLER) || (parkinglot->cfg.parkedcalltransfers == AST_FEATURE_FLAG_BYBOTH)) {
05024          ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
05025       }
05026       if ((parkinglot->cfg.parkedcallreparking == AST_FEATURE_FLAG_BYCALLEE) || (parkinglot->cfg.parkedcallreparking == AST_FEATURE_FLAG_BYBOTH)) {
05027          ast_set_flag(&(config.features_callee), AST_FEATURE_PARKCALL);
05028       }
05029       if ((parkinglot->cfg.parkedcallreparking == AST_FEATURE_FLAG_BYCALLER) || (parkinglot->cfg.parkedcallreparking == AST_FEATURE_FLAG_BYBOTH)) {
05030          ast_set_flag(&(config.features_caller), AST_FEATURE_PARKCALL);
05031       }
05032       if ((parkinglot->cfg.parkedcallhangup == AST_FEATURE_FLAG_BYCALLEE) || (parkinglot->cfg.parkedcallhangup == AST_FEATURE_FLAG_BYBOTH)) {
05033          ast_set_flag(&(config.features_callee), AST_FEATURE_DISCONNECT);
05034       }
05035       if ((parkinglot->cfg.parkedcallhangup == AST_FEATURE_FLAG_BYCALLER) || (parkinglot->cfg.parkedcallhangup == AST_FEATURE_FLAG_BYBOTH)) {
05036          ast_set_flag(&(config.features_caller), AST_FEATURE_DISCONNECT);
05037       }
05038       if ((parkinglot->cfg.parkedcallrecording == AST_FEATURE_FLAG_BYCALLEE) || (parkinglot->cfg.parkedcallrecording == AST_FEATURE_FLAG_BYBOTH)) {
05039          ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMON);
05040       }
05041       if ((parkinglot->cfg.parkedcallrecording == AST_FEATURE_FLAG_BYCALLER) || (parkinglot->cfg.parkedcallrecording == AST_FEATURE_FLAG_BYBOTH)) {
05042          ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMON);
05043       }
05044 
05045       res = ast_bridge_call(chan, peer, &config);
05046 
05047       pbx_builtin_setvar_helper(chan, "PARKEDCHANNEL", peer->name);
05048       ast_cdr_setdestchan(chan->cdr, peer->name);
05049 
05050       /* Simulate the PBX hanging up */
05051       ast_hangup(peer);
05052    } else {
05053       if (ast_stream_and_wait(chan, "pbx-invalidpark", "")) {
05054          ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", "pbx-invalidpark",
05055             chan->name);
05056       }
05057       ast_verb(3, "Channel %s tried to retrieve nonexistent parked call %d\n",
05058          chan->name, park);
05059    }
05060 
05061    parkinglot_unref(parkinglot);
05062    return -1;
05063 }
05064 
05065 /*!
05066  * \brief Unreference parkinglot object.
05067  */
05068 static void parkinglot_unref(struct ast_parkinglot *parkinglot) 
05069 {
05070    ast_debug(3, "Multiparking: %s refcount now %d\n", parkinglot->name,
05071       ao2_ref(parkinglot, 0) - 1);
05072    ao2_ref(parkinglot, -1);
05073 }
05074 
05075 static struct ast_parkinglot *parkinglot_addref(struct ast_parkinglot *parkinglot)
05076 {
05077    int refcount;
05078 
05079    refcount = ao2_ref(parkinglot, +1);
05080    ast_debug(3, "Multiparking: %s refcount now %d\n", parkinglot->name, refcount + 1);
05081    return parkinglot;
05082 }
05083 
05084 /*! \brief Destroy a parking lot */
05085 static void parkinglot_destroy(void *obj)
05086 {
05087    struct ast_parkinglot *doomed = obj;
05088 
05089    /*
05090     * No need to destroy parked calls here because any parked call
05091     * holds a parking lot reference.  Therefore the parkings list
05092     * must be empty.
05093     */
05094    ast_assert(AST_LIST_EMPTY(&doomed->parkings));
05095    AST_LIST_HEAD_DESTROY(&doomed->parkings);
05096 }
05097 
05098 /*! \brief Allocate parking lot structure */
05099 static struct ast_parkinglot *create_parkinglot(const char *name)
05100 {
05101    struct ast_parkinglot *newlot;
05102 
05103    if (ast_strlen_zero(name)) { /* No name specified */
05104       return NULL;
05105    }
05106 
05107    newlot = ao2_alloc(sizeof(*newlot), parkinglot_destroy);
05108    if (!newlot)
05109       return NULL;
05110    
05111    ast_copy_string(newlot->name, name, sizeof(newlot->name));
05112    newlot->cfg.is_invalid = 1;/* No config is set yet. */
05113    AST_LIST_HEAD_INIT(&newlot->parkings);
05114 
05115    return newlot;
05116 }
05117 
05118 /*! 
05119  * \brief Add parking hints for all defined parking spaces.
05120  * \param context Dialplan context to add the hints.
05121  * \param start Starting space in parkinglot.
05122  * \param stop Ending space in parkinglot.
05123  */
05124 static void park_add_hints(const char *context, int start, int stop)
05125 {
05126    int numext;
05127    char device[AST_MAX_EXTENSION];
05128    char exten[10];
05129 
05130    for (numext = start; numext <= stop; numext++) {
05131       snprintf(exten, sizeof(exten), "%d", numext);
05132       snprintf(device, sizeof(device), "park:%s@%s", exten, context);
05133       ast_add_extension(context, 1, exten, PRIORITY_HINT, NULL, NULL, device, NULL, NULL, registrar);
05134    }
05135 }
05136 
05137 /*! Default configuration for default parking lot. */
05138 static const struct parkinglot_cfg parkinglot_cfg_default_default = {
05139    .mohclass = "default",
05140    .parkext = DEFAULT_PARK_EXTENSION,
05141    .parking_con = "parkedcalls",
05142    .parking_start = 701,
05143    .parking_stop = 750,
05144    .parkingtime = DEFAULT_PARK_TIME,
05145 };
05146 
05147 /*! Default configuration for normal parking lots. */
05148 static const struct parkinglot_cfg parkinglot_cfg_default = {
05149    .parkext = DEFAULT_PARK_EXTENSION,
05150    .parkingtime = DEFAULT_PARK_TIME,
05151 };
05152 
05153 /*!
05154  * \internal
05155  * \brief Set parking lot feature flag configuration value.
05156  *
05157  * \param pl_name Parking lot name for diagnostic messages.
05158  * \param param Parameter value to set.
05159  * \param var Current configuration variable item.
05160  *
05161  * \return Nothing
05162  */
05163 static void parkinglot_feature_flag_cfg(const char *pl_name, int *param, struct ast_variable *var)
05164 {
05165    ast_debug(1, "Setting parking lot %s %s to %s\n", pl_name, var->name, var->value);
05166    if (!strcasecmp(var->value, "both")) {
05167       *param = AST_FEATURE_FLAG_BYBOTH;
05168    } else if (!strcasecmp(var->value, "caller")) {
05169       *param = AST_FEATURE_FLAG_BYCALLER;
05170    } else if (!strcasecmp(var->value, "callee")) {
05171       *param = AST_FEATURE_FLAG_BYCALLEE;
05172    }
05173 }
05174 
05175 /*!
05176  * \internal
05177  * \brief Read parking lot configuration.
05178  *
05179  * \param pl_name Parking lot name for diagnostic messages.
05180  * \param cfg Parking lot config to update that is already initialized with defaults.
05181  * \param var Config variable list.
05182  *
05183  * \retval 0 on success.
05184  * \retval -1 on error.
05185  */
05186 static int parkinglot_config_read(const char *pl_name, struct parkinglot_cfg *cfg, struct ast_variable *var)
05187 {
05188    int error = 0;
05189 
05190    while (var) {
05191       if (!strcasecmp(var->name, "context")) {
05192          ast_copy_string(cfg->parking_con, var->value, sizeof(cfg->parking_con));
05193       } else if (!strcasecmp(var->name, "parkext")) {
05194          ast_copy_string(cfg->parkext, var->value, sizeof(cfg->parkext));
05195       } else if (!strcasecmp(var->name, "parkext_exclusive")) {
05196          cfg->parkext_exclusive = ast_true(var->value);
05197       } else if (!strcasecmp(var->name, "parkinghints")) {
05198          cfg->parkaddhints = ast_true(var->value);
05199       } else if (!strcasecmp(var->name, "parkedmusicclass")) {
05200          ast_copy_string(cfg->mohclass, var->value, sizeof(cfg->mohclass));
05201       } else if (!strcasecmp(var->name, "parkingtime")) {
05202          int parkingtime = 0;
05203 
05204          if ((sscanf(var->value, "%30d", &parkingtime) != 1) || parkingtime < 1) {
05205             ast_log(LOG_WARNING, "%s is not a valid parkingtime\n", var->value);
05206             error = -1;
05207          } else {
05208             cfg->parkingtime = parkingtime * 1000;
05209          }
05210       } else if (!strcasecmp(var->name, "parkpos")) {
05211          int start = 0;
05212          int end = 0;
05213 
05214          if (sscanf(var->value, "%30d-%30d", &start, &end) != 2) {
05215             ast_log(LOG_WARNING,
05216                "Format for parking positions is a-b, where a and b are numbers at line %d of %s\n",
05217                var->lineno, var->file);
05218             error = -1;
05219          } else if (end < start || start <= 0 || end <= 0) {
05220             ast_log(LOG_WARNING, "Parking range is invalid. Must be a <= b, at line %d of %s\n",
05221                var->lineno, var->file);
05222             error = -1;
05223          } else {
05224             cfg->parking_start = start;
05225             cfg->parking_stop = end;
05226          }
05227       } else if (!strcasecmp(var->name, "findslot")) {
05228          cfg->parkfindnext = (!strcasecmp(var->value, "next"));
05229       } else if (!strcasecmp(var->name, "parkedcalltransfers")) {
05230          parkinglot_feature_flag_cfg(pl_name, &cfg->parkedcalltransfers, var);
05231       } else if (!strcasecmp(var->name, "parkedcallreparking")) {
05232          parkinglot_feature_flag_cfg(pl_name, &cfg->parkedcallreparking, var);
05233       } else if (!strcasecmp(var->name, "parkedcallhangup")) {
05234          parkinglot_feature_flag_cfg(pl_name, &cfg->parkedcallhangup, var);
05235       } else if (!strcasecmp(var->name, "parkedcallrecording")) {
05236          parkinglot_feature_flag_cfg(pl_name, &cfg->parkedcallrecording, var);
05237       }
05238       var = var->next;
05239    }
05240 
05241    /* Check for configuration errors */
05242    if (ast_strlen_zero(cfg->parking_con)) {
05243       ast_log(LOG_WARNING, "Parking lot %s needs context\n", pl_name);
05244       error = -1;
05245    }
05246    if (ast_strlen_zero(cfg->parkext)) {
05247       ast_log(LOG_WARNING, "Parking lot %s needs parkext\n", pl_name);
05248       error = -1;
05249    }
05250    if (!cfg->parking_start) {
05251       ast_log(LOG_WARNING, "Parking lot %s needs parkpos\n", pl_name);
05252       error = -1;
05253    }
05254    if (error) {
05255       cfg->is_invalid = 1;
05256    }
05257 
05258    return error;
05259 }
05260 
05261 /*!
05262  * \internal
05263  * \brief Activate the given parkinglot.
05264  *
05265  * \param parkinglot Parking lot to activate.
05266  *
05267  * \details
05268  * Insert into the dialplan the context, parking lot access
05269  * extension, and optional dialplan hints.
05270  *
05271  * \retval 0 on success.
05272  * \retval -1 on error.
05273  */
05274 static int parkinglot_activate(struct ast_parkinglot *parkinglot)
05275 {
05276    int disabled = 0;
05277    char app_data[5 + AST_MAX_CONTEXT];
05278 
05279    /* Create Park option list.  Must match with struct park_app_args options. */
05280    if (parkinglot->cfg.parkext_exclusive) {
05281       /* Specify the parking lot this parking extension parks calls. */
05282       snprintf(app_data, sizeof(app_data), ",,,,,%s", parkinglot->name);
05283    } else {
05284       /* The dialplan must specify which parking lot to use. */
05285       app_data[0] = '\0';
05286    }
05287 
05288    /* Create context */
05289    if (!ast_context_find_or_create(NULL, NULL, parkinglot->cfg.parking_con, registrar)) {
05290       ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n",
05291          parkinglot->cfg.parking_con);
05292       disabled = 1;
05293 
05294    /* Add a parking extension into the context */
05295    } else if (ast_add_extension(parkinglot->cfg.parking_con, 1, parkinglot->cfg.parkext,
05296       1, NULL, NULL, parkcall, ast_strdup(app_data), ast_free_ptr, registrar)) {
05297       ast_log(LOG_ERROR, "Could not create parking lot %s access exten %s@%s\n",
05298          parkinglot->name, parkinglot->cfg.parkext, parkinglot->cfg.parking_con);
05299       disabled = 1;
05300    } else {
05301       /* Add parking hints */
05302       if (parkinglot->cfg.parkaddhints) {
05303          park_add_hints(parkinglot->cfg.parking_con, parkinglot->cfg.parking_start,
05304             parkinglot->cfg.parking_stop);
05305       }
05306 
05307       /*
05308        * XXX Not sure why we should need to notify the metermaids for
05309        * this exten.  It was originally done for the default parking
05310        * lot entry exten only but should be done for all entry extens
05311        * if we do it for one.
05312        */
05313       /* Notify metermaids about parking lot entry exten state. */
05314       notify_metermaids(parkinglot->cfg.parkext, parkinglot->cfg.parking_con,
05315          AST_DEVICE_INUSE);
05316    }
05317 
05318    parkinglot->disabled = disabled;
05319    return disabled ? -1 : 0;
05320 }
05321 
05322 /*! \brief Build parkinglot from configuration and chain it in if it doesn't already exist */
05323 static struct ast_parkinglot *build_parkinglot(const char *pl_name, struct ast_variable *var)
05324 {
05325    struct ast_parkinglot *parkinglot;
05326    const struct parkinglot_cfg *cfg_defaults;
05327    struct parkinglot_cfg new_cfg;
05328    int cfg_error;
05329    int oldparkinglot = 0;
05330 
05331    parkinglot = find_parkinglot(pl_name);
05332    if (parkinglot) {
05333       oldparkinglot = 1;
05334    } else {
05335       parkinglot = create_parkinglot(pl_name);
05336       if (!parkinglot) {
05337          return NULL;
05338       }
05339    }
05340    if (!strcmp(parkinglot->name, DEFAULT_PARKINGLOT)) {
05341       cfg_defaults = &parkinglot_cfg_default_default;
05342    } else {
05343       cfg_defaults = &parkinglot_cfg_default;
05344    }
05345    new_cfg = *cfg_defaults;
05346 
05347    ast_debug(1, "Building parking lot %s\n", parkinglot->name);
05348 
05349    ao2_lock(parkinglot);
05350 
05351    /* Do some config stuff */
05352    cfg_error = parkinglot_config_read(parkinglot->name, &new_cfg, var);
05353    if (oldparkinglot) {
05354       if (cfg_error) {
05355          /* Bad configuration read.  Keep using the original config. */
05356          ast_log(LOG_WARNING, "Changes to parking lot %s are discarded.\n",
05357             parkinglot->name);
05358          cfg_error = 0;
05359       } else if (!AST_LIST_EMPTY(&parkinglot->parkings)
05360          && memcmp(&new_cfg, &parkinglot->cfg, sizeof(parkinglot->cfg))) {
05361          /* Try reloading later when parking lot is empty. */
05362          ast_log(LOG_WARNING,
05363             "Parking lot %s has parked calls.  Parking lot changes discarded.\n",
05364             parkinglot->name);
05365          force_reload_load = 1;
05366       } else {
05367          /* Accept the new config */
05368          parkinglot->cfg = new_cfg;
05369       }
05370    } else {
05371       /* Load the initial parking lot config. */
05372       parkinglot->cfg = new_cfg;
05373    }
05374    parkinglot->the_mark = 0;
05375 
05376    ao2_unlock(parkinglot);
05377 
05378    if (cfg_error) {
05379       /* Only new parking lots could have config errors here. */
05380       ast_log(LOG_WARNING, "New parking lot %s is discarded.\n", parkinglot->name);
05381       parkinglot_unref(parkinglot);
05382       return NULL;
05383    }
05384 
05385    /* Move it into the list, if it wasn't already there */
05386    if (!oldparkinglot) {
05387       ao2_link(parkinglots, parkinglot);
05388    }
05389    parkinglot_unref(parkinglot);
05390 
05391    return parkinglot;
05392 }
05393 
05394 /*!
05395  * \internal
05396  * \brief Process an applicationmap section config line.
05397  *
05398  * \param var Config variable line.
05399  *
05400  * \return Nothing
05401  */
05402 static void process_applicationmap_line(struct ast_variable *var)
05403 {
05404    char *tmp_val = ast_strdupa(var->value);
05405    char *activateon;
05406    struct ast_call_feature *feature;
05407    AST_DECLARE_APP_ARGS(args,
05408       AST_APP_ARG(exten);
05409       AST_APP_ARG(activatedby);
05410       AST_APP_ARG(app);
05411       AST_APP_ARG(app_args);
05412       AST_APP_ARG(moh_class);
05413    );
05414 
05415    AST_STANDARD_APP_ARGS(args, tmp_val);
05416    if (strchr(args.app, '(')) {
05417       /* New syntax */
05418       args.moh_class = args.app_args;
05419       args.app_args = strchr(args.app, '(');
05420       *args.app_args++ = '\0';
05421       if (args.app_args[strlen(args.app_args) - 1] == ')') {
05422          args.app_args[strlen(args.app_args) - 1] = '\0';
05423       }
05424    }
05425 
05426    activateon = strsep(&args.activatedby, "/");
05427 
05428    /*! \todo XXX var_name or app_args ? */
05429    if (ast_strlen_zero(args.app)
05430       || ast_strlen_zero(args.exten)
05431       || ast_strlen_zero(activateon)
05432       || ast_strlen_zero(var->name)) {
05433       ast_log(LOG_NOTICE,
05434          "Please check the feature Mapping Syntax, either extension, name, or app aren't provided %s %s %s %s\n",
05435          args.app, args.exten, activateon, var->name);
05436       return;
05437    }
05438 
05439    AST_RWLIST_RDLOCK(&feature_list);
05440    if (find_dynamic_feature(var->name)) {
05441       AST_RWLIST_UNLOCK(&feature_list);
05442       ast_log(LOG_WARNING, "Dynamic Feature '%s' specified more than once!\n",
05443          var->name);
05444       return;
05445    }
05446    AST_RWLIST_UNLOCK(&feature_list);
05447 
05448    if (!(feature = ast_calloc(1, sizeof(*feature)))) {
05449       return;
05450    }
05451 
05452    ast_copy_string(feature->sname, var->name, FEATURE_SNAME_LEN);
05453    ast_copy_string(feature->app, args.app, FEATURE_APP_LEN);
05454    ast_copy_string(feature->exten, args.exten, FEATURE_EXTEN_LEN);
05455 
05456    if (args.app_args) {
05457       ast_copy_string(feature->app_args, args.app_args, FEATURE_APP_ARGS_LEN);
05458    }
05459 
05460    if (args.moh_class) {
05461       ast_copy_string(feature->moh_class, args.moh_class, FEATURE_MOH_LEN);
05462    }
05463 
05464    ast_copy_string(feature->exten, args.exten, sizeof(feature->exten));
05465    feature->operation = feature_exec_app;
05466    ast_set_flag(feature, AST_FEATURE_FLAG_NEEDSDTMF);
05467 
05468    /* Allow caller and callee to be specified for backwards compatability */
05469    if (!strcasecmp(activateon, "self") || !strcasecmp(activateon, "caller")) {
05470       ast_set_flag(feature, AST_FEATURE_FLAG_ONSELF);
05471    } else if (!strcasecmp(activateon, "peer") || !strcasecmp(activateon, "callee")) {
05472       ast_set_flag(feature, AST_FEATURE_FLAG_ONPEER);
05473    } else {
05474       ast_log(LOG_NOTICE, "Invalid 'ActivateOn' specification for feature '%s',"
05475          " must be 'self', or 'peer'\n", var->name);
05476       return;
05477    }
05478 
05479    if (ast_strlen_zero(args.activatedby)) {
05480       ast_set_flag(feature, AST_FEATURE_FLAG_BYBOTH);
05481    } else if (!strcasecmp(args.activatedby, "caller")) {
05482       ast_set_flag(feature, AST_FEATURE_FLAG_BYCALLER);
05483    } else if (!strcasecmp(args.activatedby, "callee")) {
05484       ast_set_flag(feature, AST_FEATURE_FLAG_BYCALLEE);
05485    } else if (!strcasecmp(args.activatedby, "both")) {
05486       ast_set_flag(feature, AST_FEATURE_FLAG_BYBOTH);
05487    } else {
05488       ast_log(LOG_NOTICE, "Invalid 'ActivatedBy' specification for feature '%s',"
05489          " must be 'caller', or 'callee', or 'both'\n", var->name);
05490       return;
05491    }
05492 
05493    ast_register_feature(feature);
05494 
05495    ast_verb(2, "Mapping Feature '%s' to app '%s(%s)' with code '%s'\n",
05496       var->name, args.app, args.app_args, args.exten);
05497 }
05498 
05499 static int process_config(struct ast_config *cfg)
05500 {
05501    int i;
05502    struct ast_variable *var = NULL;
05503    struct feature_group *fg = NULL;
05504    char *ctg; 
05505    static const char * const categories[] = { 
05506       /* Categories in features.conf that are not
05507        * to be parsed as group categories
05508        */
05509       "general",
05510       "featuremap",
05511       "applicationmap"
05512    };
05513 
05514    /* Set general features global defaults. */
05515    featuredigittimeout = DEFAULT_FEATURE_DIGIT_TIMEOUT;
05516 
05517    /* Set global call pickup defaults. */
05518    strcpy(pickup_ext, "*8");
05519    pickupsound[0] = '\0';
05520    pickupfailsound[0] = '\0';
05521 
05522    /* Set global call transfer defaults. */
05523    strcpy(xfersound, "beep");
05524    strcpy(xferfailsound, "beeperr");
05525    transferdigittimeout = DEFAULT_TRANSFER_DIGIT_TIMEOUT;
05526    atxfernoanswertimeout = DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER;
05527    atxferloopdelay = DEFAULT_ATXFER_LOOP_DELAY;
05528    atxferdropcall = DEFAULT_ATXFER_DROP_CALL;
05529    atxfercallbackretries = DEFAULT_ATXFER_CALLBACK_RETRIES;
05530 
05531    /* Set global call parking defaults. */
05532    comebacktoorigin = 1;
05533    courtesytone[0] = '\0';
05534    parkedplay = 0;
05535    adsipark = 0;
05536    parkeddynamic = 0;
05537 
05538    var = ast_variable_browse(cfg, "general");
05539    build_parkinglot(DEFAULT_PARKINGLOT, var);
05540    for (; var; var = var->next) {
05541       if (!strcasecmp(var->name, "parkeddynamic")) {
05542          parkeddynamic = ast_true(var->value);
05543       } else if (!strcasecmp(var->name, "adsipark")) {
05544          adsipark = ast_true(var->value);
05545       } else if (!strcasecmp(var->name, "transferdigittimeout")) {
05546          if ((sscanf(var->value, "%30d", &transferdigittimeout) != 1) || (transferdigittimeout < 1)) {
05547             ast_log(LOG_WARNING, "%s is not a valid transferdigittimeout\n", var->value);
05548             transferdigittimeout = DEFAULT_TRANSFER_DIGIT_TIMEOUT;
05549          } else {
05550             transferdigittimeout = transferdigittimeout * 1000;
05551          }
05552       } else if (!strcasecmp(var->name, "featuredigittimeout")) {
05553          if ((sscanf(var->value, "%30d", &featuredigittimeout) != 1) || (featuredigittimeout < 1)) {
05554             ast_log(LOG_WARNING, "%s is not a valid featuredigittimeout\n", var->value);
05555             featuredigittimeout = DEFAULT_FEATURE_DIGIT_TIMEOUT;
05556          }
05557       } else if (!strcasecmp(var->name, "atxfernoanswertimeout")) {
05558          if ((sscanf(var->value, "%30d", &atxfernoanswertimeout) != 1) || (atxfernoanswertimeout < 1)) {
05559             ast_log(LOG_WARNING, "%s is not a valid atxfernoanswertimeout\n", var->value);
05560             atxfernoanswertimeout = DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER;
05561          } else {
05562             atxfernoanswertimeout = atxfernoanswertimeout * 1000;
05563          }
05564       } else if (!strcasecmp(var->name, "atxferloopdelay")) {
05565          if ((sscanf(var->value, "%30u", &atxferloopdelay) != 1)) {
05566             ast_log(LOG_WARNING, "%s is not a valid atxferloopdelay\n", var->value);
05567             atxferloopdelay = DEFAULT_ATXFER_LOOP_DELAY;
05568          } else {
05569             atxferloopdelay *= 1000;
05570          }
05571       } else if (!strcasecmp(var->name, "atxferdropcall")) {
05572          atxferdropcall = ast_true(var->value);
05573       } else if (!strcasecmp(var->name, "atxfercallbackretries")) {
05574          if ((sscanf(var->value, "%30u", &atxfercallbackretries) != 1)) {
05575             ast_log(LOG_WARNING, "%s is not a valid atxfercallbackretries\n", var->value);
05576             atxfercallbackretries = DEFAULT_ATXFER_CALLBACK_RETRIES;
05577          }
05578       } else if (!strcasecmp(var->name, "courtesytone")) {
05579          ast_copy_string(courtesytone, var->value, sizeof(courtesytone));
05580       }  else if (!strcasecmp(var->name, "parkedplay")) {
05581          if (!strcasecmp(var->value, "both")) {
05582             parkedplay = 2;
05583          } else if (!strcasecmp(var->value, "parked")) {
05584             parkedplay = 1;
05585          } else {
05586             parkedplay = 0;
05587          }
05588       } else if (!strcasecmp(var->name, "xfersound")) {
05589          ast_copy_string(xfersound, var->value, sizeof(xfersound));
05590       } else if (!strcasecmp(var->name, "xferfailsound")) {
05591          ast_copy_string(xferfailsound, var->value, sizeof(xferfailsound));
05592       } else if (!strcasecmp(var->name, "pickupexten")) {
05593          ast_copy_string(pickup_ext, var->value, sizeof(pickup_ext));
05594       } else if (!strcasecmp(var->name, "pickupsound")) {
05595          ast_copy_string(pickupsound, var->value, sizeof(pickupsound));
05596       } else if (!strcasecmp(var->name, "pickupfailsound")) {
05597          ast_copy_string(pickupfailsound, var->value, sizeof(pickupfailsound));
05598       } else if (!strcasecmp(var->name, "comebacktoorigin")) {
05599          comebacktoorigin = ast_true(var->value);
05600       }
05601    }
05602 
05603    unmap_features();
05604    for (var = ast_variable_browse(cfg, "featuremap"); var; var = var->next) {
05605       if (remap_feature(var->name, var->value)) {
05606          ast_log(LOG_NOTICE, "Unknown feature '%s'\n", var->name);
05607       }
05608    }
05609 
05610    /* Map a key combination to an application */
05611    ast_unregister_features();
05612    for (var = ast_variable_browse(cfg, "applicationmap"); var; var = var->next) {
05613       process_applicationmap_line(var);
05614    }
05615 
05616    ast_unregister_groups();
05617    AST_RWLIST_WRLOCK(&feature_groups);
05618 
05619    ctg = NULL;
05620    while ((ctg = ast_category_browse(cfg, ctg))) {
05621       /* Is this a parkinglot definition ? */
05622       if (!strncasecmp(ctg, "parkinglot_", strlen("parkinglot_"))) {
05623          ast_debug(2, "Found configuration section %s, assume parking context\n", ctg);
05624          if (!build_parkinglot(ctg, ast_variable_browse(cfg, ctg))) {
05625             ast_log(LOG_ERROR, "Could not build parking lot %s. Configuration error.\n", ctg);
05626          } else {
05627             ast_debug(1, "Configured parking context %s\n", ctg);
05628          }
05629          continue;   
05630       }
05631 
05632       /* No, check if it's a group */
05633       for (i = 0; i < ARRAY_LEN(categories); i++) {
05634          if (!strcasecmp(categories[i], ctg)) {
05635             break;
05636          }
05637       }
05638       if (i < ARRAY_LEN(categories)) {
05639          continue;
05640       }
05641 
05642       if (!(fg = register_group(ctg))) {
05643          continue;
05644       }
05645 
05646       for (var = ast_variable_browse(cfg, ctg); var; var = var->next) {
05647          struct ast_call_feature *feature;
05648 
05649          AST_RWLIST_RDLOCK(&feature_list);
05650          if (!(feature = find_dynamic_feature(var->name)) && 
05651              !(feature = ast_find_call_feature(var->name))) {
05652             AST_RWLIST_UNLOCK(&feature_list);
05653             ast_log(LOG_WARNING, "Feature '%s' was not found.\n", var->name);
05654             continue;
05655          }
05656          AST_RWLIST_UNLOCK(&feature_list);
05657 
05658          register_group_feature(fg, var->value, feature);
05659       }
05660    }
05661 
05662    AST_RWLIST_UNLOCK(&feature_groups);
05663 
05664    return 0;
05665 }
05666 
05667 /*!
05668  * \internal
05669  * \brief Destroy the given dialplan usage context.
05670  *
05671  * \param doomed Parking lot usage context to destroy.
05672  *
05673  * \return Nothing
05674  */
05675 static void destroy_dialplan_usage_context(struct parking_dp_context *doomed)
05676 {
05677    struct parking_dp_ramp *ramp;
05678    struct parking_dp_spaces *spaces;
05679 
05680    while ((ramp = AST_LIST_REMOVE_HEAD(&doomed->access_extens, node))) {
05681       ast_free(ramp);
05682    }
05683    while ((spaces = AST_LIST_REMOVE_HEAD(&doomed->spaces, node))) {
05684       ast_free(spaces);
05685    }
05686    while ((spaces = AST_LIST_REMOVE_HEAD(&doomed->hints, node))) {
05687       ast_free(spaces);
05688    }
05689    ast_free(doomed);
05690 }
05691 
05692 /*!
05693  * \internal
05694  * \brief Destroy the given dialplan usage map.
05695  *
05696  * \param doomed Parking lot usage map to destroy.
05697  *
05698  * \return Nothing
05699  */
05700 static void destroy_dialplan_usage_map(struct parking_dp_map *doomed)
05701 {
05702    struct parking_dp_context *item;
05703 
05704    while ((item = AST_LIST_REMOVE_HEAD(doomed, node))) {
05705       destroy_dialplan_usage_context(item);
05706    }
05707 }
05708 
05709 /*!
05710  * \internal
05711  * \brief Create a new parking lot ramp dialplan usage node.
05712  *
05713  * \param exten Parking lot access ramp extension.
05714  * \param exclusive TRUE if the parking lot access ramp extension is exclusive.
05715  *
05716  * \retval New usage ramp node on success.
05717  * \retval NULL on error.
05718  */
05719 static struct parking_dp_ramp *build_dialplan_useage_ramp(const char *exten, int exclusive)
05720 {
05721    struct parking_dp_ramp *ramp_node;
05722 
05723    ramp_node = ast_calloc(1, sizeof(*ramp_node) + strlen(exten));
05724    if (!ramp_node) {
05725       return NULL;
05726    }
05727    ramp_node->exclusive = exclusive;
05728    strcpy(ramp_node->exten, exten);
05729    return ramp_node;
05730 }
05731 
05732 /*!
05733  * \internal
05734  * \brief Add parking lot access ramp to the context ramp usage map.
05735  *
05736  * \param ramp_map Current parking lot context ramp usage map.
05737  * \param exten Parking lot access ramp extension to add.
05738  * \param exclusive TRUE if the parking lot access ramp extension is exclusive.
05739  * \param lot Parking lot supplying reference data.
05740  * \param complain TRUE if to complain of parking lot ramp conflicts.
05741  *
05742  * \retval 0 on success.  The ramp_map is updated.
05743  * \retval -1 on failure.
05744  */
05745 static int usage_context_add_ramp(struct parking_dp_ramp_map *ramp_map, const char *exten, int exclusive, struct ast_parkinglot *lot, int complain)
05746 {
05747    struct parking_dp_ramp *cur_ramp;
05748    struct parking_dp_ramp *new_ramp;
05749    int cmp;
05750 
05751    /* Make sure that exclusive is only 0 or 1 */
05752    if (exclusive) {
05753       exclusive = 1;
05754    }
05755 
05756    AST_LIST_TRAVERSE_SAFE_BEGIN(ramp_map, cur_ramp, node) {
05757       cmp = strcmp(exten, cur_ramp->exten);
05758       if (cmp > 0) {
05759          /* The parking lot ramp goes after this node. */
05760          continue;
05761       }
05762       if (cmp == 0) {
05763          /* The ramp is already in the map. */
05764          if (complain && (cur_ramp->exclusive || exclusive)) {
05765             ast_log(LOG_WARNING,
05766                "Parking lot '%s' parkext %s@%s used by another parking lot.\n",
05767                lot->name, exten, lot->cfg.parking_con);
05768          }
05769          return 0;
05770       }
05771       /* The new parking lot ramp goes before this node. */
05772       new_ramp = build_dialplan_useage_ramp(exten, exclusive);
05773       if (!new_ramp) {
05774          return -1;
05775       }
05776       AST_LIST_INSERT_BEFORE_CURRENT(new_ramp, node);
05777       return 0;
05778    }
05779    AST_LIST_TRAVERSE_SAFE_END;
05780 
05781    /* New parking lot access ramp goes on the end. */
05782    new_ramp = build_dialplan_useage_ramp(exten, exclusive);
05783    if (!new_ramp) {
05784       return -1;
05785    }
05786    AST_LIST_INSERT_TAIL(ramp_map, new_ramp, node);
05787    return 0;
05788 }
05789 
05790 /*!
05791  * \internal
05792  * \brief Create a new parking lot spaces dialplan usage node.
05793  *
05794  * \param start First parking lot space to add.
05795  * \param stop Last parking lot space to add.
05796  *
05797  * \retval New usage ramp node on success.
05798  * \retval NULL on error.
05799  */
05800 static struct parking_dp_spaces *build_dialplan_useage_spaces(int start, int stop)
05801 {
05802    struct parking_dp_spaces *spaces_node;
05803 
05804    spaces_node = ast_calloc(1, sizeof(*spaces_node));
05805    if (!spaces_node) {
05806       return NULL;
05807    }
05808    spaces_node->start = start;
05809    spaces_node->stop = stop;
05810    return spaces_node;
05811 }
05812 
05813 /*!
05814  * \internal
05815  * \brief Add parking lot spaces to the context space usage map.
05816  *
05817  * \param space_map Current parking lot context space usage map.
05818  * \param start First parking lot space to add.
05819  * \param stop Last parking lot space to add.
05820  * \param lot Parking lot supplying reference data.
05821  * \param complain TRUE if to complain of parking lot spaces conflicts.
05822  *
05823  * \retval 0 on success.  The space_map is updated.
05824  * \retval -1 on failure.
05825  */
05826 static int usage_context_add_spaces(struct parking_dp_space_map *space_map, int start, int stop, struct ast_parkinglot *lot, int complain)
05827 {
05828    struct parking_dp_spaces *cur_node;
05829    struct parking_dp_spaces *expand_node;
05830    struct parking_dp_spaces *new_node;
05831 
05832    expand_node = NULL;
05833    AST_LIST_TRAVERSE_SAFE_BEGIN(space_map, cur_node, node) {
05834       /* NOTE: stop + 1 to combine immediately adjacent nodes into one. */
05835       if (expand_node) {
05836          /* The previous node is expanding to possibly eat following nodes. */
05837          if (expand_node->stop + 1 < cur_node->start) {
05838             /* Current node is completely after expanding node. */
05839             return 0;
05840          }
05841 
05842          if (complain
05843             && ((cur_node->start <= start && start <= cur_node->stop)
05844                || (cur_node->start <= stop && stop <= cur_node->stop)
05845                || (start < cur_node->start && cur_node->stop < stop))) {
05846             /* Only complain once per range add. */
05847             complain = 0;
05848             ast_log(LOG_WARNING,
05849                "Parking lot '%s' parkpos %d-%d@%s overlaps another parking lot.\n",
05850                lot->name, start, stop, lot->cfg.parking_con);
05851          }
05852 
05853          /* Current node is eaten by the expanding node. */
05854          if (expand_node->stop < cur_node->stop) {
05855             expand_node->stop = cur_node->stop;
05856          }
05857          AST_LIST_REMOVE_CURRENT(node);
05858          ast_free(cur_node);
05859          continue;
05860       }
05861 
05862       if (cur_node->stop + 1 < start) {
05863          /* New range is completely after current node. */
05864          continue;
05865       }
05866       if (stop + 1 < cur_node->start) {
05867          /* New range is completely before current node. */
05868          new_node = build_dialplan_useage_spaces(start, stop);
05869          if (!new_node) {
05870             return -1;
05871          }
05872          AST_LIST_INSERT_BEFORE_CURRENT(new_node, node);
05873          return 0;
05874       }
05875 
05876       if (complain
05877          && ((cur_node->start <= start && start <= cur_node->stop)
05878             || (cur_node->start <= stop && stop <= cur_node->stop)
05879             || (start < cur_node->start && cur_node->stop < stop))) {
05880          /* Only complain once per range add. */
05881          complain = 0;
05882          ast_log(LOG_WARNING,
05883             "Parking lot '%s' parkpos %d-%d@%s overlaps another parking lot.\n",
05884             lot->name, start, stop, lot->cfg.parking_con);
05885       }
05886 
05887       /* Current node range overlaps or is immediately adjacent to new range. */
05888       if (start < cur_node->start) {
05889          /* Expand the current node in the front. */
05890          cur_node->start = start;
05891       }
05892       if (stop <= cur_node->stop) {
05893          /* Current node is not expanding in the rear. */
05894          return 0;
05895       }
05896       cur_node->stop = stop;
05897       expand_node = cur_node;
05898    }
05899    AST_LIST_TRAVERSE_SAFE_END;
05900 
05901    if (expand_node) {
05902       /*
05903        * The previous node expanded and either ate all following nodes
05904        * or it was the last node.
05905        */
05906       return 0;
05907    }
05908 
05909    /* New range goes on the end. */
05910    new_node = build_dialplan_useage_spaces(start, stop);
05911    if (!new_node) {
05912       return -1;
05913    }
05914    AST_LIST_INSERT_TAIL(space_map, new_node, node);
05915    return 0;
05916 }
05917 
05918 /*!
05919  * \internal
05920  * \brief Add parking lot spaces to the context dialplan usage node.
05921  *
05922  * \param ctx_node Usage node to add parking lot spaces.
05923  * \param lot Parking lot to add data to ctx_node.
05924  * \param complain TRUE if to complain of parking lot ramp and spaces conflicts.
05925  *
05926  * \retval 0 on success.
05927  * \retval -1 on error.
05928  */
05929 static int dialplan_usage_add_parkinglot_data(struct parking_dp_context *ctx_node, struct ast_parkinglot *lot, int complain)
05930 {
05931    if (usage_context_add_ramp(&ctx_node->access_extens, lot->cfg.parkext,
05932       lot->cfg.parkext_exclusive, lot, complain)) {
05933       return -1;
05934    }
05935    if (usage_context_add_spaces(&ctx_node->spaces, lot->cfg.parking_start,
05936       lot->cfg.parking_stop, lot, complain)) {
05937       return -1;
05938    }
05939    if (lot->cfg.parkaddhints
05940       && usage_context_add_spaces(&ctx_node->hints, lot->cfg.parking_start,
05941          lot->cfg.parking_stop, lot, 0)) {
05942       return -1;
05943    }
05944    return 0;
05945 }
05946 
05947 /*!
05948  * \internal
05949  * \brief Create a new parking lot context dialplan usage node.
05950  *
05951  * \param lot Parking lot to create a new dialplan usage from.
05952  *
05953  * \retval New usage context node on success.
05954  * \retval NULL on error.
05955  */
05956 static struct parking_dp_context *build_dialplan_useage_context(struct ast_parkinglot *lot)
05957 {
05958    struct parking_dp_context *ctx_node;
05959 
05960    ctx_node = ast_calloc(1, sizeof(*ctx_node) + strlen(lot->cfg.parking_con));
05961    if (!ctx_node) {
05962       return NULL;
05963    }
05964    if (dialplan_usage_add_parkinglot_data(ctx_node, lot, 0)) {
05965       destroy_dialplan_usage_context(ctx_node);
05966       return NULL;
05967    }
05968    strcpy(ctx_node->context, lot->cfg.parking_con);
05969    return ctx_node;
05970 }
05971 
05972 /*!
05973  * \internal
05974  * \brief Add the given parking lot dialplan usage to the dialplan usage map.
05975  *
05976  * \param usage_map Parking lot usage map to add the given parking lot.
05977  * \param lot Parking lot to add dialplan usage.
05978  * \param complain TRUE if to complain of parking lot ramp and spaces conflicts.
05979  *
05980  * \retval 0 on success.
05981  * \retval -1 on error.
05982  */
05983 static int dialplan_usage_add_parkinglot(struct parking_dp_map *usage_map, struct ast_parkinglot *lot, int complain)
05984 {
05985    struct parking_dp_context *cur_ctx;
05986    struct parking_dp_context *new_ctx;
05987    int cmp;
05988 
05989    AST_LIST_TRAVERSE_SAFE_BEGIN(usage_map, cur_ctx, node) {
05990       cmp = strcmp(lot->cfg.parking_con, cur_ctx->context);
05991       if (cmp > 0) {
05992          /* The parking lot context goes after this node. */
05993          continue;
05994       }
05995       if (cmp == 0) {
05996          /* This is the node we will add parking lot spaces to the map. */
05997          return dialplan_usage_add_parkinglot_data(cur_ctx, lot, complain);
05998       }
05999       /* The new parking lot context goes before this node. */
06000       new_ctx = build_dialplan_useage_context(lot);
06001       if (!new_ctx) {
06002          return -1;
06003       }
06004       AST_LIST_INSERT_BEFORE_CURRENT(new_ctx, node);
06005       return 0;
06006    }
06007    AST_LIST_TRAVERSE_SAFE_END;
06008 
06009    /* New parking lot context goes on the end. */
06010    new_ctx = build_dialplan_useage_context(lot);
06011    if (!new_ctx) {
06012       return -1;
06013    }
06014    AST_LIST_INSERT_TAIL(usage_map, new_ctx, node);
06015    return 0;
06016 }
06017 
06018 /*!
06019  * \internal
06020  * \brief Build the dialplan usage map of the current parking lot container.
06021  *
06022  * \param usage_map Parking lot usage map.  Must already be initialized.
06023  * \param complain TRUE if to complain of parking lot ramp and spaces conflicts.
06024  *
06025  * \retval 0 on success.  The usage_map is filled in.
06026  * \retval -1 on failure.  Built usage_map is incomplete.
06027  */
06028 static int build_dialplan_useage_map(struct parking_dp_map *usage_map, int complain)
06029 {
06030    int status = 0;
06031    struct ao2_iterator iter;
06032    struct ast_parkinglot *curlot;
06033 
06034    /* For all parking lots */
06035    iter = ao2_iterator_init(parkinglots, 0);
06036    for (; (curlot = ao2_iterator_next(&iter)); ao2_ref(curlot, -1)) {
06037       /* Add the parking lot to the map. */
06038       if (dialplan_usage_add_parkinglot(usage_map, curlot, complain)) {
06039          ao2_ref(curlot, -1);
06040          status = -1;
06041          break;
06042       }
06043    }
06044    ao2_iterator_destroy(&iter);
06045 
06046    return status;
06047 }
06048 
06049 /*!
06050  * \internal
06051  * \brief Remove the given extension if it exists.
06052  *
06053  * \param context Dialplan database context name.
06054  * \param exten Extension to remove.
06055  * \param priority Extension priority to remove.
06056  *
06057  * \return Nothing
06058  */
06059 static void remove_exten_if_exist(const char *context, const char *exten, int priority)
06060 {
06061    struct pbx_find_info q = { .stacklen = 0 }; /* the rest is reset in pbx_find_extension */
06062 
06063    if (pbx_find_extension(NULL, NULL, &q, context, exten, priority, NULL, NULL,
06064       E_MATCH)) {
06065       ast_debug(1, "Removing unneeded parking lot exten: %s@%s priority:%d\n",
06066          context, exten, priority);
06067       ast_context_remove_extension(context, exten, priority, registrar);
06068    }
06069 }
06070 
06071 /*!
06072  * \internal
06073  * \brief Remove unused parking lot access ramp items.
06074  *
06075  * \param context Dialplan database context name.
06076  * \param old_ramps Before configuration reload access ramp usage map.
06077  * \param new_ramps After configuration reload access ramp usage map.
06078  *
06079  * \details
06080  * Remove access ramp items that were in the old context but not in the
06081  * new context.
06082  *
06083  * \return Nothing
06084  */
06085 static void remove_dead_ramp_usage(const char *context, struct parking_dp_ramp_map *old_ramps, struct parking_dp_ramp_map *new_ramps)
06086 {
06087    struct parking_dp_ramp *old_ramp;
06088    struct parking_dp_ramp *new_ramp;
06089    int cmp;
06090 
06091    old_ramp = AST_LIST_FIRST(old_ramps);
06092    new_ramp = AST_LIST_FIRST(new_ramps);
06093 
06094    while (new_ramp) {
06095       if (!old_ramp) {
06096          /* No old ramps left, so no dead ramps can remain. */
06097          return;
06098       }
06099       cmp = strcmp(old_ramp->exten, new_ramp->exten);
06100       if (cmp < 0) {
06101          /* New map does not have old ramp. */
06102          remove_exten_if_exist(context, old_ramp->exten, 1);
06103          old_ramp = AST_LIST_NEXT(old_ramp, node);
06104          continue;
06105       }
06106       if (cmp == 0) {
06107          /* Old and new map have this ramp. */
06108          old_ramp = AST_LIST_NEXT(old_ramp, node);
06109       } else {
06110          /* Old map does not have new ramp. */
06111       }
06112       new_ramp = AST_LIST_NEXT(new_ramp, node);
06113    }
06114 
06115    /* Any old ramps left must be dead. */
06116    for (; old_ramp; old_ramp = AST_LIST_NEXT(old_ramp, node)) {
06117       remove_exten_if_exist(context, old_ramp->exten, 1);
06118    }
06119 }
06120 
06121 /*!
06122  * \internal
06123  * \brief Destroy the given parking space.
06124  *
06125  * \param context Dialplan database context name.
06126  * \param space Parking space.
06127  *
06128  * \return Nothing
06129  */
06130 static void destroy_space(const char *context, int space)
06131 {
06132    char exten[AST_MAX_EXTENSION];
06133 
06134    /* Destroy priorities of the parking space that we registered. */
06135    snprintf(exten, sizeof(exten), "%d", space);
06136    remove_exten_if_exist(context, exten, PRIORITY_HINT);
06137    remove_exten_if_exist(context, exten, 1);
06138 }
06139 
06140 /*!
06141  * \internal
06142  * \brief Remove unused parking lot space items.
06143  *
06144  * \param context Dialplan database context name.
06145  * \param old_spaces Before configuration reload parking space usage map.
06146  * \param new_spaces After configuration reload parking space usage map.
06147  * \param destroy_space Function to destroy parking space item.
06148  *
06149  * \details
06150  * Remove parking space items that were in the old context but
06151  * not in the new context.
06152  *
06153  * \return Nothing
06154  */
06155 static void remove_dead_spaces_usage(const char *context,
06156    struct parking_dp_space_map *old_spaces, struct parking_dp_space_map *new_spaces,
06157    void (*destroy_space)(const char *context, int space))
06158 {
06159    struct parking_dp_spaces *old_range;
06160    struct parking_dp_spaces *new_range;
06161    int space;/*!< Current position in the current old range. */
06162    int stop;
06163 
06164    old_range = AST_LIST_FIRST(old_spaces);
06165    new_range = AST_LIST_FIRST(new_spaces);
06166    space = -1;
06167 
06168    while (old_range) {
06169       if (space < old_range->start) {
06170          space = old_range->start;
06171       }
06172       if (new_range) {
06173          if (space < new_range->start) {
06174             /* Current position in old range starts before new range. */
06175             if (old_range->stop < new_range->start) {
06176                /* Old range ends before new range. */
06177                stop = old_range->stop;
06178                old_range = AST_LIST_NEXT(old_range, node);
06179             } else {
06180                /* Tail of old range overlaps new range. */
06181                stop = new_range->start - 1;
06182             }
06183          } else if (/* new_range->start <= space && */ space <= new_range->stop) {
06184             /* Current position in old range overlaps new range. */
06185             if (old_range->stop <= new_range->stop) {
06186                /* Old range ends at or before new range. */
06187                old_range = AST_LIST_NEXT(old_range, node);
06188             } else {
06189                /* Old range extends beyond end of new range. */
06190                space = new_range->stop + 1;
06191                new_range = AST_LIST_NEXT(new_range, node);
06192             }
06193             continue;
06194          } else /* if (new_range->stop < space) */ {
06195             /* Current position in old range starts after new range. */
06196             new_range = AST_LIST_NEXT(new_range, node);
06197             continue;
06198          }
06199       } else {
06200          /* No more new ranges.  All remaining old spaces are dead. */
06201          stop = old_range->stop;
06202          old_range = AST_LIST_NEXT(old_range, node);
06203       }
06204 
06205       /* Destroy dead parking spaces. */
06206       for (; space <= stop; ++space) {
06207          destroy_space(context, space);
06208       }
06209    }
06210 }
06211 
06212 /*!
06213  * \internal
06214  * \brief Remove unused parking lot context items.
06215  *
06216  * \param context Dialplan database context name.
06217  * \param old_ctx Before configuration reload context usage map.
06218  * \param new_ctx After configuration reload context usage map.
06219  *
06220  * \details
06221  * Remove context usage items that were in the old context but not in the
06222  * new context.
06223  *
06224  * \return Nothing
06225  */
06226 static void remove_dead_context_usage(const char *context, struct parking_dp_context *old_ctx, struct parking_dp_context *new_ctx)
06227 {
06228    remove_dead_ramp_usage(context, &old_ctx->access_extens, &new_ctx->access_extens);
06229    remove_dead_spaces_usage(context, &old_ctx->spaces, &new_ctx->spaces, destroy_space);
06230 #if 0
06231    /* I don't think we should destroy hints if the parking space still exists. */
06232    remove_dead_spaces_usage(context, &old_ctx->hints, &new_ctx->hints, destroy_space_hint);
06233 #endif
06234 }
06235 
06236 /*!
06237  * \internal
06238  * \brief Remove unused parking lot dialplan items.
06239  *
06240  * \param old_map Before configuration reload dialplan usage map.
06241  * \param new_map After configuration reload dialplan usage map.
06242  *
06243  * \details
06244  * Remove dialplan items that were in the old map but not in the
06245  * new map.
06246  *
06247  * \return Nothing
06248  */
06249 static void remove_dead_dialplan_useage(struct parking_dp_map *old_map, struct parking_dp_map *new_map)
06250 {
06251    struct parking_dp_context *old_ctx;
06252    struct parking_dp_context *new_ctx;
06253    struct ast_context *con;
06254    int cmp;
06255 
06256    old_ctx = AST_LIST_FIRST(old_map);
06257    new_ctx = AST_LIST_FIRST(new_map);
06258 
06259    while (new_ctx) {
06260       if (!old_ctx) {
06261          /* No old contexts left, so no dead stuff can remain. */
06262          return;
06263       }
06264       cmp = strcmp(old_ctx->context, new_ctx->context);
06265       if (cmp < 0) {
06266          /* New map does not have old map context. */
06267          con = ast_context_find(old_ctx->context);
06268          if (con) {
06269             ast_context_destroy(con, registrar);
06270          }
06271          old_ctx = AST_LIST_NEXT(old_ctx, node);
06272          continue;
06273       }
06274       if (cmp == 0) {
06275          /* Old and new map have this context. */
06276          remove_dead_context_usage(old_ctx->context, old_ctx, new_ctx);
06277          old_ctx = AST_LIST_NEXT(old_ctx, node);
06278       } else {
06279          /* Old map does not have new map context. */
06280       }
06281       new_ctx = AST_LIST_NEXT(new_ctx, node);
06282    }
06283 
06284    /* Any old contexts left must be dead. */
06285    for (; old_ctx; old_ctx = AST_LIST_NEXT(old_ctx, node)) {
06286       con = ast_context_find(old_ctx->context);
06287       if (con) {
06288          ast_context_destroy(con, registrar);
06289       }
06290    }
06291 }
06292 
06293 static int parkinglot_markall_cb(void *obj, void *arg, int flags)
06294 {
06295    struct ast_parkinglot *parkinglot = obj;
06296 
06297    parkinglot->the_mark = 1;
06298    return 0;
06299 }
06300 
06301 static int parkinglot_is_marked_cb(void *obj, void *arg, int flags)
06302 {
06303    struct ast_parkinglot *parkinglot = obj;
06304 
06305    if (parkinglot->the_mark) {
06306       if (AST_LIST_EMPTY(&parkinglot->parkings)) {
06307          /* This parking lot can actually be deleted. */
06308          return CMP_MATCH;
06309       }
06310       /* Try reloading later when parking lot is empty. */
06311       ast_log(LOG_WARNING,
06312          "Parking lot %s has parked calls.  Could not remove.\n",
06313          parkinglot->name);
06314       parkinglot->disabled = 1;
06315       force_reload_load = 1;
06316    }
06317 
06318    return 0;
06319 }
06320 
06321 static int parkinglot_activate_cb(void *obj, void *arg, int flags)
06322 {
06323    struct ast_parkinglot *parkinglot = obj;
06324 
06325    if (parkinglot->the_mark) {
06326       /*
06327        * Don't activate a parking lot that still bears the_mark since
06328        * it is effectively deleted.
06329        */
06330       return 0;
06331    }
06332 
06333    if (parkinglot_activate(parkinglot)) {
06334       /*
06335        * The parking lot failed to activate.  Allow reloading later to
06336        * see if that fixes it.
06337        */
06338       force_reload_load = 1;
06339       ast_log(LOG_WARNING, "Parking lot %s not open for business.\n", parkinglot->name);
06340    } else {
06341       ast_debug(1, "Parking lot %s now open for business. (parkpos %d-%d)\n",
06342          parkinglot->name, parkinglot->cfg.parking_start,
06343          parkinglot->cfg.parking_stop);
06344    }
06345 
06346    return 0;
06347 }
06348 
06349 static int load_config(int reload)
06350 {
06351    struct ast_flags config_flags = {
06352       reload && !force_reload_load ? CONFIG_FLAG_FILEUNCHANGED : 0 };
06353    struct ast_config *cfg;
06354    struct parking_dp_map old_usage_map = AST_LIST_HEAD_NOLOCK_INIT_VALUE;
06355    struct parking_dp_map new_usage_map = AST_LIST_HEAD_NOLOCK_INIT_VALUE;
06356 
06357    /* We are reloading now and have already determined if we will force the reload. */
06358    force_reload_load = 0;
06359 
06360    if (!default_parkinglot) {
06361       /* Must create the default default parking lot */
06362       default_parkinglot = build_parkinglot(DEFAULT_PARKINGLOT, NULL);
06363       if (!default_parkinglot) {
06364          ast_log(LOG_ERROR, "Configuration of default default parking lot failed.\n");
06365          return -1;
06366       }
06367       ast_debug(1, "Configuration of default default parking lot done.\n");
06368       parkinglot_addref(default_parkinglot);
06369    }
06370 
06371    cfg = ast_config_load2("features.conf", "features", config_flags);
06372    if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
06373       /* No sense in asking for reload trouble if nothing changed. */
06374       ast_debug(1, "features.conf did not change.\n");
06375       return 0;
06376    }
06377    if (cfg == CONFIG_STATUS_FILEMISSING
06378       || cfg == CONFIG_STATUS_FILEINVALID) {
06379       ast_log(LOG_WARNING, "Could not load features.conf\n");
06380       return 0;
06381    }
06382 
06383    /* Save current parking lot dialplan needs. */
06384    if (build_dialplan_useage_map(&old_usage_map, 0)) {
06385       destroy_dialplan_usage_map(&old_usage_map);
06386 
06387       /* Allow reloading later to see if conditions have improved. */
06388       force_reload_load = 1;
06389       return -1;
06390    }
06391 
06392    ao2_t_callback(parkinglots, OBJ_NODATA, parkinglot_markall_cb, NULL,
06393       "callback to mark all parking lots");
06394    process_config(cfg);
06395    ast_config_destroy(cfg);
06396    ao2_t_callback(parkinglots, OBJ_NODATA | OBJ_UNLINK, parkinglot_is_marked_cb, NULL,
06397       "callback to remove marked parking lots");
06398 
06399    /* Save updated parking lot dialplan needs. */
06400    if (build_dialplan_useage_map(&new_usage_map, 1)) {
06401       /*
06402        * Yuck, if this failure caused any parking lot dialplan items
06403        * to be lost, they will likely remain lost until Asterisk is
06404        * restarted.
06405        */
06406       destroy_dialplan_usage_map(&old_usage_map);
06407       destroy_dialplan_usage_map(&new_usage_map);
06408       return -1;
06409    }
06410 
06411    /* Remove no longer needed parking lot dialplan usage. */
06412    remove_dead_dialplan_useage(&old_usage_map, &new_usage_map);
06413 
06414    destroy_dialplan_usage_map(&old_usage_map);
06415    destroy_dialplan_usage_map(&new_usage_map);
06416 
06417    ao2_t_callback(parkinglots, OBJ_NODATA, parkinglot_activate_cb, NULL,
06418       "callback to activate all parking lots");
06419 
06420    return 0;
06421 }
06422 
06423 /*!
06424  * \brief CLI command to list configured features
06425  * \param e
06426  * \param cmd
06427  * \param a
06428  *
06429  * \retval CLI_SUCCESS on success.
06430  * \retval NULL when tab completion is used.
06431  */
06432 static char *handle_feature_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06433 {
06434    int i;
06435    struct ast_call_feature *feature;
06436    struct ao2_iterator iter;
06437    struct ast_parkinglot *curlot;
06438 #define HFS_FORMAT "%-25s %-7s %-7s\n"
06439 
06440    switch (cmd) {
06441    
06442    case CLI_INIT:
06443       e->command = "features show";
06444       e->usage =
06445          "Usage: features show\n"
06446          "       Lists configured features\n";
06447       return NULL;
06448    case CLI_GENERATE:
06449       return NULL;
06450    }
06451 
06452    ast_cli(a->fd, HFS_FORMAT, "Builtin Feature", "Default", "Current");
06453    ast_cli(a->fd, HFS_FORMAT, "---------------", "-------", "-------");
06454 
06455    ast_cli(a->fd, HFS_FORMAT, "Pickup", "*8", ast_pickup_ext());          /* default hardcoded above, so we'll hardcode it here */
06456 
06457    ast_rwlock_rdlock(&features_lock);
06458    for (i = 0; i < FEATURES_COUNT; i++)
06459       ast_cli(a->fd, HFS_FORMAT, builtin_features[i].fname, builtin_features[i].default_exten, builtin_features[i].exten);
06460    ast_rwlock_unlock(&features_lock);
06461 
06462    ast_cli(a->fd, "\n");
06463    ast_cli(a->fd, HFS_FORMAT, "Dynamic Feature", "Default", "Current");
06464    ast_cli(a->fd, HFS_FORMAT, "---------------", "-------", "-------");
06465    if (AST_RWLIST_EMPTY(&feature_list)) {
06466       ast_cli(a->fd, "(none)\n");
06467    } else {
06468       AST_RWLIST_RDLOCK(&feature_list);
06469       AST_RWLIST_TRAVERSE(&feature_list, feature, feature_entry) {
06470          ast_cli(a->fd, HFS_FORMAT, feature->sname, "no def", feature->exten);
06471       }
06472       AST_RWLIST_UNLOCK(&feature_list);
06473    }
06474 
06475    ast_cli(a->fd, "\nFeature Groups:\n");
06476    ast_cli(a->fd, "---------------\n");
06477    if (AST_RWLIST_EMPTY(&feature_groups)) {
06478       ast_cli(a->fd, "(none)\n");
06479    } else {
06480       struct feature_group *fg;
06481       struct feature_group_exten *fge;
06482 
06483       AST_RWLIST_RDLOCK(&feature_groups);
06484       AST_RWLIST_TRAVERSE(&feature_groups, fg, entry) {
06485          ast_cli(a->fd, "===> Group: %s\n", fg->gname);
06486          AST_LIST_TRAVERSE(&fg->features, fge, entry) {
06487             ast_cli(a->fd, "===> --> %s (%s)\n", fge->feature->sname, fge->exten);
06488          }
06489       }
06490       AST_RWLIST_UNLOCK(&feature_groups);
06491    }
06492 
06493    iter = ao2_iterator_init(parkinglots, 0);
06494    while ((curlot = ao2_iterator_next(&iter))) {
06495       ast_cli(a->fd, "\nCall parking (Parking lot: %s)\n", curlot->name);
06496       ast_cli(a->fd, "------------\n");
06497       ast_cli(a->fd,"%-22s:      %s\n", "Parking extension", curlot->cfg.parkext);
06498       ast_cli(a->fd,"%-22s:      %s\n", "Parking context", curlot->cfg.parking_con);
06499       ast_cli(a->fd,"%-22s:      %d-%d\n", "Parked call extensions",
06500          curlot->cfg.parking_start, curlot->cfg.parking_stop);
06501       ast_cli(a->fd,"%-22s:      %d ms\n", "Parkingtime", curlot->cfg.parkingtime);
06502       ast_cli(a->fd,"%-22s:      %s\n", "MusicOnHold class", curlot->cfg.mohclass);
06503       ast_cli(a->fd,"%-22s:      %s\n", "Enabled", AST_CLI_YESNO(!curlot->disabled));
06504       ast_cli(a->fd,"\n");
06505       ao2_ref(curlot, -1);
06506    }
06507    ao2_iterator_destroy(&iter);
06508 
06509    return CLI_SUCCESS;
06510 }
06511 
06512 int ast_features_reload(void)
06513 {
06514    struct ast_context *con;
06515    int res;
06516 
06517    ast_mutex_lock(&features_reload_lock);/* Searialize reloading features.conf */
06518 
06519    /*
06520     * Always destroy the parking_con_dial context to remove buildup
06521     * of recalled extensions in the context.  At worst, the parked
06522     * call gets hungup attempting to run an invalid extension when
06523     * we are trying to callback the parker or the preset return
06524     * extension.  This is a small window of opportunity on an
06525     * execution chain that is not expected to happen very often.
06526     */
06527    con = ast_context_find(parking_con_dial);
06528    if (con) {
06529       ast_context_destroy(con, registrar);
06530    }
06531 
06532    res = load_config(1);
06533    ast_mutex_unlock(&features_reload_lock);
06534 
06535    return res;
06536 }
06537 
06538 static char *handle_features_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06539 {
06540    switch (cmd) { 
06541    case CLI_INIT:
06542       e->command = "features reload";
06543       e->usage =
06544          "Usage: features reload\n"
06545          "       Reloads configured call features from features.conf\n";
06546       return NULL;
06547    case CLI_GENERATE:
06548       return NULL;
06549    }
06550    ast_features_reload();
06551 
06552    return CLI_SUCCESS;
06553 }
06554 
06555 /*!
06556  * \brief Actual bridge
06557  * \param chan
06558  * \param tmpchan
06559  * 
06560  * Stop hold music, lock both channels, masq channels,
06561  * after bridge return channel to next priority.
06562  */
06563 static void do_bridge_masquerade(struct ast_channel *chan, struct ast_channel *tmpchan)
06564 {
06565    ast_moh_stop(chan);
06566    ast_channel_lock_both(chan, tmpchan);
06567    ast_setstate(tmpchan, chan->_state);
06568    tmpchan->readformat = chan->readformat;
06569    tmpchan->writeformat = chan->writeformat;
06570    ast_channel_unlock(chan);
06571    ast_channel_unlock(tmpchan);
06572 
06573    ast_channel_masquerade(tmpchan, chan);
06574 
06575    /* must be done without any channel locks held */
06576    ast_do_masquerade(tmpchan);
06577 
06578    /* when returning from bridge, the channel will continue at the next priority */
06579    ast_explicit_goto(tmpchan, chan->context, chan->exten, chan->priority + 1);
06580 }
06581 
06582 /*!
06583  * \brief Bridge channels together
06584  * \param s
06585  * \param m
06586  * 
06587  * Make sure valid channels were specified, 
06588  * send errors if any of the channels could not be found/locked, answer channels if needed,
06589  * create the placeholder channels and grab the other channels 
06590  * make the channels compatible, send error if we fail doing so 
06591  * setup the bridge thread object and start the bridge.
06592  * 
06593  * \retval 0 on success or on incorrect use.
06594  * \retval 1 on failure to bridge channels.
06595  */
06596 static int action_bridge(struct mansession *s, const struct message *m)
06597 {
06598    const char *channela = astman_get_header(m, "Channel1");
06599    const char *channelb = astman_get_header(m, "Channel2");
06600    const char *playtone = astman_get_header(m, "Tone");
06601    struct ast_channel *chana = NULL, *chanb = NULL, *chans[2];
06602    struct ast_channel *tmpchana = NULL, *tmpchanb = NULL;
06603    struct ast_bridge_thread_obj *tobj = NULL;
06604 
06605    /* make sure valid channels were specified */
06606    if (ast_strlen_zero(channela) || ast_strlen_zero(channelb)) {
06607       astman_send_error(s, m, "Missing channel parameter in request");
06608       return 0;
06609    }
06610 
06611    /* Start with chana */
06612    chana = ast_channel_get_by_name_prefix(channela, strlen(channela));
06613 
06614    /* send errors if any of the channels could not be found/locked */
06615    if (!chana) {
06616       char buf[256];
06617       snprintf(buf, sizeof(buf), "Channel1 does not exists: %s", channela);
06618       astman_send_error(s, m, buf);
06619       return 0;
06620    }
06621 
06622    /* Answer the channels if needed */
06623    if (chana->_state != AST_STATE_UP)
06624       ast_answer(chana);
06625 
06626    /* create the placeholder channels and grab the other channels */
06627    if (!(tmpchana = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL, 
06628       NULL, NULL, chana->linkedid, 0, "Bridge/%s", chana->name))) {
06629       astman_send_error(s, m, "Unable to create temporary channel!");
06630       chana = ast_channel_unref(chana);
06631       return 1;
06632    }
06633 
06634    do_bridge_masquerade(chana, tmpchana);
06635 
06636    chana = ast_channel_unref(chana);
06637 
06638    /* now do chanb */
06639    chanb = ast_channel_get_by_name_prefix(channelb, strlen(channelb));
06640    /* send errors if any of the channels could not be found/locked */
06641    if (!chanb) {
06642       char buf[256];
06643       snprintf(buf, sizeof(buf), "Channel2 does not exists: %s", channelb);
06644       ast_hangup(tmpchana);
06645       astman_send_error(s, m, buf);
06646       return 0;
06647    }
06648 
06649    /* Answer the channels if needed */
06650    if (chanb->_state != AST_STATE_UP)
06651       ast_answer(chanb);
06652 
06653    /* create the placeholder channels and grab the other channels */
06654    if (!(tmpchanb = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL, 
06655       NULL, NULL, chanb->linkedid, 0, "Bridge/%s", chanb->name))) {
06656       astman_send_error(s, m, "Unable to create temporary channels!");
06657       ast_hangup(tmpchana);
06658       chanb = ast_channel_unref(chanb);
06659       return 1;
06660    }
06661 
06662    do_bridge_masquerade(chanb, tmpchanb);
06663 
06664    chanb = ast_channel_unref(chanb);
06665 
06666    /* make the channels compatible, send error if we fail doing so */
06667    if (ast_channel_make_compatible(tmpchana, tmpchanb)) {
06668       ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for manager bridge\n", tmpchana->name, tmpchanb->name);
06669       astman_send_error(s, m, "Could not make channels compatible for manager bridge");
06670       ast_hangup(tmpchana);
06671       ast_hangup(tmpchanb);
06672       return 1;
06673    }
06674 
06675    /* setup the bridge thread object and start the bridge */
06676    if (!(tobj = ast_calloc(1, sizeof(*tobj)))) {
06677       ast_log(LOG_WARNING, "Unable to spawn a new bridge thread on %s and %s: %s\n", tmpchana->name, tmpchanb->name, strerror(errno));
06678       astman_send_error(s, m, "Unable to spawn a new bridge thread");
06679       ast_hangup(tmpchana);
06680       ast_hangup(tmpchanb);
06681       return 1;
06682    }
06683 
06684    tobj->chan = tmpchana;
06685    tobj->peer = tmpchanb;
06686    tobj->return_to_pbx = 1;
06687 
06688    if (ast_true(playtone)) {
06689       if (!ast_strlen_zero(xfersound) && !ast_streamfile(tmpchanb, xfersound, tmpchanb->language)) {
06690          if (ast_waitstream(tmpchanb, "") < 0)
06691             ast_log(LOG_WARNING, "Failed to play a courtesy tone on chan %s\n", tmpchanb->name);
06692       }
06693    }
06694 
06695    chans[0] = tmpchana;
06696    chans[1] = tmpchanb;
06697 
06698    ast_manager_event_multichan(EVENT_FLAG_CALL, "BridgeAction", 2, chans,
06699             "Response: Success\r\n"
06700             "Channel1: %s\r\n"
06701             "Channel2: %s\r\n", tmpchana->name, tmpchanb->name);
06702 
06703    bridge_call_thread_launch(tobj);
06704 
06705    astman_send_ack(s, m, "Launched bridge thread with success");
06706 
06707    return 0;
06708 }
06709 
06710 /*!
06711  * \brief CLI command to list parked calls
06712  * \param e 
06713  * \param cmd
06714  * \param a
06715  *  
06716  * Check right usage, lock parking lot, display parked calls, unlock parking lot list.
06717  * \retval CLI_SUCCESS on success.
06718  * \retval CLI_SHOWUSAGE on incorrect number of arguments.
06719  * \retval NULL when tab completion is used.
06720  */
06721 static char *handle_parkedcalls(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06722 {
06723    struct parkeduser *cur;
06724    int numparked = 0;
06725    struct ao2_iterator iter;
06726    struct ast_parkinglot *curlot;
06727 
06728    switch (cmd) {
06729    case CLI_INIT:
06730       e->command = "parkedcalls show";
06731       e->usage =
06732          "Usage: parkedcalls show\n"
06733          "       List currently parked calls\n";
06734       return NULL;
06735    case CLI_GENERATE:
06736       return NULL;
06737    }
06738 
06739    if (a->argc > e->args)
06740       return CLI_SHOWUSAGE;
06741 
06742    ast_cli(a->fd, "%-10s %-25s (%-15s %-12s %4s) %s\n", "Num", "Channel",
06743       "Context", "Extension", "Pri", "Timeout");
06744 
06745    iter = ao2_iterator_init(parkinglots, 0);
06746    while ((curlot = ao2_iterator_next(&iter))) {
06747       int lotparked = 0;
06748 
06749       /* subtract ref for iterator and for configured parking lot */
06750       ast_cli(a->fd, "*** Parking lot: %s (%d)\n", curlot->name,
06751          ao2_ref(curlot, 0) - 2 - (curlot == default_parkinglot));
06752 
06753       AST_LIST_LOCK(&curlot->parkings);
06754       AST_LIST_TRAVERSE(&curlot->parkings, cur, list) {
06755          ast_cli(a->fd, "%-10.10s %-25s (%-15s %-12s %4d) %6lds\n",
06756             cur->parkingexten, cur->chan->name, cur->context, cur->exten,
06757             cur->priority,
06758             (long) (cur->start.tv_sec + (cur->parkingtime / 1000) - time(NULL)));
06759          ++lotparked;
06760       }
06761       AST_LIST_UNLOCK(&curlot->parkings);
06762       if (lotparked) {
06763          numparked += lotparked;
06764          ast_cli(a->fd, "   %d parked call%s in parking lot %s\n", lotparked,
06765             ESS(lotparked), curlot->name);
06766       }
06767 
06768       ao2_ref(curlot, -1);
06769    }
06770    ao2_iterator_destroy(&iter);
06771 
06772    ast_cli(a->fd, "---\n%d parked call%s in total.\n", numparked, ESS(numparked));
06773 
06774    return CLI_SUCCESS;
06775 }
06776 
06777 static struct ast_cli_entry cli_features[] = {
06778    AST_CLI_DEFINE(handle_feature_show, "Lists configured features"),
06779    AST_CLI_DEFINE(handle_features_reload, "Reloads configured features"),
06780    AST_CLI_DEFINE(handle_parkedcalls, "List currently parked calls"),
06781 };
06782 
06783 /*! 
06784  * \brief Dump parking lot status
06785  * \param s
06786  * \param m
06787  * 
06788  * Lock parking lot, iterate list and append parked calls status, unlock parking lot.
06789  * \return Always RESULT_SUCCESS 
06790  */
06791 static int manager_parking_status(struct mansession *s, const struct message *m)
06792 {
06793    struct parkeduser *cur;
06794    const char *id = astman_get_header(m, "ActionID");
06795    char idText[256] = "";
06796    struct ao2_iterator iter;
06797    struct ast_parkinglot *curlot;
06798    int numparked = 0;
06799 
06800    if (!ast_strlen_zero(id))
06801       snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
06802 
06803    astman_send_ack(s, m, "Parked calls will follow");
06804 
06805    iter = ao2_iterator_init(parkinglots, 0);
06806    while ((curlot = ao2_iterator_next(&iter))) {
06807       AST_LIST_LOCK(&curlot->parkings);
06808       AST_LIST_TRAVERSE(&curlot->parkings, cur, list) {
06809          astman_append(s, "Event: ParkedCall\r\n"
06810             "Parkinglot: %s\r\n"
06811             "Exten: %d\r\n"
06812             "Channel: %s\r\n"
06813             "From: %s\r\n"
06814             "Timeout: %ld\r\n"
06815             "CallerIDNum: %s\r\n"
06816             "CallerIDName: %s\r\n"
06817             "ConnectedLineNum: %s\r\n"
06818             "ConnectedLineName: %s\r\n"
06819             "%s"
06820             "\r\n",
06821             curlot->name,
06822             cur->parkingnum, cur->chan->name, cur->peername,
06823             (long) cur->start.tv_sec + (long) (cur->parkingtime / 1000) - (long) time(NULL),
06824             S_COR(cur->chan->caller.id.number.valid, cur->chan->caller.id.number.str, ""),   /* XXX in other places it is <unknown> */
06825             S_COR(cur->chan->caller.id.name.valid, cur->chan->caller.id.name.str, ""),
06826             S_COR(cur->chan->connected.id.number.valid, cur->chan->connected.id.number.str, ""),   /* XXX in other places it is <unknown> */
06827             S_COR(cur->chan->connected.id.name.valid, cur->chan->connected.id.name.str, ""),
06828             idText);
06829          ++numparked;
06830       }
06831       AST_LIST_UNLOCK(&curlot->parkings);
06832       ao2_ref(curlot, -1);
06833    }
06834    ao2_iterator_destroy(&iter);
06835 
06836    astman_append(s,
06837       "Event: ParkedCallsComplete\r\n"
06838       "Total: %d\r\n"
06839       "%s"
06840       "\r\n",
06841       numparked, idText);
06842 
06843    return RESULT_SUCCESS;
06844 }
06845 
06846 /*!
06847  * \brief Create manager event for parked calls
06848  * \param s
06849  * \param m
06850  *
06851  * Get channels involved in park, create event.
06852  * \return Always 0
06853  */
06854 static int manager_park(struct mansession *s, const struct message *m)
06855 {
06856    const char *channel = astman_get_header(m, "Channel");
06857    const char *channel2 = astman_get_header(m, "Channel2");
06858    const char *timeout = astman_get_header(m, "Timeout");
06859    const char *parkinglotname = astman_get_header(m, "Parkinglot");
06860    char buf[BUFSIZ];
06861    int res = 0;
06862    struct ast_channel *ch1, *ch2;
06863    struct ast_park_call_args args = {0,};
06864 
06865    if (ast_strlen_zero(channel)) {
06866       astman_send_error(s, m, "Channel not specified");
06867       return 0;
06868    }
06869 
06870    if (ast_strlen_zero(channel2)) {
06871       astman_send_error(s, m, "Channel2 not specified");
06872       return 0;
06873    }
06874 
06875    if (!ast_strlen_zero(timeout)) {
06876       if (sscanf(timeout, "%30d", &args.timeout) != 1) {
06877          astman_send_error(s, m, "Invalid timeout value.");
06878          return 0;
06879       }
06880    }
06881 
06882    if (!(ch1 = ast_channel_get_by_name(channel))) {
06883       snprintf(buf, sizeof(buf), "Channel does not exist: %s", channel);
06884       astman_send_error(s, m, buf);
06885       return 0;
06886    }
06887 
06888    if (!(ch2 = ast_channel_get_by_name(channel2))) {
06889       snprintf(buf, sizeof(buf), "Channel does not exist: %s", channel2);
06890       astman_send_error(s, m, buf);
06891       ast_channel_unref(ch1);
06892       return 0;
06893    }
06894 
06895    if (!ast_strlen_zero(parkinglotname)) {
06896       args.parkinglot = find_parkinglot(parkinglotname);
06897    }
06898 
06899    res = masq_park_call(ch1, ch2, 0, NULL, 0, &args);
06900    if (!res) {
06901       ast_softhangup(ch2, AST_SOFTHANGUP_EXPLICIT);
06902       astman_send_ack(s, m, "Park successful");
06903    } else {
06904       astman_send_error(s, m, "Park failure");
06905    }
06906 
06907    if (args.parkinglot) {
06908       parkinglot_unref(args.parkinglot);
06909    }
06910    ch1 = ast_channel_unref(ch1);
06911    ch2 = ast_channel_unref(ch2);
06912 
06913    return 0;
06914 }
06915 
06916 /*!
06917  * The presence of this datastore on the channel indicates that
06918  * someone is attemting to pickup or has picked up the channel.
06919  * The purpose is to prevent a race between two channels
06920  * attempting to pickup the same channel.
06921  */
06922 static const struct ast_datastore_info pickup_active = {
06923    .type = "pickup-active",
06924 };
06925 
06926 int ast_can_pickup(struct ast_channel *chan)
06927 {
06928    if (!chan->pbx && !chan->masq && !ast_test_flag(chan, AST_FLAG_ZOMBIE)
06929       && (chan->_state == AST_STATE_RINGING
06930          || chan->_state == AST_STATE_RING
06931          /*
06932           * Check the down state as well because some SIP devices do not
06933           * give 180 ringing when they can just give 183 session progress
06934           * instead.  Issue 14005.  (Some ISDN switches as well for that
06935           * matter.)
06936           */
06937          || chan->_state == AST_STATE_DOWN)
06938       && !ast_channel_datastore_find(chan, &pickup_active, NULL)) {
06939       return 1;
06940    }
06941    return 0;
06942 }
06943 
06944 static int find_channel_by_group(void *obj, void *arg, void *data, int flags)
06945 {
06946    struct ast_channel *target = obj;/*!< Potential pickup target */
06947    struct ast_channel *chan = data;/*!< Channel wanting to pickup call */
06948 
06949    ast_channel_lock(target);
06950    if (chan != target && (chan->pickupgroup & target->callgroup)
06951       && ast_can_pickup(target)) {
06952       /* Return with the channel still locked on purpose */
06953       return CMP_MATCH | CMP_STOP;
06954    }
06955    ast_channel_unlock(target);
06956 
06957    return 0;
06958 }
06959 
06960 /*!
06961  * \brief Pickup a call
06962  * \param chan channel that initiated pickup.
06963  *
06964  * Walk list of channels, checking it is not itself, channel is pbx one,
06965  * check that the callgroup for both channels are the same and the channel is ringing.
06966  * Answer calling channel, flag channel as answered on queue, masq channels together.
06967  */
06968 int ast_pickup_call(struct ast_channel *chan)
06969 {
06970    struct ast_channel *target;/*!< Potential pickup target */
06971    int res = -1;
06972    ast_debug(1, "pickup attempt by %s\n", chan->name);
06973 
06974    /* The found channel is already locked. */
06975    target = ast_channel_callback(find_channel_by_group, NULL, chan, 0);
06976    if (target) {
06977       ast_log(LOG_NOTICE, "pickup %s attempt by %s\n", target->name, chan->name);
06978 
06979       res = ast_do_pickup(chan, target);
06980       ast_channel_unlock(target);
06981       if (!res) {
06982          if (!ast_strlen_zero(pickupsound)) {
06983             pbx_builtin_setvar_helper(target, "BRIDGE_PLAY_SOUND", pickupsound);
06984          }
06985       } else {
06986          ast_log(LOG_WARNING, "pickup %s failed by %s\n", target->name, chan->name);
06987       }
06988       target = ast_channel_unref(target);
06989    }
06990 
06991    if (res < 0) {
06992       ast_debug(1, "No call pickup possible... for %s\n", chan->name);
06993       if (!ast_strlen_zero(pickupfailsound)) {
06994          ast_answer(chan);
06995          ast_stream_and_wait(chan, pickupfailsound, "");
06996       }
06997    }
06998 
06999    return res;
07000 }
07001 
07002 int ast_do_pickup(struct ast_channel *chan, struct ast_channel *target)
07003 {
07004    struct ast_party_connected_line connected_caller;
07005    struct ast_channel *chans[2] = { chan, target };
07006    struct ast_datastore *ds_pickup;
07007    const char *chan_name;/*!< A masquerade changes channel names. */
07008    const char *target_name;/*!< A masquerade changes channel names. */
07009    int res = -1;
07010 
07011    target_name = ast_strdupa(target->name);
07012    ast_debug(1, "Call pickup on '%s' by '%s'\n", target_name, chan->name);
07013 
07014    /* Mark the target to block any call pickup race. */
07015    ds_pickup = ast_datastore_alloc(&pickup_active, NULL);
07016    if (!ds_pickup) {
07017       ast_log(LOG_WARNING,
07018          "Unable to create channel datastore on '%s' for call pickup\n", target_name);
07019       return -1;
07020    }
07021    ast_channel_datastore_add(target, ds_pickup);
07022 
07023    ast_party_connected_line_init(&connected_caller);
07024    ast_party_connected_line_copy(&connected_caller, &target->connected);
07025    ast_channel_unlock(target);/* The pickup race is avoided so we do not need the lock anymore. */
07026    connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
07027    if (ast_channel_connected_line_macro(NULL, chan, &connected_caller, 0, 0)) {
07028       ast_channel_update_connected_line(chan, &connected_caller, NULL);
07029    }
07030    ast_party_connected_line_free(&connected_caller);
07031 
07032    ast_channel_lock(chan);
07033    chan_name = ast_strdupa(chan->name);
07034    ast_connected_line_copy_from_caller(&connected_caller, &chan->caller);
07035    ast_channel_unlock(chan);
07036    connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
07037    ast_channel_queue_connected_line_update(chan, &connected_caller, NULL);
07038    ast_party_connected_line_free(&connected_caller);
07039 
07040    ast_cel_report_event(target, AST_CEL_PICKUP, NULL, NULL, chan);
07041 
07042    if (ast_answer(chan)) {
07043       ast_log(LOG_WARNING, "Unable to answer '%s'\n", chan_name);
07044       goto pickup_failed;
07045    }
07046 
07047    if (ast_queue_control(chan, AST_CONTROL_ANSWER)) {
07048       ast_log(LOG_WARNING, "Unable to queue answer on '%s'\n", chan_name);
07049       goto pickup_failed;
07050    }
07051 
07052    if (ast_channel_masquerade(target, chan)) {
07053       ast_log(LOG_WARNING, "Unable to masquerade '%s' into '%s'\n", chan_name,
07054          target_name);
07055       goto pickup_failed;
07056    }
07057 
07058    /* If you want UniqueIDs, set channelvars in manager.conf to CHANNEL(uniqueid) */
07059    ast_manager_event_multichan(EVENT_FLAG_CALL, "Pickup", 2, chans,
07060       "Channel: %s\r\n"
07061       "TargetChannel: %s\r\n",
07062       chan_name, target_name);
07063 
07064    /* Do the masquerade manually to make sure that it is completed. */
07065    ast_do_masquerade(target);
07066    res = 0;
07067 
07068 pickup_failed:
07069    ast_channel_lock(target);
07070    if (!ast_channel_datastore_remove(target, ds_pickup)) {
07071       ast_datastore_free(ds_pickup);
07072    }
07073 
07074    return res;
07075 }
07076 
07077 static char *app_bridge = "Bridge";
07078 
07079 enum {
07080    BRIDGE_OPT_PLAYTONE = (1 << 0),
07081    OPT_CALLEE_HANGUP =  (1 << 1),
07082    OPT_CALLER_HANGUP =  (1 << 2),
07083    OPT_DURATION_LIMIT = (1 << 3),
07084    OPT_DURATION_STOP =  (1 << 4),
07085    OPT_CALLEE_TRANSFER = (1 << 5),
07086    OPT_CALLER_TRANSFER = (1 << 6),
07087    OPT_CALLEE_MONITOR = (1 << 7),
07088    OPT_CALLER_MONITOR = (1 << 8),
07089    OPT_CALLEE_PARK = (1 << 9),
07090    OPT_CALLER_PARK = (1 << 10),
07091    OPT_CALLEE_KILL = (1 << 11),
07092 };
07093  
07094 enum {
07095    OPT_ARG_DURATION_LIMIT = 0,
07096    OPT_ARG_DURATION_STOP,
07097    /* note: this entry _MUST_ be the last one in the enum */
07098    OPT_ARG_ARRAY_SIZE,
07099 };
07100 
07101 AST_APP_OPTIONS(bridge_exec_options, BEGIN_OPTIONS
07102    AST_APP_OPTION('p', BRIDGE_OPT_PLAYTONE),
07103    AST_APP_OPTION('h', OPT_CALLEE_HANGUP),
07104    AST_APP_OPTION('H', OPT_CALLER_HANGUP),
07105    AST_APP_OPTION('k', OPT_CALLEE_PARK),
07106    AST_APP_OPTION('K', OPT_CALLER_PARK),
07107    AST_APP_OPTION_ARG('L', OPT_DURATION_LIMIT, OPT_ARG_DURATION_LIMIT),
07108    AST_APP_OPTION_ARG('S', OPT_DURATION_STOP, OPT_ARG_DURATION_STOP),
07109    AST_APP_OPTION('t', OPT_CALLEE_TRANSFER),
07110    AST_APP_OPTION('T', OPT_CALLER_TRANSFER),
07111    AST_APP_OPTION('w', OPT_CALLEE_MONITOR),
07112    AST_APP_OPTION('W', OPT_CALLER_MONITOR),
07113    AST_APP_OPTION('x', OPT_CALLEE_KILL),
07114 END_OPTIONS );
07115 
07116 int ast_bridge_timelimit(struct ast_channel *chan, struct ast_bridge_config *config,
07117    char *parse, struct timeval *calldurationlimit)
07118 {
07119    char *stringp = ast_strdupa(parse);
07120    char *limit_str, *warning_str, *warnfreq_str;
07121    const char *var;
07122    int play_to_caller = 0, play_to_callee = 0;
07123    int delta;
07124 
07125    limit_str = strsep(&stringp, ":");
07126    warning_str = strsep(&stringp, ":");
07127    warnfreq_str = strsep(&stringp, ":");
07128 
07129    config->timelimit = atol(limit_str);
07130    if (warning_str)
07131       config->play_warning = atol(warning_str);
07132    if (warnfreq_str)
07133       config->warning_freq = atol(warnfreq_str);
07134 
07135    if (!config->timelimit) {
07136       ast_log(LOG_WARNING, "Bridge does not accept L(%s), hanging up.\n", limit_str);
07137       config->timelimit = config->play_warning = config->warning_freq = 0;
07138       config->warning_sound = NULL;
07139       return -1; /* error */
07140    } else if ( (delta = config->play_warning - config->timelimit) > 0) {
07141       int w = config->warning_freq;
07142 
07143       /*
07144        * If the first warning is requested _after_ the entire call
07145        * would end, and no warning frequency is requested, then turn
07146        * off the warning. If a warning frequency is requested, reduce
07147        * the 'first warning' time by that frequency until it falls
07148        * within the call's total time limit.
07149        *
07150        * Graphically:
07151        *                timelim->|    delta        |<-playwarning
07152        *      0__________________|_________________|
07153        *                       | w  |    |    |    |
07154        *
07155        * so the number of intervals to cut is 1+(delta-1)/w
07156        */
07157       if (w == 0) {
07158          config->play_warning = 0;
07159       } else {
07160          config->play_warning -= w * ( 1 + (delta-1)/w );
07161          if (config->play_warning < 1)
07162             config->play_warning = config->warning_freq = 0;
07163       }
07164    }
07165    
07166    ast_channel_lock(chan);
07167 
07168    var = pbx_builtin_getvar_helper(chan, "LIMIT_PLAYAUDIO_CALLER");
07169    play_to_caller = var ? ast_true(var) : 1;
07170 
07171    var = pbx_builtin_getvar_helper(chan, "LIMIT_PLAYAUDIO_CALLEE");
07172    play_to_callee = var ? ast_true(var) : 0;
07173 
07174    if (!play_to_caller && !play_to_callee)
07175       play_to_caller = 1;
07176 
07177    var = pbx_builtin_getvar_helper(chan, "LIMIT_WARNING_FILE");
07178    config->warning_sound = !ast_strlen_zero(var) ? ast_strdup(var) : ast_strdup("timeleft");
07179 
07180    /* The code looking at config wants a NULL, not just "", to decide
07181     * that the message should not be played, so we replace "" with NULL.
07182     * Note, pbx_builtin_getvar_helper _can_ return NULL if the variable is
07183     * not found.
07184     */
07185 
07186    var = pbx_builtin_getvar_helper(chan, "LIMIT_TIMEOUT_FILE");
07187    config->end_sound = !ast_strlen_zero(var) ? ast_strdup(var) : NULL;
07188 
07189    var = pbx_builtin_getvar_helper(chan, "LIMIT_CONNECT_FILE");
07190    config->start_sound = !ast_strlen_zero(var) ? ast_strdup(var) : NULL;
07191 
07192    ast_channel_unlock(chan);
07193 
07194    /* undo effect of S(x) in case they are both used */
07195    calldurationlimit->tv_sec = 0;
07196    calldurationlimit->tv_usec = 0;
07197 
07198    /* more efficient to do it like S(x) does since no advanced opts */
07199    if (!config->play_warning && !config->start_sound && !config->end_sound && config->timelimit) {
07200       calldurationlimit->tv_sec = config->timelimit / 1000;
07201       calldurationlimit->tv_usec = (config->timelimit % 1000) * 1000;
07202       ast_verb(3, "Setting call duration limit to %.3lf seconds.\n",
07203          calldurationlimit->tv_sec + calldurationlimit->tv_usec / 1000000.0);
07204       config->timelimit = play_to_caller = play_to_callee =
07205       config->play_warning = config->warning_freq = 0;
07206    } else {
07207       ast_verb(4, "Limit Data for this call:\n");
07208       ast_verb(4, "timelimit      = %ld ms (%.3lf s)\n", config->timelimit, config->timelimit / 1000.0);
07209       ast_verb(4, "play_warning   = %ld ms (%.3lf s)\n", config->play_warning, config->play_warning / 1000.0);
07210       ast_verb(4, "play_to_caller = %s\n", play_to_caller ? "yes" : "no");
07211       ast_verb(4, "play_to_callee = %s\n", play_to_callee ? "yes" : "no");
07212       ast_verb(4, "warning_freq   = %ld ms (%.3lf s)\n", config->warning_freq, config->warning_freq / 1000.0);
07213       ast_verb(4, "start_sound    = %s\n", S_OR(config->start_sound, ""));
07214       ast_verb(4, "warning_sound  = %s\n", config->warning_sound);
07215       ast_verb(4, "end_sound      = %s\n", S_OR(config->end_sound, ""));
07216    }
07217    if (play_to_caller)
07218       ast_set_flag(&(config->features_caller), AST_FEATURE_PLAY_WARNING);
07219    if (play_to_callee)
07220       ast_set_flag(&(config->features_callee), AST_FEATURE_PLAY_WARNING);
07221    return 0;
07222 }
07223 
07224 
07225 /*!
07226  * \brief Bridge channels
07227  * \param chan
07228  * \param data channel to bridge with.
07229  * 
07230  * Split data, check we aren't bridging with ourself, check valid channel,
07231  * answer call if not already, check compatible channels, setup bridge config
07232  * now bridge call, if transfered party hangs up return to PBX extension.
07233  */
07234 static int bridge_exec(struct ast_channel *chan, const char *data)
07235 {
07236    struct ast_channel *current_dest_chan, *final_dest_chan, *chans[2];
07237    char *tmp_data  = NULL;
07238    struct ast_flags opts = { 0, };
07239    struct ast_bridge_config bconfig = { { 0, }, };
07240    char *opt_args[OPT_ARG_ARRAY_SIZE];
07241    struct timeval calldurationlimit = { 0, };
07242 
07243    AST_DECLARE_APP_ARGS(args,
07244       AST_APP_ARG(dest_chan);
07245       AST_APP_ARG(options);
07246    );
07247    
07248    if (ast_strlen_zero(data)) {
07249       ast_log(LOG_WARNING, "Bridge require at least 1 argument specifying the other end of the bridge\n");
07250       return -1;
07251    }
07252 
07253    tmp_data = ast_strdupa(data);
07254    AST_STANDARD_APP_ARGS(args, tmp_data);
07255    if (!ast_strlen_zero(args.options))
07256       ast_app_parse_options(bridge_exec_options, &opts, opt_args, args.options);
07257 
07258    /* avoid bridge with ourselves */
07259    if (!strcmp(chan->name, args.dest_chan)) {
07260       ast_log(LOG_WARNING, "Unable to bridge channel %s with itself\n", chan->name);
07261       ast_manager_event(chan, EVENT_FLAG_CALL, "BridgeExec",
07262                "Response: Failed\r\n"
07263                "Reason: Unable to bridge channel to itself\r\n"
07264                "Channel1: %s\r\n"
07265                "Channel2: %s\r\n",
07266                chan->name, args.dest_chan);
07267       pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "LOOP");
07268       return 0;
07269    }
07270 
07271    /* make sure we have a valid end point */
07272    if (!(current_dest_chan = ast_channel_get_by_name_prefix(args.dest_chan,
07273          strlen(args.dest_chan)))) {
07274       ast_log(LOG_WARNING, "Bridge failed because channel %s does not exists or we "
07275          "cannot get its lock\n", args.dest_chan);
07276       ast_manager_event(chan, EVENT_FLAG_CALL, "BridgeExec",
07277                "Response: Failed\r\n"
07278                "Reason: Cannot grab end point\r\n"
07279                "Channel1: %s\r\n"
07280                "Channel2: %s\r\n", chan->name, args.dest_chan);
07281       pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "NONEXISTENT");
07282       return 0;
07283    }
07284 
07285    /* answer the channel if needed */
07286    if (current_dest_chan->_state != AST_STATE_UP) {
07287       ast_answer(current_dest_chan);
07288    }
07289 
07290    /* try to allocate a place holder where current_dest_chan will be placed */
07291    if (!(final_dest_chan = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL, 
07292       NULL, NULL, current_dest_chan->linkedid, 0, "Bridge/%s", current_dest_chan->name))) {
07293       ast_log(LOG_WARNING, "Cannot create placeholder channel for chan %s\n", args.dest_chan);
07294       ast_manager_event(chan, EVENT_FLAG_CALL, "BridgeExec",
07295                "Response: Failed\r\n"
07296                "Reason: cannot create placeholder\r\n"
07297                "Channel1: %s\r\n"
07298                "Channel2: %s\r\n", chan->name, args.dest_chan);
07299    }
07300 
07301    do_bridge_masquerade(current_dest_chan, final_dest_chan);
07302 
07303    chans[0] = current_dest_chan;
07304    chans[1] = final_dest_chan;
07305 
07306    /* now current_dest_chan is a ZOMBIE and with softhangup set to 1 and final_dest_chan is our end point */
07307    /* try to make compatible, send error if we fail */
07308    if (ast_channel_make_compatible(chan, final_dest_chan) < 0) {
07309       ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for bridge\n", chan->name, final_dest_chan->name);
07310       ast_manager_event_multichan(EVENT_FLAG_CALL, "BridgeExec", 2, chans,
07311                "Response: Failed\r\n"
07312                "Reason: Could not make channels compatible for bridge\r\n"
07313                "Channel1: %s\r\n"
07314                "Channel2: %s\r\n", chan->name, final_dest_chan->name);
07315       ast_hangup(final_dest_chan); /* may be we should return this channel to the PBX? */
07316       pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "INCOMPATIBLE");
07317       current_dest_chan = ast_channel_unref(current_dest_chan);
07318       return 0;
07319    }
07320 
07321    /* Report that the bridge will be successfull */
07322    ast_manager_event_multichan(EVENT_FLAG_CALL, "BridgeExec", 2, chans,
07323             "Response: Success\r\n"
07324             "Channel1: %s\r\n"
07325             "Channel2: %s\r\n", chan->name, final_dest_chan->name);
07326 
07327    /* we have 2 valid channels to bridge, now it is just a matter of setting up the bridge config and starting the bridge */  
07328    if (ast_test_flag(&opts, BRIDGE_OPT_PLAYTONE) && !ast_strlen_zero(xfersound)) {
07329       if (!ast_streamfile(final_dest_chan, xfersound, final_dest_chan->language)) {
07330          if (ast_waitstream(final_dest_chan, "") < 0)
07331             ast_log(LOG_WARNING, "Failed to play courtesy tone on %s\n", final_dest_chan->name);
07332       }
07333    }
07334    
07335    current_dest_chan = ast_channel_unref(current_dest_chan);
07336    
07337    if (ast_test_flag(&opts, OPT_DURATION_LIMIT) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_LIMIT])) {
07338       if (ast_bridge_timelimit(chan, &bconfig, opt_args[OPT_ARG_DURATION_LIMIT], &calldurationlimit))
07339          goto done;
07340    }
07341 
07342    if (ast_test_flag(&opts, OPT_CALLEE_TRANSFER))
07343       ast_set_flag(&(bconfig.features_callee), AST_FEATURE_REDIRECT);
07344    if (ast_test_flag(&opts, OPT_CALLER_TRANSFER))
07345       ast_set_flag(&(bconfig.features_caller), AST_FEATURE_REDIRECT);
07346    if (ast_test_flag(&opts, OPT_CALLEE_HANGUP))
07347       ast_set_flag(&(bconfig.features_callee), AST_FEATURE_DISCONNECT);
07348    if (ast_test_flag(&opts, OPT_CALLER_HANGUP))
07349       ast_set_flag(&(bconfig.features_caller), AST_FEATURE_DISCONNECT);
07350    if (ast_test_flag(&opts, OPT_CALLEE_MONITOR))
07351       ast_set_flag(&(bconfig.features_callee), AST_FEATURE_AUTOMON);
07352    if (ast_test_flag(&opts, OPT_CALLER_MONITOR)) 
07353       ast_set_flag(&(bconfig.features_caller), AST_FEATURE_AUTOMON);
07354    if (ast_test_flag(&opts, OPT_CALLEE_PARK))
07355       ast_set_flag(&(bconfig.features_callee), AST_FEATURE_PARKCALL);
07356    if (ast_test_flag(&opts, OPT_CALLER_PARK))
07357       ast_set_flag(&(bconfig.features_caller), AST_FEATURE_PARKCALL);
07358 
07359    ast_bridge_call(chan, final_dest_chan, &bconfig);
07360 
07361    /* the bridge has ended, set BRIDGERESULT to SUCCESS. If the other channel has not been hung up, return it to the PBX */
07362    pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "SUCCESS");
07363    if (!ast_check_hangup(final_dest_chan) && !ast_test_flag(&opts, OPT_CALLEE_KILL)) {
07364       ast_debug(1, "starting new PBX in %s,%s,%d for chan %s\n", 
07365          final_dest_chan->context, final_dest_chan->exten, 
07366          final_dest_chan->priority, final_dest_chan->name);
07367 
07368       if (ast_pbx_start(final_dest_chan) != AST_PBX_SUCCESS) {
07369          ast_log(LOG_WARNING, "FAILED continuing PBX on dest chan %s\n", final_dest_chan->name);
07370          ast_hangup(final_dest_chan);
07371       } else
07372          ast_debug(1, "SUCCESS continuing PBX on chan %s\n", final_dest_chan->name);
07373    } else {
07374       ast_debug(1, "hangup chan %s since the other endpoint has hung up or the x flag was passed\n", final_dest_chan->name);
07375       ast_hangup(final_dest_chan);
07376    }
07377 done:
07378    if (bconfig.warning_sound) {
07379       ast_free((char *)bconfig.warning_sound);
07380    }
07381    if (bconfig.end_sound) {
07382       ast_free((char *)bconfig.end_sound);
07383    }
07384    if (bconfig.start_sound) {
07385       ast_free((char *)bconfig.start_sound);
07386    }
07387 
07388    return 0;
07389 }
07390 
07391 #if defined(TEST_FRAMEWORK)
07392 /*!
07393  * \internal
07394  * \brief Convert parking spaces map list to a comma separated string.
07395  *
07396  * \param str String buffer to fill.
07397  * \param spaces Parking spaces map list to convert.
07398  *
07399  * \return Nothing
07400  */
07401 static void create_spaces_str(struct ast_str **str, struct parking_dp_space_map *spaces)
07402 {
07403    const char *comma;
07404    struct parking_dp_spaces *cur;
07405 
07406    ast_str_reset(*str);
07407    comma = "";
07408    AST_LIST_TRAVERSE(spaces, cur, node) {
07409       if (cur->start == cur->stop) {
07410          ast_str_append(str, 0, "%s%d", comma, cur->start);
07411       } else {
07412          ast_str_append(str, 0, "%s%d-%d", comma, cur->start, cur->stop);
07413       }
07414       comma = ",";
07415    }
07416 }
07417 #endif   /* defined(TEST_FRAMEWORK) */
07418 
07419 #if defined(TEST_FRAMEWORK)
07420 /*!
07421  * \internal
07422  * \brief Compare parking spaces map to what is expected.
07423  *
07424  * \param test Unit test context.
07425  * \param spaces Parking spaces map list to check.
07426  * \param expected String to compare with.
07427  * \param what What is being compared.
07428  *
07429  * \retval 0 successful compare.
07430  * \retval nonzero if failed to compare.
07431  */
07432 static int check_spaces(struct ast_test *test, struct parking_dp_space_map *spaces, const char *expected, const char *what)
07433 {
07434    int cmp;
07435    struct ast_str *str = ast_str_alloca(1024);
07436 
07437    create_spaces_str(&str, spaces);
07438    cmp = strcmp(expected, ast_str_buffer(str));
07439    if (cmp) {
07440       ast_test_status_update(test,
07441          "Unexpected parking space map for %s. Expect:'%s' Got:'%s'\n",
07442          what, expected, ast_str_buffer(str));
07443    }
07444    return cmp;
07445 }
07446 #endif   /* defined(TEST_FRAMEWORK) */
07447 
07448 #if defined(TEST_FRAMEWORK)
07449 /*!
07450  * \internal
07451  * \brief Add a dead space to the dead spaces list.
07452  *
07453  * \param context Dead spaces list ptr pretending to be a context name ptr.
07454  * \param space Dead space to add to the list.
07455  *
07456  * \return Nothing
07457  */
07458 static void test_add_dead_space(const char *context, int space)
07459 {
07460    struct parking_dp_space_map *dead_spaces = (struct parking_dp_space_map *) context;
07461 
07462    usage_context_add_spaces(dead_spaces, space, space, NULL, 0);
07463 }
07464 #endif   /* defined(TEST_FRAMEWORK) */
07465 
07466 #if defined(TEST_FRAMEWORK)
07467 struct test_map {
07468    const char *ramp;
07469    int start;
07470    int stop;
07471    const char *expect;
07472 };
07473 
07474 /*!
07475  * \internal
07476  * \brief Build a parking lot dialplan usage test map from a table.
07477  *
07478  * \param test Unit test context.
07479  * \param lot Parking lot to use to build test usage map.
07480  * \param table_name Name of passed in table.
07481  * \param table Usage information to put in the usage map.
07482  * \param num_entries Number of entries in the table.
07483  *
07484  * \retval Created context node on success.
07485  * \retval NULL on error.
07486  */
07487 static struct parking_dp_context *test_build_maps(struct ast_test *test,
07488    struct ast_parkinglot *lot, const char *table_name, const struct test_map *table,
07489    size_t num_entries)
07490 {
07491    struct parking_dp_context *ctx_node;
07492    int cur_index = 0;
07493    char what[40];
07494 
07495    snprintf(what, sizeof(what), "%s[%d]", table_name, cur_index);
07496    ast_copy_string(lot->cfg.parkext, table->ramp, sizeof(lot->cfg.parkext));
07497    lot->cfg.parking_start = table->start;
07498    lot->cfg.parking_stop = table->stop;
07499    ctx_node = build_dialplan_useage_context(lot);
07500    if (!ctx_node) {
07501       ast_test_status_update(test, "Failed to create parking lot context map for %s\n",
07502          what);
07503       return NULL;
07504    }
07505    if (check_spaces(test, &ctx_node->spaces, table->expect, what)) {
07506       destroy_dialplan_usage_context(ctx_node);
07507       return NULL;
07508    }
07509    while (--num_entries) {
07510       ++cur_index;
07511       ++table;
07512       snprintf(what, sizeof(what), "%s[%d]", table_name, cur_index);
07513       ast_copy_string(lot->cfg.parkext, table->ramp, sizeof(lot->cfg.parkext));
07514       lot->cfg.parking_start = table->start;
07515       lot->cfg.parking_stop = table->stop;
07516       if (dialplan_usage_add_parkinglot_data(ctx_node, lot, 1)) {
07517          ast_test_status_update(test, "Failed to add parking lot data for %s\n", what);
07518          destroy_dialplan_usage_context(ctx_node);
07519          return NULL;
07520       }
07521       if (check_spaces(test, &ctx_node->spaces, table->expect, what)) {
07522          destroy_dialplan_usage_context(ctx_node);
07523          return NULL;
07524       }
07525    }
07526    return ctx_node;
07527 }
07528 
07529 static const struct test_map test_old_ctx[] = {
07530    /* The following order of building ctx is important to test adding items to the lists. */
07531    { "702", 14, 15, "14-15" },
07532    { "700", 10, 11, "10-11,14-15" },
07533    { "701", 18, 19, "10-11,14-15,18-19" },
07534    { "703", 12, 13, "10-15,18-19" },
07535    { "704", 16, 17, "10-19" },
07536 
07537    /* Parking ramp and space conflicts are intended with these lines. */
07538    { "704", 9, 19, "9-19" },
07539    { "704", 9, 20, "9-20" },
07540    { "704", 8, 21, "8-21" },
07541 
07542    /* Add more spaces to ctx to test removing dead parking spaces. */
07543    { "705", 23, 25, "8-21,23-25" },
07544    { "706", 28, 31, "8-21,23-25,28-31" },
07545    { "707", 33, 34, "8-21,23-25,28-31,33-34" },
07546    { "708", 38, 40, "8-21,23-25,28-31,33-34,38-40" },
07547    { "709", 42, 43, "8-21,23-25,28-31,33-34,38-40,42-43" },
07548 };
07549 
07550 static const struct test_map test_new_ctx[] = {
07551    { "702", 4, 5, "4-5" },
07552    { "704", 24, 26, "4-5,24-26" },
07553    { "709", 29, 30, "4-5,24-26,29-30" },
07554    { "710", 32, 35, "4-5,24-26,29-30,32-35" },
07555    { "711", 37, 39, "4-5,24-26,29-30,32-35,37-39" },
07556 };
07557 #endif   /* defined(TEST_FRAMEWORK) */
07558 
07559 #if defined(TEST_FRAMEWORK)
07560 /*!
07561  * \internal
07562  * \brief Test parking dialplan usage map code.
07563  *
07564  * \param test Unit test context.
07565  *
07566  * \retval 0 on success.
07567  * \retval -1 on error.
07568  */
07569 static int test_dialplan_usage_map(struct ast_test *test)
07570 {
07571    struct parking_dp_context *old_ctx;
07572    struct parking_dp_context *new_ctx;
07573    struct ast_parkinglot *lot;
07574    struct parking_dp_spaces *spaces;
07575    struct parking_dp_space_map dead_spaces = AST_LIST_HEAD_NOLOCK_INIT_VALUE;
07576    int res;
07577 
07578    ast_test_status_update(test, "Test parking dialplan usage map code\n");
07579 
07580    lot = create_parkinglot("test_lot");
07581    if (!lot) {
07582       return -1;
07583    }
07584    ast_copy_string(lot->cfg.parking_con, "test-ctx", sizeof(lot->cfg.parking_con));
07585    lot->cfg.parkext_exclusive = 1;
07586 
07587    ast_test_status_update(test,
07588       "Build old_ctx map\n");
07589    ast_log(LOG_NOTICE, "6 Ramp and space conflict warnings are expected.\n");
07590    old_ctx = test_build_maps(test, lot, "test_old_ctx", test_old_ctx,
07591       ARRAY_LEN(test_old_ctx));
07592    if (!old_ctx) {
07593       ao2_ref(lot, -1);
07594       return -1;
07595    }
07596 
07597    ast_test_status_update(test, "Build new_ctx map\n");
07598    new_ctx = test_build_maps(test, lot, "test_new_ctx", test_new_ctx,
07599       ARRAY_LEN(test_new_ctx));
07600    if (!new_ctx) {
07601       res = -1;
07602       goto fail_old_ctx;
07603    }
07604 
07605    ast_test_status_update(test, "Test removing dead parking spaces\n");
07606    remove_dead_spaces_usage((void *) &dead_spaces, &old_ctx->spaces,
07607       &new_ctx->spaces, test_add_dead_space);
07608    if (check_spaces(test, &dead_spaces, "8-21,23,28,31,40,42-43", "dead_spaces")) {
07609       res = -1;
07610       goto fail_dead_spaces;
07611    }
07612 
07613    res = 0;
07614 
07615 fail_dead_spaces:
07616    while ((spaces = AST_LIST_REMOVE_HEAD(&dead_spaces, node))) {
07617       ast_free(spaces);
07618    }
07619    destroy_dialplan_usage_context(new_ctx);
07620 
07621 fail_old_ctx:
07622    destroy_dialplan_usage_context(old_ctx);
07623    ao2_ref(lot, -1);
07624    return res;
07625 }
07626 #endif   /* defined(TEST_FRAMEWORK) */
07627 
07628 #if defined(TEST_FRAMEWORK)
07629 static int fake_fixup(struct ast_channel *clonechan, struct ast_channel *original)
07630 {
07631    return 0;
07632 }
07633 #endif   /* defined(TEST_FRAMEWORK) */
07634 
07635 #if defined(TEST_FRAMEWORK)
07636 static struct ast_channel *create_test_channel(const struct ast_channel_tech *fake_tech)
07637 {
07638    struct ast_channel *test_channel1;
07639 
07640    if (!(test_channel1 = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL,
07641       NULL, NULL, 0, 0, "TestChannel1"))) {
07642       ast_log(LOG_WARNING, "Whoa, test channel creation failed.\n");
07643       return NULL;
07644    }
07645 
07646    /* normally this is done in the channel driver */
07647    test_channel1->nativeformats = AST_FORMAT_GSM;
07648    test_channel1->writeformat = AST_FORMAT_GSM;
07649    test_channel1->rawwriteformat = AST_FORMAT_GSM;
07650    test_channel1->readformat = AST_FORMAT_GSM;
07651    test_channel1->rawreadformat = AST_FORMAT_GSM;
07652    test_channel1->tech = fake_tech;
07653 
07654    return test_channel1;
07655 }
07656 #endif   /* defined(TEST_FRAMEWORK) */
07657 
07658 #if defined(TEST_FRAMEWORK)
07659 static int unpark_test_channel(struct ast_channel *toremove, struct ast_park_call_args *args)
07660 {
07661    struct ast_context *con;
07662    struct parkeduser *pu_toremove;
07663    int res = 0;
07664 
07665    args->pu->notquiteyet = 1; /* go ahead and stop processing the test parking */
07666 
07667    AST_LIST_LOCK(&args->pu->parkinglot->parkings);
07668    AST_LIST_TRAVERSE_SAFE_BEGIN(&args->pu->parkinglot->parkings, pu_toremove, list) {
07669       if (pu_toremove == args->pu) {
07670          AST_LIST_REMOVE_CURRENT(list);
07671          break;
07672       }
07673    }
07674    AST_LIST_TRAVERSE_SAFE_END;
07675    AST_LIST_UNLOCK(&args->pu->parkinglot->parkings);
07676 
07677    if (!pu_toremove) {
07678       ast_log(LOG_WARNING, "Whoa, could not find parking test call!\n");
07679       return -1;
07680    }
07681 
07682    con = ast_context_find(args->pu->parkinglot->cfg.parking_con);
07683    if (con) {
07684       if (ast_context_remove_extension2(con, args->pu->parkingexten, 1, NULL, 0)) {
07685          ast_log(LOG_WARNING, "Whoa, failed to remove the parking extension!\n");
07686          res = -1;
07687       } else {
07688          notify_metermaids(args->pu->parkingexten,
07689             pu_toremove->parkinglot->cfg.parking_con, AST_DEVICE_NOT_INUSE);
07690       }
07691    } else {
07692       ast_log(LOG_WARNING, "Whoa, no parking context?\n");
07693       res = -1;
07694    }
07695 
07696    parkinglot_unref(pu_toremove->parkinglot);
07697    ast_free(pu_toremove);
07698    args->pu = NULL;
07699 
07700    if (!res && toremove) {
07701       ast_hangup(toremove);
07702    }
07703    return res;
07704 }
07705 #endif   /* defined(TEST_FRAMEWORK) */
07706 
07707 #if defined(TEST_FRAMEWORK)
07708 AST_TEST_DEFINE(features_test)
07709 {
07710    struct ast_channel *test_channel1 = NULL;
07711    struct ast_channel *parked_chan = NULL;
07712    struct ast_parkinglot *dynlot;
07713    struct ast_park_call_args args = {
07714       .timeout = DEFAULT_PARK_TIME,
07715    };
07716 
07717    int res = 0;
07718 
07719    static const struct ast_channel_tech fake_tech = {
07720       .fixup = fake_fixup, /* silence warning from masquerade */
07721    };
07722 
07723    static const char unique_lot_1[] = "myuniquetestparkinglot314";
07724    static const char unique_lot_2[] = "myuniquetestparkinglot3141592654";
07725    static const char unique_context_1[] = "myuniquetestcontext314";
07726    static const char unique_context_2[] = "myuniquetestcontext3141592654";
07727    static const char parkinglot_parkext[] = "750";
07728    static const char parkinglot_range[] = "751-760";
07729 
07730    switch (cmd) {
07731    case TEST_INIT:
07732       info->name = "features_test";
07733       info->category = "/main/features/";
07734       info->summary = "Features unit test";
07735       info->description =
07736          "Tests whether parking respects PARKINGLOT settings";
07737       return AST_TEST_NOT_RUN;
07738    case TEST_EXECUTE:
07739       break;
07740    }
07741 
07742    if (test_dialplan_usage_map(test)) {
07743       res = -1;
07744       goto exit_features_test;
07745    }
07746 
07747    /* changing a config option is a bad practice, but must be done in this case */
07748    parkeddynamic = 1;
07749 
07750    ast_test_status_update(test, "Test parking functionality with defaults\n");
07751    if (!(test_channel1 = create_test_channel(&fake_tech))) {
07752       res = -1;
07753       goto exit_features_test;
07754    }
07755    if (park_call_full(test_channel1, NULL, &args)) {
07756       res = -1;
07757       goto exit_features_test;
07758    }
07759    if (unpark_test_channel(test_channel1, &args)) {
07760       res = -1;
07761       goto exit_features_test;
07762    }
07763 
07764 
07765    ast_test_status_update(test, "Check that certain parking options are respected\n");
07766    if (!(test_channel1 = create_test_channel(&fake_tech))) {
07767       res = -1;
07768       goto exit_features_test;
07769    }
07770    pbx_builtin_setvar_helper(test_channel1, "PARKINGLOT", unique_lot_1);
07771    pbx_builtin_setvar_helper(test_channel1, "PARKINGDYNCONTEXT", unique_context_1);
07772    pbx_builtin_setvar_helper(test_channel1, "PARKINGDYNEXTEN", parkinglot_parkext);
07773    pbx_builtin_setvar_helper(test_channel1, "PARKINGDYNPOS", parkinglot_range);
07774    if (park_call_full(test_channel1, NULL, &args)) {
07775       res = -1;
07776       goto exit_features_test;
07777    }
07778    /* grab newly created parking lot for destruction in the end */
07779    dynlot = args.pu->parkinglot;
07780    if (args.pu->parkingnum != 751
07781       || strcmp(dynlot->name, unique_lot_1)
07782       || strcmp(dynlot->cfg.parking_con, unique_context_1)
07783       || strcmp(dynlot->cfg.parkext, parkinglot_parkext)
07784       || dynlot->cfg.parking_start != 751
07785       || dynlot->cfg.parking_stop != 760) {
07786       ast_test_status_update(test, "Parking settings were not respected\n");
07787       ast_test_status_update(test, "Dyn-name:%s\n", dynlot->name);
07788       ast_test_status_update(test, "Dyn-context:%s\n", dynlot->cfg.parking_con);
07789       ast_test_status_update(test, "Dyn-parkext:%s\n", dynlot->cfg.parkext);
07790       ast_test_status_update(test, "Dyn-parkpos:%d-%d\n", dynlot->cfg.parking_start,
07791          dynlot->cfg.parking_stop);
07792       ast_test_status_update(test, "Parked in space:%d\n", args.pu->parkingnum);
07793       if (!unpark_test_channel(test_channel1, &args)) {
07794          test_channel1 = NULL;
07795       }
07796       res = -1;
07797       goto exit_features_test;
07798    } else {
07799       ast_test_status_update(test, "Parking settings for non-masquerading park verified\n");
07800    }
07801    if (unpark_test_channel(test_channel1, &args)) {
07802       res = -1;
07803       goto exit_features_test;
07804    }
07805 
07806 
07807    ast_test_status_update(test, "Check #2 that certain parking options are respected\n");
07808    if (!(test_channel1 = create_test_channel(&fake_tech))) {
07809       res = -1;
07810       goto exit_features_test;
07811    }
07812    pbx_builtin_setvar_helper(test_channel1, "PARKINGLOT", unique_lot_2);
07813    pbx_builtin_setvar_helper(test_channel1, "PARKINGDYNCONTEXT", unique_context_2);
07814    pbx_builtin_setvar_helper(test_channel1, "PARKINGDYNEXTEN", parkinglot_parkext);
07815    pbx_builtin_setvar_helper(test_channel1, "PARKINGDYNPOS", parkinglot_range);
07816    if (masq_park_call(test_channel1, NULL, 0, NULL, 0, &args)) {
07817       res = -1;
07818       goto exit_features_test;
07819    }
07820    /* hangup zombie channel */
07821    ast_hangup(test_channel1);
07822    test_channel1 = NULL;
07823 
07824    dynlot = args.pu->parkinglot;
07825    if (args.pu->parkingnum != 751
07826       || strcmp(dynlot->name, unique_lot_2)
07827       || strcmp(dynlot->cfg.parking_con, unique_context_2)
07828       || strcmp(dynlot->cfg.parkext, parkinglot_parkext)
07829       || dynlot->cfg.parking_start != 751
07830       || dynlot->cfg.parking_stop != 760) {
07831       ast_test_status_update(test, "Parking settings were not respected\n");
07832       ast_test_status_update(test, "Dyn-name:%s\n", dynlot->name);
07833       ast_test_status_update(test, "Dyn-context:%s\n", dynlot->cfg.parking_con);
07834       ast_test_status_update(test, "Dyn-parkext:%s\n", dynlot->cfg.parkext);
07835       ast_test_status_update(test, "Dyn-parkpos:%d-%d\n", dynlot->cfg.parking_start,
07836          dynlot->cfg.parking_stop);
07837       ast_test_status_update(test, "Parked in space:%d\n", args.pu->parkingnum);
07838       res = -1;
07839    } else {
07840       ast_test_status_update(test, "Parking settings for masquerading park verified\n");
07841    }
07842 
07843    /* find the real channel */
07844    parked_chan = ast_channel_get_by_name("TestChannel1");
07845    if (unpark_test_channel(parked_chan, &args)) {
07846       if (parked_chan) {
07847          ast_hangup(parked_chan);
07848       }
07849       res = -1;
07850    }
07851 
07852 
07853 exit_features_test:
07854 
07855    if (test_channel1) {
07856       ast_hangup(test_channel1);
07857    }
07858 
07859    force_reload_load = 1;
07860    ast_features_reload();
07861    return res ? AST_TEST_FAIL : AST_TEST_PASS;
07862 }
07863 #endif   /* defined(TEST_FRAMEWORK) */
07864 
07865 int ast_features_init(void)
07866 {
07867    int res;
07868 
07869    parkinglots = ao2_container_alloc(7, parkinglot_hash_cb, parkinglot_cmp_cb);
07870    if (!parkinglots) {
07871       return -1;
07872    }
07873 
07874    res = load_config(0);
07875    if (res) {
07876       return res;
07877    }
07878    ast_cli_register_multiple(cli_features, ARRAY_LEN(cli_features));
07879    ast_pthread_create(&parking_thread, NULL, do_parking_thread, NULL);
07880    ast_register_application2(app_bridge, bridge_exec, NULL, NULL, NULL);
07881    res = ast_register_application2(parkedcall, parked_call_exec, NULL, NULL, NULL);
07882    if (!res)
07883       res = ast_register_application2(parkcall, park_call_exec, NULL, NULL, NULL);
07884    if (!res) {
07885       ast_manager_register_xml("ParkedCalls", 0, manager_parking_status);
07886       ast_manager_register_xml("Park", EVENT_FLAG_CALL, manager_park);
07887       ast_manager_register_xml("Bridge", EVENT_FLAG_CALL, action_bridge);
07888    }
07889 
07890    res |= ast_devstate_prov_add("Park", metermaidstate);
07891 #if defined(TEST_FRAMEWORK)
07892    res |= AST_TEST_REGISTER(features_test);
07893 #endif   /* defined(TEST_FRAMEWORK) */
07894 
07895    return res;
07896 }