Thu Apr 28 2011 17:15:22

Asterisk developer's documentation


features.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2008, Digium, Inc.
00005  *
00006  * Mark Spencer <markster@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*! \file
00020  *
00021  * \brief Routines implementing call features as call pickup, parking and transfer
00022  *
00023  * \author Mark Spencer <markster@digium.com> 
00024  */
00025 
00026 #include "asterisk.h"
00027 
00028 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 307227 $")
00029 
00030 #include "asterisk/_private.h"
00031 
00032 #include <pthread.h>
00033 #include <signal.h>
00034 #include <sys/time.h>
00035 #include <sys/signal.h>
00036 #include <netinet/in.h>
00037 
00038 #include "asterisk/lock.h"
00039 #include "asterisk/file.h"
00040 #include "asterisk/channel.h"
00041 #include "asterisk/pbx.h"
00042 #include "asterisk/causes.h"
00043 #include "asterisk/module.h"
00044 #include "asterisk/translate.h"
00045 #include "asterisk/app.h"
00046 #include "asterisk/say.h"
00047 #include "asterisk/features.h"
00048 #include "asterisk/musiconhold.h"
00049 #include "asterisk/config.h"
00050 #include "asterisk/cli.h"
00051 #include "asterisk/manager.h"
00052 #include "asterisk/utils.h"
00053 #include "asterisk/adsi.h"
00054 #include "asterisk/devicestate.h"
00055 #include "asterisk/monitor.h"
00056 #include "asterisk/audiohook.h"
00057 #include "asterisk/global_datastores.h"
00058 #include "asterisk/astobj2.h"
00059 
00060 /*
00061  * Party A - transferee
00062  * Party B - transferer
00063  * Party C - target of transfer
00064  *
00065  * DTMF attended transfer works within the channel bridge.
00066  * Unfortunately, when either party A or B in the channel bridge
00067  * hangs up, that channel is not completely hung up until the
00068  * transfer completes.  This is a real problem depending upon
00069  * the channel technology involved.
00070  *
00071  * For chan_dahdi, the channel is crippled until the hangup is
00072  * complete.  Either the channel is not useable (analog) or the
00073  * protocol disconnect messages are held up (PRI/BRI/SS7) and
00074  * the media is not released.
00075  *
00076  * For chan_sip, a call limit of one is going to block that
00077  * endpoint from any further calls until the hangup is complete.
00078  *
00079  * For party A this is a minor problem.  The party A channel
00080  * will only be in this condition while party B is dialing and
00081  * when party B and C are conferring.  The conversation between
00082  * party B and C is expected to be a short one.  Party B is
00083  * either asking a question of party C or announcing party A.
00084  * Also party A does not have much incentive to hangup at this
00085  * point.
00086  *
00087  * For party B this can be a major problem during a blonde
00088  * transfer.  (A blonde transfer is our term for an attended
00089  * transfer that is converted into a blind transfer. :))  Party
00090  * B could be the operator.  When party B hangs up, he assumes
00091  * that he is out of the original call entirely.  The party B
00092  * channel will be in this condition while party C is ringing,
00093  * while attempting to recall party B, and while waiting between
00094  * call attempts.
00095  *
00096  * WARNING:
00097  * The ATXFER_NULL_TECH conditional is a hack to fix the
00098  * problem.  It will replace the party B channel technology with
00099  * a NULL channel driver.  The consequences of this code is that
00100  * the 'h' extension will not be able to access any channel
00101  * technology specific information like SIP statistics for the
00102  * call.
00103  *
00104  * Uncomment the ATXFER_NULL_TECH define below to replace the
00105  * party B channel technology in the channel bridge to complete
00106  * hanging up the channel technology.
00107  */
00108 //#define ATXFER_NULL_TECH 1
00109 
00110 /*** DOCUMENTATION
00111    <application name="Bridge" language="en_US">
00112       <synopsis>
00113          Bridge two channels.
00114       </synopsis>
00115       <syntax>
00116          <parameter name="channel" required="true">
00117             <para>The current channel is bridged to the specified <replaceable>channel</replaceable>.</para>
00118          </parameter>
00119          <parameter name="options">
00120             <optionlist>
00121                <option name="p">
00122                   <para>Play a courtesy tone to <replaceable>channel</replaceable>.</para>
00123                </option>
00124             </optionlist>
00125          </parameter>
00126       </syntax>
00127       <description>
00128          <para>Allows the ability to bridge two channels via the dialplan.</para>
00129          <para>This application sets the following channel variable upon completion:</para>
00130          <variablelist>
00131             <variable name="BRIDGERESULT">
00132                <para>The result of the bridge attempt as a text string.</para>
00133                <value name="SUCCESS" />
00134                <value name="FAILURE" />
00135                <value name="LOOP" />
00136                <value name="NONEXISTENT" />
00137                <value name="INCOMPATIBLE" />
00138             </variable>
00139          </variablelist>
00140       </description>
00141    </application>
00142    <application name="ParkedCall" language="en_US">
00143       <synopsis>
00144          Answer a parked call.
00145       </synopsis>
00146       <syntax>
00147          <parameter name="exten" required="true" />
00148       </syntax>
00149       <description>
00150          <para>Used to connect to a parked call. This application is always
00151          registered internally and does not need to be explicitly added
00152          into the dialplan, although you should include the <literal>parkedcalls</literal>
00153          context. If no extension is provided, then the first available
00154          parked call will be acquired.</para>
00155       </description>
00156       <see-also>
00157          <ref type="application">Park</ref>
00158          <ref type="application">ParkAndAnnounce</ref>
00159       </see-also>
00160    </application>
00161    <application name="Park" language="en_US">
00162       <synopsis>
00163          Park yourself.
00164       </synopsis>
00165       <syntax>
00166          <parameter name="timeout">
00167             <para>A custom parking timeout for this parked call. Value in milliseconds.</para>
00168          </parameter>
00169          <parameter name="return_context">
00170             <para>The context to return the call to after it times out.</para>
00171          </parameter>
00172          <parameter name="return_exten">
00173             <para>The extension to return the call to after it times out.</para>
00174          </parameter>
00175          <parameter name="return_priority">
00176             <para>The priority to return the call to after it times out.</para>
00177          </parameter>
00178          <parameter name="options">
00179             <para>A list of options for this parked call.</para>
00180             <optionlist>
00181                <option name="r">
00182                   <para>Send ringing instead of MOH to the parked call.</para>
00183                </option>
00184                <option name="R">
00185                   <para>Randomize the selection of a parking space.</para>
00186                </option>
00187                <option name="s">
00188                   <para>Silence announcement of the parking space number.</para>
00189                </option>
00190             </optionlist>
00191          </parameter>
00192       </syntax>
00193       <description>
00194          <para>Used to park yourself (typically in combination with a supervised
00195          transfer to know the parking space). This application is always
00196          registered internally and does not need to be explicitly added
00197          into the dialplan, although you should include the <literal>parkedcalls</literal>
00198          context (or the context specified in <filename>features.conf</filename>).</para>
00199          <para>If you set the <variable>PARKINGLOT</variable> variable, the call will be parked
00200          in the specifed parking context. Note setting this variable overrides the <variable>
00201          PARKINGLOT</variable> set by the <literal>CHANNEL</literal> function.</para>
00202          <para>If you set the <variable>PARKINGEXTEN</variable> variable to an extension in your
00203          parking context, Park() will park the call on that extension, unless
00204          it already exists. In that case, execution will continue at next priority.</para>
00205       </description>
00206       <see-also>
00207          <ref type="application">ParkAndAnnounce</ref>
00208          <ref type="application">ParkedCall</ref>
00209       </see-also>
00210    </application>
00211  ***/
00212 
00213 #define DEFAULT_PARK_TIME                    45000 /*!< ms */
00214 #define DEFAULT_TRANSFER_DIGIT_TIMEOUT          3000  /*!< ms */
00215 #define DEFAULT_FEATURE_DIGIT_TIMEOUT           1000  /*!< ms */
00216 #define DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER 15000 /*!< ms */
00217 #define DEFAULT_PARKINGLOT                   "default"
00218 #define DEFAULT_ATXFER_DROP_CALL             0     /*!< Do not drop call. */
00219 #define DEFAULT_ATXFER_LOOP_DELAY               10000 /*!< ms */
00220 #define DEFAULT_ATXFER_CALLBACK_RETRIES            2
00221 
00222 #define AST_MAX_WATCHERS 256
00223 #define MAX_DIAL_FEATURE_OPTIONS 30
00224 
00225 struct feature_group_exten {
00226    AST_LIST_ENTRY(feature_group_exten) entry;
00227    AST_DECLARE_STRING_FIELDS(
00228       AST_STRING_FIELD(exten);
00229    );
00230    struct ast_call_feature *feature;
00231 };
00232 
00233 struct feature_group {
00234    AST_LIST_ENTRY(feature_group) entry;
00235    AST_DECLARE_STRING_FIELDS(
00236       AST_STRING_FIELD(gname);
00237    );
00238    AST_LIST_HEAD_NOLOCK(, feature_group_exten) features;
00239 };
00240 
00241 static AST_RWLIST_HEAD_STATIC(feature_groups, feature_group);
00242 
00243 static char *parkedcall = "ParkedCall";
00244 
00245 static char pickup_ext[AST_MAX_EXTENSION];                 /*!< Call pickup extension */
00246 
00247 /*! \brief Description of one parked call, added to a list while active, then removed.
00248    The list belongs to a parkinglot 
00249 */
00250 struct parkeduser {
00251    struct ast_channel *chan;                   /*!< Parking channel */
00252    struct timeval start;                       /*!< Time the parking started */
00253    int parkingnum;                             /*!< Parking lot */
00254    char parkingexten[AST_MAX_EXTENSION];       /*!< If set beforehand, parking extension used for this call */
00255    char context[AST_MAX_CONTEXT];              /*!< Where to go if our parking time expires */
00256    char exten[AST_MAX_EXTENSION];
00257    int priority;
00258    int parkingtime;                            /*!< Maximum length in parking lot before return */
00259    unsigned int notquiteyet:1;
00260    unsigned int options_specified:1;
00261    char peername[1024];
00262    unsigned char moh_trys;
00263    struct ast_parkinglot *parkinglot;
00264    AST_LIST_ENTRY(parkeduser) list;
00265 };
00266 
00267 /*! \brief Structure for parking lots which are put in a container. */
00268 struct ast_parkinglot {
00269    char name[AST_MAX_CONTEXT];
00270    char parking_con[AST_MAX_EXTENSION];      /*!< Context for which parking is made accessible */
00271    char parking_con_dial[AST_MAX_EXTENSION]; /*!< Context for dialback for parking (KLUDGE) */
00272    int parking_start;            /*!< First available extension for parking */
00273    int parking_stop;          /*!< Last available extension for parking */
00274    int parking_offset;
00275    int parkfindnext;
00276    int parkingtime;           /*!< Default parking time */
00277    char mohclass[MAX_MUSICCLASS];                  /*!< Music class used for parking */
00278    int parkaddhints;                               /*!< Add parking hints automatically */
00279    int parkedcalltransfers;                        /*!< Enable DTMF based transfers on bridge when picking up parked calls */
00280    int parkedcallreparking;                        /*!< Enable DTMF based parking on bridge when picking up parked calls */
00281    int parkedcallhangup;                           /*!< Enable DTMF based hangup on a bridge when pickup up parked calls */
00282    int parkedcallrecording;                        /*!< Enable DTMF based recording on a bridge when picking up parked calls */
00283    AST_LIST_HEAD(parkinglot_parklist, parkeduser) parkings; /*!< List of active parkings in this parkinglot */
00284 };
00285 
00286 /*! \brief The list of parking lots configured. Always at least one  - the default parking lot */
00287 static struct ao2_container *parkinglots;
00288  
00289 struct ast_parkinglot *default_parkinglot;
00290 char parking_ext[AST_MAX_EXTENSION];            /*!< Extension you type to park the call */
00291 
00292 static char courtesytone[256];                             /*!< Courtesy tone */
00293 static int parkedplay = 0;                                 /*!< Who to play the courtesy tone to */
00294 static char xfersound[256];                                /*!< Call transfer sound */
00295 static char xferfailsound[256];                            /*!< Call transfer failure sound */
00296 static char pickupsound[256];                              /*!< Pickup sound */
00297 static char pickupfailsound[256];                          /*!< Pickup failure sound */
00298 
00299 static int adsipark;
00300 
00301 static int transferdigittimeout;
00302 static int featuredigittimeout;
00303 static int comebacktoorigin = 1;
00304 
00305 static int atxfernoanswertimeout;
00306 static unsigned int atxferdropcall;
00307 static unsigned int atxferloopdelay;
00308 static unsigned int atxfercallbackretries;
00309 
00310 static char *registrar = "features";         /*!< Registrar for operations */
00311 
00312 /* module and CLI command definitions */
00313 static char *parkcall = PARK_APP_NAME;
00314 
00315 static struct ast_app *monitor_app = NULL;
00316 static int monitor_ok = 1;
00317 
00318 static struct ast_app *mixmonitor_app = NULL;
00319 static int mixmonitor_ok = 1;
00320 
00321 static struct ast_app *stopmixmonitor_app = NULL;
00322 static int stopmixmonitor_ok = 1;
00323 
00324 static pthread_t parking_thread;
00325 struct ast_dial_features {
00326    struct ast_flags features_caller;
00327    struct ast_flags features_callee;
00328    int is_caller;
00329 };
00330 
00331 #if defined(ATXFER_NULL_TECH)
00332 static struct ast_frame *null_read(struct ast_channel *chan)
00333 {
00334    /* Hangup channel. */
00335    return NULL;
00336 }
00337 
00338 static struct ast_frame *null_exception(struct ast_channel *chan)
00339 {
00340    /* Hangup channel. */
00341    return NULL;
00342 }
00343 
00344 static int null_write(struct ast_channel *chan, struct ast_frame *frame)
00345 {
00346    /* Hangup channel. */
00347    return -1;
00348 }
00349 
00350 static int null_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
00351 {
00352    /* No problem fixing up the channel. */
00353    return 0;
00354 }
00355 
00356 static int null_hangup(struct ast_channel *chan)
00357 {
00358    chan->tech_pvt = NULL;
00359    return 0;
00360 }
00361 
00362 static const struct ast_channel_tech null_tech = {
00363    .type = "NULL",
00364    .description = "NULL channel driver for atxfer",
00365    .capabilities = -1,
00366    .read = null_read,
00367    .exception = null_exception,
00368    .write = null_write,
00369    .fixup = null_fixup,
00370    .hangup = null_hangup,
00371 };
00372 #endif   /* defined(ATXFER_NULL_TECH) */
00373 
00374 #if defined(ATXFER_NULL_TECH)
00375 /*!
00376  * \internal
00377  * \brief Set the channel technology to the NULL technology.
00378  *
00379  * \param chan Channel to change technology.
00380  *
00381  * \return Nothing
00382  */
00383 static void set_null_chan_tech(struct ast_channel *chan)
00384 {
00385    int idx;
00386 
00387    ast_channel_lock(chan);
00388 
00389    /* Hangup the channel's physical side */
00390    if (chan->tech->hangup) {
00391       chan->tech->hangup(chan);
00392    }
00393    if (chan->tech_pvt) {
00394       ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n",
00395          chan->name);
00396       ast_free(chan->tech_pvt);
00397       chan->tech_pvt = NULL;
00398    }
00399 
00400    /* Install the NULL technology and wake up anyone waiting on it. */
00401    chan->tech = &null_tech;
00402    for (idx = 0; idx < AST_MAX_FDS; ++idx) {
00403       switch (idx) {
00404       case AST_ALERT_FD:
00405       case AST_TIMING_FD:
00406       case AST_GENERATOR_FD:
00407          /* Don't clear these fd's. */
00408          break;
00409       default:
00410          ast_channel_set_fd(chan, idx, -1);
00411          break;
00412       }
00413    }
00414    ast_queue_frame(chan, &ast_null_frame);
00415 
00416    ast_channel_unlock(chan);
00417 }
00418 #endif   /* defined(ATXFER_NULL_TECH) */
00419 
00420 #if defined(ATXFER_NULL_TECH)
00421 /*!
00422  * \internal
00423  * \brief Set the channel name to something unique.
00424  *
00425  * \param chan Channel to change name.
00426  *
00427  * \return Nothing
00428  */
00429 static void set_new_chan_name(struct ast_channel *chan)
00430 {
00431    char *orig_name;
00432    static int seq_num;
00433 
00434    ast_channel_lock(chan);
00435 
00436    orig_name = ast_strdupa(chan->name);
00437    ast_string_field_build(chan, name, "%s<XFER_%x>", orig_name,
00438       ast_atomic_fetchadd_int(&seq_num, +1));
00439 
00440    ast_channel_unlock(chan);
00441 }
00442 #endif   /* defined(ATXFER_NULL_TECH) */
00443 
00444 static void *dial_features_duplicate(void *data)
00445 {
00446    struct ast_dial_features *df = data, *df_copy;
00447  
00448    if (!(df_copy = ast_calloc(1, sizeof(*df)))) {
00449       return NULL;
00450    }
00451  
00452    memcpy(df_copy, df, sizeof(*df));
00453  
00454    return df_copy;
00455  }
00456  
00457  static void dial_features_destroy(void *data)
00458  {
00459    struct ast_dial_features *df = data;
00460    if (df) {
00461       ast_free(df);
00462    }
00463  }
00464  
00465  const struct ast_datastore_info dial_features_info = {
00466    .type = "dial-features",
00467    .destroy = dial_features_destroy,
00468    .duplicate = dial_features_duplicate,
00469  };
00470  
00471 /* Forward declarations */
00472 static struct ast_parkinglot *parkinglot_addref(struct ast_parkinglot *parkinglot);
00473 static void parkinglot_unref(struct ast_parkinglot *parkinglot);
00474 static void parkinglot_destroy(void *obj);
00475 int manage_parkinglot(struct ast_parkinglot *curlot, const struct pollfd *pfds, const int nfds, struct pollfd **new_pfds, int *new_nfds, int *fs);
00476 struct ast_parkinglot *find_parkinglot(const char *name);
00477 
00478 
00479 const char *ast_parking_ext(void)
00480 {
00481    return parking_ext;
00482 }
00483 
00484 const char *ast_pickup_ext(void)
00485 {
00486    return pickup_ext;
00487 }
00488 
00489 struct ast_bridge_thread_obj 
00490 {
00491    struct ast_bridge_config bconfig;
00492    struct ast_channel *chan;
00493    struct ast_channel *peer;
00494    unsigned int return_to_pbx:1;
00495 };
00496 
00497 static int parkinglot_hash_cb(const void *obj, const int flags)
00498 {
00499    const struct ast_parkinglot *parkinglot = obj;
00500 
00501    return ast_str_case_hash(parkinglot->name);
00502 }
00503 
00504 static int parkinglot_cmp_cb(void *obj, void *arg, int flags)
00505 {
00506    struct ast_parkinglot *parkinglot = obj, *parkinglot2 = arg;
00507 
00508    return !strcasecmp(parkinglot->name, parkinglot2->name) ? CMP_MATCH | CMP_STOP : 0;
00509 }
00510 
00511 /*!
00512  * \brief store context, extension and priority 
00513  * \param chan, context, ext, pri
00514 */
00515 static void set_c_e_p(struct ast_channel *chan, const char *context, const char *ext, int pri)
00516 {
00517    ast_copy_string(chan->context, context, sizeof(chan->context));
00518    ast_copy_string(chan->exten, ext, sizeof(chan->exten));
00519    chan->priority = pri;
00520 }
00521 
00522 /*!
00523  * \brief Check goto on transfer
00524  * \param chan
00525  *
00526  * Check if channel has 'GOTO_ON_BLINDXFR' set, if not exit.
00527  * When found make sure the types are compatible. Check if channel is valid
00528  * if so start the new channel else hangup the call. 
00529 */
00530 static void check_goto_on_transfer(struct ast_channel *chan) 
00531 {
00532    struct ast_channel *xferchan;
00533    const char *val = pbx_builtin_getvar_helper(chan, "GOTO_ON_BLINDXFR");
00534    char *x, *goto_on_transfer;
00535    struct ast_frame *f;
00536 
00537    if (ast_strlen_zero(val))
00538       return;
00539 
00540    goto_on_transfer = ast_strdupa(val);
00541 
00542    if (!(xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "%s", chan->name)))
00543       return;
00544 
00545    for (x = goto_on_transfer; x && *x; x++) {
00546       if (*x == '^')
00547          *x = ',';
00548    }
00549    /* Make formats okay */
00550    xferchan->readformat = chan->readformat;
00551    xferchan->writeformat = chan->writeformat;
00552    ast_channel_masquerade(xferchan, chan);
00553    ast_parseable_goto(xferchan, goto_on_transfer);
00554    xferchan->_state = AST_STATE_UP;
00555    ast_clear_flag(xferchan, AST_FLAGS_ALL);  
00556    ast_channel_clear_softhangup(xferchan, AST_SOFTHANGUP_ALL);
00557    if ((f = ast_read(xferchan))) {
00558       ast_frfree(f);
00559       f = NULL;
00560       ast_pbx_start(xferchan);
00561    } else {
00562       ast_hangup(xferchan);
00563    }
00564 }
00565 
00566 static struct ast_channel *feature_request_and_dial(struct ast_channel *caller,
00567    const char *caller_name, struct ast_channel *transferee, const char *type,
00568    int format, void *data, int timeout, int *outstate, const char *cid_num,
00569    const char *cid_name, const char *language);
00570 
00571 /*!
00572  * \brief bridge the call 
00573  * \param data thread bridge.
00574  *
00575  * Set Last Data for respective channels, reset cdr for channels
00576  * bridge call, check if we're going back to dialplan
00577  * if not hangup both legs of the call
00578 */
00579 static void *bridge_call_thread(void *data)
00580 {
00581    struct ast_bridge_thread_obj *tobj = data;
00582    int res;
00583 
00584    tobj->chan->appl = !tobj->return_to_pbx ? "Transferred Call" : "ManagerBridge";
00585    tobj->chan->data = tobj->peer->name;
00586    tobj->peer->appl = !tobj->return_to_pbx ? "Transferred Call" : "ManagerBridge";
00587    tobj->peer->data = tobj->chan->name;
00588 
00589    ast_bridge_call(tobj->peer, tobj->chan, &tobj->bconfig);
00590 
00591    if (tobj->return_to_pbx) {
00592       if (!ast_check_hangup(tobj->peer)) {
00593          ast_log(LOG_VERBOSE, "putting peer %s into PBX again\n", tobj->peer->name);
00594          res = ast_pbx_start(tobj->peer);
00595          if (res != AST_PBX_SUCCESS)
00596             ast_log(LOG_WARNING, "FAILED continuing PBX on peer %s\n", tobj->peer->name);
00597       } else
00598          ast_hangup(tobj->peer);
00599       if (!ast_check_hangup(tobj->chan)) {
00600          ast_log(LOG_VERBOSE, "putting chan %s into PBX again\n", tobj->chan->name);
00601          res = ast_pbx_start(tobj->chan);
00602          if (res != AST_PBX_SUCCESS)
00603             ast_log(LOG_WARNING, "FAILED continuing PBX on chan %s\n", tobj->chan->name);
00604       } else
00605          ast_hangup(tobj->chan);
00606    } else {
00607       ast_hangup(tobj->chan);
00608       ast_hangup(tobj->peer);
00609    }
00610 
00611    ast_free(tobj);
00612 
00613    return NULL;
00614 }
00615 
00616 /*!
00617  * \brief create thread for the parked call
00618  * \param data
00619  *
00620  * Create thread and attributes, call bridge_call_thread
00621 */
00622 static void bridge_call_thread_launch(void *data) 
00623 {
00624    pthread_t thread;
00625    pthread_attr_t attr;
00626    struct sched_param sched;
00627 
00628    pthread_attr_init(&attr);
00629    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
00630    ast_pthread_create(&thread, &attr, bridge_call_thread, data);
00631    pthread_attr_destroy(&attr);
00632    memset(&sched, 0, sizeof(sched));
00633    pthread_setschedparam(thread, SCHED_RR, &sched);
00634 }
00635 
00636 /*!
00637  * \brief Announce call parking by ADSI
00638  * \param chan .
00639  * \param parkingexten .
00640  * Create message to show for ADSI, display message.
00641  * \retval 0 on success.
00642  * \retval -1 on failure.
00643 */
00644 static int adsi_announce_park(struct ast_channel *chan, char *parkingexten)
00645 {
00646    int res;
00647    int justify[5] = {ADSI_JUST_CENT, ADSI_JUST_CENT, ADSI_JUST_CENT, ADSI_JUST_CENT};
00648    char tmp[256];
00649    char *message[5] = {NULL, NULL, NULL, NULL, NULL};
00650 
00651    snprintf(tmp, sizeof(tmp), "Parked on %s", parkingexten);
00652    message[0] = tmp;
00653    res = ast_adsi_load_session(chan, NULL, 0, 1);
00654    if (res == -1)
00655       return res;
00656    return ast_adsi_print(chan, message, justify, 1);
00657 }
00658 
00659 /*! \brief Find parking lot name from channel */
00660 static const char *findparkinglotname(struct ast_channel *chan)
00661 {
00662    const char *temp, *parkinglot = NULL;
00663 
00664    /* Check if the channel has a parking lot */
00665    if (!ast_strlen_zero(chan->parkinglot))
00666       parkinglot = chan->parkinglot;
00667 
00668    /* Channel variables override everything */
00669 
00670    if ((temp  = pbx_builtin_getvar_helper(chan, "PARKINGLOT")))
00671       return temp;
00672 
00673    return parkinglot;
00674 }
00675 
00676 /*! \brief Notify metermaids that we've changed an extension */
00677 static void notify_metermaids(const char *exten, char *context, enum ast_device_state state)
00678 {
00679    ast_debug(4, "Notification of state change to metermaids %s@%s\n to state '%s'", 
00680       exten, context, ast_devstate2str(state));
00681 
00682    ast_devstate_changed(state, "park:%s@%s", exten, context);
00683 }
00684 
00685 /*! \brief metermaids callback from devicestate.c */
00686 static enum ast_device_state metermaidstate(const char *data)
00687 {
00688    char *context;
00689    char *exten;
00690 
00691    context = ast_strdupa(data);
00692 
00693    exten = strsep(&context, "@");
00694    if (!context)
00695       return AST_DEVICE_INVALID;
00696    
00697    ast_debug(4, "Checking state of exten %s in context %s\n", exten, context);
00698 
00699    if (!ast_exists_extension(NULL, context, exten, 1, NULL))
00700       return AST_DEVICE_NOT_INUSE;
00701 
00702    return AST_DEVICE_INUSE;
00703 }
00704 
00705 /*! Options to pass to park_call_full */
00706 enum ast_park_call_options {
00707    /*! Provide ringing to the parked caller instead of music on hold */
00708    AST_PARK_OPT_RINGING =   (1 << 0),
00709    /*! Randomly choose a parking spot for the caller instead of choosing
00710     *  the first one that is available. */
00711    AST_PARK_OPT_RANDOMIZE = (1 << 1),
00712    /*! Do not announce the parking number */
00713    AST_PARK_OPT_SILENCE = (1 << 2),
00714 };
00715 
00716 struct ast_park_call_args {
00717    /*! How long to wait in the parking lot before the call gets sent back
00718     *  to the specified return extension (or a best guess at where it came
00719     *  from if not explicitly specified). */
00720    int timeout;
00721    /*! An output parameter to store the parking space where the parked caller
00722     *  was placed. */
00723    int *extout;
00724    const char *orig_chan_name;
00725    const char *return_con;
00726    const char *return_ext;
00727    int return_pri;
00728    uint32_t flags;
00729    /*! Parked user that has already obtained a parking space */
00730    struct parkeduser *pu;
00731 };
00732 
00733 static struct parkeduser *park_space_reserve(struct ast_channel *chan,
00734  struct ast_channel *peer, struct ast_park_call_args *args)
00735 {
00736    struct parkeduser *pu;
00737    int i, parking_space = -1, parking_range;
00738    const char *parkinglotname = NULL;
00739    const char *parkingexten;
00740    struct ast_parkinglot *parkinglot = NULL;
00741    
00742    if (peer)
00743       parkinglotname = findparkinglotname(peer);
00744    else /* peer was NULL, check chan (ParkAndAnnounce / res_agi) */
00745       parkinglotname = findparkinglotname(chan);
00746 
00747    if (parkinglotname) {
00748       if (option_debug)
00749          ast_log(LOG_DEBUG, "Found chanvar Parkinglot: %s\n", parkinglotname);
00750       parkinglot = find_parkinglot(parkinglotname);   
00751    }
00752    if (!parkinglot) {
00753       parkinglot = parkinglot_addref(default_parkinglot);
00754    }
00755 
00756    if (option_debug)
00757       ast_log(LOG_DEBUG, "Parkinglot: %s\n", parkinglot->name);
00758 
00759    /* Allocate memory for parking data */
00760    if (!(pu = ast_calloc(1, sizeof(*pu)))) {
00761       parkinglot_unref(parkinglot);
00762       return NULL;
00763    }
00764 
00765    /* Lock parking list */
00766    AST_LIST_LOCK(&parkinglot->parkings);
00767    /* Check for channel variable PARKINGEXTEN */
00768    ast_channel_lock(chan);
00769    parkingexten = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGEXTEN"), ""));
00770    ast_channel_unlock(chan);
00771    if (!ast_strlen_zero(parkingexten)) {
00772       /*!\note The API forces us to specify a numeric parking slot, even
00773        * though the architecture would tend to support non-numeric extensions
00774        * (as are possible with SIP, for example).  Hence, we enforce that
00775        * limitation here.  If extout was not numeric, we could permit
00776        * arbitrary non-numeric extensions.
00777        */
00778         if (sscanf(parkingexten, "%30d", &parking_space) != 1 || parking_space < 0) {
00779          AST_LIST_UNLOCK(&parkinglot->parkings);
00780          parkinglot_unref(parkinglot);
00781             free(pu);
00782             ast_log(LOG_WARNING, "PARKINGEXTEN does not indicate a valid parking slot: '%s'.\n", parkingexten);
00783             return NULL;
00784         }
00785         snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", parking_space);
00786 
00787       if (ast_exists_extension(NULL, parkinglot->parking_con, pu->parkingexten, 1, NULL)) {
00788          ast_log(LOG_WARNING, "Requested parking extension already exists: %s@%s\n", parkingexten, parkinglot->parking_con);
00789          AST_LIST_UNLOCK(&parkinglot->parkings);
00790          parkinglot_unref(parkinglot);
00791          ast_free(pu);
00792          return NULL;
00793       }
00794    } else {
00795       int start;
00796       struct parkeduser *cur = NULL;
00797 
00798       /* Select parking space within range */
00799       parking_range = parkinglot->parking_stop - parkinglot->parking_start + 1;
00800 
00801       if (ast_test_flag(args, AST_PARK_OPT_RANDOMIZE)) {
00802          start = ast_random() % (parkinglot->parking_stop - parkinglot->parking_start + 1);
00803       } else {
00804          start = parkinglot->parking_start;
00805       }
00806 
00807       for (i = start; 1; i++) {
00808          if (i == parkinglot->parking_stop + 1) {
00809             i = parkinglot->parking_start - 1;
00810             break;
00811          }
00812 
00813          AST_LIST_TRAVERSE(&parkinglot->parkings, cur, list) {
00814             if (cur->parkingnum == i) {
00815                break;
00816             }
00817          }
00818          if (!cur) {
00819             parking_space = i;
00820             break;
00821          }
00822       }
00823 
00824       if (i == start - 1 && cur) {
00825          ast_log(LOG_WARNING, "No more parking spaces\n");
00826          ast_free(pu);
00827          AST_LIST_UNLOCK(&parkinglot->parkings);
00828          parkinglot_unref(parkinglot);
00829          return NULL;
00830       }
00831       /* Set pointer for next parking */
00832       if (parkinglot->parkfindnext) 
00833          parkinglot->parking_offset = parking_space - parkinglot->parking_start + 1;
00834       snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", parking_space);
00835    }
00836 
00837    pu->notquiteyet = 1;
00838    pu->parkingnum = parking_space;
00839    pu->parkinglot = parkinglot_addref(parkinglot);
00840    AST_LIST_INSERT_TAIL(&parkinglot->parkings, pu, list);
00841    parkinglot_unref(parkinglot);
00842 
00843    return pu;
00844 }
00845 
00846 /* Park a call */
00847 static int park_call_full(struct ast_channel *chan, struct ast_channel *peer, struct ast_park_call_args *args)
00848 {
00849    struct ast_context *con;
00850    int parkingnum_copy;
00851    struct parkeduser *pu = args->pu;
00852    const char *event_from;
00853 
00854    if (pu == NULL)
00855       pu = park_space_reserve(chan, peer, args);
00856    if (pu == NULL)
00857       return 1; /* Continue execution if possible */
00858 
00859    snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", pu->parkingnum);
00860    
00861    chan->appl = "Parked Call";
00862    chan->data = NULL; 
00863 
00864    pu->chan = chan;
00865    
00866    /* Put the parked channel on hold if we have two different channels */
00867    if (chan != peer) {
00868       if (ast_test_flag(args, AST_PARK_OPT_RINGING)) {
00869          ast_indicate(pu->chan, AST_CONTROL_RINGING);
00870       } else {
00871          ast_indicate_data(pu->chan, AST_CONTROL_HOLD, 
00872             S_OR(pu->parkinglot->mohclass, NULL),
00873             !ast_strlen_zero(pu->parkinglot->mohclass) ? strlen(pu->parkinglot->mohclass) + 1 : 0);
00874       }
00875    }
00876    
00877    pu->start = ast_tvnow();
00878    pu->parkingtime = (args->timeout > 0) ? args->timeout : pu->parkinglot->parkingtime;
00879    parkingnum_copy = pu->parkingnum;
00880    if (args->extout)
00881       *(args->extout) = pu->parkingnum;
00882 
00883    if (peer) { 
00884       /* This is so ugly that it hurts, but implementing get_base_channel() on local channels
00885          could have ugly side effects.  We could have transferer<->local,1<->local,2<->parking
00886          and we need the callback name to be that of transferer.  Since local,1/2 have the same
00887          name we can be tricky and just grab the bridged channel from the other side of the local
00888       */
00889       if (!strcasecmp(peer->tech->type, "Local")) {
00890          struct ast_channel *tmpchan, *base_peer;
00891          char other_side[AST_CHANNEL_NAME];
00892          char *c;
00893          ast_copy_string(other_side, S_OR(args->orig_chan_name, peer->name), sizeof(other_side));
00894          if ((c = strrchr(other_side, ';'))) {
00895             *++c = '1';
00896          }
00897          if ((tmpchan = ast_get_channel_by_name_locked(other_side))) {
00898             if ((base_peer = ast_bridged_channel(tmpchan))) {
00899                ast_copy_string(pu->peername, base_peer->name, sizeof(pu->peername));
00900             }
00901             ast_channel_unlock(tmpchan);
00902          }
00903       } else {
00904          ast_copy_string(pu->peername, S_OR(args->orig_chan_name, peer->name), sizeof(pu->peername));
00905       }
00906    }
00907 
00908    /* Remember what had been dialed, so that if the parking
00909       expires, we try to come back to the same place */
00910 
00911    pu->options_specified = (!ast_strlen_zero(args->return_con) || !ast_strlen_zero(args->return_ext) || args->return_pri);
00912 
00913    /* If extension has options specified, they override all other possibilities
00914    such as the returntoorigin flag and transferred context. Information on
00915    extension options is lost here, so we set a flag */
00916 
00917    ast_copy_string(pu->context, 
00918       S_OR(args->return_con, S_OR(chan->macrocontext, chan->context)), 
00919       sizeof(pu->context));
00920    ast_copy_string(pu->exten, 
00921       S_OR(args->return_ext, S_OR(chan->macroexten, chan->exten)), 
00922       sizeof(pu->exten));
00923    pu->priority = args->return_pri ? args->return_pri : 
00924       (chan->macropriority ? chan->macropriority : chan->priority);
00925 
00926    /* If parking a channel directly, don't quiet yet get parking running on it.
00927     * All parking lot entries are put into the parking lot with notquiteyet on. */
00928    if (peer != chan) 
00929       pu->notquiteyet = 0;
00930 
00931    /* Wake up the (presumably select()ing) thread */
00932    pthread_kill(parking_thread, SIGURG);
00933    ast_verb(2, "Parked %s on %d (lot %s). Will timeout back to extension [%s] %s, %d in %d seconds\n", pu->chan->name, pu->parkingnum, pu->parkinglot->name, pu->context, pu->exten, pu->priority, (pu->parkingtime/1000));
00934 
00935    if (peer) {
00936       event_from = peer->name;
00937    } else {
00938       event_from = pbx_builtin_getvar_helper(chan, "BLINDTRANSFER");
00939    }
00940 
00941    manager_event(EVENT_FLAG_CALL, "ParkedCall",
00942       "Exten: %s\r\n"
00943       "Channel: %s\r\n"
00944       "Parkinglot: %s\r\n"
00945       "From: %s\r\n"
00946       "Timeout: %ld\r\n"
00947       "CallerIDNum: %s\r\n"
00948       "CallerIDName: %s\r\n"
00949       "Uniqueid: %s\r\n",
00950       pu->parkingexten, pu->chan->name, pu->parkinglot->name, event_from ? event_from : "",
00951       (long)pu->start.tv_sec + (long)(pu->parkingtime/1000) - (long)time(NULL),
00952       S_OR(pu->chan->cid.cid_num, "<unknown>"),
00953       S_OR(pu->chan->cid.cid_name, "<unknown>"),
00954       pu->chan->uniqueid
00955       );
00956 
00957    if (peer && adsipark && ast_adsi_available(peer)) {
00958       adsi_announce_park(peer, pu->parkingexten);  /* Only supports parking numbers */
00959       ast_adsi_unload_session(peer);
00960    }
00961 
00962    con = ast_context_find_or_create(NULL, NULL, pu->parkinglot->parking_con, registrar);
00963    if (!con)   /* Still no context? Bad */
00964       ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", pu->parkinglot->parking_con);
00965    if (con) {
00966       if (!ast_add_extension2(con, 1, pu->parkingexten, 1, NULL, NULL, parkedcall, ast_strdup(pu->parkingexten), ast_free_ptr, registrar))
00967          notify_metermaids(pu->parkingexten, pu->parkinglot->parking_con, AST_DEVICE_INUSE);
00968    }
00969 
00970    AST_LIST_UNLOCK(&pu->parkinglot->parkings);
00971 
00972    /* Only say number if it's a number and the channel hasn't been masqueraded away */
00973    if (peer && !ast_test_flag(args, AST_PARK_OPT_SILENCE) && (ast_strlen_zero(args->orig_chan_name) || !strcasecmp(peer->name, args->orig_chan_name))) {
00974       /* If a channel is masqueraded into peer while playing back the parking slot number do not continue playing it back. This is the case if an attended transfer occurs. */
00975       ast_set_flag(peer, AST_FLAG_MASQ_NOSTREAM);
00976       /* Tell the peer channel the number of the parking space */
00977       ast_say_digits(peer, pu->parkingnum, "", peer->language);
00978       ast_clear_flag(peer, AST_FLAG_MASQ_NOSTREAM);
00979    }
00980    if (peer == chan) { /* pu->notquiteyet = 1 */
00981       /* Wake up parking thread if we're really done */
00982       ast_indicate_data(pu->chan, AST_CONTROL_HOLD, 
00983          S_OR(pu->parkinglot->mohclass, NULL),
00984          !ast_strlen_zero(pu->parkinglot->mohclass) ? strlen(pu->parkinglot->mohclass) + 1 : 0);
00985       pu->notquiteyet = 0;
00986       pthread_kill(parking_thread, SIGURG);
00987    }
00988    return 0;
00989 }
00990 
00991 /*! \brief Park a call */
00992 int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeout, int *extout)
00993 {
00994    struct ast_park_call_args args = {
00995       .timeout = timeout,
00996       .extout = extout,
00997    };
00998 
00999    return park_call_full(chan, peer, &args);
01000 }
01001 
01002 static int masq_park_call(struct ast_channel *rchan, struct ast_channel *peer, int timeout, int *extout, int play_announcement, struct ast_park_call_args *args)
01003 {
01004    struct ast_channel *chan;
01005    struct ast_frame *f;
01006    int park_status;
01007    struct ast_park_call_args park_args = {0,};
01008 
01009    if (!args) {
01010       args = &park_args;
01011       args->timeout = timeout;
01012       args->extout = extout;
01013    }
01014 
01015    if ((args->pu = park_space_reserve(rchan, peer, args)) == NULL) {
01016       if (peer)
01017          ast_stream_and_wait(peer, "beeperr", "");
01018       return AST_FEATURE_RETURN_PARKFAILED;
01019    }
01020 
01021    /* Make a new, fake channel that we'll use to masquerade in the real one */
01022    if (!(chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, rchan->accountcode, rchan->exten, rchan->context, rchan->amaflags, "Parked/%s",rchan->name))) {
01023       ast_log(LOG_WARNING, "Unable to create parked channel\n");
01024       return -1;
01025    }
01026 
01027    /* Make formats okay */
01028    chan->readformat = rchan->readformat;
01029    chan->writeformat = rchan->writeformat;
01030    ast_channel_masquerade(chan, rchan);
01031 
01032    /* Setup the extensions and such */
01033    set_c_e_p(chan, rchan->context, rchan->exten, rchan->priority);
01034 
01035    /* Setup the macro extension and such */
01036    ast_copy_string(chan->macrocontext,rchan->macrocontext,sizeof(chan->macrocontext));
01037    ast_copy_string(chan->macroexten,rchan->macroexten,sizeof(chan->macroexten));
01038    chan->macropriority = rchan->macropriority;
01039 
01040    /* Make the masq execute */
01041    if ((f = ast_read(chan)))
01042       ast_frfree(f);
01043 
01044    if (peer == rchan) {
01045       peer = chan;
01046    }
01047 
01048    if (peer && (!play_announcement && args == &park_args)) {
01049       args->orig_chan_name = ast_strdupa(peer->name);
01050    }
01051 
01052    park_status = park_call_full(chan, peer, args);
01053    if (park_status == 1) {
01054    /* would be nice to play "invalid parking extension" */
01055       ast_hangup(chan);
01056       return -1;
01057    }
01058 
01059    return 0;
01060 }
01061 
01062 /* Park call via masqueraded channel */
01063 int ast_masq_park_call(struct ast_channel *rchan, struct ast_channel *peer, int timeout, int *extout)
01064 {
01065    return masq_park_call(rchan, peer, timeout, extout, 0, NULL);
01066 }
01067 
01068 static int masq_park_call_announce_args(struct ast_channel *rchan, struct ast_channel *peer, struct ast_park_call_args *args)
01069 {
01070    return masq_park_call(rchan, peer, 0, NULL, 1, args);
01071 }
01072 
01073 static int masq_park_call_announce(struct ast_channel *rchan, struct ast_channel *peer, int timeout, int *extout)
01074 {
01075    return masq_park_call(rchan, peer, timeout, extout, 1, NULL);
01076 }
01077 
01078 #define FEATURE_SENSE_CHAN (1 << 0)
01079 #define FEATURE_SENSE_PEER (1 << 1)
01080 
01081 /*! 
01082  * \brief set caller and callee according to the direction 
01083  * \param caller, callee, peer, chan, sense
01084  *
01085  * Detect who triggered feature and set callee/caller variables accordingly
01086 */
01087 static void set_peers(struct ast_channel **caller, struct ast_channel **callee,
01088    struct ast_channel *peer, struct ast_channel *chan, int sense)
01089 {
01090    if (sense == FEATURE_SENSE_PEER) {
01091       *caller = peer;
01092       *callee = chan;
01093    } else {
01094       *callee = peer;
01095       *caller = chan;
01096    }
01097 }
01098 
01099 /*! 
01100  * \brief support routing for one touch call parking
01101  * \param chan channel parking call
01102  * \param peer channel to be parked
01103  * \param config unsed
01104  * \param code unused
01105  * \param sense feature options
01106  *
01107  * \param data
01108  * Setup channel, set return exten,priority to 's,1'
01109  * answer chan, sleep chan, park call
01110 */
01111 static int builtin_parkcall(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
01112 {
01113    struct ast_channel *parker;
01114    struct ast_channel *parkee;
01115    int res = 0;
01116 
01117    set_peers(&parker, &parkee, peer, chan, sense);
01118    /* we used to set chan's exten and priority to "s" and 1
01119       here, but this generates (in some cases) an invalid
01120       extension, and if "s" exists, could errantly
01121       cause execution of extensions you don't expect. It
01122       makes more sense to let nature take its course
01123       when chan finishes, and let the pbx do its thing
01124       and hang up when the park is over.
01125    */
01126    if (chan->_state != AST_STATE_UP)
01127       res = ast_answer(chan);
01128    if (!res)
01129       res = ast_safe_sleep(chan, 1000);
01130 
01131    if (!res) { /* one direction used to call park_call.... */
01132       res = masq_park_call_announce(parkee, parker, 0, NULL);
01133       /* PBX should hangup zombie channel if a masquerade actually occurred (res=0) */
01134    }
01135 
01136    return res;
01137 }
01138 
01139 /*! \brief Play message to both caller and callee in bridged call, plays synchronously, autoservicing the
01140    other channel during the message, so please don't use this for very long messages
01141  */
01142 static int play_message_in_bridged_call(struct ast_channel *caller_chan, struct ast_channel *callee_chan, const char *audiofile)
01143 {
01144    /* First play for caller, put other channel on auto service */
01145    if (ast_autoservice_start(callee_chan))
01146       return -1;
01147    ast_autoservice_ignore(callee_chan, AST_FRAME_DTMF_END);
01148    if (ast_stream_and_wait(caller_chan, audiofile, "")) {
01149       ast_log(LOG_WARNING, "Failed to play automon message!\n");
01150       ast_autoservice_stop(callee_chan);
01151       return -1;
01152    }
01153    if (ast_autoservice_stop(callee_chan))
01154       return -1;
01155    /* Then play for callee, put other channel on auto service */
01156    if (ast_autoservice_start(caller_chan))
01157       return -1;
01158    ast_autoservice_ignore(caller_chan, AST_FRAME_DTMF_END);
01159    if (ast_stream_and_wait(callee_chan, audiofile, "")) {
01160       ast_log(LOG_WARNING, "Failed to play automon message !\n");
01161       ast_autoservice_stop(caller_chan);
01162       return -1;
01163    }
01164    if (ast_autoservice_stop(caller_chan))
01165       return -1;
01166    return(0);
01167 }
01168 
01169 /*!
01170  * \brief Monitor a channel by DTMF
01171  * \param chan channel requesting monitor
01172  * \param peer channel to be monitored
01173  * \param config
01174  * \param code
01175  * \param sense feature options
01176  *
01177  * \param data
01178  * Check monitor app enabled, setup channels, both caller/callee chans not null
01179  * get TOUCH_MONITOR variable for filename if exists, exec monitor app.
01180  * \retval AST_FEATURE_RETURN_SUCCESS on success.
01181  * \retval -1 on error.
01182 */
01183 static int builtin_automonitor(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
01184 {
01185    char *caller_chan_id = NULL, *callee_chan_id = NULL, *args = NULL, *touch_filename = NULL;
01186    int x = 0;
01187    size_t len;
01188    struct ast_channel *caller_chan, *callee_chan;
01189    const char *automon_message_start = NULL;
01190    const char *automon_message_stop = NULL;
01191 
01192    if (!monitor_ok) {
01193       ast_log(LOG_ERROR,"Cannot record the call. The monitor application is disabled.\n");
01194       return -1;
01195    }
01196 
01197    if (!monitor_app && !(monitor_app = pbx_findapp("Monitor"))) {
01198       monitor_ok = 0;
01199       ast_log(LOG_ERROR,"Cannot record the call. The monitor application is disabled.\n");
01200       return -1;
01201    }
01202 
01203    set_peers(&caller_chan, &callee_chan, peer, chan, sense);
01204    if (caller_chan) {   /* Find extra messages */
01205       automon_message_start = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_MESSAGE_START");
01206       automon_message_stop = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_MESSAGE_STOP");
01207    }
01208 
01209    if (!ast_strlen_zero(courtesytone)) {  /* Play courtesy tone if configured */
01210       if(play_message_in_bridged_call(caller_chan, callee_chan, courtesytone) == -1) {
01211          return -1;
01212       }
01213    }
01214    
01215    if (callee_chan->monitor) {
01216       ast_verb(4, "User hit '%s' to stop recording call.\n", code);
01217       if (!ast_strlen_zero(automon_message_stop)) {
01218          play_message_in_bridged_call(caller_chan, callee_chan, automon_message_stop);
01219       }
01220       callee_chan->monitor->stop(callee_chan, 1);
01221       return AST_FEATURE_RETURN_SUCCESS;
01222    }
01223 
01224    if (caller_chan && callee_chan) {
01225       const char *touch_format = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_FORMAT");
01226       const char *touch_monitor = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR");
01227       const char *touch_monitor_prefix = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_PREFIX");
01228 
01229       if (!touch_format)
01230          touch_format = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR_FORMAT");
01231 
01232       if (!touch_monitor)
01233          touch_monitor = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR");
01234    
01235       if (!touch_monitor_prefix)
01236          touch_monitor_prefix = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR_PREFIX");
01237    
01238       if (touch_monitor) {
01239          len = strlen(touch_monitor) + 50;
01240          args = alloca(len);
01241          touch_filename = alloca(len);
01242          snprintf(touch_filename, len, "%s-%ld-%s", S_OR(touch_monitor_prefix, "auto"), (long)time(NULL), touch_monitor);
01243          snprintf(args, len, "%s,%s,m", S_OR(touch_format, "wav"), touch_filename);
01244       } else {
01245          caller_chan_id = ast_strdupa(S_OR(caller_chan->cid.cid_num, caller_chan->name));
01246          callee_chan_id = ast_strdupa(S_OR(callee_chan->cid.cid_num, callee_chan->name));
01247          len = strlen(caller_chan_id) + strlen(callee_chan_id) + 50;
01248          args = alloca(len);
01249          touch_filename = alloca(len);
01250          snprintf(touch_filename, len, "%s-%ld-%s-%s", S_OR(touch_monitor_prefix, "auto"), (long)time(NULL), caller_chan_id, callee_chan_id);
01251          snprintf(args, len, "%s,%s,m", S_OR(touch_format, "wav"), touch_filename);
01252       }
01253 
01254       for(x = 0; x < strlen(args); x++) {
01255          if (args[x] == '/')
01256             args[x] = '-';
01257       }
01258       
01259       ast_verb(4, "User hit '%s' to record call. filename: %s\n", code, args);
01260 
01261       pbx_exec(callee_chan, monitor_app, args);
01262       pbx_builtin_setvar_helper(callee_chan, "TOUCH_MONITOR_OUTPUT", touch_filename);
01263       pbx_builtin_setvar_helper(caller_chan, "TOUCH_MONITOR_OUTPUT", touch_filename);
01264 
01265       if (!ast_strlen_zero(automon_message_start)) {  /* Play start message for both channels */
01266          play_message_in_bridged_call(caller_chan, callee_chan, automon_message_start);
01267       }
01268    
01269       return AST_FEATURE_RETURN_SUCCESS;
01270    }
01271    
01272    ast_log(LOG_NOTICE,"Cannot record the call. One or both channels have gone away.\n");  
01273    return -1;
01274 }
01275 
01276 static int builtin_automixmonitor(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
01277 {
01278    char *caller_chan_id = NULL, *callee_chan_id = NULL, *args = NULL, *touch_filename = NULL;
01279    int x = 0;
01280    size_t len;
01281    struct ast_channel *caller_chan, *callee_chan;
01282    const char *mixmonitor_spy_type = "MixMonitor";
01283    int count = 0;
01284 
01285    if (!mixmonitor_ok) {
01286       ast_log(LOG_ERROR,"Cannot record the call. The mixmonitor application is disabled.\n");
01287       return -1;
01288    }
01289 
01290    if (!(mixmonitor_app = pbx_findapp("MixMonitor"))) {
01291       mixmonitor_ok = 0;
01292       ast_log(LOG_ERROR,"Cannot record the call. The mixmonitor application is disabled.\n");
01293       return -1;
01294    }
01295 
01296    set_peers(&caller_chan, &callee_chan, peer, chan, sense);
01297 
01298    if (!ast_strlen_zero(courtesytone)) {
01299       if (ast_autoservice_start(callee_chan))
01300          return -1;
01301       ast_autoservice_ignore(callee_chan, AST_FRAME_DTMF_END);
01302       if (ast_stream_and_wait(caller_chan, courtesytone, "")) {
01303          ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
01304          ast_autoservice_stop(callee_chan);
01305          return -1;
01306       }
01307       if (ast_autoservice_stop(callee_chan))
01308          return -1;
01309    }
01310 
01311    ast_channel_lock(callee_chan);
01312    count = ast_channel_audiohook_count_by_source(callee_chan, mixmonitor_spy_type, AST_AUDIOHOOK_TYPE_SPY);
01313    ast_channel_unlock(callee_chan);
01314 
01315    /* This means a mixmonitor is attached to the channel, running or not is unknown. */
01316    if (count > 0) {
01317       
01318       ast_verb(3, "User hit '%s' to stop recording call.\n", code);
01319 
01320       /* Make sure they are running */
01321       ast_channel_lock(callee_chan);
01322       count = ast_channel_audiohook_count_by_source_running(callee_chan, mixmonitor_spy_type, AST_AUDIOHOOK_TYPE_SPY);
01323       ast_channel_unlock(callee_chan);
01324       if (count > 0) {
01325          if (!stopmixmonitor_ok) {
01326             ast_log(LOG_ERROR,"Cannot stop recording the call. The stopmixmonitor application is disabled.\n");
01327             return -1;
01328          }
01329          if (!(stopmixmonitor_app = pbx_findapp("StopMixMonitor"))) {
01330             stopmixmonitor_ok = 0;
01331             ast_log(LOG_ERROR,"Cannot stop recording the call. The stopmixmonitor application is disabled.\n");
01332             return -1;
01333          } else {
01334             pbx_exec(callee_chan, stopmixmonitor_app, "");
01335             return AST_FEATURE_RETURN_SUCCESS;
01336          }
01337       }
01338       
01339       ast_log(LOG_WARNING,"Stopped MixMonitors are attached to the channel.\n"); 
01340    }        
01341 
01342    if (caller_chan && callee_chan) {
01343       const char *touch_format = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MIXMONITOR_FORMAT");
01344       const char *touch_monitor = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MIXMONITOR");
01345 
01346       if (!touch_format)
01347          touch_format = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MIXMONITOR_FORMAT");
01348 
01349       if (!touch_monitor)
01350          touch_monitor = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MIXMONITOR");
01351 
01352       if (touch_monitor) {
01353          len = strlen(touch_monitor) + 50;
01354          args = alloca(len);
01355          touch_filename = alloca(len);
01356          snprintf(touch_filename, len, "auto-%ld-%s", (long)time(NULL), touch_monitor);
01357          snprintf(args, len, "%s.%s,b", touch_filename, (touch_format) ? touch_format : "wav");
01358       } else {
01359          caller_chan_id = ast_strdupa(S_OR(caller_chan->cid.cid_num, caller_chan->name));
01360          callee_chan_id = ast_strdupa(S_OR(callee_chan->cid.cid_num, callee_chan->name));
01361          len = strlen(caller_chan_id) + strlen(callee_chan_id) + 50;
01362          args = alloca(len);
01363          touch_filename = alloca(len);
01364          snprintf(touch_filename, len, "auto-%ld-%s-%s", (long)time(NULL), caller_chan_id, callee_chan_id);
01365          snprintf(args, len, "%s.%s,b", touch_filename, S_OR(touch_format, "wav"));
01366       }
01367 
01368       for( x = 0; x < strlen(args); x++) {
01369          if (args[x] == '/')
01370             args[x] = '-';
01371       }
01372 
01373       ast_verb(3, "User hit '%s' to record call. filename: %s\n", code, touch_filename);
01374 
01375       pbx_exec(callee_chan, mixmonitor_app, args);
01376       pbx_builtin_setvar_helper(callee_chan, "TOUCH_MIXMONITOR_OUTPUT", touch_filename);
01377       pbx_builtin_setvar_helper(caller_chan, "TOUCH_MIXMONITOR_OUTPUT", touch_filename);
01378       return AST_FEATURE_RETURN_SUCCESS;
01379    
01380    }
01381 
01382    ast_log(LOG_NOTICE,"Cannot record the call. One or both channels have gone away.\n");
01383    return -1;
01384 
01385 }
01386 
01387 static int builtin_disconnect(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
01388 {
01389    ast_verb(4, "User hit '%s' to disconnect call.\n", code);
01390    return AST_FEATURE_RETURN_HANGUP;
01391 }
01392 
01393 static int finishup(struct ast_channel *chan)
01394 {
01395    ast_indicate(chan, AST_CONTROL_UNHOLD);
01396 
01397    return ast_autoservice_stop(chan);
01398 }
01399 
01400 /*!
01401  * \brief Find the context for the transfer
01402  * \param transferer
01403  * \param transferee
01404  * 
01405  * Grab the TRANSFER_CONTEXT, if fails try grabbing macrocontext.
01406  * \return a context string
01407 */
01408 static const char *real_ctx(struct ast_channel *transferer, struct ast_channel *transferee)
01409 {
01410    const char *s = pbx_builtin_getvar_helper(transferer, "TRANSFER_CONTEXT");
01411    if (ast_strlen_zero(s)) {
01412       s = pbx_builtin_getvar_helper(transferee, "TRANSFER_CONTEXT");
01413    }
01414    if (ast_strlen_zero(s)) { /* Use the non-macro context to transfer the call XXX ? */
01415       s = transferer->macrocontext;
01416    }
01417    if (ast_strlen_zero(s)) {
01418       s = transferer->context;
01419    }
01420    return s;  
01421 }
01422 
01423 /*!
01424  * \brief Blind transfer user to another extension
01425  * \param chan channel to be transfered
01426  * \param peer channel initiated blind transfer
01427  * \param config
01428  * \param code
01429  * \param data
01430  * \param sense  feature options
01431  * 
01432  * Place chan on hold, check if transferred to parkinglot extension,
01433  * otherwise check extension exists and transfer caller.
01434  * \retval AST_FEATURE_RETURN_SUCCESS.
01435  * \retval -1 on failure.
01436 */
01437 static int builtin_blindtransfer(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
01438 {
01439    struct ast_channel *transferer;
01440    struct ast_channel *transferee;
01441    const char *transferer_real_context;
01442    char xferto[256];
01443    int res, parkstatus = 0;
01444 
01445    set_peers(&transferer, &transferee, peer, chan, sense);
01446    transferer_real_context = real_ctx(transferer, transferee);
01447    /* Start autoservice on chan while we talk to the originator */
01448    ast_autoservice_start(transferee);
01449    ast_autoservice_ignore(transferee, AST_FRAME_DTMF_END);
01450    ast_indicate(transferee, AST_CONTROL_HOLD);
01451 
01452    memset(xferto, 0, sizeof(xferto));
01453 
01454    /* Transfer */
01455    res = ast_stream_and_wait(transferer, "pbx-transfer", AST_DIGIT_ANY);
01456    if (res < 0) {
01457       finishup(transferee);
01458       return -1; /* error ? */
01459    }
01460    if (res > 0)   /* If they've typed a digit already, handle it */
01461       xferto[0] = (char) res;
01462 
01463    ast_stopstream(transferer);
01464    res = ast_app_dtget(transferer, transferer_real_context, xferto, sizeof(xferto), 100, transferdigittimeout);
01465    if (res < 0) {  /* hangup or error, (would be 0 for invalid and 1 for valid) */
01466       finishup(transferee);
01467       return -1;
01468    }
01469    if (res == 0) {
01470       if (xferto[0]) {
01471          ast_log(LOG_WARNING, "Extension '%s' does not exist in context '%s'\n",
01472             xferto, transferer_real_context);
01473       } else {
01474          /* Does anyone care about this case? */
01475          ast_log(LOG_WARNING, "No digits dialed.\n");
01476       }
01477       ast_stream_and_wait(transferer, "pbx-invalid", "");
01478       finishup(transferee);
01479       return AST_FEATURE_RETURN_SUCCESS;
01480    }
01481 
01482    if (!strcmp(xferto, ast_parking_ext())) {
01483       res = finishup(transferee);
01484       if (res) {
01485       } else if (!(parkstatus = masq_park_call_announce(transferee, transferer, 0, NULL))) { /* success */
01486          /* We return non-zero, but tell the PBX not to hang the channel when
01487             the thread dies -- We have to be careful now though.  We are responsible for 
01488             hanging up the channel, else it will never be hung up! */
01489 
01490          return 0;
01491       } else {
01492          ast_log(LOG_WARNING, "Unable to park call %s, parkstatus = %d\n", transferee->name, parkstatus);
01493       }
01494       ast_autoservice_start(transferee);
01495    } else {
01496       pbx_builtin_setvar_helper(transferer, "BLINDTRANSFER", transferee->name);
01497       pbx_builtin_setvar_helper(transferee, "BLINDTRANSFER", transferer->name);
01498       res=finishup(transferee);
01499       if (!transferer->cdr) { /* this code should never get called (in a perfect world) */
01500          transferer->cdr=ast_cdr_alloc();
01501          if (transferer->cdr) {
01502             ast_cdr_init(transferer->cdr, transferer); /* initialize our channel's cdr */
01503             ast_cdr_start(transferer->cdr);
01504          }
01505       }
01506       if (transferer->cdr) {
01507          struct ast_cdr *swap = transferer->cdr;
01508          ast_log(LOG_DEBUG,"transferer=%s; transferee=%s; lastapp=%s; lastdata=%s; chan=%s; dstchan=%s\n",
01509                transferer->name, transferee->name, transferer->cdr->lastapp, transferer->cdr->lastdata, 
01510                transferer->cdr->channel, transferer->cdr->dstchannel);
01511          ast_log(LOG_DEBUG,"TRANSFEREE; lastapp=%s; lastdata=%s, chan=%s; dstchan=%s\n",
01512                transferee->cdr->lastapp, transferee->cdr->lastdata, transferee->cdr->channel, transferee->cdr->dstchannel);
01513          ast_log(LOG_DEBUG,"transferer_real_context=%s; xferto=%s\n", transferer_real_context, xferto);
01514          /* swap cdrs-- it will save us some time & work */
01515          transferer->cdr = transferee->cdr;
01516          transferee->cdr = swap;
01517       }
01518       if (!transferee->pbx) {
01519          /* Doh!  Use our handy async_goto functions */
01520          ast_verb(3, "Transferring %s to '%s' (context %s) priority 1\n"
01521                         ,transferee->name, xferto, transferer_real_context);
01522          if (ast_async_goto(transferee, transferer_real_context, xferto, 1))
01523             ast_log(LOG_WARNING, "Async goto failed :-(\n");
01524       } else {
01525          /* Set the channel's new extension, since it exists, using transferer context */
01526          ast_set_flag(transferee, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */
01527          ast_log(LOG_DEBUG,"ABOUT TO AST_ASYNC_GOTO, have a pbx... set HANGUP_DONT on chan=%s\n", transferee->name);
01528          set_c_e_p(transferee, transferer_real_context, xferto, 0);
01529       }
01530       check_goto_on_transfer(transferer);
01531       return res;
01532    }
01533    if (parkstatus != AST_FEATURE_RETURN_PARKFAILED
01534       && ast_stream_and_wait(transferer, xferfailsound, "")) {
01535       finishup(transferee);
01536       return -1;
01537    }
01538    ast_stopstream(transferer);
01539    res = finishup(transferee);
01540    if (res) {
01541       ast_verb(2, "Hungup during autoservice stop on '%s'\n", transferee->name);
01542       return res;
01543    }
01544    return AST_FEATURE_RETURN_SUCCESS;
01545 }
01546 
01547 /*!
01548  * \brief make channels compatible
01549  * \param c
01550  * \param newchan
01551  * \retval 0 on success.
01552  * \retval -1 on failure.
01553 */
01554 static int check_compat(struct ast_channel *c, struct ast_channel *newchan)
01555 {
01556    if (ast_channel_make_compatible(c, newchan) < 0) {
01557       ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n",
01558          c->name, newchan->name);
01559       ast_hangup(newchan);
01560       return -1;
01561    }
01562    return 0;
01563 }
01564 
01565 /*!
01566  * \brief Attended transfer
01567  * \param chan transfered user
01568  * \param peer person transfering call
01569  * \param config
01570  * \param code
01571  * \param sense feature options
01572  *
01573  * \param data
01574  * Get extension to transfer to, if you cannot generate channel (or find extension)
01575  * return to host channel. After called channel answered wait for hangup of transferer,
01576  * bridge call between transfer peer (taking them off hold) to attended transfer channel.
01577  *
01578  * \return -1 on failure
01579 */
01580 static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
01581 {
01582    struct ast_channel *transferer;/* Party B */
01583    struct ast_channel *transferee;/* Party A */
01584    const char *transferer_real_context;
01585    char xferto[256] = "";
01586    int res;
01587    int outstate=0;
01588    struct ast_channel *newchan;
01589    struct ast_channel *xferchan;
01590    struct ast_bridge_thread_obj *tobj;
01591    struct ast_bridge_config bconfig;
01592    int l;
01593    struct ast_datastore *features_datastore;
01594    struct ast_dial_features *dialfeatures = NULL;
01595    char *transferer_tech;
01596    char *transferer_name;
01597    char *transferer_name_orig;
01598    char *dash;
01599 
01600    ast_debug(1, "Executing Attended Transfer %s, %s (sense=%d) \n", chan->name, peer->name, sense);
01601    set_peers(&transferer, &transferee, peer, chan, sense);
01602    transferer_real_context = real_ctx(transferer, transferee);
01603 
01604    /* Start autoservice on transferee while we talk to the transferer */
01605    ast_autoservice_start(transferee);
01606    ast_indicate(transferee, AST_CONTROL_HOLD);
01607 
01608    /* Transfer */
01609    res = ast_stream_and_wait(transferer, "pbx-transfer", AST_DIGIT_ANY);
01610    if (res < 0) {
01611       finishup(transferee);
01612       return -1;
01613    }
01614    if (res > 0) /* If they've typed a digit already, handle it */
01615       xferto[0] = (char) res;
01616 
01617    /* this is specific of atxfer */
01618    res = ast_app_dtget(transferer, transferer_real_context, xferto, sizeof(xferto), 100, transferdigittimeout);
01619    if (res < 0) {  /* hangup or error, (would be 0 for invalid and 1 for valid) */
01620       finishup(transferee);
01621       return -1;
01622    }
01623    l = strlen(xferto);
01624    if (res == 0) {
01625       if (l) {
01626          ast_log(LOG_WARNING, "Extension '%s' does not exist in context '%s'\n",
01627             xferto, transferer_real_context);
01628       } else {
01629          /* Does anyone care about this case? */
01630          ast_log(LOG_WARNING, "No digits dialed for atxfer.\n");
01631       }
01632       ast_stream_and_wait(transferer, "pbx-invalid", "");
01633       finishup(transferee);
01634       return AST_FEATURE_RETURN_SUCCESS;
01635    }
01636 
01637    /* If we are attended transfering to parking, just use builtin_parkcall instead of trying to track all of
01638     * the different variables for handling this properly with a builtin_atxfer */
01639    if (!strcmp(xferto, ast_parking_ext())) {
01640       finishup(transferee);
01641       return builtin_parkcall(chan, peer, config, code, sense, data);
01642    }
01643 
01644    /* Append context to dialed transfer number. */
01645    snprintf(xferto + l, sizeof(xferto) - l, "@%s/n", transferer_real_context);
01646 
01647    /* If we are performing an attended transfer and we have two channels involved then
01648       copy sound file information to play upon attended transfer completion */
01649    if (transferee) {
01650       const char *chan1_attended_sound = pbx_builtin_getvar_helper(transferer, "ATTENDED_TRANSFER_COMPLETE_SOUND");
01651       const char *chan2_attended_sound = pbx_builtin_getvar_helper(transferee, "ATTENDED_TRANSFER_COMPLETE_SOUND");
01652 
01653       if (!ast_strlen_zero(chan1_attended_sound)) {
01654          pbx_builtin_setvar_helper(transferer, "BRIDGE_PLAY_SOUND", chan1_attended_sound);
01655       }
01656       if (!ast_strlen_zero(chan2_attended_sound)) {
01657          pbx_builtin_setvar_helper(transferee, "BRIDGE_PLAY_SOUND", chan2_attended_sound);
01658       }
01659    }
01660 
01661    /* Extract redial transferer information from the channel name. */
01662    transferer_name_orig = ast_strdupa(transferer->name);
01663    transferer_name = ast_strdupa(transferer_name_orig);
01664    transferer_tech = strsep(&transferer_name, "/");
01665    dash = strrchr(transferer_name, '-');
01666    if (dash) {
01667       /* Trim off channel name sequence/serial number. */
01668       *dash = '\0';
01669    }
01670 
01671    /* Stop autoservice so we can monitor all parties involved in the transfer. */
01672    if (ast_autoservice_stop(transferee) < 0) {
01673       ast_indicate(transferee, AST_CONTROL_UNHOLD);
01674       return -1;
01675    }
01676 
01677    /* Dial party C */
01678    newchan = feature_request_and_dial(transferer, transferer_name_orig, transferee,
01679       "Local", ast_best_codec(transferer->nativeformats), xferto, atxfernoanswertimeout,
01680       &outstate, transferer->cid.cid_num, transferer->cid.cid_name,
01681       transferer->language);
01682    ast_debug(2, "Dial party C result: newchan:%d, outstate:%d\n", !!newchan, outstate);
01683 
01684    if (!ast_check_hangup(transferer)) {
01685       int hangup_dont = 0;
01686 
01687       /* Transferer (party B) is up */
01688       ast_debug(1, "Actually doing an attended transfer.\n");
01689 
01690       /* Start autoservice on transferee while the transferer deals with party C. */
01691       ast_autoservice_start(transferee);
01692 
01693       ast_indicate(transferer, -1);
01694       if (!newchan) {
01695          /* any reason besides user requested cancel and busy triggers the failed sound */
01696          switch (outstate) {
01697          case AST_CONTROL_UNHOLD:/* Caller requested cancel or party C answer timeout. */
01698          case AST_CONTROL_BUSY:
01699          case AST_CONTROL_CONGESTION:
01700             if (ast_stream_and_wait(transferer, xfersound, "")) {
01701                ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
01702             }
01703             break;
01704          default:
01705             if (ast_stream_and_wait(transferer, xferfailsound, "")) {
01706                ast_log(LOG_WARNING, "Failed to play transfer failed sound!\n");
01707             }
01708             break;
01709          }
01710          finishup(transferee);
01711          return AST_FEATURE_RETURN_SUCCESS;
01712       }
01713 
01714       if (check_compat(transferer, newchan)) {
01715          if (ast_stream_and_wait(transferer, xferfailsound, "")) {
01716             ast_log(LOG_WARNING, "Failed to play transfer failed sound!\n");
01717          }
01718          /* we do mean transferee here, NOT transferer */
01719          finishup(transferee);
01720          return AST_FEATURE_RETURN_SUCCESS;
01721       }
01722       memset(&bconfig,0,sizeof(struct ast_bridge_config));
01723       ast_set_flag(&(bconfig.features_caller), AST_FEATURE_DISCONNECT);
01724       ast_set_flag(&(bconfig.features_callee), AST_FEATURE_DISCONNECT);
01725 
01726       /* ast_bridge_call clears AST_FLAG_BRIDGE_HANGUP_DONT, but we don't
01727          want that to happen here because we're also in another bridge already
01728        */
01729       if (ast_test_flag(chan, AST_FLAG_BRIDGE_HANGUP_DONT)) {
01730          hangup_dont = 1;
01731       }
01732       /* Let party B and party C talk as long as they want. */
01733       ast_bridge_call(transferer, newchan, &bconfig);
01734       if (hangup_dont) {
01735          ast_set_flag(chan, AST_FLAG_BRIDGE_HANGUP_DONT);
01736       }
01737 
01738       if (ast_check_hangup(newchan) || !ast_check_hangup(transferer)) {
01739          ast_hangup(newchan);
01740          if (ast_stream_and_wait(transferer, xfersound, "")) {
01741             ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
01742          }
01743          finishup(transferee);
01744          return AST_FEATURE_RETURN_SUCCESS;
01745       }
01746 
01747       /* Transferer (party B) is confirmed hung up at this point. */
01748       if (check_compat(transferee, newchan)) {
01749          finishup(transferee);
01750          return -1;
01751       }
01752 
01753       ast_indicate(transferee, AST_CONTROL_UNHOLD);
01754       if ((ast_autoservice_stop(transferee) < 0)
01755          || (ast_waitfordigit(transferee, 100) < 0)
01756          || (ast_waitfordigit(newchan, 100) < 0)
01757          || ast_check_hangup(transferee)
01758          || ast_check_hangup(newchan)) {
01759          ast_hangup(newchan);
01760          return -1;
01761       }
01762    } else if (!ast_check_hangup(transferee)) {
01763       /* Transferer (party B) has hung up at this point.  Doing blonde transfer. */
01764       ast_debug(1, "Actually doing a blonde transfer.\n");
01765 
01766       if (!newchan && !atxferdropcall) {
01767          /* Party C is not available, try to call party B back. */
01768          unsigned int tries = 0;
01769 
01770          if (ast_strlen_zero(transferer_name) || ast_strlen_zero(transferer_tech)) {
01771             ast_log(LOG_WARNING,
01772                "Transferer channel name: '%s' cannot be used for callback.\n",
01773                transferer_name_orig);
01774             ast_indicate(transferee, AST_CONTROL_UNHOLD);
01775             return -1;
01776          }
01777 
01778          tries = 0;
01779          for (;;) {
01780             /* Try to get party B back. */
01781             ast_debug(1, "We're trying to callback %s/%s\n",
01782                transferer_tech, transferer_name);
01783             newchan = feature_request_and_dial(transferer, transferer_name_orig,
01784                transferee, transferer_tech,
01785                ast_best_codec(transferee->nativeformats), transferer_name,
01786                atxfernoanswertimeout, &outstate, transferee->cid.cid_num,
01787                transferee->cid.cid_name, transferer->language);
01788             ast_debug(2, "Dial party B result: newchan:%d, outstate:%d\n",
01789                !!newchan, outstate);
01790             if (newchan || ast_check_hangup(transferee)) {
01791                break;
01792             }
01793 
01794             ++tries;
01795             if (atxfercallbackretries <= tries) {
01796                /* No more callback tries remaining. */
01797                break;
01798             }
01799 
01800             if (atxferloopdelay) {
01801                /* Transfer failed, sleeping */
01802                ast_debug(1, "Sleeping for %d ms before retrying atxfer.\n",
01803                   atxferloopdelay);
01804                ast_safe_sleep(transferee, atxferloopdelay);
01805                if (ast_check_hangup(transferee)) {
01806                   return -1;
01807                }
01808             }
01809 
01810             /* Retry dialing party C. */
01811             ast_debug(1, "We're retrying to call %s/%s\n", "Local", xferto);
01812             newchan = feature_request_and_dial(transferer, transferer_name_orig,
01813                transferee, "Local", ast_best_codec(transferee->nativeformats),
01814                xferto, atxfernoanswertimeout, &outstate, transferer->cid.cid_num,
01815                transferer->cid.cid_name, transferer->language);
01816             ast_debug(2, "Redial party C result: newchan:%d, outstate:%d\n",
01817                !!newchan, outstate);
01818             if (newchan || ast_check_hangup(transferee)) {
01819                break;
01820             }
01821          }
01822       }
01823       ast_indicate(transferee, AST_CONTROL_UNHOLD);
01824       if (!newchan) {
01825          /* No party C or could not callback party B. */
01826          return -1;
01827       }
01828 
01829       /* newchan is up, we should prepare transferee and bridge them */
01830       if (ast_check_hangup(newchan)) {
01831          ast_hangup(newchan);
01832          return -1;
01833       }
01834       if (check_compat(transferee, newchan)) {
01835          return -1;
01836       }
01837    } else {
01838       /*
01839        * Both the transferer and transferee have hungup.  If newchan
01840        * is up, hang it up as it has no one to talk to.
01841        */
01842       ast_debug(1, "Everyone is hungup.\n");
01843       if (newchan) {
01844          ast_hangup(newchan);
01845       }
01846       return -1;
01847    }
01848 
01849    /* Initiate the channel transfer of party A to party C (or recalled party B). */
01850 
01851    xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Transfered/%s", transferee->name);
01852    if (!xferchan) {
01853       ast_hangup(newchan);
01854       return -1;
01855    }
01856 
01857    /* Give party A a momentary ringback tone during transfer. */
01858    xferchan->visible_indication = AST_CONTROL_RINGING;
01859 
01860    /* Make formats okay */
01861    xferchan->readformat = transferee->readformat;
01862    xferchan->writeformat = transferee->writeformat;
01863 
01864    ast_channel_masquerade(xferchan, transferee);
01865    ast_explicit_goto(xferchan, transferee->context, transferee->exten, transferee->priority);
01866    xferchan->_state = AST_STATE_UP;
01867    ast_clear_flag(xferchan, AST_FLAGS_ALL);
01868 
01869    /* Do the masquerade manually to make sure that is is completed. */
01870    ast_channel_lock(xferchan);
01871    if (xferchan->masq) {
01872       ast_do_masquerade(xferchan);
01873    }
01874    ast_channel_unlock(xferchan);
01875 
01876    newchan->_state = AST_STATE_UP;
01877    ast_clear_flag(newchan, AST_FLAGS_ALL);
01878    tobj = ast_calloc(1, sizeof(*tobj));
01879    if (!tobj) {
01880       ast_hangup(xferchan);
01881       ast_hangup(newchan);
01882       return -1;
01883    }
01884 
01885    ast_channel_lock(newchan);
01886    if ((features_datastore = ast_channel_datastore_find(newchan, &dial_features_info, NULL))) {
01887       dialfeatures = features_datastore->data;
01888    }
01889    ast_channel_unlock(newchan);
01890 
01891    if (dialfeatures) {
01892       /* newchan should always be the callee and shows up as callee in dialfeatures, but for some reason
01893          I don't currently understand, the abilities of newchan seem to be stored on the caller side */
01894       ast_copy_flags(&(config->features_callee), &(dialfeatures->features_caller), AST_FLAGS_ALL);
01895       dialfeatures = NULL;
01896    }
01897 
01898    ast_channel_lock(xferchan);
01899    if ((features_datastore = ast_channel_datastore_find(xferchan, &dial_features_info, NULL))) {
01900       dialfeatures = features_datastore->data;
01901    }
01902    ast_channel_unlock(xferchan);
01903 
01904    if (dialfeatures) {
01905       ast_copy_flags(&(config->features_caller), &(dialfeatures->features_caller), AST_FLAGS_ALL);
01906    }
01907 
01908    tobj->chan = newchan;
01909    tobj->peer = xferchan;
01910    tobj->bconfig = *config;
01911 
01912    if (tobj->bconfig.end_bridge_callback_data_fixup) {
01913       tobj->bconfig.end_bridge_callback_data_fixup(&tobj->bconfig, tobj->peer, tobj->chan);
01914    }
01915 
01916    if (ast_stream_and_wait(newchan, xfersound, ""))
01917       ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
01918    bridge_call_thread_launch(tobj);
01919    return -1;/* The transferee is masqueraded and the original bridged channels can be hungup. */
01920 }
01921 
01922 /* add atxfer and automon as undefined so you can only use em if you configure them */
01923 #define FEATURES_COUNT ARRAY_LEN(builtin_features)
01924 
01925 AST_RWLOCK_DEFINE_STATIC(features_lock);
01926 
01927 static struct ast_call_feature builtin_features[] = 
01928 {
01929    { AST_FEATURE_REDIRECT, "Blind Transfer", "blindxfer", "#", "#", builtin_blindtransfer, AST_FEATURE_FLAG_NEEDSDTMF, "" },
01930    { AST_FEATURE_REDIRECT, "Attended Transfer", "atxfer", "", "", builtin_atxfer, AST_FEATURE_FLAG_NEEDSDTMF, "" },
01931    { AST_FEATURE_AUTOMON, "One Touch Monitor", "automon", "", "", builtin_automonitor, AST_FEATURE_FLAG_NEEDSDTMF, "" },
01932    { AST_FEATURE_DISCONNECT, "Disconnect Call", "disconnect", "*", "*", builtin_disconnect, AST_FEATURE_FLAG_NEEDSDTMF, "" },
01933    { AST_FEATURE_PARKCALL, "Park Call", "parkcall", "", "", builtin_parkcall, AST_FEATURE_FLAG_NEEDSDTMF, "" },
01934    { AST_FEATURE_AUTOMIXMON, "One Touch MixMonitor", "automixmon", "", "", builtin_automixmonitor, AST_FEATURE_FLAG_NEEDSDTMF, "" },
01935 };
01936 
01937 
01938 static AST_RWLIST_HEAD_STATIC(feature_list, ast_call_feature);
01939 
01940 /*! \brief register new feature into feature_list*/
01941 void ast_register_feature(struct ast_call_feature *feature)
01942 {
01943    if (!feature) {
01944       ast_log(LOG_NOTICE,"You didn't pass a feature!\n");
01945       return;
01946    }
01947   
01948    AST_RWLIST_WRLOCK(&feature_list);
01949    AST_RWLIST_INSERT_HEAD(&feature_list,feature,feature_entry);
01950    AST_RWLIST_UNLOCK(&feature_list);
01951 
01952    ast_verb(2, "Registered Feature '%s'\n",feature->sname);
01953 }
01954 
01955 /*! 
01956  * \brief Add new feature group
01957  * \param fgname feature group name.
01958  *
01959  * Add new feature group to the feature group list insert at head of list.
01960  * \note This function MUST be called while feature_groups is locked.
01961 */
01962 static struct feature_group *register_group(const char *fgname)
01963 {
01964    struct feature_group *fg;
01965 
01966    if (!fgname) {
01967       ast_log(LOG_NOTICE, "You didn't pass a new group name!\n");
01968       return NULL;
01969    }
01970 
01971    if (!(fg = ast_calloc(1, sizeof(*fg)))) {
01972       return NULL;
01973    }
01974 
01975    if (ast_string_field_init(fg, 128)) {
01976       ast_free(fg);
01977       return NULL;
01978    }
01979 
01980    ast_string_field_set(fg, gname, fgname);
01981 
01982    AST_LIST_INSERT_HEAD(&feature_groups, fg, entry);
01983 
01984    ast_verb(2, "Registered group '%s'\n", fg->gname);
01985 
01986    return fg;
01987 }
01988 
01989 /*! 
01990  * \brief Add feature to group
01991  * \param fg feature group
01992  * \param exten
01993  * \param feature feature to add.
01994  *
01995  * Check fg and feature specified, add feature to list
01996  * \note This function MUST be called while feature_groups is locked. 
01997 */
01998 static void register_group_feature(struct feature_group *fg, const char *exten, struct ast_call_feature *feature)
01999 {
02000    struct feature_group_exten *fge;
02001 
02002    if (!fg) {
02003       ast_log(LOG_NOTICE, "You didn't pass a group!\n");
02004       return;
02005    }
02006 
02007    if (!feature) {
02008       ast_log(LOG_NOTICE, "You didn't pass a feature!\n");
02009       return;
02010    }
02011 
02012    if (!(fge = ast_calloc(1, sizeof(*fge)))) {
02013       return;
02014    }
02015 
02016    if (ast_string_field_init(fge, 128)) {
02017       ast_free(fge);
02018       return;
02019    }
02020 
02021    ast_string_field_set(fge, exten, S_OR(exten, feature->exten));
02022 
02023    fge->feature = feature;
02024 
02025    AST_LIST_INSERT_HEAD(&fg->features, fge, entry);
02026 
02027    ast_verb(2, "Registered feature '%s' for group '%s' at exten '%s'\n",
02028                feature->sname, fg->gname, fge->exten);
02029 }
02030 
02031 void ast_unregister_feature(struct ast_call_feature *feature)
02032 {
02033    if (!feature) {
02034       return;
02035    }
02036 
02037    AST_RWLIST_WRLOCK(&feature_list);
02038    AST_RWLIST_REMOVE(&feature_list, feature, feature_entry);
02039    AST_RWLIST_UNLOCK(&feature_list);
02040 
02041    ast_free(feature);
02042 }
02043 
02044 /*! \brief Remove all features in the list */
02045 static void ast_unregister_features(void)
02046 {
02047    struct ast_call_feature *feature;
02048 
02049    AST_RWLIST_WRLOCK(&feature_list);
02050    while ((feature = AST_RWLIST_REMOVE_HEAD(&feature_list, feature_entry))) {
02051       ast_free(feature);
02052    }
02053    AST_RWLIST_UNLOCK(&feature_list);
02054 }
02055 
02056 /*! \brief find a call feature by name */
02057 static struct ast_call_feature *find_dynamic_feature(const char *name)
02058 {
02059    struct ast_call_feature *tmp;
02060 
02061    AST_RWLIST_TRAVERSE(&feature_list, tmp, feature_entry) {
02062       if (!strcasecmp(tmp->sname, name)) {
02063          break;
02064       }
02065    }
02066 
02067    return tmp;
02068 }
02069 
02070 /*! \brief Remove all feature groups in the list */
02071 static void ast_unregister_groups(void)
02072 {
02073    struct feature_group *fg;
02074    struct feature_group_exten *fge;
02075 
02076    AST_RWLIST_WRLOCK(&feature_groups);
02077    while ((fg = AST_LIST_REMOVE_HEAD(&feature_groups, entry))) {
02078       while ((fge = AST_LIST_REMOVE_HEAD(&fg->features, entry))) {
02079          ast_string_field_free_memory(fge);
02080          ast_free(fge);
02081       }
02082 
02083       ast_string_field_free_memory(fg);
02084       ast_free(fg);
02085    }
02086    AST_RWLIST_UNLOCK(&feature_groups);
02087 }
02088 
02089 /*! 
02090  * \brief Find a group by name 
02091  * \param name feature name
02092  * \retval feature group on success.
02093  * \retval NULL on failure.
02094 */
02095 static struct feature_group *find_group(const char *name)
02096 {
02097    struct feature_group *fg = NULL;
02098 
02099    AST_LIST_TRAVERSE(&feature_groups, fg, entry) {
02100       if (!strcasecmp(fg->gname, name))
02101          break;
02102    }
02103 
02104    return fg;
02105 }
02106 
02107 void ast_rdlock_call_features(void)
02108 {
02109    ast_rwlock_rdlock(&features_lock);
02110 }
02111 
02112 void ast_unlock_call_features(void)
02113 {
02114    ast_rwlock_unlock(&features_lock);
02115 }
02116 
02117 struct ast_call_feature *ast_find_call_feature(const char *name)
02118 {
02119    int x;
02120    for (x = 0; x < FEATURES_COUNT; x++) {
02121       if (!strcasecmp(name, builtin_features[x].sname))
02122          return &builtin_features[x];
02123    }
02124    return NULL;
02125 }
02126 
02127 /*!
02128  * \brief exec an app by feature 
02129  * \param chan,peer,config,code,sense,data
02130  *
02131  * Find a feature, determine which channel activated
02132  * \retval AST_FEATURE_RETURN_NO_HANGUP_PEER
02133  * \retval -1 error.
02134  * \retval -2 when an application cannot be found.
02135 */
02136 static int feature_exec_app(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
02137 {
02138    struct ast_app *app;
02139    struct ast_call_feature *feature = data;
02140    struct ast_channel *work, *idle;
02141    int res;
02142 
02143    if (!feature) { /* shouldn't ever happen! */
02144       ast_log(LOG_NOTICE, "Found feature before, but at execing we've lost it??\n");
02145       return -1; 
02146    }
02147 
02148    if (sense == FEATURE_SENSE_CHAN) {
02149       if (!ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLER))
02150          return AST_FEATURE_RETURN_KEEPTRYING;
02151       if (ast_test_flag(feature, AST_FEATURE_FLAG_ONSELF)) {
02152          work = chan;
02153          idle = peer;
02154       } else {
02155          work = peer;
02156          idle = chan;
02157       }
02158    } else {
02159       if (!ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLEE))
02160          return AST_FEATURE_RETURN_KEEPTRYING;
02161       if (ast_test_flag(feature, AST_FEATURE_FLAG_ONSELF)) {
02162          work = peer;
02163          idle = chan;
02164       } else {
02165          work = chan;
02166          idle = peer;
02167       }
02168    }
02169 
02170    if (!(app = pbx_findapp(feature->app))) {
02171       ast_log(LOG_WARNING, "Could not find application (%s)\n", feature->app);
02172       return -2;
02173    }
02174 
02175    ast_autoservice_start(idle);
02176    ast_autoservice_ignore(idle, AST_FRAME_DTMF_END);
02177    
02178    if (!ast_strlen_zero(feature->moh_class))
02179       ast_moh_start(idle, feature->moh_class, NULL);
02180 
02181    res = pbx_exec(work, app, feature->app_args);
02182 
02183    if (!ast_strlen_zero(feature->moh_class))
02184       ast_moh_stop(idle);
02185 
02186    ast_autoservice_stop(idle);
02187 
02188    if (res) {
02189       return AST_FEATURE_RETURN_SUCCESSBREAK;
02190    }
02191    return AST_FEATURE_RETURN_SUCCESS;  /*! \todo XXX should probably return res */
02192 }
02193 
02194 static void unmap_features(void)
02195 {
02196    int x;
02197 
02198    ast_rwlock_wrlock(&features_lock);
02199    for (x = 0; x < FEATURES_COUNT; x++)
02200       strcpy(builtin_features[x].exten, builtin_features[x].default_exten);
02201    ast_rwlock_unlock(&features_lock);
02202 }
02203 
02204 static int remap_feature(const char *name, const char *value)
02205 {
02206    int x, res = -1;
02207 
02208    ast_rwlock_wrlock(&features_lock);
02209    for (x = 0; x < FEATURES_COUNT; x++) {
02210       if (strcasecmp(builtin_features[x].sname, name))
02211          continue;
02212 
02213       ast_copy_string(builtin_features[x].exten, value, sizeof(builtin_features[x].exten));
02214       res = 0;
02215       break;
02216    }
02217    ast_rwlock_unlock(&features_lock);
02218 
02219    return res;
02220 }
02221 
02222 /*!
02223  * \brief Check the dynamic features
02224  * \param chan,peer,config,code,sense
02225  *
02226  * Lock features list, browse for code, unlock list
02227  * \retval res on success.
02228  * \retval -1 on failure.
02229 */
02230 static int feature_interpret(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense)
02231 {
02232    int x;
02233    struct ast_flags features;
02234    struct ast_call_feature *feature = NULL;
02235    struct feature_group *fg = NULL;
02236    struct feature_group_exten *fge;
02237    const char *peer_dynamic_features, *chan_dynamic_features;
02238    char dynamic_features_buf[128];
02239    char *tmp, *tok;
02240    int res = AST_FEATURE_RETURN_PASSDIGITS;
02241    int feature_detected = 0;
02242 
02243    if (sense == FEATURE_SENSE_CHAN) {
02244       ast_copy_flags(&features, &(config->features_caller), AST_FLAGS_ALL);
02245    }
02246    else {
02247       ast_copy_flags(&features, &(config->features_callee), AST_FLAGS_ALL);
02248    }
02249 
02250    ast_channel_lock(peer);
02251    peer_dynamic_features = ast_strdupa(S_OR(pbx_builtin_getvar_helper(peer, "DYNAMIC_FEATURES"),""));
02252    ast_channel_unlock(peer);
02253 
02254    ast_channel_lock(chan);
02255    chan_dynamic_features = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "DYNAMIC_FEATURES"),""));
02256    ast_channel_unlock(chan);
02257 
02258    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,""));
02259 
02260    ast_debug(3, "Feature interpret: chan=%s, peer=%s, code=%s, sense=%d, features=%d, dynamic=%s\n", chan->name, peer->name, code, sense, features.flags, dynamic_features_buf);
02261 
02262    ast_rwlock_rdlock(&features_lock);
02263    for (x = 0; x < FEATURES_COUNT; x++) {
02264       if ((ast_test_flag(&features, builtin_features[x].feature_mask)) &&
02265           !ast_strlen_zero(builtin_features[x].exten)) {
02266          /* Feature is up for consideration */
02267          if (!strcmp(builtin_features[x].exten, code)) {
02268             ast_debug(3, "Feature detected: fname=%s sname=%s exten=%s\n", builtin_features[x].fname, builtin_features[x].sname, builtin_features[x].exten);
02269             res = builtin_features[x].operation(chan, peer, config, code, sense, NULL);
02270             feature_detected = 1;
02271             break;
02272          } else if (!strncmp(builtin_features[x].exten, code, strlen(code))) {
02273             if (res == AST_FEATURE_RETURN_PASSDIGITS)
02274                res = AST_FEATURE_RETURN_STOREDIGITS;
02275          }
02276       }
02277    }
02278    ast_rwlock_unlock(&features_lock);
02279 
02280    if (ast_strlen_zero(dynamic_features_buf) || feature_detected)
02281       return res;
02282 
02283    tmp = dynamic_features_buf;
02284 
02285    while ((tok = strsep(&tmp, "#"))) {
02286       AST_RWLIST_RDLOCK(&feature_groups);
02287 
02288       fg = find_group(tok);
02289 
02290       if (fg) {
02291          AST_LIST_TRAVERSE(&fg->features, fge, entry) {
02292             if (!strcmp(fge->exten, code)) {
02293                res = fge->feature->operation(chan, peer, config, code, sense, fge->feature);
02294                memcpy(feature, fge->feature, sizeof(feature));
02295                if (res != AST_FEATURE_RETURN_KEEPTRYING) {
02296                   AST_RWLIST_UNLOCK(&feature_groups);
02297                   break;
02298                }
02299                res = AST_FEATURE_RETURN_PASSDIGITS;
02300             } else if (!strncmp(fge->exten, code, strlen(code))) {
02301                res = AST_FEATURE_RETURN_STOREDIGITS;
02302             }
02303          }
02304          if (fge) {
02305             break;
02306          }
02307       }
02308 
02309       AST_RWLIST_UNLOCK(&feature_groups);
02310 
02311       AST_RWLIST_RDLOCK(&feature_list);
02312 
02313       if (!(feature = find_dynamic_feature(tok))) {
02314          AST_RWLIST_UNLOCK(&feature_list);
02315          continue;
02316       }
02317          
02318       /* Feature is up for consideration */
02319       if (!strcmp(feature->exten, code)) {
02320          ast_verb(3, " Feature Found: %s exten: %s\n",feature->sname, tok);
02321          res = feature->operation(chan, peer, config, code, sense, feature);
02322          if (res != AST_FEATURE_RETURN_KEEPTRYING) {
02323             AST_RWLIST_UNLOCK(&feature_list);
02324             break;
02325          }
02326          res = AST_FEATURE_RETURN_PASSDIGITS;
02327       } else if (!strncmp(feature->exten, code, strlen(code)))
02328          res = AST_FEATURE_RETURN_STOREDIGITS;
02329 
02330       AST_RWLIST_UNLOCK(&feature_list);
02331    }
02332    
02333    return res;
02334 }
02335 
02336 static void set_config_flags(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config)
02337 {
02338    int x;
02339    
02340    ast_clear_flag(config, AST_FLAGS_ALL);
02341 
02342    ast_rwlock_rdlock(&features_lock);
02343    for (x = 0; x < FEATURES_COUNT; x++) {
02344       if (!ast_test_flag(builtin_features + x, AST_FEATURE_FLAG_NEEDSDTMF))
02345          continue;
02346 
02347       if (ast_test_flag(&(config->features_caller), builtin_features[x].feature_mask))
02348          ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
02349 
02350       if (ast_test_flag(&(config->features_callee), builtin_features[x].feature_mask))
02351          ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
02352    }
02353    ast_rwlock_unlock(&features_lock);
02354    
02355    if (chan && peer && !(ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_0) && ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_1))) {
02356       const char *dynamic_features = pbx_builtin_getvar_helper(chan, "DYNAMIC_FEATURES");
02357 
02358       if (dynamic_features) {
02359          char *tmp = ast_strdupa(dynamic_features);
02360          char *tok;
02361          struct ast_call_feature *feature;
02362 
02363          /* while we have a feature */
02364          while ((tok = strsep(&tmp, "#"))) {
02365             struct feature_group *fg;
02366 
02367             AST_RWLIST_RDLOCK(&feature_groups);
02368             AST_RWLIST_TRAVERSE(&feature_groups, fg, entry) {
02369                struct feature_group_exten *fge;
02370 
02371                AST_LIST_TRAVERSE(&fg->features, fge, entry) {
02372                   if (ast_test_flag(fge->feature, AST_FEATURE_FLAG_BYCALLER)) {
02373                      ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
02374                   }
02375                   if (ast_test_flag(fge->feature, AST_FEATURE_FLAG_BYCALLEE)) {
02376                      ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
02377                   }
02378                }
02379             }
02380             AST_RWLIST_UNLOCK(&feature_groups);
02381 
02382             AST_RWLIST_RDLOCK(&feature_list);
02383             if ((feature = find_dynamic_feature(tok)) && ast_test_flag(feature, AST_FEATURE_FLAG_NEEDSDTMF)) {
02384                if (ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLER)) {
02385                   ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
02386                }
02387                if (ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLEE)) {
02388                   ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
02389                }
02390             }
02391             AST_RWLIST_UNLOCK(&feature_list);
02392          }
02393       }
02394    }
02395 }
02396 
02397 /*!
02398  * \internal
02399  * \brief Get feature and dial.
02400  *
02401  * \param caller Channel to represent as the calling channel for the dialed channel.
02402  * \param caller_name Original caller channel name.
02403  * \param transferee Channel that the dialed channel will be transferred to.
02404  * \param type Channel technology type to dial.
02405  * \param format Codec formats for dialed channel.
02406  * \param data Dialed channel extra parameters for ast_request() and ast_call().
02407  * \param timeout Time limit for dialed channel to answer in ms. Must be greater than zero.
02408  * \param outstate Status of dialed channel if unsuccessful.
02409  * \param cid_num CallerID number to give dialed channel.
02410  * \param cid_name CallerID name to give dialed channel.
02411  * \param language Language of the caller.
02412  *
02413  * \note
02414  * outstate can be:
02415  * 0, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION,
02416  * AST_CONTROL_ANSWER, or AST_CONTROL_UNHOLD.  If
02417  * AST_CONTROL_UNHOLD then the caller channel cancelled the
02418  * transfer or the dialed channel did not answer before the
02419  * timeout.
02420  *
02421  * \details
02422  * Request channel, set channel variables, initiate call,
02423  * check if they want to disconnect, go into loop, check if timeout has elapsed,
02424  * check if person to be transfered hung up, check for answer break loop,
02425  * set cdr return channel.
02426  *
02427  * \retval Channel Connected channel for transfer.
02428  * \retval NULL on failure to get third party connected.
02429  *
02430  * \note This is similar to __ast_request_and_dial() in channel.c
02431  */
02432 static struct ast_channel *feature_request_and_dial(struct ast_channel *caller,
02433    const char *caller_name, struct ast_channel *transferee, const char *type,
02434    int format, void *data, int timeout, int *outstate, const char *cid_num,
02435    const char *cid_name, const char *language)
02436 {
02437    int state = 0;
02438    int cause = 0;
02439    int to;
02440    int caller_hungup;
02441    int transferee_hungup;
02442    struct ast_channel *chan;
02443    struct ast_channel *monitor_chans[3];
02444    struct ast_channel *active_channel;
02445    int ready = 0;
02446    struct timeval started;
02447    int x, len = 0;
02448    char *disconnect_code = NULL, *dialed_code = NULL;
02449    struct ast_frame *f;
02450    AST_LIST_HEAD_NOLOCK(, ast_frame) deferred_frames;
02451 
02452    caller_hungup = ast_check_hangup(caller);
02453 
02454    if (!(chan = ast_request(type, format, data, &cause))) {
02455       ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
02456       switch (cause) {
02457       case AST_CAUSE_BUSY:
02458          state = AST_CONTROL_BUSY;
02459          break;
02460       case AST_CAUSE_CONGESTION:
02461          state = AST_CONTROL_CONGESTION;
02462          break;
02463       default:
02464          state = 0;
02465          break;
02466       }
02467       goto done;
02468    }
02469 
02470    ast_set_callerid(chan, cid_num, cid_name, cid_num);
02471    ast_string_field_set(chan, language, language);
02472    ast_channel_inherit_variables(caller, chan);
02473    pbx_builtin_setvar_helper(chan, "TRANSFERERNAME", caller_name);
02474 
02475    if (ast_call(chan, data, timeout)) {
02476       ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
02477       switch (chan->hangupcause) {
02478       case AST_CAUSE_BUSY:
02479          state = AST_CONTROL_BUSY;
02480          break;
02481       case AST_CAUSE_CONGESTION:
02482          state = AST_CONTROL_CONGESTION;
02483          break;
02484       default:
02485          state = 0;
02486          break;
02487       }
02488       goto done;
02489    }
02490 
02491    /* support dialing of the featuremap disconnect code while performing an attended tranfer */
02492    ast_rwlock_rdlock(&features_lock);
02493    for (x = 0; x < FEATURES_COUNT; x++) {
02494       if (strcasecmp(builtin_features[x].sname, "disconnect"))
02495          continue;
02496 
02497       disconnect_code = builtin_features[x].exten;
02498       len = strlen(disconnect_code) + 1;
02499       dialed_code = alloca(len);
02500       memset(dialed_code, 0, len);
02501       break;
02502    }
02503    ast_rwlock_unlock(&features_lock);
02504    x = 0;
02505    started = ast_tvnow();
02506    to = timeout;
02507    AST_LIST_HEAD_INIT_NOLOCK(&deferred_frames);
02508 
02509    ast_poll_channel_add(caller, chan);
02510 
02511    transferee_hungup = 0;
02512    while (!ast_check_hangup(transferee) && (chan->_state != AST_STATE_UP)) {
02513       int num_chans = 0;
02514 
02515       monitor_chans[num_chans++] = transferee;
02516       monitor_chans[num_chans++] = chan;
02517       if (!caller_hungup) {
02518          if (ast_check_hangup(caller)) {
02519             caller_hungup = 1;
02520 
02521 #if defined(ATXFER_NULL_TECH)
02522             /* Change caller's name to ensure that it will remain unique. */
02523             set_new_chan_name(caller);
02524 
02525             /*
02526              * Get rid of caller's physical technology so it is free for
02527              * other calls.
02528              */
02529             set_null_chan_tech(caller);
02530 #endif   /* defined(ATXFER_NULL_TECH) */
02531          } else {
02532             /* caller is not hungup so monitor it. */
02533             monitor_chans[num_chans++] = caller;
02534          }
02535       }
02536 
02537       /* see if the timeout has been violated */
02538       if (ast_tvdiff_ms(ast_tvnow(), started) > timeout) {
02539          state = AST_CONTROL_UNHOLD;
02540          ast_log(LOG_NOTICE, "We exceeded our AT-timeout for %s\n", chan->name);
02541          break; /*doh! timeout*/
02542       }
02543 
02544       active_channel = ast_waitfor_n(monitor_chans, num_chans, &to);
02545       if (!active_channel)
02546          continue;
02547 
02548       f = NULL;
02549       if (transferee == active_channel) {
02550          struct ast_frame *dup_f;
02551 
02552          f = ast_read(transferee);
02553          if (f == NULL) { /*doh! where'd he go?*/
02554             transferee_hungup = 1;
02555             state = 0;
02556             break;
02557          }
02558          if (ast_is_deferrable_frame(f)) {
02559             dup_f = ast_frisolate(f);
02560             if (dup_f) {
02561                if (dup_f == f) {
02562                   f = NULL;
02563                }
02564                AST_LIST_INSERT_HEAD(&deferred_frames, dup_f, frame_list);
02565             }
02566          }
02567       } else if (chan == active_channel) {
02568          if (!ast_strlen_zero(chan->call_forward)) {
02569             state = 0;
02570             chan = ast_call_forward(caller, chan, NULL, format, NULL, &state);
02571             if (!chan) {
02572                break;
02573             }
02574             continue;
02575          }
02576          f = ast_read(chan);
02577          if (f == NULL) { /*doh! where'd he go?*/
02578             switch (chan->hangupcause) {
02579             case AST_CAUSE_BUSY:
02580                state = AST_CONTROL_BUSY;
02581                break;
02582             case AST_CAUSE_CONGESTION:
02583                state = AST_CONTROL_CONGESTION;
02584                break;
02585             default:
02586                state = 0;
02587                break;
02588             }
02589             break;
02590          }
02591 
02592          if (f->frametype == AST_FRAME_CONTROL) {
02593             if (f->subclass == AST_CONTROL_RINGING) {
02594                ast_verb(3, "%s is ringing\n", chan->name);
02595                ast_indicate(caller, AST_CONTROL_RINGING);
02596             } else if (f->subclass == AST_CONTROL_BUSY) {
02597                state = f->subclass;
02598                ast_verb(3, "%s is busy\n", chan->name);
02599                ast_indicate(caller, AST_CONTROL_BUSY);
02600                ast_frfree(f);
02601                break;
02602             } else if (f->subclass == AST_CONTROL_CONGESTION) {
02603                state = f->subclass;
02604                ast_verb(3, "%s is congested\n", chan->name);
02605                ast_indicate(caller, AST_CONTROL_CONGESTION);
02606                ast_frfree(f);
02607                break;
02608             } else if (f->subclass == AST_CONTROL_ANSWER) {
02609                /* This is what we are hoping for */
02610                state = f->subclass;
02611                ast_frfree(f);
02612                ready=1;
02613                break;
02614             } else if (f->subclass != -1 && f->subclass != AST_CONTROL_PROGRESS) {
02615                ast_log(LOG_NOTICE, "Don't know what to do about control frame: %d\n", f->subclass);
02616             }
02617             /* else who cares */
02618          } else if (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO) {
02619             ast_write(caller, f);
02620          }
02621       } else if (caller == active_channel) {
02622          f = ast_read(caller);
02623          if (f) {
02624             if (f->frametype == AST_FRAME_DTMF) {
02625                dialed_code[x++] = f->subclass;
02626                dialed_code[x] = '\0';
02627                if (strlen(dialed_code) == len) {
02628                   x = 0;
02629                } else if (x && strncmp(dialed_code, disconnect_code, x)) {
02630                   x = 0;
02631                   dialed_code[x] = '\0';
02632                }
02633                if (*dialed_code && !strcmp(dialed_code, disconnect_code)) {
02634                   /* Caller Canceled the call */
02635                   state = AST_CONTROL_UNHOLD;
02636                   ast_frfree(f);
02637                   break;
02638                }
02639             } else if (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO) {
02640                ast_write(chan, f);
02641             }
02642          }
02643       }
02644       if (f)
02645          ast_frfree(f);
02646    } /* end while */
02647 
02648    ast_poll_channel_del(caller, chan);
02649 
02650    /*
02651     * We need to free all the deferred frames, but we only need to
02652     * queue the deferred frames if no hangup was received.
02653     */
02654    ast_channel_lock(transferee);
02655    transferee_hungup = (transferee_hungup || ast_check_hangup(transferee));
02656    while ((f = AST_LIST_REMOVE_HEAD(&deferred_frames, frame_list))) {
02657       if (!transferee_hungup) {
02658          ast_queue_frame_head(transferee, f);
02659       }
02660       ast_frfree(f);
02661    }
02662    ast_channel_unlock(transferee);
02663 
02664 done:
02665    ast_indicate(caller, -1);
02666    if (chan && (ready || chan->_state == AST_STATE_UP)) {
02667       state = AST_CONTROL_ANSWER;
02668    } else if (chan) {
02669       ast_hangup(chan);
02670       chan = NULL;
02671    }
02672 
02673    if (outstate)
02674       *outstate = state;
02675 
02676    return chan;
02677 }
02678 
02679 /*!
02680  * \brief return the first unlocked cdr in a possible chain
02681 */
02682 static struct ast_cdr *pick_unlocked_cdr(struct ast_cdr *cdr)
02683 {
02684    struct ast_cdr *cdr_orig = cdr;
02685    while (cdr) {
02686       if (!ast_test_flag(cdr,AST_CDR_FLAG_LOCKED))
02687          return cdr;
02688       cdr = cdr->next;
02689    }
02690    return cdr_orig; /* everybody LOCKED or some other weirdness, like a NULL */
02691 }
02692 
02693 static void set_bridge_features_on_config(struct ast_bridge_config *config, const char *features)
02694 {
02695    const char *feature;
02696 
02697    if (ast_strlen_zero(features)) {
02698       return;
02699    }
02700 
02701    for (feature = features; *feature; feature++) {
02702       switch (*feature) {
02703       case 'T' :
02704       case 't' :
02705          ast_set_flag(&(config->features_caller), AST_FEATURE_REDIRECT);
02706          break;
02707       case 'K' :
02708       case 'k' :
02709          ast_set_flag(&(config->features_caller), AST_FEATURE_PARKCALL);
02710          break;
02711       case 'H' :
02712       case 'h' :
02713          ast_set_flag(&(config->features_caller), AST_FEATURE_DISCONNECT);
02714          break;
02715       case 'W' :
02716       case 'w' :
02717          ast_set_flag(&(config->features_caller), AST_FEATURE_AUTOMON);
02718          break;
02719       default :
02720          ast_log(LOG_WARNING, "Skipping unknown feature code '%c'\n", *feature);
02721       }
02722    }
02723 }
02724 
02725 static void add_features_datastores(struct ast_channel *caller, struct ast_channel *callee, struct ast_bridge_config *config)
02726 {
02727    struct ast_datastore *ds_callee_features = NULL, *ds_caller_features = NULL;
02728    struct ast_dial_features *callee_features = NULL, *caller_features = NULL;
02729 
02730    ast_channel_lock(caller);
02731    ds_caller_features = ast_channel_datastore_find(caller, &dial_features_info, NULL);
02732    ast_channel_unlock(caller);
02733    if (!ds_caller_features) {
02734       if (!(ds_caller_features = ast_datastore_alloc(&dial_features_info, NULL))) {
02735          ast_log(LOG_WARNING, "Unable to create channel datastore for caller features. Aborting!\n");
02736          return;
02737       }
02738       if (!(caller_features = ast_calloc(1, sizeof(*caller_features)))) {
02739          ast_log(LOG_WARNING, "Unable to allocate memory for callee feature flags. Aborting!\n");
02740          ast_datastore_free(ds_caller_features);
02741          return;
02742       }
02743       ds_caller_features->inheritance = DATASTORE_INHERIT_FOREVER;
02744       caller_features->is_caller = 1;
02745       ast_copy_flags(&(caller_features->features_callee), &(config->features_callee), AST_FLAGS_ALL);
02746       ast_copy_flags(&(caller_features->features_caller), &(config->features_caller), AST_FLAGS_ALL);
02747       ds_caller_features->data = caller_features;
02748       ast_channel_lock(caller);
02749       ast_channel_datastore_add(caller, ds_caller_features);
02750       ast_channel_unlock(caller);
02751    } else {
02752       /* If we don't return here, then when we do a builtin_atxfer we will copy the disconnect
02753        * flags over from the atxfer to the caller */
02754       return;
02755    }
02756 
02757    ast_channel_lock(callee);
02758    ds_callee_features = ast_channel_datastore_find(callee, &dial_features_info, NULL);
02759    ast_channel_unlock(callee);
02760    if (!ds_callee_features) {
02761       if (!(ds_callee_features = ast_datastore_alloc(&dial_features_info, NULL))) {
02762          ast_log(LOG_WARNING, "Unable to create channel datastore for callee features. Aborting!\n");
02763          return;
02764       }
02765       if (!(callee_features = ast_calloc(1, sizeof(*callee_features)))) {
02766          ast_log(LOG_WARNING, "Unable to allocate memory for callee feature flags. Aborting!\n");
02767          ast_datastore_free(ds_callee_features);
02768          return;
02769       }
02770       ds_callee_features->inheritance = DATASTORE_INHERIT_FOREVER;
02771       callee_features->is_caller = 0;
02772       ast_copy_flags(&(callee_features->features_callee), &(config->features_caller), AST_FLAGS_ALL);
02773       ast_copy_flags(&(callee_features->features_caller), &(config->features_callee), AST_FLAGS_ALL);
02774       ds_callee_features->data = callee_features;
02775       ast_channel_lock(callee);
02776       ast_channel_datastore_add(callee, ds_callee_features);
02777       ast_channel_unlock(callee);
02778    }
02779 
02780    return;
02781 }
02782 
02783 /*!
02784  * \brief bridge the call and set CDR
02785  * \param chan,peer,config
02786  * 
02787  * Set start time, check for two channels,check if monitor on
02788  * check for feature activation, create new CDR
02789  * \retval res on success.
02790  * \retval -1 on failure to bridge.
02791 */
02792 int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast_bridge_config *config)
02793 {
02794    /* Copy voice back and forth between the two channels.  Give the peer
02795       the ability to transfer calls with '#<extension' syntax. */
02796    struct ast_frame *f;
02797    struct ast_channel *who;
02798    char chan_featurecode[FEATURE_MAX_LEN + 1]="";
02799    char peer_featurecode[FEATURE_MAX_LEN + 1]="";
02800    char orig_channame[AST_MAX_EXTENSION];
02801    char orig_peername[AST_MAX_EXTENSION];
02802    int res;
02803    int diff;
02804    int hasfeatures=0;
02805    int hadfeatures=0;
02806    int autoloopflag;
02807    struct ast_option_header *aoh;
02808    struct ast_bridge_config backup_config;
02809    struct ast_cdr *bridge_cdr = NULL;
02810    struct ast_cdr *orig_peer_cdr = NULL;
02811    struct ast_cdr *chan_cdr = chan->cdr; /* the proper chan cdr, if there are forked cdrs */
02812    struct ast_cdr *peer_cdr = peer->cdr; /* the proper chan cdr, if there are forked cdrs */
02813    struct ast_cdr *new_chan_cdr = NULL; /* the proper chan cdr, if there are forked cdrs */
02814    struct ast_cdr *new_peer_cdr = NULL; /* the proper chan cdr, if there are forked cdrs */
02815 
02816    memset(&backup_config, 0, sizeof(backup_config));
02817 
02818    config->start_time = ast_tvnow();
02819 
02820    if (chan && peer) {
02821       pbx_builtin_setvar_helper(chan, "BRIDGEPEER", peer->name);
02822       pbx_builtin_setvar_helper(peer, "BRIDGEPEER", chan->name);
02823    } else if (chan) {
02824       pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", NULL);
02825    }
02826 
02827    set_bridge_features_on_config(config, pbx_builtin_getvar_helper(chan, "BRIDGE_FEATURES"));
02828    add_features_datastores(chan, peer, config);
02829 
02830    /* This is an interesting case.  One example is if a ringing channel gets redirected to
02831     * an extension that picks up a parked call.  This will make sure that the call taken
02832     * out of parking gets told that the channel it just got bridged to is still ringing. */
02833    if (chan->_state == AST_STATE_RINGING && peer->visible_indication != AST_CONTROL_RINGING) {
02834       ast_indicate(peer, AST_CONTROL_RINGING);
02835    }
02836 
02837    if (monitor_ok) {
02838       const char *monitor_exec;
02839       struct ast_channel *src = NULL;
02840       if (!monitor_app) { 
02841          if (!(monitor_app = pbx_findapp("Monitor")))
02842             monitor_ok=0;
02843       }
02844       if ((monitor_exec = pbx_builtin_getvar_helper(chan, "AUTO_MONITOR"))) 
02845          src = chan;
02846       else if ((monitor_exec = pbx_builtin_getvar_helper(peer, "AUTO_MONITOR")))
02847          src = peer;
02848       if (monitor_app && src) {
02849          char *tmp = ast_strdupa(monitor_exec);
02850          pbx_exec(src, monitor_app, tmp);
02851       }
02852    }
02853 
02854    set_config_flags(chan, peer, config);
02855    config->firstpass = 1;
02856 
02857    /* Answer if need be */
02858    if (chan->_state != AST_STATE_UP) {
02859       if (ast_raw_answer(chan, 1)) {
02860          return -1;
02861       }
02862    }
02863 
02864    ast_copy_string(orig_channame,chan->name,sizeof(orig_channame));
02865    ast_copy_string(orig_peername,peer->name,sizeof(orig_peername));
02866    orig_peer_cdr = peer_cdr;
02867    
02868    if (!chan_cdr || (chan_cdr && !ast_test_flag(chan_cdr, AST_CDR_FLAG_POST_DISABLED))) {
02869       
02870       if (chan_cdr) {
02871          ast_set_flag(chan_cdr, AST_CDR_FLAG_MAIN);
02872          ast_cdr_update(chan);
02873          bridge_cdr = ast_cdr_dup(chan_cdr);
02874          /* rip any forked CDR's off of the chan_cdr and attach
02875           * them to the bridge_cdr instead */
02876          bridge_cdr->next = chan_cdr->next;
02877          chan_cdr->next = NULL;
02878          ast_copy_string(bridge_cdr->lastapp, S_OR(chan->appl, ""), sizeof(bridge_cdr->lastapp));
02879          ast_copy_string(bridge_cdr->lastdata, S_OR(chan->data, ""), sizeof(bridge_cdr->lastdata));
02880          if (peer_cdr && !ast_strlen_zero(peer_cdr->userfield)) {
02881             ast_copy_string(bridge_cdr->userfield, peer_cdr->userfield, sizeof(bridge_cdr->userfield));
02882          }
02883          ast_cdr_setaccount(peer, chan->accountcode);
02884 
02885       } else {
02886          /* better yet, in a xfer situation, find out why the chan cdr got zapped (pun unintentional) */
02887          bridge_cdr = ast_cdr_alloc(); /* this should be really, really rare/impossible? */
02888          ast_copy_string(bridge_cdr->channel, chan->name, sizeof(bridge_cdr->channel));
02889          ast_copy_string(bridge_cdr->dstchannel, peer->name, sizeof(bridge_cdr->dstchannel));
02890          ast_copy_string(bridge_cdr->uniqueid, chan->uniqueid, sizeof(bridge_cdr->uniqueid));
02891          ast_copy_string(bridge_cdr->lastapp, S_OR(chan->appl, ""), sizeof(bridge_cdr->lastapp));
02892          ast_copy_string(bridge_cdr->lastdata, S_OR(chan->data, ""), sizeof(bridge_cdr->lastdata));
02893          ast_cdr_setcid(bridge_cdr, chan);
02894          bridge_cdr->disposition = (chan->_state == AST_STATE_UP) ?  AST_CDR_ANSWERED : AST_CDR_NULL;
02895          bridge_cdr->amaflags = chan->amaflags ? chan->amaflags :  ast_default_amaflags;
02896          ast_copy_string(bridge_cdr->accountcode, chan->accountcode, sizeof(bridge_cdr->accountcode));
02897          /* Destination information */
02898          ast_copy_string(bridge_cdr->dst, chan->exten, sizeof(bridge_cdr->dst));
02899          ast_copy_string(bridge_cdr->dcontext, chan->context, sizeof(bridge_cdr->dcontext));
02900          if (peer_cdr) {
02901             bridge_cdr->start = peer_cdr->start;
02902             ast_copy_string(bridge_cdr->userfield, peer_cdr->userfield, sizeof(bridge_cdr->userfield));
02903          } else {
02904             ast_cdr_start(bridge_cdr);
02905          }
02906       }
02907       ast_debug(4,"bridge answer set, chan answer set\n");
02908       /* peer_cdr->answer will be set when a macro runs on the peer;
02909          in that case, the bridge answer will be delayed while the
02910          macro plays on the peer channel. The peer answered the call
02911          before the macro started playing. To the phone system,
02912          this is billable time for the call, even tho the caller
02913          hears nothing but ringing while the macro does its thing. */
02914 
02915       /* Another case where the peer cdr's time will be set, is when
02916          A self-parks by pickup up phone and dialing 700, then B
02917          picks up A by dialing its parking slot; there may be more 
02918          practical paths that get the same result, tho... in which
02919          case you get the previous answer time from the Park... which
02920          is before the bridge's start time, so I added in the 
02921          tvcmp check to the if below */
02922 
02923       if (peer_cdr && !ast_tvzero(peer_cdr->answer) && ast_tvcmp(peer_cdr->answer, bridge_cdr->start) >= 0) {
02924          ast_cdr_setanswer(bridge_cdr, peer_cdr->answer);
02925          ast_cdr_setdisposition(bridge_cdr, peer_cdr->disposition);
02926          if (chan_cdr) {
02927             ast_cdr_setanswer(chan_cdr, peer_cdr->answer);
02928             ast_cdr_setdisposition(chan_cdr, peer_cdr->disposition);
02929          }
02930       } else {
02931          ast_cdr_answer(bridge_cdr);
02932          if (chan_cdr) {
02933             ast_cdr_answer(chan_cdr); /* for the sake of cli status checks */
02934          }
02935       }
02936       if (ast_test_flag(chan,AST_FLAG_BRIDGE_HANGUP_DONT) && (chan_cdr || peer_cdr)) {
02937          if (chan_cdr) {
02938             ast_set_flag(chan_cdr, AST_CDR_FLAG_BRIDGED);
02939          }
02940          if (peer_cdr) {
02941             ast_set_flag(peer_cdr, AST_CDR_FLAG_BRIDGED);
02942          }
02943       }
02944       /* the DIALED flag may be set if a dialed channel is transfered
02945        * and then bridged to another channel.  In order for the
02946        * bridge CDR to be written, the DIALED flag must not be
02947        * present. */
02948       ast_clear_flag(bridge_cdr, AST_CDR_FLAG_DIALED);
02949    }
02950    for (;;) {
02951       struct ast_channel *other; /* used later */
02952    
02953       res = ast_channel_bridge(chan, peer, config, &f, &who);
02954       
02955       /* When frame is not set, we are probably involved in a situation
02956          where we've timed out.
02957          When frame is set, we'll come this code twice; once for DTMF_BEGIN
02958          and also for DTMF_END. If we flow into the following 'if' for both, then 
02959          our wait times are cut in half, as both will subtract from the
02960          feature_timer. Not good!
02961       */
02962       if (config->feature_timer && (!f || f->frametype == AST_FRAME_DTMF_END)) {
02963          /* Update time limit for next pass */
02964          diff = ast_tvdiff_ms(ast_tvnow(), config->start_time);
02965          if (res == AST_BRIDGE_RETRY) {
02966             /* The feature fully timed out but has not been updated. Skip
02967              * the potential round error from the diff calculation and
02968              * explicitly set to expired. */
02969             config->feature_timer = -1;
02970          } else {
02971             config->feature_timer -= diff;
02972          }
02973 
02974          if (hasfeatures) {
02975             /* Running on backup config, meaning a feature might be being
02976                activated, but that's no excuse to keep things going 
02977                indefinitely! */
02978             if (backup_config.feature_timer && ((backup_config.feature_timer -= diff) <= 0)) {
02979                ast_debug(1, "Timed out, realtime this time!\n");
02980                config->feature_timer = 0;
02981                who = chan;
02982                if (f)
02983                   ast_frfree(f);
02984                f = NULL;
02985                res = 0;
02986             } else if (config->feature_timer <= 0) {
02987                /* Not *really* out of time, just out of time for
02988                   digits to come in for features. */
02989                ast_debug(1, "Timed out for feature!\n");
02990                if (!ast_strlen_zero(peer_featurecode)) {
02991                   ast_dtmf_stream(chan, peer, peer_featurecode, 0, 0);
02992                   memset(peer_featurecode, 0, sizeof(peer_featurecode));
02993                }
02994                if (!ast_strlen_zero(chan_featurecode)) {
02995                   ast_dtmf_stream(peer, chan, chan_featurecode, 0, 0);
02996                   memset(chan_featurecode, 0, sizeof(chan_featurecode));
02997                }
02998                if (f)
02999                   ast_frfree(f);
03000                hasfeatures = !ast_strlen_zero(chan_featurecode) || !ast_strlen_zero(peer_featurecode);
03001                if (!hasfeatures) {
03002                   /* Restore original (possibly time modified) bridge config */
03003                   memcpy(config, &backup_config, sizeof(struct ast_bridge_config));
03004                   memset(&backup_config, 0, sizeof(backup_config));
03005                }
03006                hadfeatures = hasfeatures;
03007                /* Continue as we were */
03008                continue;
03009             } else if (!f) {
03010                /* The bridge returned without a frame and there is a feature in progress.
03011                 * However, we don't think the feature has quite yet timed out, so just
03012                 * go back into the bridge. */
03013                continue;
03014             }
03015          } else {
03016             if (config->feature_timer <=0) {
03017                /* We ran out of time */
03018                config->feature_timer = 0;
03019                who = chan;
03020                if (f)
03021                   ast_frfree(f);
03022                f = NULL;
03023                res = 0;
03024             }
03025          }
03026       }
03027       if (res < 0) {
03028          if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_test_flag(peer, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan) && !ast_check_hangup(peer))
03029             ast_log(LOG_WARNING, "Bridge failed on channels %s and %s\n", chan->name, peer->name);
03030          goto before_you_go;
03031       }
03032       
03033       if (!f || (f->frametype == AST_FRAME_CONTROL &&
03034             (f->subclass == AST_CONTROL_HANGUP || f->subclass == AST_CONTROL_BUSY || 
03035                f->subclass == AST_CONTROL_CONGESTION))) {
03036          res = -1;
03037          break;
03038       }
03039       /* many things should be sent to the 'other' channel */
03040       other = (who == chan) ? peer : chan;
03041       if (f->frametype == AST_FRAME_CONTROL) {
03042          switch (f->subclass) {
03043          case AST_CONTROL_RINGING:
03044          case AST_CONTROL_FLASH:
03045          case -1:
03046             ast_indicate(other, f->subclass);
03047             break;
03048          case AST_CONTROL_HOLD:
03049          case AST_CONTROL_UNHOLD:
03050             ast_indicate_data(other, f->subclass, f->data.ptr, f->datalen);
03051             break;
03052          case AST_CONTROL_OPTION:
03053             aoh = f->data.ptr;
03054             /* Forward option Requests */
03055             if (aoh && aoh->flag == AST_OPTION_FLAG_REQUEST) {
03056                ast_channel_setoption(other, ntohs(aoh->option), aoh->data, 
03057                   f->datalen - sizeof(struct ast_option_header), 0);
03058             }
03059             break;
03060          }
03061       } else if (f->frametype == AST_FRAME_DTMF_BEGIN) {
03062          /* eat it */
03063       } else if (f->frametype == AST_FRAME_DTMF) {
03064          char *featurecode;
03065          int sense;
03066 
03067          hadfeatures = hasfeatures;
03068          /* This cannot overrun because the longest feature is one shorter than our buffer */
03069          if (who == chan) {
03070             sense = FEATURE_SENSE_CHAN;
03071             featurecode = chan_featurecode;
03072          } else  {
03073             sense = FEATURE_SENSE_PEER;
03074             featurecode = peer_featurecode;
03075          }
03076          /*! append the event to featurecode. we rely on the string being zero-filled, and
03077           * not overflowing it. 
03078           * \todo XXX how do we guarantee the latter ?
03079           */
03080          featurecode[strlen(featurecode)] = f->subclass;
03081          /* Get rid of the frame before we start doing "stuff" with the channels */
03082          ast_frfree(f);
03083          f = NULL;
03084          config->feature_timer = backup_config.feature_timer;
03085          res = feature_interpret(chan, peer, config, featurecode, sense);
03086          switch(res) {
03087          case AST_FEATURE_RETURN_PASSDIGITS:
03088             ast_dtmf_stream(other, who, featurecode, 0, 0);
03089             /* Fall through */
03090          case AST_FEATURE_RETURN_SUCCESS:
03091             memset(featurecode, 0, sizeof(chan_featurecode));
03092             break;
03093          }
03094          if (res >= AST_FEATURE_RETURN_PASSDIGITS) {
03095             res = 0;
03096          } else 
03097             break;
03098          hasfeatures = !ast_strlen_zero(chan_featurecode) || !ast_strlen_zero(peer_featurecode);
03099          if (hadfeatures && !hasfeatures) {
03100             /* Restore backup */
03101             memcpy(config, &backup_config, sizeof(struct ast_bridge_config));
03102             memset(&backup_config, 0, sizeof(struct ast_bridge_config));
03103          } else if (hasfeatures) {
03104             if (!hadfeatures) {
03105                /* Backup configuration */
03106                memcpy(&backup_config, config, sizeof(struct ast_bridge_config));
03107                /* Setup temporary config options */
03108                config->play_warning = 0;
03109                ast_clear_flag(&(config->features_caller), AST_FEATURE_PLAY_WARNING);
03110                ast_clear_flag(&(config->features_callee), AST_FEATURE_PLAY_WARNING);
03111                config->warning_freq = 0;
03112                config->warning_sound = NULL;
03113                config->end_sound = NULL;
03114                config->start_sound = NULL;
03115                config->firstpass = 0;
03116             }
03117             config->start_time = ast_tvnow();
03118             config->feature_timer = featuredigittimeout;
03119             ast_debug(1, "Set time limit to %ld ms\n", config->feature_timer);
03120          }
03121       }
03122       if (f)
03123          ast_frfree(f);
03124 
03125    }
03126    before_you_go:
03127 
03128    if (ast_test_flag(chan,AST_FLAG_BRIDGE_HANGUP_DONT)) {
03129       ast_clear_flag(chan,AST_FLAG_BRIDGE_HANGUP_DONT); /* its job is done */
03130       if (bridge_cdr) {
03131          ast_cdr_discard(bridge_cdr);
03132          /* QUESTION: should we copy bridge_cdr fields to the peer before we throw it away? */
03133       }
03134       return res; /* if we shouldn't do the h-exten, we shouldn't do the bridge cdr, either! */
03135    }
03136 
03137    if (config->end_bridge_callback) {
03138       config->end_bridge_callback(config->end_bridge_callback_data);
03139    }
03140 
03141    /* run the hangup exten on the chan object IFF it was NOT involved in a parking situation 
03142     * if it were, then chan belongs to a different thread now, and might have been hung up long
03143      * ago.
03144     */
03145    if (!ast_test_flag(&(config->features_caller),AST_FEATURE_NO_H_EXTEN) &&
03146       ast_exists_extension(chan, chan->context, "h", 1, chan->cid.cid_num)) {
03147       struct ast_cdr *swapper = NULL;
03148       char savelastapp[AST_MAX_EXTENSION];
03149       char savelastdata[AST_MAX_EXTENSION];
03150       char save_exten[AST_MAX_EXTENSION];
03151       int  save_prio;
03152       int  found = 0;   /* set if we find at least one match */
03153       int  spawn_error = 0;
03154       
03155       autoloopflag = ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP);
03156       ast_set_flag(chan, AST_FLAG_IN_AUTOLOOP);
03157       if (bridge_cdr && ast_opt_end_cdr_before_h_exten) {
03158          ast_cdr_end(bridge_cdr);
03159       }
03160       /* swap the bridge cdr and the chan cdr for a moment, and let the endbridge
03161          dialplan code operate on it */
03162       ast_channel_lock(chan);
03163       if (bridge_cdr) {
03164          swapper = chan->cdr;
03165          ast_copy_string(savelastapp, bridge_cdr->lastapp, sizeof(bridge_cdr->lastapp));
03166          ast_copy_string(savelastdata, bridge_cdr->lastdata, sizeof(bridge_cdr->lastdata));
03167          chan->cdr = bridge_cdr;
03168       }
03169       ast_copy_string(save_exten, chan->exten, sizeof(save_exten));
03170       save_prio = chan->priority;
03171       ast_copy_string(chan->exten, "h", sizeof(chan->exten));
03172       chan->priority = 1;
03173       ast_channel_unlock(chan);
03174       while ((spawn_error = ast_spawn_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num, &found, 1)) == 0) {
03175          chan->priority++;
03176       }
03177       if (spawn_error && (!ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num) || ast_check_hangup(chan))) {
03178          /* if the extension doesn't exist or a hangup occurred, this isn't really a spawn error */
03179          spawn_error = 0;
03180       }
03181       if (found && spawn_error) {
03182          /* Something bad happened, or a hangup has been requested. */
03183          ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", chan->context, chan->exten, chan->priority, chan->name);
03184          ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", chan->context, chan->exten, chan->priority, chan->name);
03185       }
03186       /* swap it back */
03187       ast_channel_lock(chan);
03188       ast_copy_string(chan->exten, save_exten, sizeof(chan->exten));
03189       chan->priority = save_prio;
03190       if (bridge_cdr) {
03191          if (chan->cdr == bridge_cdr) {
03192             chan->cdr = swapper;
03193          } else {
03194             bridge_cdr = NULL;
03195          }
03196       }
03197       if (!spawn_error) {
03198          ast_set_flag(chan, AST_FLAG_BRIDGE_HANGUP_RUN);
03199       }
03200       ast_channel_unlock(chan);
03201       /* protect the lastapp/lastdata against the effects of the hangup/dialplan code */
03202       if (bridge_cdr) {
03203          ast_copy_string(bridge_cdr->lastapp, savelastapp, sizeof(bridge_cdr->lastapp));
03204          ast_copy_string(bridge_cdr->lastdata, savelastdata, sizeof(bridge_cdr->lastdata));
03205       }
03206       ast_set2_flag(chan, autoloopflag, AST_FLAG_IN_AUTOLOOP);
03207    }
03208    
03209    /* obey the NoCDR() wishes. -- move the DISABLED flag to the bridge CDR if it was set on the channel during the bridge... */
03210    new_chan_cdr = pick_unlocked_cdr(chan->cdr); /* the proper chan cdr, if there are forked cdrs */
03211    if (bridge_cdr && new_chan_cdr && ast_test_flag(new_chan_cdr, AST_CDR_FLAG_POST_DISABLED))
03212       ast_set_flag(bridge_cdr, AST_CDR_FLAG_POST_DISABLED);
03213 
03214    /* we can post the bridge CDR at this point */
03215    if (bridge_cdr) {
03216       ast_cdr_end(bridge_cdr);
03217       ast_cdr_detach(bridge_cdr);
03218    }
03219    
03220    /* do a specialized reset on the beginning channel
03221       CDR's, if they still exist, so as not to mess up
03222       issues in future bridges;
03223       
03224       Here are the rules of the game:
03225       1. The chan and peer channel pointers will not change
03226          during the life of the bridge.
03227       2. But, in transfers, the channel names will change.
03228          between the time the bridge is started, and the
03229          time the channel ends. 
03230          Usually, when a channel changes names, it will
03231          also change CDR pointers.
03232       3. Usually, only one of the two channels (chan or peer)
03233          will change names.
03234       4. Usually, if a channel changes names during a bridge,
03235          it is because of a transfer. Usually, in these situations,
03236          it is normal to see 2 bridges running simultaneously, and
03237          it is not unusual to see the two channels that change
03238          swapped between bridges.
03239       5. After a bridge occurs, we have 2 or 3 channels' CDRs
03240          to attend to; if the chan or peer changed names,
03241          we have the before and after attached CDR's.
03242    */
03243    
03244    if (new_chan_cdr) {
03245       struct ast_channel *chan_ptr = NULL;
03246  
03247       if (strcasecmp(orig_channame, chan->name) != 0) { 
03248          /* old channel */
03249          chan_ptr = ast_get_channel_by_name_locked(orig_channame);
03250          if (chan_ptr) {
03251             if (!ast_bridged_channel(chan_ptr)) {
03252                struct ast_cdr *cur;
03253                for (cur = chan_ptr->cdr; cur; cur = cur->next) {
03254                   if (cur == chan_cdr) {
03255                      break;
03256                   }
03257                }
03258                if (cur)
03259                   ast_cdr_specialized_reset(chan_cdr,0);
03260             }
03261             ast_channel_unlock(chan_ptr);
03262          }
03263          /* new channel */
03264          ast_cdr_specialized_reset(new_chan_cdr,0);
03265       } else {
03266          ast_cdr_specialized_reset(chan->cdr,0); /* nothing changed, reset the chan cdr  */
03267       }
03268    }
03269    
03270    {
03271       struct ast_channel *chan_ptr = NULL;
03272       new_peer_cdr = pick_unlocked_cdr(peer->cdr); /* the proper chan cdr, if there are forked cdrs */
03273       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))
03274          ast_set_flag(new_peer_cdr, AST_CDR_FLAG_POST_DISABLED); /* DISABLED is viral-- it will propagate across a bridge */
03275       if (strcasecmp(orig_peername, peer->name) != 0) { 
03276          /* old channel */
03277          chan_ptr = ast_get_channel_by_name_locked(orig_peername);
03278          if (chan_ptr) {
03279             if (!ast_bridged_channel(chan_ptr)) {
03280                struct ast_cdr *cur;
03281                for (cur = chan_ptr->cdr; cur; cur = cur->next) {
03282                   if (cur == peer_cdr) {
03283                      break;
03284                   }
03285                }
03286                if (cur)
03287                   ast_cdr_specialized_reset(peer_cdr,0);
03288             }
03289             ast_channel_unlock(chan_ptr);
03290          }
03291          /* new channel */
03292          if (new_peer_cdr) {
03293             ast_cdr_specialized_reset(new_peer_cdr, 0);
03294          }
03295       } else {
03296          ast_cdr_specialized_reset(peer->cdr, 0); /* nothing changed, reset the peer cdr  */
03297       }
03298    }
03299    
03300    return res;
03301 }
03302 
03303 /*! \brief Output parking event to manager */
03304 static void post_manager_event(const char *s, struct parkeduser *pu)
03305 {
03306    manager_event(EVENT_FLAG_CALL, s,
03307       "Exten: %s\r\n"
03308       "Channel: %s\r\n"
03309       "Parkinglot: %s\r\n"
03310       "CallerIDNum: %s\r\n"
03311       "CallerIDName: %s\r\n"
03312       "UniqueID: %s\r\n",
03313       pu->parkingexten, 
03314       pu->chan->name,
03315       pu->parkinglot->name,
03316       S_OR(pu->chan->cid.cid_num, "<unknown>"),
03317       S_OR(pu->chan->cid.cid_name, "<unknown>"),
03318       pu->chan->uniqueid
03319       );
03320 }
03321 
03322 static char *callback_dialoptions(struct ast_flags *features_callee, struct ast_flags *features_caller, char *options, size_t len)
03323 {
03324    int i = 0;
03325    enum {
03326       OPT_CALLEE_REDIRECT   = 't',
03327       OPT_CALLER_REDIRECT   = 'T',
03328       OPT_CALLEE_AUTOMON    = 'w',
03329       OPT_CALLER_AUTOMON    = 'W',
03330       OPT_CALLEE_DISCONNECT = 'h',
03331       OPT_CALLER_DISCONNECT = 'H',
03332       OPT_CALLEE_PARKCALL   = 'k',
03333       OPT_CALLER_PARKCALL   = 'K',
03334    };
03335 
03336    memset(options, 0, len);
03337    if (ast_test_flag(features_caller, AST_FEATURE_REDIRECT) && i < len) {
03338       options[i++] = OPT_CALLER_REDIRECT;
03339    }
03340    if (ast_test_flag(features_caller, AST_FEATURE_AUTOMON) && i < len) {
03341       options[i++] = OPT_CALLER_AUTOMON;
03342    }
03343    if (ast_test_flag(features_caller, AST_FEATURE_DISCONNECT) && i < len) {
03344       options[i++] = OPT_CALLER_DISCONNECT;
03345    }
03346    if (ast_test_flag(features_caller, AST_FEATURE_PARKCALL) && i < len) {
03347       options[i++] = OPT_CALLER_PARKCALL;
03348    }
03349 
03350    if (ast_test_flag(features_callee, AST_FEATURE_REDIRECT) && i < len) {
03351       options[i++] = OPT_CALLEE_REDIRECT;
03352    }
03353    if (ast_test_flag(features_callee, AST_FEATURE_AUTOMON) && i < len) {
03354       options[i++] = OPT_CALLEE_AUTOMON;
03355    }
03356    if (ast_test_flag(features_callee, AST_FEATURE_DISCONNECT) && i < len) {
03357       options[i++] = OPT_CALLEE_DISCONNECT;
03358    }
03359    if (ast_test_flag(features_callee, AST_FEATURE_PARKCALL) && i < len) {
03360       options[i++] = OPT_CALLEE_PARKCALL;
03361    }
03362 
03363    return options;
03364 }
03365 
03366 /*! \brief Run management on parkinglots, called once per parkinglot */
03367 int manage_parkinglot(struct ast_parkinglot *curlot, const struct pollfd *pfds, const int nfds, struct pollfd **new_pfds, int *new_nfds, int *ms)
03368 {
03369    struct parkeduser *pu;
03370    int res = 0;
03371    char parkingslot[AST_MAX_EXTENSION];
03372 
03373    /* Lock parking list */
03374    AST_LIST_LOCK(&curlot->parkings);
03375    AST_LIST_TRAVERSE_SAFE_BEGIN(&curlot->parkings, pu, list) {
03376       struct ast_channel *chan = pu->chan;   /* shorthand */
03377       int tms;        /* timeout for this item */
03378       int x;          /* fd index in channel */
03379       struct ast_context *con;
03380 
03381       if (pu->notquiteyet) { /* Pretend this one isn't here yet */
03382          continue;
03383       }
03384       tms = ast_tvdiff_ms(ast_tvnow(), pu->start);
03385       if (tms > pu->parkingtime) {
03386          /* Stop music on hold */
03387          ast_indicate(pu->chan, AST_CONTROL_UNHOLD);
03388          /* Get chan, exten from derived kludge */
03389          if (pu->peername[0]) {
03390             char *peername = ast_strdupa(pu->peername);
03391             char *dash = strrchr(peername, '-');
03392             char peername_flat[AST_MAX_EXTENSION]; /* using something like DAHDI/52 for an extension name is NOT a good idea */
03393             int i;
03394 
03395             if (dash) {
03396                *dash = '\0';
03397             }
03398             ast_copy_string(peername_flat, peername, sizeof(peername_flat));
03399             for (i = 0; peername_flat[i] && i < AST_MAX_EXTENSION; i++) {
03400                if (peername_flat[i] == '/') {
03401                   peername_flat[i] = '0';
03402                }
03403             }
03404             con = ast_context_find_or_create(NULL, NULL, pu->parkinglot->parking_con_dial, registrar);
03405             if (!con) {
03406                ast_log(LOG_ERROR, "Parking dial context '%s' does not exist and unable to create\n", pu->parkinglot->parking_con_dial);
03407             }
03408             if (con) {
03409                char returnexten[AST_MAX_EXTENSION];
03410                struct ast_datastore *features_datastore;
03411                struct ast_dial_features *dialfeatures = NULL;
03412 
03413                ast_channel_lock(chan);
03414 
03415                if ((features_datastore = ast_channel_datastore_find(chan, &dial_features_info, NULL)))
03416                   dialfeatures = features_datastore->data;
03417 
03418                ast_channel_unlock(chan);
03419 
03420                if (!strncmp(peername, "Parked/", 7)) {
03421                   peername += 7;
03422                }
03423 
03424                if (dialfeatures) {
03425                   char buf[MAX_DIAL_FEATURE_OPTIONS] = {0,};
03426                   snprintf(returnexten, sizeof(returnexten), "%s,30,%s", peername, callback_dialoptions(&(dialfeatures->features_callee), &(dialfeatures->features_caller), buf, sizeof(buf)));
03427                } else { /* Existing default */
03428                   ast_log(LOG_WARNING, "Dialfeatures not found on %s, using default!\n", chan->name);
03429                   snprintf(returnexten, sizeof(returnexten), "%s,30,t", peername);
03430                }
03431 
03432                ast_add_extension2(con, 1, peername_flat, 1, NULL, NULL, "Dial", ast_strdup(returnexten), ast_free_ptr, registrar);
03433             }
03434             if (pu->options_specified == 1) {
03435                /* Park() was called with overriding return arguments, respect those arguments */
03436                set_c_e_p(chan, pu->context, pu->exten, pu->priority);
03437             } else {
03438                if (comebacktoorigin) {
03439                   set_c_e_p(chan, pu->parkinglot->parking_con_dial, peername_flat, 1);
03440                } else {
03441                   ast_log(LOG_WARNING, "now going to parkedcallstimeout,s,1 | ps is %d\n",pu->parkingnum);
03442                   snprintf(parkingslot, sizeof(parkingslot), "%d", pu->parkingnum);
03443                   pbx_builtin_setvar_helper(chan, "PARKINGSLOT", parkingslot);
03444                   set_c_e_p(chan, "parkedcallstimeout", peername_flat, 1);
03445                }
03446             }
03447          } else {
03448             /* They've been waiting too long, send them back to where they came.  Theoretically they
03449                should have their original extensions and such, but we copy to be on the safe side */
03450             set_c_e_p(chan, pu->context, pu->exten, pu->priority);
03451          }
03452          post_manager_event("ParkedCallTimeOut", pu);
03453 
03454          ast_verb(2, "Timeout for %s parked on %d (%s). Returning to %s,%s,%d\n", pu->chan->name, pu->parkingnum, pu->parkinglot->name, pu->chan->context, pu->chan->exten, pu->chan->priority);
03455          /* Start up the PBX, or hang them up */
03456          if (ast_pbx_start(chan))  {
03457             ast_log(LOG_WARNING, "Unable to restart the PBX for user on '%s', hanging them up...\n", pu->chan->name);
03458             ast_hangup(chan);
03459          }
03460          /* And take them out of the parking lot */
03461          con = ast_context_find(pu->parkinglot->parking_con);
03462          if (con) {
03463             if (ast_context_remove_extension2(con, pu->parkingexten, 1, NULL, 0))
03464                ast_log(LOG_WARNING, "Whoa, failed to remove the parking extension!\n");
03465             else
03466                notify_metermaids(pu->parkingexten, curlot->parking_con, AST_DEVICE_NOT_INUSE);
03467          } else
03468             ast_log(LOG_WARNING, "Whoa, no parking context?\n");
03469          AST_LIST_REMOVE_CURRENT(list);
03470          free(pu);
03471       } else { /* still within parking time, process descriptors */
03472          for (x = 0; x < AST_MAX_FDS; x++) {
03473             struct ast_frame *f;
03474             int y;
03475 
03476             if (chan->fds[x] == -1) {
03477                continue;   /* nothing on this descriptor */
03478             }
03479 
03480             for (y = 0; y < nfds; y++) {
03481                if (pfds[y].fd == chan->fds[x]) {
03482                   /* Found poll record! */
03483                   break;
03484                }
03485             }
03486             if (y == nfds) {
03487                /* Not found */
03488                continue;
03489             }
03490 
03491             if (!(pfds[y].revents & (POLLIN | POLLERR | POLLPRI))) {
03492                /* Next x */
03493                continue;
03494             }
03495 
03496             if (pfds[y].revents & POLLPRI) {
03497                ast_set_flag(chan, AST_FLAG_EXCEPTION);
03498             } else {
03499                ast_clear_flag(chan, AST_FLAG_EXCEPTION);
03500             }
03501             chan->fdno = x;
03502 
03503             /* See if they need servicing */
03504             f = ast_read(pu->chan);
03505             /* Hangup? */
03506             if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass ==  AST_CONTROL_HANGUP))) {
03507                if (f)
03508                   ast_frfree(f);
03509                post_manager_event("ParkedCallGiveUp", pu);
03510 
03511                /* There's a problem, hang them up*/
03512                ast_verb(2, "%s got tired of being parked\n", chan->name);
03513                ast_hangup(chan);
03514                /* And take them out of the parking lot */
03515                con = ast_context_find(curlot->parking_con);
03516                if (con) {
03517                   if (ast_context_remove_extension2(con, pu->parkingexten, 1, NULL, 0))
03518                      ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
03519                   else
03520                      notify_metermaids(pu->parkingexten, curlot->parking_con, AST_DEVICE_NOT_INUSE);
03521                } else
03522                   ast_log(LOG_WARNING, "Whoa, no parking context for parking lot %s?\n", curlot->name);
03523                AST_LIST_REMOVE_CURRENT(list);
03524                free(pu);
03525                break;
03526             } else {
03527                /* XXX Maybe we could do something with packets, like dial "0" for operator or something XXX */
03528                ast_frfree(f);
03529                if (pu->moh_trys < 3 && !chan->generatordata) {
03530                   ast_debug(1, "MOH on parked call stopped by outside source.  Restarting on channel %s.\n", chan->name);
03531                   ast_indicate_data(chan, AST_CONTROL_HOLD, 
03532                      S_OR(curlot->mohclass, NULL),
03533                      (!ast_strlen_zero(curlot->mohclass) ? strlen(curlot->mohclass) + 1 : 0));
03534                   pu->moh_trys++;
03535                }
03536                goto std;   /* XXX Ick: jumping into an else statement??? XXX */
03537             }
03538          } /* End for */
03539          if (x >= AST_MAX_FDS) {
03540 std:        for (x = 0; x < AST_MAX_FDS; x++) { /* mark fds for next round */
03541                if (chan->fds[x] > -1) {
03542                   void *tmp = ast_realloc(*new_pfds, (*new_nfds + 1) * sizeof(struct pollfd));
03543                   if (!tmp) {
03544                      continue;
03545                   }
03546                   *new_pfds = tmp;
03547                   (*new_pfds)[*new_nfds].fd = chan->fds[x];
03548                   (*new_pfds)[*new_nfds].events = POLLIN | POLLERR | POLLPRI;
03549                   (*new_pfds)[*new_nfds].revents = 0;
03550                   (*new_nfds)++;
03551                }
03552             }
03553             /* Keep track of our shortest wait */
03554             if (tms < *ms || *ms < 0) {
03555                *ms = tms;
03556             }
03557          }
03558       }
03559    }
03560    AST_LIST_TRAVERSE_SAFE_END;
03561    AST_LIST_UNLOCK(&curlot->parkings);
03562 
03563    return res;
03564 }
03565 
03566 /*! 
03567  * \brief Take care of parked calls and unpark them if needed 
03568  * \param ignore unused var.
03569  * 
03570  * Start inf loop, lock parking lot, check if any parked channels have gone above timeout
03571  * if so, remove channel from parking lot and return it to the extension that parked it.
03572  * Check if parked channel decided to hangup, wait until next FD via select().
03573 */
03574 static void *do_parking_thread(void *ignore)
03575 {
03576    struct pollfd *pfds = NULL, *new_pfds = NULL;
03577    int nfds = 0, new_nfds = 0;
03578 
03579    for (;;) {
03580       struct ao2_iterator iter;
03581       struct ast_parkinglot *curlot;
03582       int ms = -1;   /* poll2 timeout, uninitialized */
03583       iter = ao2_iterator_init(parkinglots, 0);
03584 
03585       while ((curlot = ao2_iterator_next(&iter))) {
03586          manage_parkinglot(curlot, pfds, nfds, &new_pfds, &new_nfds, &ms);
03587          ao2_ref(curlot, -1);
03588       }
03589       ao2_iterator_destroy(&iter);
03590 
03591       /* Recycle */
03592       ast_free(pfds);
03593       pfds = new_pfds;
03594       nfds = new_nfds;
03595       new_pfds = NULL;
03596       new_nfds = 0;
03597 
03598       /* Wait for something to happen */
03599       ast_poll(pfds, nfds, ms);
03600       pthread_testcancel();
03601    }
03602    /* If this WERE reached, we'd need to free(pfds) */
03603    return NULL;   /* Never reached */
03604 }
03605 
03606 /*! \brief Find parkinglot by name */
03607 struct ast_parkinglot *find_parkinglot(const char *name)
03608 {
03609    struct ast_parkinglot *parkinglot = NULL;
03610    struct ast_parkinglot tmp_parkinglot;
03611    
03612    if (ast_strlen_zero(name))
03613       return NULL;
03614 
03615    ast_copy_string(tmp_parkinglot.name, name, sizeof(tmp_parkinglot.name));
03616 
03617    parkinglot = ao2_find(parkinglots, &tmp_parkinglot, OBJ_POINTER);
03618 
03619    if (parkinglot && option_debug)
03620       ast_log(LOG_DEBUG, "Found Parkinglot: %s\n", parkinglot->name);
03621 
03622    return parkinglot;
03623 }
03624 
03625 AST_APP_OPTIONS(park_call_options, BEGIN_OPTIONS
03626    AST_APP_OPTION('r', AST_PARK_OPT_RINGING),
03627    AST_APP_OPTION('R', AST_PARK_OPT_RANDOMIZE),
03628    AST_APP_OPTION('s', AST_PARK_OPT_SILENCE),
03629 END_OPTIONS );
03630 
03631 /*! \brief Park a call */
03632 static int park_call_exec(struct ast_channel *chan, void *data)
03633 {
03634    /* Cache the original channel name in case we get masqueraded in the middle
03635     * of a park--it is still theoretically possible for a transfer to happen before
03636     * we get here, but it is _really_ unlikely */
03637    char *orig_chan_name = ast_strdupa(chan->name);
03638    char orig_exten[AST_MAX_EXTENSION];
03639    int orig_priority = chan->priority;
03640 
03641    /* Data is unused at the moment but could contain a parking
03642       lot context eventually */
03643    int res = 0;
03644 
03645    char *parse = NULL;
03646    AST_DECLARE_APP_ARGS(app_args,
03647       AST_APP_ARG(timeout);
03648       AST_APP_ARG(return_con);
03649       AST_APP_ARG(return_ext);
03650       AST_APP_ARG(return_pri);
03651       AST_APP_ARG(options);
03652    );
03653 
03654    parse = ast_strdupa(data);
03655    AST_STANDARD_APP_ARGS(app_args, parse);
03656 
03657    ast_copy_string(orig_exten, chan->exten, sizeof(orig_exten));
03658 
03659    /* Setup the exten/priority to be s/1 since we don't know
03660       where this call should return */
03661    strcpy(chan->exten, "s");
03662    chan->priority = 1;
03663 
03664    /* Answer if call is not up */
03665    if (chan->_state != AST_STATE_UP)
03666       res = ast_answer(chan);
03667 
03668    /* Sleep to allow VoIP streams to settle down */
03669    if (!res)
03670       res = ast_safe_sleep(chan, 1000);
03671 
03672    /* Park the call */
03673    if (!res) {
03674       struct ast_park_call_args args = {
03675          .orig_chan_name = orig_chan_name,
03676       };
03677       struct ast_flags flags = { 0 };
03678 
03679       if (parse) {
03680          if (!ast_strlen_zero(app_args.timeout)) {
03681             if (sscanf(app_args.timeout, "%30d", &args.timeout) != 1) {
03682                ast_log(LOG_WARNING, "Invalid timeout '%s' provided\n", app_args.timeout);
03683                args.timeout = 0;
03684             }
03685          }
03686          if (!ast_strlen_zero(app_args.return_con)) {
03687             args.return_con = app_args.return_con;
03688          }
03689          if (!ast_strlen_zero(app_args.return_ext)) {
03690             args.return_ext = app_args.return_ext;
03691          }
03692          if (!ast_strlen_zero(app_args.return_pri)) {
03693             if (sscanf(app_args.return_pri, "%30d", &args.return_pri) != 1) {
03694                ast_log(LOG_WARNING, "Invalid priority '%s' specified\n", app_args.return_pri);
03695                args.return_pri = 0;
03696             }
03697          }
03698       }
03699 
03700       ast_app_parse_options(park_call_options, &flags, NULL, app_args.options);
03701       args.flags = flags.flags;
03702 
03703       res = masq_park_call_announce_args(chan, chan, &args);
03704       /* Continue on in the dialplan */
03705       if (res == 1) {
03706          ast_copy_string(chan->exten, orig_exten, sizeof(chan->exten));
03707          chan->priority = orig_priority;
03708          res = 0;
03709       } else if (!res) {
03710          res = 1;
03711       }
03712    }
03713 
03714    return res;
03715 }
03716 
03717 /*! \brief Pickup parked call */
03718 static int park_exec_full(struct ast_channel *chan, void *data, struct ast_parkinglot *parkinglot)
03719 {
03720    int res = 0;
03721    struct ast_channel *peer=NULL;
03722    struct parkeduser *pu;
03723    struct ast_context *con;
03724    int park = 0;
03725    struct ast_bridge_config config;
03726 
03727    if (data)
03728       park = atoi((char *)data);
03729 
03730    parkinglot = find_parkinglot(findparkinglotname(chan));  
03731    if (!parkinglot)
03732       parkinglot = default_parkinglot;
03733 
03734    AST_LIST_LOCK(&parkinglot->parkings);
03735    AST_LIST_TRAVERSE_SAFE_BEGIN(&parkinglot->parkings, pu, list) {
03736       if (!pu->notquiteyet && (!data || pu->parkingnum == park)) {
03737          if (pu->chan->pbx) { /* do not allow call to be picked up until the PBX thread is finished */
03738             AST_LIST_UNLOCK(&parkinglot->parkings);
03739             return -1;
03740          }
03741          AST_LIST_REMOVE_CURRENT(list);
03742          break;
03743       }
03744    }
03745    AST_LIST_TRAVERSE_SAFE_END;
03746    AST_LIST_UNLOCK(&parkinglot->parkings);
03747 
03748    if (pu) {
03749       peer = pu->chan;
03750       con = ast_context_find(parkinglot->parking_con);
03751       if (con) {
03752          if (ast_context_remove_extension2(con, pu->parkingexten, 1, NULL, 0))
03753             ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
03754          else
03755             notify_metermaids(pu->parkingexten, parkinglot->parking_con, AST_DEVICE_NOT_INUSE);
03756       } else
03757          ast_log(LOG_WARNING, "Whoa, no parking context?\n");
03758 
03759       manager_event(EVENT_FLAG_CALL, "UnParkedCall",
03760          "Exten: %s\r\n"
03761          "Channel: %s\r\n"
03762          "From: %s\r\n"
03763          "CallerIDNum: %s\r\n"
03764          "CallerIDName: %s\r\n",
03765          pu->parkingexten, pu->chan->name, chan->name,
03766          S_OR(pu->chan->cid.cid_num, "<unknown>"),
03767          S_OR(pu->chan->cid.cid_name, "<unknown>")
03768          );
03769 
03770       ast_free(pu);
03771    }
03772    /* JK02: it helps to answer the channel if not already up */
03773    if (chan->_state != AST_STATE_UP)
03774       ast_answer(chan);
03775 
03776    //XXX Why do we unlock here ?
03777    // uncomment it for now, till my setup with debug_threads and detect_deadlocks starts to complain
03778    //ASTOBJ_UNLOCK(parkinglot);
03779 
03780    if (peer) {
03781       struct ast_datastore *features_datastore;
03782       struct ast_dial_features *dialfeatures = NULL;
03783 
03784       /* Play a courtesy to the source(s) configured to prefix the bridge connecting */
03785 
03786       if (!ast_strlen_zero(courtesytone)) {
03787          int error = 0;
03788          ast_indicate(peer, AST_CONTROL_UNHOLD);
03789          if (parkedplay == 0) {
03790             error = ast_stream_and_wait(chan, courtesytone, "");
03791          } else if (parkedplay == 1) {
03792             error = ast_stream_and_wait(peer, courtesytone, "");
03793          } else if (parkedplay == 2) {
03794             if (!ast_streamfile(chan, courtesytone, chan->language) &&
03795                   !ast_streamfile(peer, courtesytone, chan->language)) {
03796                /*! \todo XXX we would like to wait on both! */
03797                res = ast_waitstream(chan, "");
03798                if (res >= 0)
03799                   res = ast_waitstream(peer, "");
03800                if (res < 0)
03801                   error = 1;
03802             }
03803          }
03804          if (error) {
03805             ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
03806             ast_hangup(peer);
03807             return -1;
03808          }
03809       } else
03810          ast_indicate(peer, AST_CONTROL_UNHOLD);
03811 
03812       res = ast_channel_make_compatible(chan, peer);
03813       if (res < 0) {
03814          ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for bridge\n", chan->name, peer->name);
03815          ast_hangup(peer);
03816          return -1;
03817       }
03818       /* This runs sorta backwards, since we give the incoming channel control, as if it
03819          were the person called. */
03820       ast_verb(3, "Channel %s connected to parked call %d\n", chan->name, park);
03821 
03822       pbx_builtin_setvar_helper(chan, "PARKEDCHANNEL", peer->name);
03823       ast_cdr_setdestchan(chan->cdr, peer->name);
03824       memset(&config, 0, sizeof(struct ast_bridge_config));
03825 
03826       /* Get datastore for peer and apply it's features to the callee side of the bridge config */
03827       ast_channel_lock(peer);
03828       if ((features_datastore = ast_channel_datastore_find(peer, &dial_features_info, NULL))) {
03829          dialfeatures = features_datastore->data;
03830       }
03831       ast_channel_unlock(peer);
03832 
03833       /* When the datastores for both caller and callee are created, both the callee and caller channels
03834        * use the features_caller flag variable to represent themselves. With that said, the config.features_callee
03835        * flags should be copied from the datastore's caller feature flags regardless if peer was a callee
03836        * or caller. */
03837       if (dialfeatures) {
03838          ast_copy_flags(&(config.features_callee), &(dialfeatures->features_caller), AST_FLAGS_ALL);
03839       }
03840 
03841       if ((parkinglot->parkedcalltransfers == AST_FEATURE_FLAG_BYCALLEE) || (parkinglot->parkedcalltransfers == AST_FEATURE_FLAG_BYBOTH)) {
03842          ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
03843       }
03844       if ((parkinglot->parkedcalltransfers == AST_FEATURE_FLAG_BYCALLER) || (parkinglot->parkedcalltransfers == AST_FEATURE_FLAG_BYBOTH)) {
03845          ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
03846       }
03847       if ((parkinglot->parkedcallreparking == AST_FEATURE_FLAG_BYCALLEE) || (parkinglot->parkedcallreparking == AST_FEATURE_FLAG_BYBOTH)) {
03848          ast_set_flag(&(config.features_callee), AST_FEATURE_PARKCALL);
03849       }
03850       if ((parkinglot->parkedcallreparking == AST_FEATURE_FLAG_BYCALLER) || (parkinglot->parkedcallreparking == AST_FEATURE_FLAG_BYBOTH)) {
03851          ast_set_flag(&(config.features_caller), AST_FEATURE_PARKCALL);
03852       }
03853       if ((parkinglot->parkedcallhangup == AST_FEATURE_FLAG_BYCALLEE) || (parkinglot->parkedcallhangup == AST_FEATURE_FLAG_BYBOTH)) {
03854          ast_set_flag(&(config.features_callee), AST_FEATURE_DISCONNECT);
03855       }
03856       if ((parkinglot->parkedcallhangup == AST_FEATURE_FLAG_BYCALLER) || (parkinglot->parkedcallhangup == AST_FEATURE_FLAG_BYBOTH)) {
03857          ast_set_flag(&(config.features_caller), AST_FEATURE_DISCONNECT);
03858       }
03859       if ((parkinglot->parkedcallrecording == AST_FEATURE_FLAG_BYCALLEE) || (parkinglot->parkedcallrecording == AST_FEATURE_FLAG_BYBOTH)) {
03860          ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMON);
03861       }
03862       if ((parkinglot->parkedcallrecording == AST_FEATURE_FLAG_BYCALLER) || (parkinglot->parkedcallrecording == AST_FEATURE_FLAG_BYBOTH)) {
03863          ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMON);
03864       }
03865 
03866       res = ast_bridge_call(chan, peer, &config);
03867 
03868       pbx_builtin_setvar_helper(chan, "PARKEDCHANNEL", peer->name);
03869       ast_cdr_setdestchan(chan->cdr, peer->name);
03870 
03871       /* Simulate the PBX hanging up */
03872       ast_hangup(peer);
03873       return -1;
03874    } else {
03875       /*! \todo XXX Play a message XXX */
03876       if (ast_stream_and_wait(chan, "pbx-invalidpark", ""))
03877          ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", "pbx-invalidpark", chan->name);
03878       ast_verb(3, "Channel %s tried to talk to nonexistent parked call %d\n", chan->name, park);
03879       res = -1;
03880    }
03881 
03882    return -1;
03883 }
03884 
03885 static int park_exec(struct ast_channel *chan, void *data) 
03886 {
03887    return park_exec_full(chan, data, default_parkinglot);
03888 }
03889 
03890 /*! \brief Unreference parkinglot object. If no more references,
03891    then go ahead and delete it */
03892 static void parkinglot_unref(struct ast_parkinglot *parkinglot) 
03893 {
03894    int refcount = ao2_ref(parkinglot, -1);
03895    if (option_debug > 2)
03896       ast_log(LOG_DEBUG, "Multiparking: %s refcount now %d\n", parkinglot->name, refcount - 1);
03897 }
03898 
03899 static struct ast_parkinglot *parkinglot_addref(struct ast_parkinglot *parkinglot)
03900 {
03901    int refcount = ao2_ref(parkinglot, +1);
03902    if (option_debug > 2)
03903       ast_log(LOG_DEBUG, "Multiparking: %s refcount now %d\n", parkinglot->name, refcount + 1);
03904    return parkinglot;
03905 }
03906 
03907 /*! \brief Allocate parking lot structure */
03908 static struct ast_parkinglot *create_parkinglot(char *name)
03909 {
03910    struct ast_parkinglot *newlot = (struct ast_parkinglot *) NULL;
03911 
03912    if (!name)
03913       return NULL;
03914 
03915    newlot = ao2_alloc(sizeof(*newlot), parkinglot_destroy);
03916    if (!newlot)
03917       return NULL;
03918    
03919    ast_copy_string(newlot->name, name, sizeof(newlot->name));
03920    AST_LIST_HEAD_INIT(&newlot->parkings);
03921 
03922    return newlot;
03923 }
03924 
03925 /*! \brief Destroy a parking lot */
03926 static void parkinglot_destroy(void *obj)
03927 {
03928    struct ast_parkinglot *ruin = obj;
03929    struct ast_context *con;
03930    con = ast_context_find(ruin->parking_con);
03931    if (con)
03932       ast_context_destroy(con, registrar);
03933    ao2_unlink(parkinglots, ruin);
03934 }
03935 
03936 /*! \brief Build parkinglot from configuration and chain it in */
03937 static struct ast_parkinglot *build_parkinglot(char *name, struct ast_variable *var)
03938 {
03939    struct ast_parkinglot *parkinglot;
03940    struct ast_context *con = NULL;
03941 
03942    struct ast_variable *confvar = var;
03943    int error = 0;
03944    int start = 0, end = 0;
03945    int oldparkinglot = 0;
03946 
03947    parkinglot = find_parkinglot(name);
03948    if (parkinglot)
03949       oldparkinglot = 1;
03950    else
03951       parkinglot = create_parkinglot(name);
03952 
03953    if (!parkinglot)
03954       return NULL;
03955 
03956    ao2_lock(parkinglot);
03957 
03958    if (option_debug)
03959       ast_log(LOG_DEBUG, "Building parking lot %s\n", name);
03960    
03961    /* Do some config stuff */
03962    while(confvar) {
03963       if (!strcasecmp(confvar->name, "context")) {
03964          ast_copy_string(parkinglot->parking_con, confvar->value, sizeof(parkinglot->parking_con));
03965       } else if (!strcasecmp(confvar->name, "parkingtime")) {
03966          if ((sscanf(confvar->value, "%30d", &parkinglot->parkingtime) != 1) || (parkinglot->parkingtime < 1)) {
03967             ast_log(LOG_WARNING, "%s is not a valid parkingtime\n", confvar->value);
03968             parkinglot->parkingtime = DEFAULT_PARK_TIME;
03969          } else
03970             parkinglot->parkingtime = parkinglot->parkingtime * 1000;
03971       } else if (!strcasecmp(confvar->name, "parkpos")) {
03972          if (sscanf(confvar->value, "%30d-%30d", &start, &end) != 2) {
03973             ast_log(LOG_WARNING, "Format for parking positions is a-b, where a and b are numbers at line %d of parking.conf\n", confvar->lineno);
03974             error = 1;
03975          } else {
03976             parkinglot->parking_start = start;
03977             parkinglot->parking_stop = end;
03978          }
03979       } else if (!strcasecmp(confvar->name, "findslot")) {
03980          parkinglot->parkfindnext = (!strcasecmp(confvar->value, "next"));
03981       } else if (!strcasecmp(confvar->name, "parkedcalltransfers") ||
03982             !strcasecmp(confvar->name, "parkedcallreparking") ||
03983             !strcasecmp(confvar->name, "parkedcallhangup") ||
03984             !strcasecmp(confvar->name, "parkedcallrecording")) {
03985          if (!strcasecmp(confvar->value, "both")) {
03986             parkinglot->parkedcalltransfers = AST_FEATURE_FLAG_BYBOTH;
03987          } else if (!strcasecmp(confvar->value, "caller")) {
03988             parkinglot->parkedcalltransfers = AST_FEATURE_FLAG_BYCALLER;
03989          } else if (!strcasecmp(confvar->value, "callee")) {
03990             parkinglot->parkedcalltransfers = AST_FEATURE_FLAG_BYCALLEE;
03991          }
03992       }
03993       confvar = confvar->next;
03994    }
03995    /* make sure parkingtime is set if not specified */
03996    if (parkinglot->parkingtime == 0) {
03997       parkinglot->parkingtime = DEFAULT_PARK_TIME;
03998    }
03999 
04000    if (!var) { /* Default parking lot */
04001       ast_copy_string(parkinglot->parking_con, "parkedcalls", sizeof(parkinglot->parking_con));
04002       ast_copy_string(parkinglot->mohclass, "default", sizeof(parkinglot->mohclass));
04003    }
04004    ast_copy_string(parkinglot->parking_con_dial, "park-dial", sizeof(parkinglot->parking_con_dial));
04005 
04006    /* Check for errors */
04007    if (ast_strlen_zero(parkinglot->parking_con)) {
04008       ast_log(LOG_WARNING, "Parking lot %s lacks context\n", name);
04009       error = 1;
04010    }
04011 
04012    /* Create context */
04013    if (!error && !(con = ast_context_find_or_create(NULL, NULL, parkinglot->parking_con, registrar))) {
04014       ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", parkinglot->parking_con);
04015       error = 1;
04016    }
04017 
04018    /* Add a parking extension into the context */
04019    if (!error && !oldparkinglot) {
04020       if (!ast_strlen_zero(ast_parking_ext())) {
04021          if (ast_add_extension2(con, 1, ast_parking_ext(), 1, NULL, NULL, parkcall, strdup(""), ast_free_ptr, registrar) == -1)
04022             error = 1;
04023       }
04024    }
04025 
04026    ao2_unlock(parkinglot);
04027 
04028    if (error) {
04029       ast_log(LOG_WARNING, "Parking %s not open for business. Configuration error.\n", name);
04030       parkinglot_destroy(parkinglot);
04031       return NULL;
04032    }
04033    if (option_debug)
04034       ast_log(LOG_DEBUG, "Parking %s now open for business. (start exten %d end %d)\n", name, start, end);
04035 
04036 
04037    /* Move it into the list, if it wasn't already there */
04038    if (!oldparkinglot) {
04039       ao2_link(parkinglots, parkinglot);
04040    }
04041    parkinglot_unref(parkinglot);
04042 
04043    return parkinglot;
04044 }
04045 
04046 
04047 /*! 
04048  * \brief Add parking hints for all defined parking lots 
04049  * \param context
04050  * \param start starting parkinglot number
04051  * \param stop ending parkinglot number
04052 */
04053 static void park_add_hints(char *context, int start, int stop)
04054 {
04055    int numext;
04056    char device[AST_MAX_EXTENSION];
04057    char exten[10];
04058 
04059    for (numext = start; numext <= stop; numext++) {
04060       snprintf(exten, sizeof(exten), "%d", numext);
04061       snprintf(device, sizeof(device), "park:%s@%s", exten, context);
04062       ast_add_extension(context, 1, exten, PRIORITY_HINT, NULL, NULL, device, NULL, NULL, registrar);
04063    }
04064 }
04065 
04066 static int load_config(void) 
04067 {
04068    int start = 0, end = 0;
04069    int res;
04070    int i;
04071    struct ast_context *con = NULL;
04072    struct ast_config *cfg = NULL;
04073    struct ast_variable *var = NULL;
04074    struct feature_group *fg = NULL;
04075    struct ast_flags config_flags = { 0 };
04076    char old_parking_ext[AST_MAX_EXTENSION];
04077    char old_parking_con[AST_MAX_EXTENSION] = "";
04078    char *ctg; 
04079    static const char *categories[] = { 
04080       /* Categories in features.conf that are not
04081        * to be parsed as group categories
04082        */
04083       "general",
04084       "featuremap",
04085       "applicationmap"
04086    };
04087 
04088    if (default_parkinglot) {
04089       strcpy(old_parking_con, default_parkinglot->parking_con);
04090       strcpy(old_parking_ext, parking_ext);
04091    } else {
04092       default_parkinglot = build_parkinglot(DEFAULT_PARKINGLOT, NULL);
04093       if (default_parkinglot) {
04094          ao2_lock(default_parkinglot);
04095          default_parkinglot->parking_start = 701;
04096          default_parkinglot->parking_stop = 750;
04097          default_parkinglot->parking_offset = 0;
04098          default_parkinglot->parkfindnext = 0;
04099          default_parkinglot->parkingtime = DEFAULT_PARK_TIME;
04100          ao2_unlock(default_parkinglot);
04101       }
04102    }
04103    if (default_parkinglot) {
04104       if (option_debug)
04105          ast_log(LOG_DEBUG, "Configuration of default parkinglot done.\n");
04106    } else {
04107       ast_log(LOG_ERROR, "Configuration of default parkinglot failed.\n");
04108       return -1;
04109    }
04110    
04111 
04112    /* Reset to defaults */
04113    strcpy(parking_ext, "700");
04114    strcpy(pickup_ext, "*8");
04115    courtesytone[0] = '\0';
04116    strcpy(xfersound, "beep");
04117    strcpy(xferfailsound, "beeperr");
04118    pickupsound[0] = '\0';
04119    pickupfailsound[0] = '\0';
04120    adsipark = 0;
04121    comebacktoorigin = 1;
04122 
04123    default_parkinglot->parkaddhints = 0;
04124    default_parkinglot->parkedcalltransfers = 0;
04125    default_parkinglot->parkedcallreparking = 0;
04126    default_parkinglot->parkedcallrecording = 0;
04127    default_parkinglot->parkedcallhangup = 0;
04128 
04129    transferdigittimeout = DEFAULT_TRANSFER_DIGIT_TIMEOUT;
04130    featuredigittimeout = DEFAULT_FEATURE_DIGIT_TIMEOUT;
04131    atxfernoanswertimeout = DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER;
04132    atxferloopdelay = DEFAULT_ATXFER_LOOP_DELAY;
04133    atxferdropcall = DEFAULT_ATXFER_DROP_CALL;
04134    atxfercallbackretries = DEFAULT_ATXFER_CALLBACK_RETRIES;
04135 
04136    cfg = ast_config_load2("features.conf", "features", config_flags);
04137    if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
04138       ast_log(LOG_WARNING,"Could not load features.conf\n");
04139       return 0;
04140    }
04141    for (var = ast_variable_browse(cfg, "general"); var; var = var->next) {
04142       if (!strcasecmp(var->name, "parkext")) {
04143          ast_copy_string(parking_ext, var->value, sizeof(parking_ext));
04144       } else if (!strcasecmp(var->name, "context")) {
04145          ast_copy_string(default_parkinglot->parking_con, var->value, sizeof(default_parkinglot->parking_con));
04146       } else if (!strcasecmp(var->name, "parkingtime")) {
04147          if ((sscanf(var->value, "%30d", &default_parkinglot->parkingtime) != 1) || (default_parkinglot->parkingtime < 1)) {
04148             ast_log(LOG_WARNING, "%s is not a valid parkingtime\n", var->value);
04149             default_parkinglot->parkingtime = DEFAULT_PARK_TIME;
04150          } else
04151             default_parkinglot->parkingtime = default_parkinglot->parkingtime * 1000;
04152       } else if (!strcasecmp(var->name, "parkpos")) {
04153          if (sscanf(var->value, "%30d-%30d", &start, &end) != 2) {
04154             ast_log(LOG_WARNING, "Format for parking positions is a-b, where a and b are numbers at line %d of features.conf\n", var->lineno);
04155          } else if (default_parkinglot) {
04156             default_parkinglot->parking_start = start;
04157             default_parkinglot->parking_stop = end;
04158          } else {
04159             ast_log(LOG_WARNING, "No default parking lot!\n");
04160          }
04161       } else if (!strcasecmp(var->name, "findslot")) {
04162          default_parkinglot->parkfindnext = (!strcasecmp(var->value, "next"));
04163       } else if (!strcasecmp(var->name, "parkinghints")) {
04164          default_parkinglot->parkaddhints = ast_true(var->value);
04165       } else if (!strcasecmp(var->name, "parkedcalltransfers")) {
04166          if (!strcasecmp(var->value, "both"))
04167             default_parkinglot->parkedcalltransfers = AST_FEATURE_FLAG_BYBOTH;
04168          else if (!strcasecmp(var->value, "caller"))
04169             default_parkinglot->parkedcalltransfers = AST_FEATURE_FLAG_BYCALLER;
04170          else if (!strcasecmp(var->value, "callee"))
04171             default_parkinglot->parkedcalltransfers = AST_FEATURE_FLAG_BYCALLEE;
04172       } else if (!strcasecmp(var->name, "parkedcallreparking")) {
04173          if (!strcasecmp(var->value, "both"))
04174             default_parkinglot->parkedcallreparking = AST_FEATURE_FLAG_BYBOTH;
04175          else if (!strcasecmp(var->value, "caller"))
04176             default_parkinglot->parkedcallreparking = AST_FEATURE_FLAG_BYCALLER;
04177          else if (!strcasecmp(var->value, "callee"))
04178             default_parkinglot->parkedcallreparking = AST_FEATURE_FLAG_BYCALLEE;
04179       } else if (!strcasecmp(var->name, "parkedcallhangup")) {
04180          if (!strcasecmp(var->value, "both"))
04181             default_parkinglot->parkedcallhangup = AST_FEATURE_FLAG_BYBOTH;
04182          else if (!strcasecmp(var->value, "caller"))
04183             default_parkinglot->parkedcallhangup = AST_FEATURE_FLAG_BYCALLER;
04184          else if (!strcasecmp(var->value, "callee"))
04185             default_parkinglot->parkedcallhangup = AST_FEATURE_FLAG_BYCALLEE;
04186       } else if (!strcasecmp(var->name, "parkedcallrecording")) {
04187          if (!strcasecmp(var->value, "both"))
04188             default_parkinglot->parkedcallrecording = AST_FEATURE_FLAG_BYBOTH;
04189          else if (!strcasecmp(var->value, "caller"))
04190             default_parkinglot->parkedcallrecording = AST_FEATURE_FLAG_BYCALLER;
04191          else if (!strcasecmp(var->value, "callee"))
04192             default_parkinglot->parkedcallrecording = AST_FEATURE_FLAG_BYCALLEE;
04193       } else if (!strcasecmp(var->name, "adsipark")) {
04194          adsipark = ast_true(var->value);
04195       } else if (!strcasecmp(var->name, "transferdigittimeout")) {
04196          if ((sscanf(var->value, "%30d", &transferdigittimeout) != 1) || (transferdigittimeout < 1)) {
04197             ast_log(LOG_WARNING, "%s is not a valid transferdigittimeout\n", var->value);
04198             transferdigittimeout = DEFAULT_TRANSFER_DIGIT_TIMEOUT;
04199          } else
04200             transferdigittimeout = transferdigittimeout * 1000;
04201       } else if (!strcasecmp(var->name, "featuredigittimeout")) {
04202          if ((sscanf(var->value, "%30d", &featuredigittimeout) != 1) || (featuredigittimeout < 1)) {
04203             ast_log(LOG_WARNING, "%s is not a valid featuredigittimeout\n", var->value);
04204             featuredigittimeout = DEFAULT_FEATURE_DIGIT_TIMEOUT;
04205          }
04206       } else if (!strcasecmp(var->name, "atxfernoanswertimeout")) {
04207          if ((sscanf(var->value, "%30d", &atxfernoanswertimeout) != 1) || (atxfernoanswertimeout < 1)) {
04208             ast_log(LOG_WARNING, "%s is not a valid atxfernoanswertimeout\n", var->value);
04209             atxfernoanswertimeout = DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER;
04210          } else
04211             atxfernoanswertimeout = atxfernoanswertimeout * 1000;
04212       } else if (!strcasecmp(var->name, "atxferloopdelay")) {
04213          if ((sscanf(var->value, "%30u", &atxferloopdelay) != 1)) {
04214             ast_log(LOG_WARNING, "%s is not a valid atxferloopdelay\n", var->value);
04215             atxferloopdelay = DEFAULT_ATXFER_LOOP_DELAY;
04216          } else 
04217             atxferloopdelay *= 1000;
04218       } else if (!strcasecmp(var->name, "atxferdropcall")) {
04219          atxferdropcall = ast_true(var->value);
04220       } else if (!strcasecmp(var->name, "atxfercallbackretries")) {
04221          if ((sscanf(var->value, "%30u", &atxfercallbackretries) != 1)) {
04222             ast_log(LOG_WARNING, "%s is not a valid atxfercallbackretries\n", var->value);
04223             atxfercallbackretries = DEFAULT_ATXFER_CALLBACK_RETRIES;
04224          }
04225       } else if (!strcasecmp(var->name, "courtesytone")) {
04226          ast_copy_string(courtesytone, var->value, sizeof(courtesytone));
04227       }  else if (!strcasecmp(var->name, "parkedplay")) {
04228          if (!strcasecmp(var->value, "both"))
04229             parkedplay = 2;
04230          else if (!strcasecmp(var->value, "parked"))
04231             parkedplay = 1;
04232          else
04233             parkedplay = 0;
04234       } else if (!strcasecmp(var->name, "xfersound")) {
04235          ast_copy_string(xfersound, var->value, sizeof(xfersound));
04236       } else if (!strcasecmp(var->name, "xferfailsound")) {
04237          ast_copy_string(xferfailsound, var->value, sizeof(xferfailsound));
04238       } else if (!strcasecmp(var->name, "pickupexten")) {
04239          ast_copy_string(pickup_ext, var->value, sizeof(pickup_ext));
04240       } else if (!strcasecmp(var->name, "pickupsound")) {
04241          ast_copy_string(pickupsound, var->value, sizeof(pickupsound));
04242       } else if (!strcasecmp(var->name, "pickupfailsound")) {
04243          ast_copy_string(pickupfailsound, var->value, sizeof(pickupfailsound));
04244       } else if (!strcasecmp(var->name, "comebacktoorigin")) {
04245          comebacktoorigin = ast_true(var->value);
04246       } else if (!strcasecmp(var->name, "parkedmusicclass")) {
04247          ast_copy_string(default_parkinglot->mohclass, var->value, sizeof(default_parkinglot->mohclass));
04248       }
04249    }
04250 
04251    unmap_features();
04252    for (var = ast_variable_browse(cfg, "featuremap"); var; var = var->next) {
04253       if (remap_feature(var->name, var->value))
04254          ast_log(LOG_NOTICE, "Unknown feature '%s'\n", var->name);
04255    }
04256 
04257    /* Map a key combination to an application*/
04258    ast_unregister_features();
04259    for (var = ast_variable_browse(cfg, "applicationmap"); var; var = var->next) {
04260       char *tmp_val = ast_strdupa(var->value);
04261       char *activateon; 
04262       struct ast_call_feature *feature;
04263       AST_DECLARE_APP_ARGS(args,
04264          AST_APP_ARG(exten);
04265          AST_APP_ARG(activatedby);
04266          AST_APP_ARG(app);
04267          AST_APP_ARG(app_args);
04268          AST_APP_ARG(moh_class);
04269       );
04270 
04271       AST_STANDARD_APP_ARGS(args, tmp_val);
04272       if (strchr(args.app, '(')) {
04273          /* New syntax */
04274          args.moh_class = args.app_args;
04275          args.app_args = strchr(args.app, '(');
04276          *args.app_args++ = '\0';
04277          if (args.app_args[strlen(args.app_args) - 1] == ')') {
04278             args.app_args[strlen(args.app_args) - 1] = '\0';
04279          }
04280       }
04281 
04282       activateon = strsep(&args.activatedby, "/"); 
04283 
04284       /*! \todo XXX var_name or app_args ? */
04285       if (ast_strlen_zero(args.app) || ast_strlen_zero(args.exten) || ast_strlen_zero(activateon) || ast_strlen_zero(var->name)) {
04286          ast_log(LOG_NOTICE, "Please check the feature Mapping Syntax, either extension, name, or app aren't provided %s %s %s %s\n",
04287             args.app, args.exten, activateon, var->name);
04288          continue;
04289       }
04290 
04291       AST_RWLIST_RDLOCK(&feature_list);
04292       if ((feature = find_dynamic_feature(var->name))) {
04293          AST_RWLIST_UNLOCK(&feature_list);
04294          ast_log(LOG_WARNING, "Dynamic Feature '%s' specified more than once!\n", var->name);
04295          continue;
04296       }
04297       AST_RWLIST_UNLOCK(&feature_list);
04298             
04299       if (!(feature = ast_calloc(1, sizeof(*feature)))) {
04300          continue;
04301       }
04302 
04303       ast_copy_string(feature->sname, var->name, FEATURE_SNAME_LEN);
04304       ast_copy_string(feature->app, args.app, FEATURE_APP_LEN);
04305       ast_copy_string(feature->exten, args.exten, FEATURE_EXTEN_LEN);
04306       
04307       if (args.app_args) {
04308          ast_copy_string(feature->app_args, args.app_args, FEATURE_APP_ARGS_LEN);
04309       }
04310 
04311       if (args.moh_class) {
04312          ast_copy_string(feature->moh_class, args.moh_class, FEATURE_MOH_LEN);
04313       }
04314 
04315       ast_copy_string(feature->exten, args.exten, sizeof(feature->exten));
04316       feature->operation = feature_exec_app;
04317       ast_set_flag(feature, AST_FEATURE_FLAG_NEEDSDTMF);
04318 
04319       /* Allow caller and calle to be specified for backwards compatability */
04320       if (!strcasecmp(activateon, "self") || !strcasecmp(activateon, "caller"))
04321          ast_set_flag(feature, AST_FEATURE_FLAG_ONSELF);
04322       else if (!strcasecmp(activateon, "peer") || !strcasecmp(activateon, "callee"))
04323          ast_set_flag(feature, AST_FEATURE_FLAG_ONPEER);
04324       else {
04325          ast_log(LOG_NOTICE, "Invalid 'ActivateOn' specification for feature '%s',"
04326             " must be 'self', or 'peer'\n", var->name);
04327          continue;
04328       }
04329 
04330       if (ast_strlen_zero(args.activatedby))
04331          ast_set_flag(feature, AST_FEATURE_FLAG_BYBOTH);
04332       else if (!strcasecmp(args.activatedby, "caller"))
04333          ast_set_flag(feature, AST_FEATURE_FLAG_BYCALLER);
04334       else if (!strcasecmp(args.activatedby, "callee"))
04335          ast_set_flag(feature, AST_FEATURE_FLAG_BYCALLEE);
04336       else if (!strcasecmp(args.activatedby, "both"))
04337          ast_set_flag(feature, AST_FEATURE_FLAG_BYBOTH);
04338       else {
04339          ast_log(LOG_NOTICE, "Invalid 'ActivatedBy' specification for feature '%s',"
04340             " must be 'caller', or 'callee', or 'both'\n", var->name);
04341          continue;
04342       }
04343 
04344       ast_register_feature(feature);
04345 
04346       ast_verb(2, "Mapping Feature '%s' to app '%s(%s)' with code '%s'\n", var->name, args.app, args.app_args, args.exten);
04347    }
04348 
04349    ast_unregister_groups();
04350    AST_RWLIST_WRLOCK(&feature_groups);
04351 
04352    ctg = NULL;
04353    while ((ctg = ast_category_browse(cfg, ctg))) {
04354       /* Is this a parkinglot definition ? */
04355       if (!strncasecmp(ctg, "parkinglot_", strlen("parkinglot_"))) {
04356          ast_debug(2, "Found configuration section %s, assume parking context\n", ctg);
04357          if(!build_parkinglot(ctg, ast_variable_browse(cfg, ctg)))
04358             ast_log(LOG_ERROR, "Could not build parking lot %s. Configuration error.\n", ctg);
04359          else
04360             ast_debug(1, "Configured parking context %s\n", ctg);
04361          continue;   
04362       }
04363       /* No, check if it's a group */
04364       for (i = 0; i < ARRAY_LEN(categories); i++) {
04365          if (!strcasecmp(categories[i], ctg))
04366             break;
04367       }
04368 
04369       if (i < ARRAY_LEN(categories)) 
04370          continue;
04371 
04372       if (!(fg = register_group(ctg)))
04373          continue;
04374 
04375       for (var = ast_variable_browse(cfg, ctg); var; var = var->next) {
04376          struct ast_call_feature *feature;
04377 
04378          AST_RWLIST_RDLOCK(&feature_list);
04379          if (!(feature = find_dynamic_feature(var->name)) && 
04380              !(feature = ast_find_call_feature(var->name))) {
04381             AST_RWLIST_UNLOCK(&feature_list);
04382             ast_log(LOG_WARNING, "Feature '%s' was not found.\n", var->name);
04383             continue;
04384          }
04385          AST_RWLIST_UNLOCK(&feature_list);
04386 
04387          register_group_feature(fg, var->value, feature);
04388       }
04389    }
04390 
04391    AST_RWLIST_UNLOCK(&feature_groups);
04392 
04393    ast_config_destroy(cfg);
04394 
04395    /* Remove the old parking extension */
04396    if (!ast_strlen_zero(old_parking_con) && (con = ast_context_find(old_parking_con))) {
04397       if(ast_context_remove_extension2(con, old_parking_ext, 1, registrar, 0))
04398             notify_metermaids(old_parking_ext, old_parking_con, AST_DEVICE_NOT_INUSE);
04399       ast_debug(1, "Removed old parking extension %s@%s\n", old_parking_ext, old_parking_con);
04400    }
04401    
04402    if (!(con = ast_context_find_or_create(NULL, NULL, default_parkinglot->parking_con, registrar))) {
04403       ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", default_parkinglot->parking_con);
04404       return -1;
04405    }
04406    res = ast_add_extension2(con, 1, ast_parking_ext(), 1, NULL, NULL, parkcall, NULL, NULL, registrar);
04407    if (default_parkinglot->parkaddhints)
04408       park_add_hints(default_parkinglot->parking_con, default_parkinglot->parking_start, default_parkinglot->parking_stop);
04409    if (!res)
04410       notify_metermaids(ast_parking_ext(), default_parkinglot->parking_con, AST_DEVICE_INUSE);
04411    return res;
04412 
04413 }
04414 
04415 /*!
04416  * \brief CLI command to list configured features
04417  * \param e
04418  * \param cmd
04419  * \param a
04420  *
04421  * \retval CLI_SUCCESS on success.
04422  * \retval NULL when tab completion is used.
04423  */
04424 static char *handle_feature_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
04425 {
04426    int i;
04427    struct ast_call_feature *feature;
04428    struct ao2_iterator iter;
04429    struct ast_parkinglot *curlot;
04430 #define HFS_FORMAT "%-25s %-7s %-7s\n"
04431 
04432    switch (cmd) {
04433    
04434    case CLI_INIT:
04435       e->command = "features show";
04436       e->usage =
04437          "Usage: features show\n"
04438          "       Lists configured features\n";
04439       return NULL;
04440    case CLI_GENERATE:
04441       return NULL;
04442    }
04443 
04444    ast_cli(a->fd, HFS_FORMAT, "Builtin Feature", "Default", "Current");
04445    ast_cli(a->fd, HFS_FORMAT, "---------------", "-------", "-------");
04446 
04447    ast_cli(a->fd, HFS_FORMAT, "Pickup", "*8", ast_pickup_ext());          /* default hardcoded above, so we'll hardcode it here */
04448 
04449    ast_rwlock_rdlock(&features_lock);
04450    for (i = 0; i < FEATURES_COUNT; i++)
04451       ast_cli(a->fd, HFS_FORMAT, builtin_features[i].fname, builtin_features[i].default_exten, builtin_features[i].exten);
04452    ast_rwlock_unlock(&features_lock);
04453 
04454    ast_cli(a->fd, "\n");
04455    ast_cli(a->fd, HFS_FORMAT, "Dynamic Feature", "Default", "Current");
04456    ast_cli(a->fd, HFS_FORMAT, "---------------", "-------", "-------");
04457    if (AST_RWLIST_EMPTY(&feature_list)) {
04458       ast_cli(a->fd, "(none)\n");
04459    } else {
04460       AST_RWLIST_RDLOCK(&feature_list);
04461       AST_RWLIST_TRAVERSE(&feature_list, feature, feature_entry) {
04462          ast_cli(a->fd, HFS_FORMAT, feature->sname, "no def", feature->exten);
04463       }
04464       AST_RWLIST_UNLOCK(&feature_list);
04465    }
04466 
04467    ast_cli(a->fd, "\nFeature Groups:\n");
04468    ast_cli(a->fd, "---------------\n");
04469    if (AST_RWLIST_EMPTY(&feature_groups)) {
04470       ast_cli(a->fd, "(none)\n");
04471    } else {
04472       struct feature_group *fg;
04473       struct feature_group_exten *fge;
04474 
04475       AST_RWLIST_RDLOCK(&feature_groups);
04476       AST_RWLIST_TRAVERSE(&feature_groups, fg, entry) {
04477          ast_cli(a->fd, "===> Group: %s\n", fg->gname);
04478          AST_LIST_TRAVERSE(&fg->features, fge, entry) {
04479             ast_cli(a->fd, "===> --> %s (%s)\n", fge->feature->sname, fge->exten);
04480          }
04481       }
04482       AST_RWLIST_UNLOCK(&feature_groups);
04483    }
04484 
04485    iter = ao2_iterator_init(parkinglots, 0);
04486    while ((curlot = ao2_iterator_next(&iter))) {
04487       ast_cli(a->fd, "\nCall parking (Parking lot: %s)\n", curlot->name);
04488       ast_cli(a->fd, "------------\n");
04489       ast_cli(a->fd,"%-22s:      %s\n", "Parking extension", parking_ext);
04490       ast_cli(a->fd,"%-22s:      %s\n", "Parking context", curlot->parking_con);
04491       ast_cli(a->fd,"%-22s:      %d-%d\n", "Parked call extensions", curlot->parking_start, curlot->parking_stop);
04492       ast_cli(a->fd,"\n");
04493       ao2_ref(curlot, -1);
04494    }
04495    ao2_iterator_destroy(&iter);
04496 
04497    return CLI_SUCCESS;
04498 }
04499 
04500 int ast_features_reload(void)
04501 {
04502    int res;
04503    /* Release parking lot list */
04504    //ASTOBJ_CONTAINER_MARKALL(&parkinglots);
04505    // TODO: I don't think any marking is necessary
04506 
04507    /* Reload configuration */
04508    res = load_config();
04509    
04510    //ASTOBJ_CONTAINER_PRUNE_MARKED(&parkinglots, parkinglot_destroy);
04511    return res;
04512 }
04513 
04514 static char *handle_features_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
04515 {
04516    switch (cmd) { 
04517    case CLI_INIT:
04518       e->command = "features reload";
04519       e->usage =
04520          "Usage: features reload\n"
04521          "       Reloads configured call features from features.conf\n";
04522       return NULL;
04523    case CLI_GENERATE:
04524       return NULL;
04525    }
04526    ast_features_reload();
04527 
04528    return CLI_SUCCESS;
04529 }
04530 
04531 static char mandescr_bridge[] =
04532 "Description: Bridge together two channels already in the PBX\n"
04533 "Variables: ( Headers marked with * are required )\n"
04534 "   *Channel1: Channel to Bridge to Channel2\n"
04535 "   *Channel2: Channel to Bridge to Channel1\n"
04536 "        Tone: (Yes|No) Play courtesy tone to Channel 2\n"
04537 "\n";
04538 
04539 /*!
04540  * \brief Actual bridge
04541  * \param chan
04542  * \param tmpchan
04543  * 
04544  * Stop hold music, lock both channels, masq channels,
04545  * after bridge return channel to next priority.
04546 */
04547 static void do_bridge_masquerade(struct ast_channel *chan, struct ast_channel *tmpchan)
04548 {
04549    ast_moh_stop(chan);
04550    ast_channel_lock(chan);
04551    ast_setstate(tmpchan, chan->_state);
04552    tmpchan->readformat = chan->readformat;
04553    tmpchan->writeformat = chan->writeformat;
04554    ast_channel_masquerade(tmpchan, chan);
04555    ast_channel_lock(tmpchan);
04556    ast_do_masquerade(tmpchan);
04557    /* when returning from bridge, the channel will continue at the next priority */
04558    ast_explicit_goto(tmpchan, chan->context, chan->exten, chan->priority + 1);
04559    ast_channel_unlock(tmpchan);
04560    ast_channel_unlock(chan);
04561 }
04562 
04563 /*!
04564  * \brief Bridge channels together
04565  * \param s
04566  * \param m
04567  * 
04568  * Make sure valid channels were specified, 
04569  * send errors if any of the channels could not be found/locked, answer channels if needed,
04570  * create the placeholder channels and grab the other channels 
04571  * make the channels compatible, send error if we fail doing so 
04572  * setup the bridge thread object and start the bridge.
04573  * 
04574  * \retval 0 on success or on incorrect use.
04575  * \retval 1 on failure to bridge channels.
04576 */
04577 static int action_bridge(struct mansession *s, const struct message *m)
04578 {
04579    const char *channela = astman_get_header(m, "Channel1");
04580    const char *channelb = astman_get_header(m, "Channel2");
04581    const char *playtone = astman_get_header(m, "Tone");
04582    struct ast_channel *chana = NULL, *chanb = NULL;
04583    struct ast_channel *tmpchana = NULL, *tmpchanb = NULL;
04584    struct ast_bridge_thread_obj *tobj = NULL;
04585 
04586    /* make sure valid channels were specified */
04587    if (ast_strlen_zero(channela) || ast_strlen_zero(channelb)) {
04588       astman_send_error(s, m, "Missing channel parameter in request");
04589       return 0;
04590    }
04591 
04592    /* The same code must be executed for chana and chanb.  To avoid a
04593     * theoretical deadlock, this code is separated so both chana and chanb will
04594     * not hold locks at the same time. */
04595 
04596    /* Start with chana */
04597    chana = ast_get_channel_by_name_prefix_locked(channela, strlen(channela));
04598 
04599    /* send errors if any of the channels could not be found/locked */
04600    if (!chana) {
04601       char buf[256];
04602       snprintf(buf, sizeof(buf), "Channel1 does not exists: %s", channela);
04603       astman_send_error(s, m, buf);
04604       return 0;
04605    }
04606 
04607    /* Answer the channels if needed */
04608    if (chana->_state != AST_STATE_UP)
04609       ast_answer(chana);
04610 
04611    /* create the placeholder channels and grab the other channels */
04612    if (!(tmpchana = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL, 
04613       NULL, NULL, 0, "Bridge/%s", chana->name))) {
04614       astman_send_error(s, m, "Unable to create temporary channel!");
04615       ast_channel_unlock(chana);
04616       return 1;
04617    }
04618 
04619    do_bridge_masquerade(chana, tmpchana);
04620    ast_channel_unlock(chana);
04621    chana = NULL;
04622 
04623    /* now do chanb */
04624    chanb = ast_get_channel_by_name_prefix_locked(channelb, strlen(channelb));
04625    /* send errors if any of the channels could not be found/locked */
04626    if (!chanb) {
04627       char buf[256];
04628       snprintf(buf, sizeof(buf), "Channel2 does not exists: %s", channelb);
04629       ast_hangup(tmpchana);
04630       astman_send_error(s, m, buf);
04631       return 0;
04632    }
04633 
04634    /* Answer the channels if needed */
04635    if (chanb->_state != AST_STATE_UP)
04636       ast_answer(chanb);
04637 
04638    /* create the placeholder channels and grab the other channels */
04639    if (!(tmpchanb = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL, 
04640       NULL, NULL, 0, "Bridge/%s", chanb->name))) {
04641       astman_send_error(s, m, "Unable to create temporary channels!");
04642       ast_hangup(tmpchana);
04643       ast_channel_unlock(chanb);
04644       return 1;
04645    }
04646    do_bridge_masquerade(chanb, tmpchanb);
04647    ast_channel_unlock(chanb);
04648    chanb = NULL;
04649 
04650    /* make the channels compatible, send error if we fail doing so */
04651    if (ast_channel_make_compatible(tmpchana, tmpchanb)) {
04652       ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for manager bridge\n", tmpchana->name, tmpchanb->name);
04653       astman_send_error(s, m, "Could not make channels compatible for manager bridge");
04654       ast_hangup(tmpchana);
04655       ast_hangup(tmpchanb);
04656       return 1;
04657    }
04658 
04659    /* setup the bridge thread object and start the bridge */
04660    if (!(tobj = ast_calloc(1, sizeof(*tobj)))) {
04661       ast_log(LOG_WARNING, "Unable to spawn a new bridge thread on %s and %s: %s\n", tmpchana->name, tmpchanb->name, strerror(errno));
04662       astman_send_error(s, m, "Unable to spawn a new bridge thread");
04663       ast_hangup(tmpchana);
04664       ast_hangup(tmpchanb);
04665       return 1;
04666    }
04667 
04668    tobj->chan = tmpchana;
04669    tobj->peer = tmpchanb;
04670    tobj->return_to_pbx = 1;
04671 
04672    if (ast_true(playtone)) {
04673       if (!ast_strlen_zero(xfersound) && !ast_streamfile(tmpchanb, xfersound, tmpchanb->language)) {
04674          if (ast_waitstream(tmpchanb, "") < 0)
04675             ast_log(LOG_WARNING, "Failed to play a courtesy tone on chan %s\n", tmpchanb->name);
04676       }
04677    }
04678 
04679    bridge_call_thread_launch(tobj);
04680 
04681    astman_send_ack(s, m, "Launched bridge thread with success");
04682 
04683    return 0;
04684 }
04685 
04686 /*!
04687  * \brief CLI command to list parked calls
04688  * \param e 
04689  * \param cmd
04690  * \param a
04691  *  
04692  * Check right usage, lock parking lot, display parked calls, unlock parking lot list.
04693  * \retval CLI_SUCCESS on success.
04694  * \retval CLI_SHOWUSAGE on incorrect number of arguments.
04695  * \retval NULL when tab completion is used.
04696 */
04697 static char *handle_parkedcalls(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
04698 {
04699    struct parkeduser *cur;
04700    int numparked = 0;
04701    struct ao2_iterator iter;
04702    struct ast_parkinglot *curlot;
04703 
04704    switch (cmd) {
04705    case CLI_INIT:
04706       e->command = "parkedcalls show";
04707       e->usage =
04708          "Usage: parkedcalls show\n"
04709          "       List currently parked calls\n";
04710       return NULL;
04711    case CLI_GENERATE:
04712       return NULL;
04713    }
04714 
04715    if (a->argc > e->args)
04716       return CLI_SHOWUSAGE;
04717 
04718    ast_cli(a->fd, "%4s %25s (%-15s %-12s %-4s) %-6s \n", "Num", "Channel"
04719       , "Context", "Extension", "Pri", "Timeout");
04720 
04721    iter = ao2_iterator_init(parkinglots, 0);
04722    while ((curlot = ao2_iterator_next(&iter))) {
04723       int lotparked = 0;
04724       ast_cli(a->fd, "*** Parking lot: %s\n", curlot->name);
04725 
04726       AST_LIST_LOCK(&curlot->parkings);
04727       AST_LIST_TRAVERSE(&curlot->parkings, cur, list) {
04728          ast_cli(a->fd, "%-10.10s %25s (%-15s %-12s %-4d) %6lds\n"
04729             ,cur->parkingexten, cur->chan->name, cur->context, cur->exten
04730             ,cur->priority,
04731             (long)(cur->start.tv_sec + (cur->parkingtime/1000) - time(NULL)) );
04732          numparked++;
04733          numparked += lotparked;
04734       }
04735       AST_LIST_UNLOCK(&curlot->parkings);
04736       if (lotparked)
04737          ast_cli(a->fd, "   %d parked call%s in parking lot %s\n", lotparked, ESS(lotparked), curlot->name);
04738 
04739       ao2_ref(curlot, -1);
04740    }
04741 
04742    ast_cli(a->fd, "---\n%d parked call%s in total.\n", numparked, ESS(numparked));
04743 
04744    return CLI_SUCCESS;
04745 }
04746 
04747 static struct ast_cli_entry cli_features[] = {
04748    AST_CLI_DEFINE(handle_feature_show, "Lists configured features"),
04749    AST_CLI_DEFINE(handle_features_reload, "Reloads configured features"),
04750    AST_CLI_DEFINE(handle_parkedcalls, "List currently parked calls"),
04751 };
04752 
04753 /*! 
04754  * \brief Dump parking lot status
04755  * \param s
04756  * \param m
04757  * 
04758  * Lock parking lot, iterate list and append parked calls status, unlock parking lot.
04759  * \return Always RESULT_SUCCESS 
04760 */
04761 static int manager_parking_status(struct mansession *s, const struct message *m)
04762 {
04763    struct parkeduser *cur;
04764    const char *id = astman_get_header(m, "ActionID");
04765    char idText[256] = "";
04766    struct ao2_iterator iter;
04767    struct ast_parkinglot *curlot;
04768 
04769    if (!ast_strlen_zero(id))
04770       snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
04771 
04772    astman_send_ack(s, m, "Parked calls will follow");
04773 
04774    iter = ao2_iterator_init(parkinglots, 0);
04775    while ((curlot = ao2_iterator_next(&iter))) {
04776 
04777       AST_LIST_LOCK(&curlot->parkings);
04778       AST_LIST_TRAVERSE(&curlot->parkings, cur, list) {
04779          astman_append(s, "Event: ParkedCall\r\n"
04780             "Exten: %d\r\n"
04781             "Channel: %s\r\n"
04782             "From: %s\r\n"
04783             "Timeout: %ld\r\n"
04784             "CallerIDNum: %s\r\n"
04785             "CallerIDName: %s\r\n"
04786             "%s"
04787             "\r\n",
04788             cur->parkingnum, cur->chan->name, cur->peername,
04789             (long) cur->start.tv_sec + (long) (cur->parkingtime / 1000) - (long) time(NULL),
04790             S_OR(cur->chan->cid.cid_num, ""),   /* XXX in other places it is <unknown> */
04791             S_OR(cur->chan->cid.cid_name, ""),
04792             idText);
04793       }
04794       AST_LIST_UNLOCK(&curlot->parkings);
04795       ao2_ref(curlot, -1);
04796    }
04797 
04798    astman_append(s,
04799       "Event: ParkedCallsComplete\r\n"
04800       "%s"
04801       "\r\n",idText);
04802 
04803 
04804    return RESULT_SUCCESS;
04805 }
04806 
04807 static char mandescr_park[] =
04808 "Description: Park a channel.\n"
04809 "Variables: (Names marked with * are required)\n"
04810 "  *Channel: Channel name to park\n"
04811 "  *Channel2: Channel to announce park info to (and return to if timeout)\n"
04812 "  Timeout: Number of milliseconds to wait before callback.\n";  
04813 
04814 /*!
04815  * \brief Create manager event for parked calls
04816  * \param s
04817  * \param m
04818  *
04819  * Get channels involved in park, create event.
04820  * \return Always 0
04821 */
04822 static int manager_park(struct mansession *s, const struct message *m)
04823 {
04824    const char *channel = astman_get_header(m, "Channel");
04825    const char *channel2 = astman_get_header(m, "Channel2");
04826    const char *timeout = astman_get_header(m, "Timeout");
04827    char buf[BUFSIZ];
04828    int to = 0;
04829    int res = 0;
04830    int parkExt = 0;
04831    struct ast_channel *ch1, *ch2;
04832 
04833    if (ast_strlen_zero(channel)) {
04834       astman_send_error(s, m, "Channel not specified");
04835       return 0;
04836    }
04837 
04838    if (ast_strlen_zero(channel2)) {
04839       astman_send_error(s, m, "Channel2 not specified");
04840       return 0;
04841    }
04842 
04843    ch1 = ast_get_channel_by_name_locked(channel);
04844    if (!ch1) {
04845       snprintf(buf, sizeof(buf), "Channel does not exist: %s", channel);
04846       astman_send_error(s, m, buf);
04847       return 0;
04848    }
04849 
04850    ch2 = ast_get_channel_by_name_locked(channel2);
04851    if (!ch2) {
04852       snprintf(buf, sizeof(buf), "Channel does not exist: %s", channel2);
04853       astman_send_error(s, m, buf);
04854       ast_channel_unlock(ch1);
04855       return 0;
04856    }
04857 
04858    if (!ast_strlen_zero(timeout)) {
04859       sscanf(timeout, "%30d", &to);
04860    }
04861 
04862    res = ast_masq_park_call(ch1, ch2, to, &parkExt);
04863    if (!res) {
04864       ast_softhangup(ch2, AST_SOFTHANGUP_EXPLICIT);
04865       astman_send_ack(s, m, "Park successful");
04866    } else {
04867       astman_send_error(s, m, "Park failure");
04868    }
04869 
04870    ast_channel_unlock(ch1);
04871    ast_channel_unlock(ch2);
04872 
04873    return 0;
04874 }
04875 
04876 static int find_channel_by_group(struct ast_channel *c, void *data) {
04877    struct ast_channel *chan = data;
04878 
04879    return !c->pbx &&
04880       /* Accessing 'chan' here is safe without locking, because there is no way for
04881          the channel do disappear from under us at this point.  pickupgroup *could*
04882          change while we're here, but that isn't a problem. */
04883       (c != chan) &&
04884       (chan->pickupgroup & c->callgroup) &&
04885       ((c->_state == AST_STATE_RINGING) || (c->_state == AST_STATE_RING)) &&
04886       !c->masq;
04887 }
04888 
04889 /*!
04890  * \brief Pickup a call
04891  * \param chan channel that initiated pickup.
04892  *
04893  * Walk list of channels, checking it is not itself, channel is pbx one,
04894  * check that the callgroup for both channels are the same and the channel is ringing.
04895  * Answer calling channel, flag channel as answered on queue, masq channels together.
04896 */
04897 int ast_pickup_call(struct ast_channel *chan)
04898 {
04899    struct ast_channel *cur = ast_channel_search_locked(find_channel_by_group, chan);
04900 
04901    if (cur) {
04902       int res = -1;
04903       ast_debug(1, "Call pickup on chan '%s' by '%s'\n",cur->name, chan->name);
04904       res = ast_answer(chan);
04905       if (res)
04906          ast_log(LOG_WARNING, "Unable to answer '%s'\n", chan->name);
04907       res = ast_queue_control(chan, AST_CONTROL_ANSWER);
04908       if (res)
04909          ast_log(LOG_WARNING, "Unable to queue answer on '%s'\n", chan->name);
04910       res = ast_channel_masquerade(cur, chan);
04911       if (res)
04912          ast_log(LOG_WARNING, "Unable to masquerade '%s' into '%s'\n", chan->name, cur->name);     /* Done */
04913       if (!ast_strlen_zero(pickupsound)) {
04914          ast_stream_and_wait(cur, pickupsound, "");
04915       }
04916       ast_channel_unlock(cur);
04917       return res;
04918    } else   {
04919       ast_debug(1, "No call pickup possible...\n");
04920       if (!ast_strlen_zero(pickupfailsound)) {
04921          ast_stream_and_wait(chan, pickupfailsound, "");
04922       }
04923    }
04924    return -1;
04925 }
04926 
04927 static char *app_bridge = "Bridge";
04928 
04929 enum {
04930    BRIDGE_OPT_PLAYTONE = (1 << 0),
04931 };
04932 
04933 AST_APP_OPTIONS(bridge_exec_options, BEGIN_OPTIONS
04934    AST_APP_OPTION('p', BRIDGE_OPT_PLAYTONE)
04935 END_OPTIONS );
04936 
04937 /*!
04938  * \brief Bridge channels
04939  * \param chan
04940  * \param data channel to bridge with.
04941  * 
04942  * Split data, check we aren't bridging with ourself, check valid channel,
04943  * answer call if not already, check compatible channels, setup bridge config
04944  * now bridge call, if transfered party hangs up return to PBX extension.
04945 */
04946 static int bridge_exec(struct ast_channel *chan, void *data)
04947 {
04948    struct ast_channel *current_dest_chan, *final_dest_chan;
04949    char *tmp_data  = NULL;
04950    struct ast_flags opts = { 0, };
04951    struct ast_bridge_config bconfig = { { 0, }, };
04952 
04953    AST_DECLARE_APP_ARGS(args,
04954       AST_APP_ARG(dest_chan);
04955       AST_APP_ARG(options);
04956    );
04957    
04958    if (ast_strlen_zero(data)) {
04959       ast_log(LOG_WARNING, "Bridge require at least 1 argument specifying the other end of the bridge\n");
04960       return -1;
04961    }
04962 
04963    tmp_data = ast_strdupa(data);
04964    AST_STANDARD_APP_ARGS(args, tmp_data);
04965    if (!ast_strlen_zero(args.options))
04966       ast_app_parse_options(bridge_exec_options, &opts, NULL, args.options);
04967 
04968    /* avoid bridge with ourselves */
04969    if (!strcmp(chan->name, args.dest_chan)) {
04970       ast_log(LOG_WARNING, "Unable to bridge channel %s with itself\n", chan->name);
04971       manager_event(EVENT_FLAG_CALL, "BridgeExec",
04972                "Response: Failed\r\n"
04973                "Reason: Unable to bridge channel to itself\r\n"
04974                "Channel1: %s\r\n"
04975                "Channel2: %s\r\n",
04976                chan->name, args.dest_chan);
04977       pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "LOOP");
04978       return 0;
04979    }
04980 
04981    /* make sure we have a valid end point */
04982    if (!(current_dest_chan = ast_get_channel_by_name_prefix_locked(args.dest_chan, 
04983       strlen(args.dest_chan)))) {
04984       ast_log(LOG_WARNING, "Bridge failed because channel %s does not exists or we "
04985          "cannot get its lock\n", args.dest_chan);
04986       manager_event(EVENT_FLAG_CALL, "BridgeExec",
04987                "Response: Failed\r\n"
04988                "Reason: Cannot grab end point\r\n"
04989                "Channel1: %s\r\n"
04990                "Channel2: %s\r\n", chan->name, args.dest_chan);
04991       pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "NONEXISTENT");
04992       return 0;
04993    }
04994 
04995    /* answer the channel if needed */
04996    if (current_dest_chan->_state != AST_STATE_UP)
04997       ast_answer(current_dest_chan);
04998 
04999    /* try to allocate a place holder where current_dest_chan will be placed */
05000    if (!(final_dest_chan = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL, 
05001       NULL, NULL, 0, "Bridge/%s", current_dest_chan->name))) {
05002       ast_log(LOG_WARNING, "Cannot create placeholder channel for chan %s\n", args.dest_chan);
05003       manager_event(EVENT_FLAG_CALL, "BridgeExec",
05004                "Response: Failed\r\n"
05005                "Reason: cannot create placeholder\r\n"
05006                "Channel1: %s\r\n"
05007                "Channel2: %s\r\n", chan->name, args.dest_chan);
05008    }
05009    do_bridge_masquerade(current_dest_chan, final_dest_chan);
05010 
05011    ast_channel_unlock(current_dest_chan);
05012 
05013    /* now current_dest_chan is a ZOMBIE and with softhangup set to 1 and final_dest_chan is our end point */
05014    /* try to make compatible, send error if we fail */
05015    if (ast_channel_make_compatible(chan, final_dest_chan) < 0) {
05016       ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for bridge\n", chan->name, final_dest_chan->name);
05017       manager_event(EVENT_FLAG_CALL, "BridgeExec",
05018                "Response: Failed\r\n"
05019                "Reason: Could not make channels compatible for bridge\r\n"
05020                "Channel1: %s\r\n"
05021                "Channel2: %s\r\n", chan->name, final_dest_chan->name);
05022       ast_hangup(final_dest_chan); /* may be we should return this channel to the PBX? */
05023       pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "INCOMPATIBLE");
05024       return 0;
05025    }
05026 
05027    /* Report that the bridge will be successfull */
05028    manager_event(EVENT_FLAG_CALL, "BridgeExec",
05029             "Response: Success\r\n"
05030             "Channel1: %s\r\n"
05031             "Channel2: %s\r\n", chan->name, final_dest_chan->name);
05032 
05033    /* we have 2 valid channels to bridge, now it is just a matter of setting up the bridge config and starting the bridge */  
05034    if (ast_test_flag(&opts, BRIDGE_OPT_PLAYTONE) && !ast_strlen_zero(xfersound)) {
05035       if (!ast_streamfile(final_dest_chan, xfersound, final_dest_chan->language)) {
05036          if (ast_waitstream(final_dest_chan, "") < 0)
05037             ast_log(LOG_WARNING, "Failed to play courtesy tone on %s\n", final_dest_chan->name);
05038       }
05039    }
05040    
05041    /* do the bridge */
05042    ast_bridge_call(chan, final_dest_chan, &bconfig);
05043 
05044    /* the bridge has ended, set BRIDGERESULT to SUCCESS. If the other channel has not been hung up, return it to the PBX */
05045    pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "SUCCESS");
05046    if (!ast_check_hangup(final_dest_chan)) {
05047       ast_debug(1, "starting new PBX in %s,%s,%d for chan %s\n", 
05048          final_dest_chan->context, final_dest_chan->exten, 
05049          final_dest_chan->priority, final_dest_chan->name);
05050 
05051       if (ast_pbx_start(final_dest_chan) != AST_PBX_SUCCESS) {
05052          ast_log(LOG_WARNING, "FAILED continuing PBX on dest chan %s\n", final_dest_chan->name);
05053          ast_hangup(final_dest_chan);
05054       } else
05055          ast_debug(1, "SUCCESS continuing PBX on chan %s\n", final_dest_chan->name);
05056    } else {
05057       ast_debug(1, "hangup chan %s since the other endpoint has hung up\n", final_dest_chan->name);
05058       ast_hangup(final_dest_chan);
05059    }
05060 
05061    return 0;
05062 }
05063 
05064 int ast_features_init(void)
05065 {
05066    int res;
05067 
05068    ast_register_application2(app_bridge, bridge_exec, NULL, NULL, NULL);
05069 
05070    parkinglots = ao2_container_alloc(7, parkinglot_hash_cb, parkinglot_cmp_cb);
05071 
05072    if ((res = load_config()))
05073       return res;
05074    ast_cli_register_multiple(cli_features, ARRAY_LEN(cli_features));
05075    ast_pthread_create(&parking_thread, NULL, do_parking_thread, NULL);
05076    res = ast_register_application2(parkedcall, park_exec, NULL, NULL, NULL);
05077    if (!res)
05078       res = ast_register_application2(parkcall, park_call_exec, NULL, NULL, NULL);
05079    if (!res) {
05080       ast_manager_register("ParkedCalls", 0, manager_parking_status, "List parked calls");
05081       ast_manager_register2("Park", EVENT_FLAG_CALL, manager_park, "Park a channel", mandescr_park); 
05082       ast_manager_register2("Bridge", EVENT_FLAG_CALL, action_bridge, "Bridge two channels already in the PBX", mandescr_bridge);
05083    }
05084 
05085    res |= ast_devstate_prov_add("Park", metermaidstate);
05086 
05087    return res;
05088 }