Mon Sep 20 2010 00:22:40

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