Fri Jul 15 2011 11:58:08

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