Sat Apr 26 2014 22:01:36

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