38f45400e4c28765bdee3af8d3e4d141f20fb6e3
[asterisk/asterisk.git] / main / features.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2008, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file
20  *
21  * \brief Routines implementing call features as call pickup, parking and transfer
22  *
23  * \author Mark Spencer <markster@digium.com> 
24  */
25
26 #include "asterisk.h"
27
28 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
29
30 #include "asterisk/_private.h"
31
32 #include <pthread.h>
33 #include <sys/time.h>
34 #include <sys/signal.h>
35 #include <netinet/in.h>
36
37 #include "asterisk/lock.h"
38 #include "asterisk/file.h"
39 #include "asterisk/channel.h"
40 #include "asterisk/pbx.h"
41 #include "asterisk/causes.h"
42 #include "asterisk/module.h"
43 #include "asterisk/translate.h"
44 #include "asterisk/app.h"
45 #include "asterisk/say.h"
46 #include "asterisk/features.h"
47 #include "asterisk/musiconhold.h"
48 #include "asterisk/config.h"
49 #include "asterisk/cli.h"
50 #include "asterisk/manager.h"
51 #include "asterisk/utils.h"
52 #include "asterisk/adsi.h"
53 #include "asterisk/devicestate.h"
54 #include "asterisk/monitor.h"
55 #include "asterisk/audiohook.h"
56 #include "asterisk/global_datastores.h"
57 #include "asterisk/astobj2.h"
58
59 /*** DOCUMENTATION
60         <application name="Bridge" language="en_US">
61                 <synopsis>
62                         Bridge two channels.
63                 </synopsis>
64                 <syntax>
65                         <parameter name="channel" required="true">
66                                 <para>The current channel is bridged to the specified <replaceable>channel</replaceable>.</para>
67                         </parameter>
68                         <parameter name="options">
69                                 <optionlist>
70                                         <option name="p">
71                                                 <para>Play a courtesy tone to <replaceable>channel</replaceable>.</para>
72                                         </option>
73                                 </optionlist>
74                         </parameter>
75                 </syntax>
76                 <description>
77                         <para>Allows the ability to bridge two channels via the dialplan.</para>
78                         <para>This application sets the following channel variable upon completion:</para>
79                         <variablelist>
80                                 <variable name="BRIDGERESULT">
81                                         <para>The result of the bridge attempt as a text string.</para>
82                                         <value name="SUCCESS" />
83                                         <value name="FAILURE" />
84                                         <value name="LOOP" />
85                                         <value name="NONEXISTENT" />
86                                         <value name="INCOMPATIBLE" />
87                                 </variable>
88                         </variablelist>
89                 </description>
90         </application>
91         <application name="ParkedCall" language="en_US">
92                 <synopsis>
93                         Answer a parked call.
94                 </synopsis>
95                 <syntax>
96                         <parameter name="exten" required="true" />
97                 </syntax>
98                 <description>
99                         <para>Used to connect to a parked call. This application is always
100                         registered internally and does not need to be explicitly added
101                         into the dialplan, although you should include the <literal>parkedcalls</literal>
102                         context. If no extension is provided, then the first available
103                         parked call will be acquired.</para>
104                 </description>
105                 <see-also>
106                         <ref type="application">Park</ref>
107                         <ref type="application">ParkAndAnnounce</ref>
108                 </see-also>
109         </application>
110         <application name="Park" language="en_US">
111                 <synopsis>
112                         Park yourself.
113                 </synopsis>
114                 <syntax>
115                         <parameter name="timeout">
116                                 <para>A custom parking timeout for this parked call.</para>
117                         </parameter>
118                         <parameter name="return_context">
119                                 <para>The context to return the call to after it times out.</para>
120                         </parameter>
121                         <parameter name="return_exten">
122                                 <para>The extension to return the call to after it times out.</para>
123                         </parameter>
124                         <parameter name="return_priority">
125                                 <para>The priority to return the call to after it times out.</para>
126                         </parameter>
127                         <parameter name="options">
128                                 <para>A list of options for this parked call.</para>
129                                 <optionlist>
130                                         <option name="r">
131                                                 <para>Send ringing instead of MOH to the parked call.</para>
132                                         </option>
133                                         <option name="R">
134                                                 <para>Randomize the selection of a parking space.</para>
135                                         </option>
136                                         <option name="s">
137                                                 <para>Silence announcement of the parking space number.</para>
138                                         </option>
139                                 </optionlist>
140                         </parameter>
141                 </syntax>
142                 <description>
143                         <para>Used to park yourself (typically in combination with a supervised
144                         transfer to know the parking space). This application is always
145                         registered internally and does not need to be explicitly added
146                         into the dialplan, although you should include the <literal>parkedcalls</literal>
147                         context (or the context specified in <filename>features.conf</filename>).</para>
148                         <para>If you set the <variable>PARKINGEXTEN</variable> variable to an extension in your
149                         parking context, Park() will park the call on that extension, unless
150                         it already exists. In that case, execution will continue at next priority.</para>
151                 </description>
152                 <see-also>
153                         <ref type="application">ParkAndAnnounce</ref>
154                         <ref type="application">ParkedCall</ref>
155                 </see-also>
156         </application>
157  ***/
158
159 #define DEFAULT_PARK_TIME 45000
160 #define DEFAULT_TRANSFER_DIGIT_TIMEOUT 3000
161 #define DEFAULT_FEATURE_DIGIT_TIMEOUT 2000
162 #define DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER 15000
163 #define DEFAULT_PARKINGLOT "default"                    /*!< Default parking lot */
164 #define DEFAULT_ATXFER_DROP_CALL 0
165 #define DEFAULT_ATXFER_LOOP_DELAY 10000
166 #define DEFAULT_ATXFER_CALLBACK_RETRIES 2
167
168 #define AST_MAX_WATCHERS 256
169
170 struct feature_group_exten {
171         AST_LIST_ENTRY(feature_group_exten) entry;
172         AST_DECLARE_STRING_FIELDS(
173                 AST_STRING_FIELD(exten);
174         );
175         struct ast_call_feature *feature;
176 };
177
178 struct feature_group {
179         AST_LIST_ENTRY(feature_group) entry;
180         AST_DECLARE_STRING_FIELDS(
181                 AST_STRING_FIELD(gname);
182         );
183         AST_LIST_HEAD_NOLOCK(, feature_group_exten) features;
184 };
185
186 static AST_RWLIST_HEAD_STATIC(feature_groups, feature_group);
187
188 static char *parkedcall = "ParkedCall";
189
190 static char pickup_ext[AST_MAX_EXTENSION];                 /*!< Call pickup extension */
191
192 /*! \brief Description of one parked call, added to a list while active, then removed.
193         The list belongs to a parkinglot 
194 */
195 struct parkeduser {
196         struct ast_channel *chan;                   /*!< Parking channel */
197         struct timeval start;                       /*!< Time the parking started */
198         int parkingnum;                             /*!< Parking lot */
199         char parkingexten[AST_MAX_EXTENSION];       /*!< If set beforehand, parking extension used for this call */
200         char context[AST_MAX_CONTEXT];              /*!< Where to go if our parking time expires */
201         char exten[AST_MAX_EXTENSION];
202         int priority;
203         int parkingtime;                            /*!< Maximum length in parking lot before return */
204         int notquiteyet;
205         char peername[1024];
206         unsigned char moh_trys;
207         struct ast_parkinglot *parkinglot;
208         AST_LIST_ENTRY(parkeduser) list;
209 };
210
211 /*! \brief Structure for parking lots which are put in a container. */
212 struct ast_parkinglot {
213         char name[AST_MAX_CONTEXT];
214         char parking_con[AST_MAX_EXTENSION];            /*!< Context for which parking is made accessible */
215         char parking_con_dial[AST_MAX_EXTENSION];       /*!< Context for dialback for parking (KLUDGE) */
216         int parking_start;                              /*!< First available extension for parking */
217         int parking_stop;                               /*!< Last available extension for parking */
218         int parking_offset;
219         int parkfindnext;
220         int parkingtime;                                /*!< Default parking time */
221         char mohclass[MAX_MUSICCLASS];                  /*!< Music class used for parking */
222         int parkaddhints;                               /*!< Add parking hints automatically */
223         int parkedcalltransfers;                        /*!< Enable DTMF based transfers on bridge when picking up parked calls */
224         int parkedcallreparking;                        /*!< Enable DTMF based parking on bridge when picking up parked calls */
225         AST_LIST_HEAD(parkinglot_parklist, parkeduser) parkings; /*!< List of active parkings in this parkinglot */
226 };
227
228 /*! \brief The list of parking lots configured. Always at least one  - the default parking lot */
229 static struct ao2_container *parkinglots;
230  
231 struct ast_parkinglot *default_parkinglot;
232 char parking_ext[AST_MAX_EXTENSION];            /*!< Extension you type to park the call */
233
234 static char courtesytone[256];                             /*!< Courtesy tone */
235 static int parkedplay = 0;                                 /*!< Who to play the courtesy tone to */
236 static char xfersound[256];                                /*!< Call transfer sound */
237 static char xferfailsound[256];                            /*!< Call transfer failure sound */
238
239 static int adsipark;
240
241 static int transferdigittimeout;
242 static int featuredigittimeout;
243 static int comebacktoorigin = 1;
244
245 static int atxfernoanswertimeout;
246 static unsigned int atxferdropcall;
247 static unsigned int atxferloopdelay;
248 static unsigned int atxfercallbackretries;
249
250 static char *registrar = "features";               /*!< Registrar for operations */
251
252 /* module and CLI command definitions */
253 static char *parkcall = PARK_APP_NAME;
254
255 static struct ast_app *monitor_app = NULL;
256 static int monitor_ok = 1;
257
258 static struct ast_app *mixmonitor_app = NULL;
259 static int mixmonitor_ok = 1;
260
261 static struct ast_app *stopmixmonitor_app = NULL;
262 static int stopmixmonitor_ok = 1;
263
264 static pthread_t parking_thread;
265
266 /* Forward declarations */
267 static struct ast_parkinglot *parkinglot_addref(struct ast_parkinglot *parkinglot);
268 static void parkinglot_unref(struct ast_parkinglot *parkinglot);
269 static void parkinglot_destroy(void *obj);
270 int manage_parkinglot(struct ast_parkinglot *curlot, fd_set *rfds, fd_set *efds, fd_set *nrfds, fd_set *nefds, int *fs, int *max);
271 struct ast_parkinglot *find_parkinglot(const char *name);
272
273
274 const char *ast_parking_ext(void)
275 {
276         return parking_ext;
277 }
278
279 const char *ast_pickup_ext(void)
280 {
281         return pickup_ext;
282 }
283
284 struct ast_bridge_thread_obj 
285 {
286         struct ast_bridge_config bconfig;
287         struct ast_channel *chan;
288         struct ast_channel *peer;
289         unsigned int return_to_pbx:1;
290 };
291
292 static int parkinglot_hash_cb(const void *obj, const int flags)
293 {
294         const struct ast_parkinglot *parkinglot = obj;
295
296         return ast_str_case_hash(parkinglot->name);
297 }
298
299 static int parkinglot_cmp_cb(void *obj, void *arg, int flags)
300 {
301         struct ast_parkinglot *parkinglot = obj, *parkinglot2 = arg;
302
303         return !strcasecmp(parkinglot->name, parkinglot2->name) ? CMP_MATCH | CMP_STOP : 0;
304 }
305
306 /*!
307  * \brief store context, extension and priority 
308  * \param chan, context, ext, pri
309 */
310 static void set_c_e_p(struct ast_channel *chan, const char *context, const char *ext, int pri)
311 {
312         ast_copy_string(chan->context, context, sizeof(chan->context));
313         ast_copy_string(chan->exten, ext, sizeof(chan->exten));
314         chan->priority = pri;
315 }
316
317 /*!
318  * \brief Check goto on transfer
319  * \param chan
320  *
321  * Check if channel has 'GOTO_ON_BLINDXFR' set, if not exit.
322  * When found make sure the types are compatible. Check if channel is valid
323  * if so start the new channel else hangup the call. 
324 */
325 static void check_goto_on_transfer(struct ast_channel *chan) 
326 {
327         struct ast_channel *xferchan;
328         const char *val = pbx_builtin_getvar_helper(chan, "GOTO_ON_BLINDXFR");
329         char *x, *goto_on_transfer;
330         struct ast_frame *f;
331
332         if (ast_strlen_zero(val))
333                 return;
334
335         goto_on_transfer = ast_strdupa(val);
336
337         if (!(xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "%s", chan->name)))
338                 return;
339
340         for (x = goto_on_transfer; x && *x; x++) {
341                 if (*x == '^')
342                         *x = '|';
343         }
344         /* Make formats okay */
345         xferchan->readformat = chan->readformat;
346         xferchan->writeformat = chan->writeformat;
347         ast_channel_masquerade(xferchan, chan);
348         ast_parseable_goto(xferchan, goto_on_transfer);
349         xferchan->_state = AST_STATE_UP;
350         ast_clear_flag(xferchan, AST_FLAGS_ALL);        
351         xferchan->_softhangup = 0;
352         if ((f = ast_read(xferchan))) {
353                 ast_frfree(f);
354                 f = NULL;
355                 ast_pbx_start(xferchan);
356         } else {
357                 ast_hangup(xferchan);
358         }
359 }
360
361 static struct ast_channel *ast_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);
362
363 /*!
364  * \brief bridge the call 
365  * \param data thread bridge.
366  *
367  * Set Last Data for respective channels, reset cdr for channels
368  * bridge call, check if we're going back to dialplan
369  * if not hangup both legs of the call
370 */
371 static void *ast_bridge_call_thread(void *data) 
372 {
373         struct ast_bridge_thread_obj *tobj = data;
374         int res;
375
376         tobj->chan->appl = !tobj->return_to_pbx ? "Transferred Call" : "ManagerBridge";
377         tobj->chan->data = tobj->peer->name;
378         tobj->peer->appl = !tobj->return_to_pbx ? "Transferred Call" : "ManagerBridge";
379         tobj->peer->data = tobj->chan->name;
380
381         ast_bridge_call(tobj->peer, tobj->chan, &tobj->bconfig);
382
383         if (tobj->return_to_pbx) {
384                 if (!ast_check_hangup(tobj->peer)) {
385                         ast_log(LOG_VERBOSE, "putting peer %s into PBX again\n", tobj->peer->name);
386                         res = ast_pbx_start(tobj->peer);
387                         if (res != AST_PBX_SUCCESS)
388                                 ast_log(LOG_WARNING, "FAILED continuing PBX on peer %s\n", tobj->peer->name);
389                 } else
390                         ast_hangup(tobj->peer);
391                 if (!ast_check_hangup(tobj->chan)) {
392                         ast_log(LOG_VERBOSE, "putting chan %s into PBX again\n", tobj->chan->name);
393                         res = ast_pbx_start(tobj->chan);
394                         if (res != AST_PBX_SUCCESS)
395                                 ast_log(LOG_WARNING, "FAILED continuing PBX on chan %s\n", tobj->chan->name);
396                 } else
397                         ast_hangup(tobj->chan);
398         } else {
399                 ast_hangup(tobj->chan);
400                 ast_hangup(tobj->peer);
401         }
402
403         ast_free(tobj);
404
405         return NULL;
406 }
407
408 /*!
409  * \brief create thread for the parked call
410  * \param data
411  *
412  * Create thread and attributes, call ast_bridge_call_thread
413 */
414 static void ast_bridge_call_thread_launch(void *data) 
415 {
416         pthread_t thread;
417         pthread_attr_t attr;
418         struct sched_param sched;
419
420         pthread_attr_init(&attr);
421         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
422         ast_pthread_create(&thread, &attr,ast_bridge_call_thread, data);
423         pthread_attr_destroy(&attr);
424         memset(&sched, 0, sizeof(sched));
425         pthread_setschedparam(thread, SCHED_RR, &sched);
426 }
427
428 /*!
429  * \brief Announce call parking by ADSI
430  * \param chan .
431  * \param parkingexten .
432  * Create message to show for ADSI, display message.
433  * \retval 0 on success.
434  * \retval -1 on failure.
435 */
436 static int adsi_announce_park(struct ast_channel *chan, char *parkingexten)
437 {
438         int res;
439         int justify[5] = {ADSI_JUST_CENT, ADSI_JUST_CENT, ADSI_JUST_CENT, ADSI_JUST_CENT};
440         char tmp[256];
441         char *message[5] = {NULL, NULL, NULL, NULL, NULL};
442
443         snprintf(tmp, sizeof(tmp), "Parked on %s", parkingexten);
444         message[0] = tmp;
445         res = ast_adsi_load_session(chan, NULL, 0, 1);
446         if (res == -1)
447                 return res;
448         return ast_adsi_print(chan, message, justify, 1);
449 }
450
451 /*! \brief Find parking lot name from channel */
452 static const char *findparkinglotname(struct ast_channel *chan)
453 {
454         const char *temp, *parkinglot = NULL;
455
456         /* Check if the channel has a parking lot */
457         if (!ast_strlen_zero(chan->parkinglot))
458                 parkinglot = chan->parkinglot;
459
460         /* Channel variables override everything */
461
462         if ((temp  = pbx_builtin_getvar_helper(chan, "PARKINGLOT")))
463                 return temp;
464
465         return parkinglot;
466 }
467
468 /*! \brief Notify metermaids that we've changed an extension */
469 static void notify_metermaids(const char *exten, char *context, enum ast_device_state state)
470 {
471         ast_debug(4, "Notification of state change to metermaids %s@%s\n to state '%s'", 
472                 exten, context, ast_devstate2str(state));
473
474         ast_devstate_changed(state, "park:%s@%s", exten, context);
475 }
476
477 /*! \brief metermaids callback from devicestate.c */
478 static enum ast_device_state metermaidstate(const char *data)
479 {
480         char *context;
481         char *exten;
482
483         context = ast_strdupa(data);
484
485         exten = strsep(&context, "@");
486         if (!context)
487                 return AST_DEVICE_INVALID;
488         
489         ast_debug(4, "Checking state of exten %s in context %s\n", exten, context);
490
491         if (!ast_exists_extension(NULL, context, exten, 1, NULL))
492                 return AST_DEVICE_NOT_INUSE;
493
494         return AST_DEVICE_INUSE;
495 }
496
497 /*! Options to pass to ast_park_call_full */
498 enum ast_park_call_options {
499         /*! Provide ringing to the parked caller instead of music on hold */
500         AST_PARK_OPT_RINGING =   (1 << 0),
501         /*! Randomly choose a parking spot for the caller instead of choosing
502          *  the first one that is available. */
503         AST_PARK_OPT_RANDOMIZE = (1 << 1),
504         /*! Do not announce the parking number */
505         AST_PARK_OPT_SILENCE = (1 << 2),
506 };
507
508 struct ast_park_call_args {
509         /*! How long to wait in the parking lot before the call gets sent back
510          *  to the specified return extension (or a best guess at where it came
511          *  from if not explicitly specified). */
512         int timeout;
513         /*! An output parameter to store the parking space where the parked caller
514          *  was placed. */
515         int *extout;
516         const char *orig_chan_name;
517         const char *return_con;
518         const char *return_ext;
519         int return_pri;
520         uint32_t flags;
521 };
522
523 /* Park a call */
524 static int ast_park_call_full(struct ast_channel *chan, struct ast_channel *peer, 
525         struct ast_park_call_args *args)
526 {
527         struct parkeduser *pu;
528         int i, x = -1, parking_range, parkingnum_copy;
529         struct ast_context *con;
530         const char *parkinglotname = NULL;
531         const char *parkingexten;
532         struct ast_parkinglot *parkinglot = NULL;
533         
534         if (peer)
535                 parkinglotname = findparkinglotname(peer);
536
537         if (parkinglotname) {
538                 if (option_debug)
539                         ast_log(LOG_DEBUG, "Found chanvar Parkinglot: %s\n", parkinglotname);
540                 parkinglot = find_parkinglot(parkinglotname);   
541         }
542         if (!parkinglot)
543                 parkinglot = default_parkinglot;
544
545         parkinglot_addref(parkinglot);
546         if (option_debug)
547                 ast_log(LOG_DEBUG, "Parkinglot: %s\n", parkinglot->name);
548
549         /* Allocate memory for parking data */
550         if (!(pu = ast_calloc(1, sizeof(*pu)))) {
551                 parkinglot_unref(parkinglot);
552                 return -1;
553         }
554
555         /* Lock parking list */
556         AST_LIST_LOCK(&parkinglot->parkings);
557         /* Check for channel variable PARKINGEXTEN */
558         parkingexten = pbx_builtin_getvar_helper(chan, "PARKINGEXTEN");
559         if (!ast_strlen_zero(parkingexten)) {
560                 /*!\note The API forces us to specify a numeric parking slot, even
561                  * though the architecture would tend to support non-numeric extensions
562                  * (as are possible with SIP, for example).  Hence, we enforce that
563                  * limitation here.  If extout was not numeric, we could permit
564                  * arbitrary non-numeric extensions.
565                  */
566         if (sscanf(parkingexten, "%d", &x) != 1 || x < 0) {
567                         AST_LIST_UNLOCK(&parkinglot->parkings);
568                         parkinglot_unref(parkinglot);
569             free(pu);
570             ast_log(LOG_WARNING, "PARKINGEXTEN does not indicate a valid parking slot: '%s'.\n", parkingexten);
571             return 1;   /* Continue execution if possible */
572         }
573         snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", x);
574
575                 if (ast_exists_extension(NULL, parkinglot->parking_con, pu->parkingexten, 1, NULL)) {
576                         AST_LIST_UNLOCK(&parkinglot->parkings);
577                         parkinglot_unref(parkinglot);
578                         ast_free(pu);
579                         ast_log(LOG_WARNING, "Requested parking extension already exists: %s@%s\n", parkingexten, parkinglot->parking_con);
580                         return 1;       /* Continue execution if possible */
581                 }
582         } else {
583                 int start;
584                 struct parkeduser *cur = NULL;
585
586                 /* Select parking space within range */
587                 parking_range = parkinglot->parking_stop - parkinglot->parking_start + 1;
588
589                 if (ast_test_flag(args, AST_PARK_OPT_RANDOMIZE)) {
590                         start = ast_random() % (parkinglot->parking_stop - parkinglot->parking_start + 1);
591                 } else {
592                         start = parkinglot->parking_start;
593                 }
594
595                 for (i = start; 1; i++) {
596                         if (i == parkinglot->parking_stop + 1) {
597                                 i = parkinglot->parking_start - 1;
598                                 continue;
599                         }
600
601                         AST_LIST_TRAVERSE(&parkinglot->parkings, cur, list) {
602                                 if (cur->parkingnum == i) {
603                                         break;
604                                 }
605                         }
606
607                         if (!cur || i == start - 1) {
608                                 x = i;
609                                 break;
610                         }
611                 }
612
613                 if (i == start - 1 && cur) {
614                         ast_log(LOG_WARNING, "No more parking spaces\n");
615                         ast_free(pu);
616                         AST_LIST_UNLOCK(&parkinglot->parkings);
617                         parkinglot_unref(parkinglot);
618                         return -1;
619                 }
620                 /* Set pointer for next parking */
621                 if (parkinglot->parkfindnext) 
622                         parkinglot->parking_offset = x - parkinglot->parking_start + 1;
623                 snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", x);
624         }
625         
626         chan->appl = "Parked Call";
627         chan->data = NULL; 
628
629         pu->chan = chan;
630         
631         /* Put the parked channel on hold if we have two different channels */
632         if (chan != peer) {
633                 if (ast_test_flag(args, AST_PARK_OPT_RINGING)) {
634                         ast_indicate(pu->chan, AST_CONTROL_RINGING);
635                 } else {
636                         ast_indicate_data(pu->chan, AST_CONTROL_HOLD, 
637                                 S_OR(parkinglot->mohclass, NULL),
638                                 !ast_strlen_zero(parkinglot->mohclass) ? strlen(parkinglot->mohclass) + 1 : 0);
639                 }
640         }
641         
642         pu->start = ast_tvnow();
643         pu->parkingnum = x;
644         pu->parkinglot = parkinglot;
645         pu->parkingtime = (args->timeout > 0) ? args->timeout : parkinglot->parkingtime;
646         parkingnum_copy = pu->parkingnum;
647         if (args->extout)
648                 *(args->extout) = x;
649
650         if (peer) 
651                 ast_copy_string(pu->peername, peer->name, sizeof(pu->peername));
652
653         /* Remember what had been dialed, so that if the parking
654            expires, we try to come back to the same place */
655         ast_copy_string(pu->context, 
656                 S_OR(args->return_con, S_OR(chan->macrocontext, chan->context)), 
657                 sizeof(pu->context));
658         ast_copy_string(pu->exten, 
659                 S_OR(args->return_ext, S_OR(chan->macroexten, chan->exten)), 
660                 sizeof(pu->exten));
661         pu->priority = pu->priority ? pu->priority : 
662                 (chan->macropriority ? chan->macropriority : chan->priority);
663
664         AST_LIST_INSERT_TAIL(&parkinglot->parkings, pu, list);
665
666         /* If parking a channel directly, don't quiet yet get parking running on it */
667         if (peer == chan) 
668                 pu->notquiteyet = 1;
669
670         /* Wake up the (presumably select()ing) thread */
671         pthread_kill(parking_thread, SIGURG);
672         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, parkinglot->name, pu->context, pu->exten, pu->priority, (pu->parkingtime/1000));
673
674         manager_event(EVENT_FLAG_CALL, "ParkedCall",
675                 "Exten: %s\r\n"
676                 "Channel: %s\r\n"
677                 "Parkinglot: %s\r\n"
678                 "From: %s\r\n"
679                 "Timeout: %ld\r\n"
680                 "CallerIDNum: %s\r\n"
681                 "CallerIDName: %s\r\n"
682                 "Uniqueid: %s\r\n",
683                 pu->parkingexten, pu->chan->name, pu->parkinglot->name, peer ? peer->name : "",
684                 (long)pu->start.tv_sec + (long)(pu->parkingtime/1000) - (long)time(NULL),
685                 S_OR(pu->chan->cid.cid_num, "<unknown>"),
686                 S_OR(pu->chan->cid.cid_name, "<unknown>"),
687                 pu->chan->uniqueid
688                 );
689
690         if (peer && adsipark && ast_adsi_available(peer)) {
691                 adsi_announce_park(peer, pu->parkingexten);     /* Only supports parking numbers */
692                 ast_adsi_unload_session(peer);
693         }
694
695         con = ast_context_find_or_create(NULL, NULL, parkinglot->parking_con, registrar);
696         if (!con)       /* Still no context? Bad */
697                 ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", parkinglot->parking_con);
698         if (con) {
699                 if (!ast_add_extension2(con, 1, pu->parkingexten, 1, NULL, NULL, parkedcall, ast_strdup(pu->parkingexten), ast_free_ptr, registrar))
700                         notify_metermaids(pu->parkingexten, parkinglot->parking_con, AST_DEVICE_INUSE);
701         }
702
703         AST_LIST_UNLOCK(&parkinglot->parkings);
704
705         /* Only say number if it's a number and the channel hasn't been masqueraded away */
706         if (peer && !ast_test_flag(args, AST_PARK_OPT_SILENCE) && (ast_strlen_zero(args->orig_chan_name) || !strcasecmp(peer->name, args->orig_chan_name))) {
707                 /* 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. */
708                 ast_set_flag(peer, AST_FLAG_MASQ_NOSTREAM);
709                 /* Tell the peer channel the number of the parking space */
710                 ast_say_digits(peer, pu->parkingnum, "", peer->language);
711                 ast_clear_flag(peer, AST_FLAG_MASQ_NOSTREAM);
712         }
713         if (peer == chan) { /* pu->notquiteyet = 1 */
714                 /* Wake up parking thread if we're really done */
715                 ast_indicate_data(pu->chan, AST_CONTROL_HOLD, 
716                         S_OR(parkinglot->mohclass, NULL),
717                         !ast_strlen_zero(parkinglot->mohclass) ? strlen(parkinglot->mohclass) + 1 : 0);
718                 pu->notquiteyet = 0;
719                 pthread_kill(parking_thread, SIGURG);
720         }
721         return 0;
722 }
723
724 /*! \brief Park a call */
725 int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeout, int *extout)
726 {
727         struct ast_park_call_args args = {
728                 .timeout = timeout,
729                 .extout = extout,
730         };
731
732         return ast_park_call_full(chan, peer, &args);
733 }
734
735 static int masq_park_call(struct ast_channel *rchan, struct ast_channel *peer, int timeout, int *extout, int play_announcement)
736 {
737         struct ast_channel *chan;
738         struct ast_frame *f;
739         char *orig_chan_name = NULL;
740         int park_status;
741
742         /* Make a new, fake channel that we'll use to masquerade in the real one */
743         if (!(chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, rchan->accountcode, rchan->exten, rchan->context, rchan->amaflags, "Parked/%s",rchan->name))) {
744                 ast_log(LOG_WARNING, "Unable to create parked channel\n");
745                 return -1;
746         }
747
748         /* Make formats okay */
749         chan->readformat = rchan->readformat;
750         chan->writeformat = rchan->writeformat;
751         ast_channel_masquerade(chan, rchan);
752
753         /* Setup the extensions and such */
754         set_c_e_p(chan, rchan->context, rchan->exten, rchan->priority);
755
756         /* Make the masq execute */
757         if ((f = ast_read(chan)))
758                 ast_frfree(f);
759
760         if (!play_announcement) {
761                 orig_chan_name = ast_strdupa(chan->name);
762         }
763
764         {
765                 struct ast_park_call_args args = {
766                         .timeout = timeout,
767                         .extout = extout,
768                         .orig_chan_name = orig_chan_name,
769                 };
770
771                 park_status = ast_park_call_full(chan, peer, &args);
772                 if (park_status == 1) {
773                 /* would be nice to play "invalid parking extension" */
774                         ast_hangup(chan);
775                         return -1;
776                 }
777         }
778
779         return 0;
780 }
781
782 /* Park call via masquraded channel */
783 int ast_masq_park_call(struct ast_channel *rchan, struct ast_channel *peer, int timeout, int *extout)
784 {
785         return masq_park_call(rchan, peer, timeout, extout, 0);
786 }
787
788 static int masq_park_call_announce(struct ast_channel *rchan, struct ast_channel *peer, int timeout, int *extout)
789 {
790         return masq_park_call(rchan, peer, timeout, extout, 1);
791 }
792
793
794
795 #define FEATURE_SENSE_CHAN      (1 << 0)
796 #define FEATURE_SENSE_PEER      (1 << 1)
797
798 /*! 
799  * \brief set caller and callee according to the direction 
800  * \param caller, callee, peer, chan, sense
801  *
802  * Detect who triggered feature and set callee/caller variables accordingly
803 */
804 static void set_peers(struct ast_channel **caller, struct ast_channel **callee,
805         struct ast_channel *peer, struct ast_channel *chan, int sense)
806 {
807         if (sense == FEATURE_SENSE_PEER) {
808                 *caller = peer;
809                 *callee = chan;
810         } else {
811                 *callee = peer;
812                 *caller = chan;
813         }
814 }
815
816 /*! 
817  * \brief support routing for one touch call parking
818  * \param chan channel parking call
819  * \param peer channel to be parked
820  * \param config unsed
821  * \param code unused
822  * \param sense feature options
823  *
824  * \param data
825  * Setup channel, set return exten,priority to 's,1'
826  * answer chan, sleep chan, park call
827 */
828 static int builtin_parkcall(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
829 {
830         struct ast_channel *parker;
831         struct ast_channel *parkee;
832         int res = 0;
833
834         set_peers(&parker, &parkee, peer, chan, sense);
835         /* Setup the exten/priority to be s/1 since we don't know
836            where this call should return */
837         strcpy(chan->exten, "s");
838         chan->priority = 1;
839         if (chan->_state != AST_STATE_UP)
840                 res = ast_answer(chan);
841         if (!res)
842                 res = ast_safe_sleep(chan, 1000);
843
844         if (!res) {
845                 if (sense == FEATURE_SENSE_CHAN) {
846                         res = ast_park_call(parkee, parker, 0, NULL);
847                         if (!res) {
848                                 if (sense == FEATURE_SENSE_CHAN) {
849                                         res = AST_PBX_NO_HANGUP_PEER_PARKED;
850                                 } else {
851                                         res = AST_PBX_KEEPALIVE;
852                                 }
853                         }
854                 } else if (sense == FEATURE_SENSE_PEER) {
855                         masq_park_call_announce(parkee, parker, 0, NULL);
856                         res = 0; /* PBX should hangup zombie channel */
857                 }
858         }
859
860         return res;
861
862 }
863
864 /*! \brief Play message to both caller and callee in bridged call, plays synchronously, autoservicing the
865         other channel during the message, so please don't use this for very long messages
866  */
867 static int play_message_in_bridged_call(struct ast_channel *caller_chan, struct ast_channel *callee_chan, const char *audiofile)
868 {
869         /* First play for caller, put other channel on auto service */
870         if (ast_autoservice_start(callee_chan))
871                 return -1;
872         if (ast_stream_and_wait(caller_chan, audiofile, "")) {
873                 ast_log(LOG_WARNING, "Failed to play automon message!\n");
874                 ast_autoservice_stop(callee_chan);
875                 return -1;
876         }
877         if (ast_autoservice_stop(callee_chan))
878                 return -1;
879         /* Then play for callee, put other channel on auto service */
880         if (ast_autoservice_start(caller_chan))
881                 return -1;
882         if (ast_stream_and_wait(callee_chan, audiofile, "")) {
883                 ast_log(LOG_WARNING, "Failed to play automon message !\n");
884                 ast_autoservice_stop(caller_chan);
885                 return -1;
886         }
887         if (ast_autoservice_stop(caller_chan))
888                 return -1;
889         return(0);
890 }
891
892 /*!
893  * \brief Monitor a channel by DTMF
894  * \param chan channel requesting monitor
895  * \param peer channel to be monitored
896  * \param config
897  * \param code
898  * \param sense feature options
899  *
900  * \param data
901  * Check monitor app enabled, setup channels, both caller/callee chans not null
902  * get TOUCH_MONITOR variable for filename if exists, exec monitor app.
903  * \retval AST_FEATURE_RETURN_SUCCESS on success.
904  * \retval -1 on error.
905 */
906 static int builtin_automonitor(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
907 {
908         char *caller_chan_id = NULL, *callee_chan_id = NULL, *args = NULL, *touch_filename = NULL;
909         int x = 0;
910         size_t len;
911         struct ast_channel *caller_chan, *callee_chan;
912         const char *automon_message_start = NULL;
913         const char *automon_message_stop = NULL;
914
915         if (!monitor_ok) {
916                 ast_log(LOG_ERROR,"Cannot record the call. The monitor application is disabled.\n");
917                 return -1;
918         }
919
920         if (!monitor_app && !(monitor_app = pbx_findapp("Monitor"))) {
921                 monitor_ok = 0;
922                 ast_log(LOG_ERROR,"Cannot record the call. The monitor application is disabled.\n");
923                 return -1;
924         }
925
926         set_peers(&caller_chan, &callee_chan, peer, chan, sense);
927         if (caller_chan) {      /* Find extra messages */
928                 automon_message_start = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_MESSAGE_START");
929                 automon_message_stop = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_MESSAGE_STOP");
930         }
931
932         if (!ast_strlen_zero(courtesytone)) {   /* Play courtesy tone if configured */
933                 if(play_message_in_bridged_call(caller_chan, callee_chan, courtesytone) == -1) {
934                         return -1;
935                 }
936         }
937         
938         if (callee_chan->monitor) {
939                 ast_verb(4, "User hit '%s' to stop recording call.\n", code);
940                 if (!ast_strlen_zero(automon_message_stop)) {
941                         play_message_in_bridged_call(caller_chan, callee_chan, automon_message_stop);
942                 }
943                 callee_chan->monitor->stop(callee_chan, 1);
944                 return AST_FEATURE_RETURN_SUCCESS;
945         }
946
947         if (caller_chan && callee_chan) {
948                 const char *touch_format = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_FORMAT");
949                 const char *touch_monitor = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR");
950                 const char *touch_monitor_prefix = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_PREFIX");
951
952                 if (!touch_format)
953                         touch_format = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR_FORMAT");
954
955                 if (!touch_monitor)
956                         touch_monitor = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR");
957         
958                 if (!touch_monitor_prefix)
959                         touch_monitor_prefix = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR_PREFIX");
960         
961                 if (touch_monitor) {
962                         len = strlen(touch_monitor) + 50;
963                         args = alloca(len);
964                         touch_filename = alloca(len);
965                         snprintf(touch_filename, len, "%s-%ld-%s", S_OR(touch_monitor_prefix, "auto"), (long)time(NULL), touch_monitor);
966                         snprintf(args, len, "%s,%s,m", S_OR(touch_format, "wav"), touch_filename);
967                 } else {
968                         caller_chan_id = ast_strdupa(S_OR(caller_chan->cid.cid_num, caller_chan->name));
969                         callee_chan_id = ast_strdupa(S_OR(callee_chan->cid.cid_num, callee_chan->name));
970                         len = strlen(caller_chan_id) + strlen(callee_chan_id) + 50;
971                         args = alloca(len);
972                         touch_filename = alloca(len);
973                         snprintf(touch_filename, len, "%s-%ld-%s-%s", S_OR(touch_monitor_prefix, "auto"), (long)time(NULL), caller_chan_id, callee_chan_id);
974                         snprintf(args, len, "%s,%s,m", S_OR(touch_format, "wav"), touch_filename);
975                 }
976
977                 for(x = 0; x < strlen(args); x++) {
978                         if (args[x] == '/')
979                                 args[x] = '-';
980                 }
981                 
982                 ast_verb(4, "User hit '%s' to record call. filename: %s\n", code, args);
983
984                 pbx_exec(callee_chan, monitor_app, args);
985                 pbx_builtin_setvar_helper(callee_chan, "TOUCH_MONITOR_OUTPUT", touch_filename);
986                 pbx_builtin_setvar_helper(caller_chan, "TOUCH_MONITOR_OUTPUT", touch_filename);
987
988                 if (!ast_strlen_zero(automon_message_start)) {  /* Play start message for both channels */
989                         play_message_in_bridged_call(caller_chan, callee_chan, automon_message_start);
990                 }
991         
992                 return AST_FEATURE_RETURN_SUCCESS;
993         }
994         
995         ast_log(LOG_NOTICE,"Cannot record the call. One or both channels have gone away.\n");   
996         return -1;
997 }
998
999 static int builtin_automixmonitor(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
1000 {
1001         char *caller_chan_id = NULL, *callee_chan_id = NULL, *args = NULL, *touch_filename = NULL;
1002         int x = 0;
1003         size_t len;
1004         struct ast_channel *caller_chan, *callee_chan;
1005         const char *mixmonitor_spy_type = "MixMonitor";
1006         int count = 0;
1007
1008         if (!mixmonitor_ok) {
1009                 ast_log(LOG_ERROR,"Cannot record the call. The mixmonitor application is disabled.\n");
1010                 return -1;
1011         }
1012
1013         if (!(mixmonitor_app = pbx_findapp("MixMonitor"))) {
1014                 mixmonitor_ok = 0;
1015                 ast_log(LOG_ERROR,"Cannot record the call. The mixmonitor application is disabled.\n");
1016                 return -1;
1017         }
1018
1019         set_peers(&caller_chan, &callee_chan, peer, chan, sense);
1020
1021         if (!ast_strlen_zero(courtesytone)) {
1022                 if (ast_autoservice_start(callee_chan))
1023                         return -1;
1024                 if (ast_stream_and_wait(caller_chan, courtesytone, "")) {
1025                         ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
1026                         ast_autoservice_stop(callee_chan);
1027                         return -1;
1028                 }
1029                 if (ast_autoservice_stop(callee_chan))
1030                         return -1;
1031         }
1032
1033         ast_channel_lock(callee_chan);
1034         count = ast_channel_audiohook_count_by_source(callee_chan, mixmonitor_spy_type, AST_AUDIOHOOK_TYPE_SPY);
1035         ast_channel_unlock(callee_chan);
1036
1037         /* This means a mixmonitor is attached to the channel, running or not is unknown. */
1038         if (count > 0) {
1039                 
1040                 ast_verb(3, "User hit '%s' to stop recording call.\n", code);
1041
1042                 /* Make sure they are running */
1043                 ast_channel_lock(callee_chan);
1044                 count = ast_channel_audiohook_count_by_source_running(callee_chan, mixmonitor_spy_type, AST_AUDIOHOOK_TYPE_SPY);
1045                 ast_channel_unlock(callee_chan);
1046                 if (count > 0) {
1047                         if (!stopmixmonitor_ok) {
1048                                 ast_log(LOG_ERROR,"Cannot stop recording the call. The stopmixmonitor application is disabled.\n");
1049                                 return -1;
1050                         }
1051                         if (!(stopmixmonitor_app = pbx_findapp("StopMixMonitor"))) {
1052                                 stopmixmonitor_ok = 0;
1053                                 ast_log(LOG_ERROR,"Cannot stop recording the call. The stopmixmonitor application is disabled.\n");
1054                                 return -1;
1055                         } else {
1056                                 pbx_exec(callee_chan, stopmixmonitor_app, "");
1057                                 return AST_FEATURE_RETURN_SUCCESS;
1058                         }
1059                 }
1060                 
1061                 ast_log(LOG_WARNING,"Stopped MixMonitors are attached to the channel.\n");      
1062         }                       
1063
1064         if (caller_chan && callee_chan) {
1065                 const char *touch_format = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MIXMONITOR_FORMAT");
1066                 const char *touch_monitor = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MIXMONITOR");
1067
1068                 if (!touch_format)
1069                         touch_format = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MIXMONITOR_FORMAT");
1070
1071                 if (!touch_monitor)
1072                         touch_monitor = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MIXMONITOR");
1073
1074                 if (touch_monitor) {
1075                         len = strlen(touch_monitor) + 50;
1076                         args = alloca(len);
1077                         touch_filename = alloca(len);
1078                         snprintf(touch_filename, len, "auto-%ld-%s", (long)time(NULL), touch_monitor);
1079                         snprintf(args, len, "%s.%s,b", touch_filename, (touch_format) ? touch_format : "wav");
1080                 } else {
1081                         caller_chan_id = ast_strdupa(S_OR(caller_chan->cid.cid_num, caller_chan->name));
1082                         callee_chan_id = ast_strdupa(S_OR(callee_chan->cid.cid_num, callee_chan->name));
1083                         len = strlen(caller_chan_id) + strlen(callee_chan_id) + 50;
1084                         args = alloca(len);
1085                         touch_filename = alloca(len);
1086                         snprintf(touch_filename, len, "auto-%ld-%s-%s", (long)time(NULL), caller_chan_id, callee_chan_id);
1087                         snprintf(args, len, "%s.%s,b", touch_filename, S_OR(touch_format, "wav"));
1088                 }
1089
1090                 for( x = 0; x < strlen(args); x++) {
1091                         if (args[x] == '/')
1092                                 args[x] = '-';
1093                 }
1094
1095                 ast_verb(3, "User hit '%s' to record call. filename: %s\n", code, touch_filename);
1096
1097                 pbx_exec(callee_chan, mixmonitor_app, args);
1098                 pbx_builtin_setvar_helper(callee_chan, "TOUCH_MIXMONITOR_OUTPUT", touch_filename);
1099                 pbx_builtin_setvar_helper(caller_chan, "TOUCH_MIXMONITOR_OUTPUT", touch_filename);
1100                 return AST_FEATURE_RETURN_SUCCESS;
1101         
1102         }
1103
1104         ast_log(LOG_NOTICE,"Cannot record the call. One or both channels have gone away.\n");
1105         return -1;
1106
1107 }
1108
1109 static int builtin_disconnect(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
1110 {
1111         ast_verb(4, "User hit '%s' to disconnect call.\n", code);
1112         return AST_FEATURE_RETURN_HANGUP;
1113 }
1114
1115 static int finishup(struct ast_channel *chan)
1116 {
1117         ast_indicate(chan, AST_CONTROL_UNHOLD);
1118
1119         return ast_autoservice_stop(chan);
1120 }
1121
1122 /*!
1123  * \brief Find the context for the transfer
1124  * \param transferer
1125  * \param transferee
1126  * 
1127  * Grab the TRANSFER_CONTEXT, if fails try grabbing macrocontext.
1128  * \return a context string
1129 */
1130 static const char *real_ctx(struct ast_channel *transferer, struct ast_channel *transferee)
1131 {
1132         const char *s = pbx_builtin_getvar_helper(transferer, "TRANSFER_CONTEXT");
1133         if (ast_strlen_zero(s)) {
1134                 s = pbx_builtin_getvar_helper(transferee, "TRANSFER_CONTEXT");
1135         }
1136         if (ast_strlen_zero(s)) { /* Use the non-macro context to transfer the call XXX ? */
1137                 s = transferer->macrocontext;
1138         }
1139         if (ast_strlen_zero(s)) {
1140                 s = transferer->context;
1141         }
1142         return s;  
1143 }
1144
1145 /*!
1146  * \brief Blind transfer user to another extension
1147  * \param chan channel to be transfered
1148  * \param peer channel initiated blind transfer
1149  * \param config
1150  * \param code
1151  * \param data
1152  * \param sense  feature options
1153  * 
1154  * Place chan on hold, check if transferred to parkinglot extension,
1155  * otherwise check extension exists and transfer caller.
1156  * \retval AST_FEATURE_RETURN_SUCCESS.
1157  * \retval -1 on failure.
1158 */
1159 static int builtin_blindtransfer(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
1160 {
1161         struct ast_channel *transferer;
1162         struct ast_channel *transferee;
1163         const char *transferer_real_context;
1164         char xferto[256];
1165         int res;
1166
1167         set_peers(&transferer, &transferee, peer, chan, sense);
1168         transferer_real_context = real_ctx(transferer, transferee);
1169         /* Start autoservice on chan while we talk to the originator */
1170         ast_autoservice_start(transferee);
1171         ast_indicate(transferee, AST_CONTROL_HOLD);
1172
1173         memset(xferto, 0, sizeof(xferto));
1174         
1175         /* Transfer */
1176         res = ast_stream_and_wait(transferer, "pbx-transfer", AST_DIGIT_ANY);
1177         if (res < 0) {
1178                 finishup(transferee);
1179                 return -1; /* error ? */
1180         }
1181         if (res > 0)    /* If they've typed a digit already, handle it */
1182                 xferto[0] = (char) res;
1183
1184         ast_stopstream(transferer);
1185         res = ast_app_dtget(transferer, transferer_real_context, xferto, sizeof(xferto), 100, transferdigittimeout);
1186         if (res < 0) {  /* hangup, would be 0 for invalid and 1 for valid */
1187                 finishup(transferee);
1188                 return res;
1189         }
1190         if (!strcmp(xferto, ast_parking_ext())) {
1191                 res = finishup(transferee);
1192                 if (res)
1193                         res = -1;
1194                 else if (!ast_park_call(transferee, transferer, 0, NULL)) {     /* success */
1195                         /* We return non-zero, but tell the PBX not to hang the channel when
1196                            the thread dies -- We have to be careful now though.  We are responsible for 
1197                            hanging up the channel, else it will never be hung up! */
1198
1199                         return (transferer == peer) ? AST_PBX_KEEPALIVE : AST_PBX_NO_HANGUP_PEER_PARKED;
1200                 } else {
1201                         ast_log(LOG_WARNING, "Unable to park call %s\n", transferee->name);
1202                 }
1203                 /*! \todo XXX Maybe we should have another message here instead of invalid extension XXX */
1204         } else if (ast_exists_extension(transferee, transferer_real_context, xferto, 1, transferer->cid.cid_num)) {
1205                 pbx_builtin_setvar_helper(transferer, "BLINDTRANSFER", transferee->name);
1206                 pbx_builtin_setvar_helper(transferee, "BLINDTRANSFER", transferer->name);
1207                 res=finishup(transferee);
1208                 if (!transferer->cdr) {
1209                         transferer->cdr=ast_cdr_alloc();
1210                         if (transferer) {
1211                                 ast_cdr_init(transferer->cdr, transferer); /* initilize our channel's cdr */
1212                                 ast_cdr_start(transferer->cdr);
1213                         }
1214                 }
1215                 if (transferer->cdr) {
1216                         ast_cdr_setdestchan(transferer->cdr, transferee->name);
1217                         ast_cdr_setapp(transferer->cdr, "BLINDTRANSFER","");
1218                 }
1219                 if (!transferee->pbx) {
1220                         /* Doh!  Use our handy async_goto functions */
1221                         ast_verb(3, "Transferring %s to '%s' (context %s) priority 1\n"
1222                                                                 ,transferee->name, xferto, transferer_real_context);
1223                         if (ast_async_goto(transferee, transferer_real_context, xferto, 1))
1224                                 ast_log(LOG_WARNING, "Async goto failed :-(\n");
1225                 } else {
1226                         /* Set the channel's new extension, since it exists, using transferer context */
1227                         set_c_e_p(transferee, transferer_real_context, xferto, 0);
1228                 }
1229                 check_goto_on_transfer(transferer);
1230                 return res;
1231         } else {
1232                 ast_verb(3, "Unable to find extension '%s' in context '%s'\n", xferto, transferer_real_context);
1233         }
1234         if (ast_stream_and_wait(transferer, xferfailsound, AST_DIGIT_ANY) < 0) {
1235                 finishup(transferee);
1236                 return -1;
1237         }
1238         ast_stopstream(transferer);
1239         res = finishup(transferee);
1240         if (res) {
1241                 ast_verb(2, "Hungup during autoservice stop on '%s'\n", transferee->name);
1242                 return res;
1243         }
1244         return AST_FEATURE_RETURN_SUCCESS;
1245 }
1246
1247 /*!
1248  * \brief make channels compatible
1249  * \param c
1250  * \param newchan
1251  * \retval 0 on success.
1252  * \retval -1 on failure.
1253 */
1254 static int check_compat(struct ast_channel *c, struct ast_channel *newchan)
1255 {
1256         if (ast_channel_make_compatible(c, newchan) < 0) {
1257                 ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n",
1258                         c->name, newchan->name);
1259                 ast_hangup(newchan);
1260                 return -1;
1261         }
1262         return 0;
1263 }
1264
1265 /*!
1266  * \brief Attended transfer
1267  * \param chan transfered user
1268  * \param peer person transfering call
1269  * \param config
1270  * \param code
1271  * \param sense feature options
1272  * 
1273  * \param data
1274  * Get extension to transfer to, if you cannot generate channel (or find extension) 
1275  * return to host channel. After called channel answered wait for hangup of transferer,
1276  * bridge call between transfer peer (taking them off hold) to attended transfer channel.
1277  *
1278  * \return -1 on failure
1279 */
1280 static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
1281 {
1282         struct ast_channel *transferer;
1283         struct ast_channel *transferee;
1284         const char *transferer_real_context;
1285         char xferto[256] = "";
1286         int res;
1287         int outstate=0;
1288         struct ast_channel *newchan;
1289         struct ast_channel *xferchan;
1290         struct ast_bridge_thread_obj *tobj;
1291         struct ast_bridge_config bconfig;
1292         struct ast_frame *f;
1293         int l;
1294
1295         ast_debug(1, "Executing Attended Transfer %s, %s (sense=%d) \n", chan->name, peer->name, sense);
1296         set_peers(&transferer, &transferee, peer, chan, sense);
1297         transferer_real_context = real_ctx(transferer, transferee);
1298         /* Start autoservice on chan while we talk to the originator */
1299         ast_autoservice_start(transferee);
1300         ast_indicate(transferee, AST_CONTROL_HOLD);
1301         
1302         /* Transfer */
1303         res = ast_stream_and_wait(transferer, "pbx-transfer", AST_DIGIT_ANY);
1304         if (res < 0) {
1305                 finishup(transferee);
1306                 return res;
1307         }
1308         if (res > 0) /* If they've typed a digit already, handle it */
1309                 xferto[0] = (char) res;
1310
1311         /* this is specific of atxfer */
1312         res = ast_app_dtget(transferer, transferer_real_context, xferto, sizeof(xferto), 100, transferdigittimeout);
1313         if (res < 0) {  /* hangup, would be 0 for invalid and 1 for valid */
1314                 finishup(transferee);
1315                 return res;
1316         }
1317         if (res == 0) {
1318                 ast_log(LOG_WARNING, "Did not read data.\n");
1319                 finishup(transferee);
1320                 if (ast_stream_and_wait(transferer, "beeperr", ""))
1321                         return -1;
1322                 return AST_FEATURE_RETURN_SUCCESS;
1323         }
1324
1325         /* valid extension, res == 1 */
1326         if (!ast_exists_extension(transferer, transferer_real_context, xferto, 1, transferer->cid.cid_num)) {
1327                 ast_log(LOG_WARNING, "Extension %s does not exist in context %s\n",xferto,transferer_real_context);
1328                 finishup(transferee);
1329                 if (ast_stream_and_wait(transferer, "beeperr", ""))
1330                         return -1;
1331                 return AST_FEATURE_RETURN_SUCCESS;
1332         }
1333
1334         l = strlen(xferto);
1335         snprintf(xferto + l, sizeof(xferto) - l, "@%s/n", transferer_real_context);     /* append context */
1336
1337         /* If we are performing an attended transfer and we have two channels involved then
1338            copy sound file information to play upon attended transfer completion */
1339         if (transferee) {
1340                 const char *chan1_attended_sound = pbx_builtin_getvar_helper(transferer, "ATTENDED_TRANSFER_COMPLETE_SOUND");
1341                 const char *chan2_attended_sound = pbx_builtin_getvar_helper(transferee, "ATTENDED_TRANSFER_COMPLETE_SOUND");
1342
1343                 if (!ast_strlen_zero(chan1_attended_sound)) {
1344                         pbx_builtin_setvar_helper(transferer, "BRIDGE_PLAY_SOUND", chan1_attended_sound);
1345                 }
1346                 if (!ast_strlen_zero(chan2_attended_sound)) {
1347                         pbx_builtin_setvar_helper(transferee, "BRIDGE_PLAY_SOUND", chan2_attended_sound);
1348                 }
1349         }
1350
1351         newchan = ast_feature_request_and_dial(transferer, transferee, "Local", ast_best_codec(transferer->nativeformats),
1352                 xferto, atxfernoanswertimeout, &outstate, transferer->cid.cid_num, transferer->cid.cid_name, 1, transferer->language);
1353
1354         if (!ast_check_hangup(transferer)) {
1355                 /* Transferer is up - old behaviour */
1356                 ast_indicate(transferer, -1);
1357                 if (!newchan) {
1358                         finishup(transferee);
1359                         /* any reason besides user requested cancel and busy triggers the failed sound */
1360                         if (outstate != AST_CONTROL_UNHOLD && outstate != AST_CONTROL_BUSY &&
1361                                 ast_stream_and_wait(transferer, xferfailsound, ""))
1362                                 return -1;
1363                         if (ast_stream_and_wait(transferer, xfersound, ""))
1364                                 ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
1365                         return AST_FEATURE_RETURN_SUCCESS;
1366                 }
1367
1368                 if (check_compat(transferer, newchan)) {
1369                         /* we do mean transferee here, NOT transferer */
1370                         finishup(transferee);
1371                         return -1;
1372                 }
1373                 memset(&bconfig,0,sizeof(struct ast_bridge_config));
1374                 ast_set_flag(&(bconfig.features_caller), AST_FEATURE_DISCONNECT);
1375                 ast_set_flag(&(bconfig.features_callee), AST_FEATURE_DISCONNECT);
1376                 res = ast_bridge_call(transferer, newchan, &bconfig);
1377                 if (ast_check_hangup(newchan) || !ast_check_hangup(transferer)) {
1378                         ast_hangup(newchan);
1379                         if (ast_stream_and_wait(transferer, xfersound, ""))
1380                                 ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
1381                         finishup(transferee);
1382                         transferer->_softhangup = 0;
1383                         return AST_FEATURE_RETURN_SUCCESS;
1384                 }
1385                 if (check_compat(transferee, newchan)) {
1386                         finishup(transferee);
1387                         return -1;
1388                 }
1389                 ast_indicate(transferee, AST_CONTROL_UNHOLD);
1390
1391                 if ((ast_autoservice_stop(transferee) < 0)
1392                  || (ast_waitfordigit(transferee, 100) < 0)
1393                  || (ast_waitfordigit(newchan, 100) < 0)
1394                  || ast_check_hangup(transferee)
1395                  || ast_check_hangup(newchan)) {
1396                         ast_hangup(newchan);
1397                         return -1;
1398                 }
1399                 xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Transfered/%s", transferee->name);
1400                 if (!xferchan) {
1401                         ast_hangup(newchan);
1402                         return -1;
1403                 }
1404                 /* Make formats okay */
1405                 xferchan->visible_indication = transferer->visible_indication;
1406                 xferchan->readformat = transferee->readformat;
1407                 xferchan->writeformat = transferee->writeformat;
1408                 ast_channel_masquerade(xferchan, transferee);
1409                 ast_explicit_goto(xferchan, transferee->context, transferee->exten, transferee->priority);
1410                 xferchan->_state = AST_STATE_UP;
1411                 ast_clear_flag(xferchan, AST_FLAGS_ALL);
1412                 xferchan->_softhangup = 0;
1413                 if ((f = ast_read(xferchan)))
1414                         ast_frfree(f);
1415                 newchan->_state = AST_STATE_UP;
1416                 ast_clear_flag(newchan, AST_FLAGS_ALL);
1417                 newchan->_softhangup = 0;
1418                 if (!(tobj = ast_calloc(1, sizeof(*tobj)))) {
1419                         ast_hangup(xferchan);
1420                         ast_hangup(newchan);
1421                         return -1;
1422                 }
1423                 tobj->chan = newchan;
1424                 tobj->peer = xferchan;
1425                 tobj->bconfig = *config;
1426
1427                 if (tobj->bconfig.end_bridge_callback_data_fixup) {
1428                         tobj->bconfig.end_bridge_callback_data_fixup(&tobj->bconfig, tobj->peer, tobj->chan);
1429                 }
1430
1431                 if (ast_stream_and_wait(newchan, xfersound, ""))
1432                         ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
1433                 ast_bridge_call_thread_launch(tobj);
1434                 return -1;      /* XXX meaning the channel is bridged ? */
1435         } else if (!ast_check_hangup(transferee)) {
1436                 /* act as blind transfer */
1437                 if (ast_autoservice_stop(transferee) < 0) {
1438                         ast_hangup(newchan);
1439                         return -1;
1440                 }
1441
1442                 if (!newchan) {
1443                         unsigned int tries = 0;
1444                         char *transferer_tech, *transferer_name = ast_strdupa(transferer->name);
1445
1446                         transferer_tech = strsep(&transferer_name, "/");
1447                         transferer_name = strsep(&transferer_name, "-");
1448
1449                         if (ast_strlen_zero(transferer_name) || ast_strlen_zero(transferer_tech)) {
1450                                 ast_log(LOG_WARNING, "Transferer has invalid channel name: '%s'\n", transferer->name);
1451                                 if (ast_stream_and_wait(transferee, "beeperr", ""))
1452                                         return -1;
1453                                 return AST_FEATURE_RETURN_SUCCESS;
1454                         }
1455
1456                         ast_log(LOG_NOTICE, "We're trying to call %s/%s\n", transferer_tech, transferer_name);
1457                         newchan = ast_feature_request_and_dial(transferee, NULL, transferer_tech, ast_best_codec(transferee->nativeformats),
1458                                 transferer_name, atxfernoanswertimeout, &outstate, transferee->cid.cid_num, transferee->cid.cid_name, 0, transferer->language);
1459                         while (!newchan && !atxferdropcall && tries < atxfercallbackretries) {
1460                                 /* Trying to transfer again */
1461                                 ast_autoservice_start(transferee);
1462                                 ast_indicate(transferee, AST_CONTROL_HOLD);
1463
1464                                 newchan = ast_feature_request_and_dial(transferer, transferee, "Local", ast_best_codec(transferer->nativeformats),
1465                                         xferto, atxfernoanswertimeout, &outstate, transferer->cid.cid_num, transferer->cid.cid_name, 1, transferer->language);
1466                                 if (ast_autoservice_stop(transferee) < 0) {
1467                                         if (newchan)
1468                                                 ast_hangup(newchan);
1469                                         return -1;
1470                                 }
1471                                 if (!newchan) {
1472                                         /* Transfer failed, sleeping */
1473                                         ast_debug(1, "Sleeping for %d ms before callback.\n", atxferloopdelay);
1474                                         ast_safe_sleep(transferee, atxferloopdelay);
1475                                         ast_debug(1, "Trying to callback...\n");
1476                                         newchan = ast_feature_request_and_dial(transferee, NULL, transferer_tech, ast_best_codec(transferee->nativeformats),
1477                                                 transferer_name, atxfernoanswertimeout, &outstate, transferee->cid.cid_num, transferee->cid.cid_name, 0, transferer->language);
1478                                 }
1479                                 tries++;
1480                         }
1481                 }
1482                 if (!newchan)
1483                         return -1;
1484
1485                 /* newchan is up, we should prepare transferee and bridge them */
1486                 if (check_compat(transferee, newchan)) {
1487                         finishup(transferee);
1488                         return -1;
1489                 }
1490                 ast_indicate(transferee, AST_CONTROL_UNHOLD);
1491
1492                 if ((ast_waitfordigit(transferee, 100) < 0)
1493                    || (ast_waitfordigit(newchan, 100) < 0)
1494                    || ast_check_hangup(transferee)
1495                    || ast_check_hangup(newchan)) {
1496                         ast_hangup(newchan);
1497                         return -1;
1498                 }
1499
1500                 xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Transfered/%s", transferee->name);
1501                 if (!xferchan) {
1502                         ast_hangup(newchan);
1503                         return -1;
1504                 }
1505                 /* Make formats okay */
1506                 xferchan->visible_indication = transferer->visible_indication;
1507                 xferchan->readformat = transferee->readformat;
1508                 xferchan->writeformat = transferee->writeformat;
1509                 ast_channel_masquerade(xferchan, transferee);
1510                 ast_explicit_goto(xferchan, transferee->context, transferee->exten, transferee->priority);
1511                 xferchan->_state = AST_STATE_UP;
1512                 ast_clear_flag(xferchan, AST_FLAGS_ALL);
1513                 xferchan->_softhangup = 0;
1514                 if ((f = ast_read(xferchan)))
1515                         ast_frfree(f);
1516                 newchan->_state = AST_STATE_UP;
1517                 ast_clear_flag(newchan, AST_FLAGS_ALL);
1518                 newchan->_softhangup = 0;
1519                 if (!(tobj = ast_calloc(1, sizeof(*tobj)))) {
1520                         ast_hangup(xferchan);
1521                         ast_hangup(newchan);
1522                         return -1;
1523                 }
1524                 tobj->chan = newchan;
1525                 tobj->peer = xferchan;
1526                 tobj->bconfig = *config;
1527
1528                 if (tobj->bconfig.end_bridge_callback_data_fixup) {
1529                         tobj->bconfig.end_bridge_callback_data_fixup(&tobj->bconfig, tobj->peer, tobj->chan);
1530                 }
1531
1532                 if (ast_stream_and_wait(newchan, xfersound, ""))
1533                         ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
1534                 ast_bridge_call_thread_launch(tobj);
1535                 return -1;      /* XXX meaning the channel is bridged ? */
1536         } else {
1537                 /* Transferee hung up */
1538                 finishup(transferee);
1539                 return -1;
1540         }
1541 }
1542
1543 /* add atxfer and automon as undefined so you can only use em if you configure them */
1544 #define FEATURES_COUNT ARRAY_LEN(builtin_features)
1545
1546 AST_RWLOCK_DEFINE_STATIC(features_lock);
1547
1548 static struct ast_call_feature builtin_features[] = 
1549 {
1550         { AST_FEATURE_REDIRECT, "Blind Transfer", "blindxfer", "#", "#", builtin_blindtransfer, AST_FEATURE_FLAG_NEEDSDTMF, "" },
1551         { AST_FEATURE_REDIRECT, "Attended Transfer", "atxfer", "", "", builtin_atxfer, AST_FEATURE_FLAG_NEEDSDTMF, "" },
1552         { AST_FEATURE_AUTOMON, "One Touch Monitor", "automon", "", "", builtin_automonitor, AST_FEATURE_FLAG_NEEDSDTMF, "" },
1553         { AST_FEATURE_DISCONNECT, "Disconnect Call", "disconnect", "*", "*", builtin_disconnect, AST_FEATURE_FLAG_NEEDSDTMF, "" },
1554         { AST_FEATURE_PARKCALL, "Park Call", "parkcall", "", "", builtin_parkcall, AST_FEATURE_FLAG_NEEDSDTMF, "" },
1555         { AST_FEATURE_AUTOMIXMON, "One Touch MixMonitor", "automixmon", "", "", builtin_automixmonitor, AST_FEATURE_FLAG_NEEDSDTMF, "" },
1556 };
1557
1558
1559 static AST_RWLIST_HEAD_STATIC(feature_list, ast_call_feature);
1560
1561 /*! \brief register new feature into feature_list*/
1562 void ast_register_feature(struct ast_call_feature *feature)
1563 {
1564         if (!feature) {
1565                 ast_log(LOG_NOTICE,"You didn't pass a feature!\n");
1566                 return;
1567         }
1568   
1569         AST_RWLIST_WRLOCK(&feature_list);
1570         AST_RWLIST_INSERT_HEAD(&feature_list,feature,feature_entry);
1571         AST_RWLIST_UNLOCK(&feature_list);
1572
1573         ast_verb(2, "Registered Feature '%s'\n",feature->sname);
1574 }
1575
1576 /*! 
1577  * \brief Add new feature group
1578  * \param fgname feature group name.
1579  *
1580  * Add new feature group to the feature group list insert at head of list.
1581  * \note This function MUST be called while feature_groups is locked.
1582 */
1583 static struct feature_group* register_group(const char *fgname)
1584 {
1585         struct feature_group *fg;
1586
1587         if (!fgname) {
1588                 ast_log(LOG_NOTICE, "You didn't pass a new group name!\n");
1589                 return NULL;
1590         }
1591
1592         if (!(fg = ast_calloc(1, sizeof(*fg))))
1593                 return NULL;
1594
1595         if (ast_string_field_init(fg, 128)) {
1596                 ast_free(fg);
1597                 return NULL;
1598         }
1599
1600         ast_string_field_set(fg, gname, fgname);
1601
1602         AST_LIST_INSERT_HEAD(&feature_groups, fg, entry);
1603
1604         ast_verb(2, "Registered group '%s'\n", fg->gname);
1605
1606         return fg;
1607 }
1608
1609 /*! 
1610  * \brief Add feature to group
1611  * \param fg feature group
1612  * \param exten
1613  * \param feature feature to add.
1614  *
1615  * Check fg and feature specified, add feature to list
1616  * \note This function MUST be called while feature_groups is locked. 
1617 */
1618 static void register_group_feature(struct feature_group *fg, const char *exten, struct ast_call_feature *feature) 
1619 {
1620         struct feature_group_exten *fge;
1621
1622         if (!fg) {
1623                 ast_log(LOG_NOTICE, "You didn't pass a group!\n");
1624                 return;
1625         }
1626
1627         if (!feature) {
1628                 ast_log(LOG_NOTICE, "You didn't pass a feature!\n");
1629                 return;
1630         }
1631
1632         if (!(fge = ast_calloc(1, sizeof(*fge))))
1633                 return;
1634
1635         if (ast_string_field_init(fge, 128)) {
1636                 ast_free(fge);
1637                 return;
1638         }
1639
1640         ast_string_field_set(fge, exten, S_OR(exten, feature->exten));
1641
1642         fge->feature = feature;
1643
1644         AST_LIST_INSERT_HEAD(&fg->features, fge, entry);                
1645
1646         ast_verb(2, "Registered feature '%s' for group '%s' at exten '%s'\n",
1647                                         feature->sname, fg->gname, exten);
1648 }
1649
1650 void ast_unregister_feature(struct ast_call_feature *feature)
1651 {
1652         if (!feature) {
1653                 return;
1654         }
1655
1656         AST_RWLIST_WRLOCK(&feature_list);
1657         AST_RWLIST_REMOVE(&feature_list, feature, feature_entry);
1658         AST_RWLIST_UNLOCK(&feature_list);
1659
1660         ast_free(feature);
1661 }
1662
1663 /*! \brief Remove all features in the list */
1664 static void ast_unregister_features(void)
1665 {
1666         struct ast_call_feature *feature;
1667
1668         AST_RWLIST_WRLOCK(&feature_list);
1669         while ((feature = AST_RWLIST_REMOVE_HEAD(&feature_list, feature_entry))) {
1670                 ast_free(feature);
1671         }
1672         AST_RWLIST_UNLOCK(&feature_list);
1673 }
1674
1675 /*! \brief find a call feature by name */
1676 static struct ast_call_feature *find_dynamic_feature(const char *name)
1677 {
1678         struct ast_call_feature *tmp;
1679
1680         AST_RWLIST_TRAVERSE(&feature_list, tmp, feature_entry) {
1681                 if (!strcasecmp(tmp->sname, name)) {
1682                         break;
1683                 }
1684         }
1685
1686         return tmp;
1687 }
1688
1689 /*! \brief Remove all feature groups in the list */
1690 static void ast_unregister_groups(void)
1691 {
1692         struct feature_group *fg;
1693         struct feature_group_exten *fge;
1694
1695         AST_RWLIST_WRLOCK(&feature_groups);
1696         while ((fg = AST_LIST_REMOVE_HEAD(&feature_groups, entry))) {
1697                 while ((fge = AST_LIST_REMOVE_HEAD(&fg->features, entry))) {
1698                         ast_string_field_free_memory(fge);
1699                         ast_free(fge);
1700                 }
1701
1702                 ast_string_field_free_memory(fg);
1703                 ast_free(fg);
1704         }
1705         AST_RWLIST_UNLOCK(&feature_groups);
1706 }
1707
1708 /*! 
1709  * \brief Find a group by name 
1710  * \param name feature name
1711  * \retval feature group on success.
1712  * \retval NULL on failure.
1713 */
1714 static struct feature_group *find_group(const char *name) {
1715         struct feature_group *fg = NULL;
1716
1717         AST_LIST_TRAVERSE(&feature_groups, fg, entry) {
1718                 if (!strcasecmp(fg->gname, name))
1719                         break;
1720         }
1721
1722         return fg;
1723 }
1724
1725 void ast_rdlock_call_features(void)
1726 {
1727         ast_rwlock_rdlock(&features_lock);
1728 }
1729
1730 void ast_unlock_call_features(void)
1731 {
1732         ast_rwlock_unlock(&features_lock);
1733 }
1734
1735 struct ast_call_feature *ast_find_call_feature(const char *name)
1736 {
1737         int x;
1738         for (x = 0; x < FEATURES_COUNT; x++) {
1739                 if (!strcasecmp(name, builtin_features[x].sname))
1740                         return &builtin_features[x];
1741         }
1742         return NULL;
1743 }
1744
1745 /*!
1746  * \brief exec an app by feature 
1747  * \param chan,peer,config,code,sense,data
1748  *
1749  * Find a feature, determine which channel activated
1750  * \retval AST_FEATURE_RETURN_PBX_KEEPALIVE,AST_FEATURE_RETURN_NO_HANGUP_PEER
1751  * \retval -1 error.
1752  * \retval -2 when an application cannot be found.
1753 */
1754 static int feature_exec_app(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
1755 {
1756         struct ast_app *app;
1757         struct ast_call_feature *feature = data;
1758         struct ast_channel *work, *idle;
1759         int res;
1760
1761         if (!feature) { /* shouldn't ever happen! */
1762                 ast_log(LOG_NOTICE, "Found feature before, but at execing we've lost it??\n");
1763                 return -1; 
1764         }
1765
1766         if (sense == FEATURE_SENSE_CHAN) {
1767                 if (!ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLER))
1768                         return AST_FEATURE_RETURN_KEEPTRYING;
1769                 if (ast_test_flag(feature, AST_FEATURE_FLAG_ONSELF)) {
1770                         work = chan;
1771                         idle = peer;
1772                 } else {
1773                         work = peer;
1774                         idle = chan;
1775                 }
1776         } else {
1777                 if (!ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLEE))
1778                         return AST_FEATURE_RETURN_KEEPTRYING;
1779                 if (ast_test_flag(feature, AST_FEATURE_FLAG_ONSELF)) {
1780                         work = peer;
1781                         idle = chan;
1782                 } else {
1783                         work = chan;
1784                         idle = peer;
1785                 }
1786         }
1787
1788         if (!(app = pbx_findapp(feature->app))) {
1789                 ast_log(LOG_WARNING, "Could not find application (%s)\n", feature->app);
1790                 return -2;
1791         }
1792
1793         ast_autoservice_start(idle);
1794         
1795         if (!ast_strlen_zero(feature->moh_class))
1796                 ast_moh_start(idle, feature->moh_class, NULL);
1797
1798         res = pbx_exec(work, app, feature->app_args);
1799
1800         if (!ast_strlen_zero(feature->moh_class))
1801                 ast_moh_stop(idle);
1802
1803         ast_autoservice_stop(idle);
1804
1805         if (res == AST_PBX_KEEPALIVE) {
1806                 /* do not hangup peer if feature is to be activated on it */
1807                 if ((ast_test_flag(feature, AST_FEATURE_FLAG_ONPEER) && sense == FEATURE_SENSE_CHAN) || (ast_test_flag(feature, AST_FEATURE_FLAG_ONSELF) && sense == FEATURE_SENSE_PEER))
1808                         return AST_FEATURE_RETURN_NO_HANGUP_PEER;
1809                 else
1810                         return AST_FEATURE_RETURN_PBX_KEEPALIVE;
1811         }
1812         else if (res == AST_PBX_NO_HANGUP_PEER)
1813                 return AST_FEATURE_RETURN_NO_HANGUP_PEER;
1814         else if (res == AST_PBX_NO_HANGUP_PEER_PARKED)
1815                 return AST_FEATURE_RETURN_NO_HANGUP_PEER_PARKED;
1816         else if (res)
1817                 return AST_FEATURE_RETURN_SUCCESSBREAK;
1818         
1819         return AST_FEATURE_RETURN_SUCCESS;      /*! \todo XXX should probably return res */
1820 }
1821
1822 static void unmap_features(void)
1823 {
1824         int x;
1825
1826         ast_rwlock_wrlock(&features_lock);
1827         for (x = 0; x < FEATURES_COUNT; x++)
1828                 strcpy(builtin_features[x].exten, builtin_features[x].default_exten);
1829         ast_rwlock_unlock(&features_lock);
1830 }
1831
1832 static int remap_feature(const char *name, const char *value)
1833 {
1834         int x, res = -1;
1835
1836         ast_rwlock_wrlock(&features_lock);
1837         for (x = 0; x < FEATURES_COUNT; x++) {
1838                 if (strcasecmp(builtin_features[x].sname, name))
1839                         continue;
1840
1841                 ast_copy_string(builtin_features[x].exten, value, sizeof(builtin_features[x].exten));
1842                 res = 0;
1843                 break;
1844         }
1845         ast_rwlock_unlock(&features_lock);
1846
1847         return res;
1848 }
1849
1850 /*!
1851  * \brief Check the dynamic features
1852  * \param chan,peer,config,code,sense
1853  *
1854  * Lock features list, browse for code, unlock list
1855  * \retval res on success.
1856  * \retval -1 on failure.
1857 */
1858 static int ast_feature_interpret(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense)
1859 {
1860         int x;
1861         struct ast_flags features;
1862         struct ast_call_feature *feature;
1863         struct feature_group *fg = NULL;
1864         struct feature_group_exten *fge;
1865         const char *dynamic_features;
1866         char *tmp, *tok;
1867         int res = AST_FEATURE_RETURN_PASSDIGITS;
1868         int feature_detected = 0;
1869
1870         if (sense == FEATURE_SENSE_CHAN) {
1871                 ast_copy_flags(&features, &(config->features_caller), AST_FLAGS_ALL);
1872                 dynamic_features = pbx_builtin_getvar_helper(chan, "DYNAMIC_FEATURES");
1873         }
1874         else {
1875                 ast_copy_flags(&features, &(config->features_callee), AST_FLAGS_ALL);
1876                 dynamic_features = pbx_builtin_getvar_helper(peer, "DYNAMIC_FEATURES");
1877         }
1878         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);
1879
1880         ast_rwlock_rdlock(&features_lock);
1881         for (x = 0; x < FEATURES_COUNT; x++) {
1882                 if ((ast_test_flag(&features, builtin_features[x].feature_mask)) &&
1883                     !ast_strlen_zero(builtin_features[x].exten)) {
1884                         /* Feature is up for consideration */
1885                         if (!strcmp(builtin_features[x].exten, code)) {
1886                                 res = builtin_features[x].operation(chan, peer, config, code, sense, NULL);
1887                                 feature_detected = 1;
1888                                 break;
1889                         } else if (!strncmp(builtin_features[x].exten, code, strlen(code))) {
1890                                 if (res == AST_FEATURE_RETURN_PASSDIGITS)
1891                                         res = AST_FEATURE_RETURN_STOREDIGITS;
1892                         }
1893                 }
1894         }
1895         ast_rwlock_unlock(&features_lock);
1896
1897         if (ast_strlen_zero(dynamic_features) || feature_detected)
1898                 return res;
1899
1900         tmp = ast_strdupa(dynamic_features);
1901
1902         while ((tok = strsep(&tmp, "#"))) {
1903                 AST_RWLIST_RDLOCK(&feature_groups);
1904
1905                 fg = find_group(tok);
1906
1907                 if (fg) {
1908                         AST_LIST_TRAVERSE(&fg->features, fge, entry) {
1909                                 if (strcasecmp(fge->exten, code))
1910                                         continue;
1911
1912                                 res = fge->feature->operation(chan, peer, config, code, sense, fge->feature);
1913                                 if (res != AST_FEATURE_RETURN_KEEPTRYING) {
1914                                         AST_RWLIST_UNLOCK(&feature_groups);
1915                                         break;
1916                                 }
1917                                 res = AST_FEATURE_RETURN_PASSDIGITS;
1918                         }
1919                         if (fge)
1920                                 break;
1921                 }
1922
1923                 AST_RWLIST_UNLOCK(&feature_groups);
1924
1925                 AST_RWLIST_RDLOCK(&feature_list);
1926
1927                 if (!(feature = find_dynamic_feature(tok))) {
1928                         AST_RWLIST_UNLOCK(&feature_list);
1929                         continue;
1930                 }
1931                         
1932                 /* Feature is up for consideration */
1933                 if (!strcmp(feature->exten, code)) {
1934                         ast_verb(3, " Feature Found: %s exten: %s\n",feature->sname, tok);
1935                         res = feature->operation(chan, peer, config, code, sense, feature);
1936                         if (res != AST_FEATURE_RETURN_KEEPTRYING) {
1937                                 AST_RWLIST_UNLOCK(&feature_list);
1938                                 break;
1939                         }
1940                         res = AST_FEATURE_RETURN_PASSDIGITS;
1941                 } else if (!strncmp(feature->exten, code, strlen(code)))
1942                         res = AST_FEATURE_RETURN_STOREDIGITS;
1943
1944                 AST_RWLIST_UNLOCK(&feature_list);
1945         }
1946         
1947         return res;
1948 }
1949
1950 static void set_config_flags(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config)
1951 {
1952         int x;
1953         
1954         ast_clear_flag(config, AST_FLAGS_ALL);
1955
1956         ast_rwlock_rdlock(&features_lock);
1957         for (x = 0; x < FEATURES_COUNT; x++) {
1958                 if (!ast_test_flag(builtin_features + x, AST_FEATURE_FLAG_NEEDSDTMF))
1959                         continue;
1960
1961                 if (ast_test_flag(&(config->features_caller), builtin_features[x].feature_mask))
1962                         ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
1963
1964                 if (ast_test_flag(&(config->features_callee), builtin_features[x].feature_mask))
1965                         ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
1966         }
1967         ast_rwlock_unlock(&features_lock);
1968         
1969         if (chan && peer && !(ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_0) && ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_1))) {
1970                 const char *dynamic_features = pbx_builtin_getvar_helper(chan, "DYNAMIC_FEATURES");
1971
1972                 if (dynamic_features) {
1973                         char *tmp = ast_strdupa(dynamic_features);
1974                         char *tok;
1975                         struct ast_call_feature *feature;
1976
1977                         /* while we have a feature */
1978                         while ((tok = strsep(&tmp, "#"))) {
1979                                 AST_RWLIST_RDLOCK(&feature_list);
1980                                 if ((feature = find_dynamic_feature(tok)) && ast_test_flag(feature, AST_FEATURE_FLAG_NEEDSDTMF)) {
1981                                         if (ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLER))
1982                                                 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
1983                                         if (ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLEE))
1984                                                 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
1985                                 }
1986                                 AST_RWLIST_UNLOCK(&feature_list);
1987                         }
1988                 }
1989         }
1990 }
1991
1992 /*! 
1993  * \brief Get feature and dial
1994  * \param caller,transferee,type,format,data,timeout,outstate,cid_num,cid_name,igncallerstate
1995  *
1996  * Request channel, set channel variables, initiate call,check if they want to disconnect
1997  * go into loop, check if timeout has elapsed, check if person to be transfered hung up,
1998  * check for answer break loop, set cdr return channel.
1999  *
2000  * \todo XXX Check - this is very similar to the code in channel.c 
2001  * \return always a channel
2002 */
2003 static struct ast_channel *ast_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)
2004 {
2005         int state = 0;
2006         int cause = 0;
2007         int to;
2008         struct ast_channel *chan;
2009         struct ast_channel *monitor_chans[2];
2010         struct ast_channel *active_channel;
2011         int res = 0, ready = 0;
2012         struct timeval started;
2013         int x, len = 0;
2014         char *disconnect_code = NULL, *dialed_code = NULL;
2015
2016         if (!(chan = ast_request(type, format, data, &cause))) {
2017                 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
2018                 switch(cause) {
2019                 case AST_CAUSE_BUSY:
2020                         state = AST_CONTROL_BUSY;
2021                         break;
2022                 case AST_CAUSE_CONGESTION:
2023                         state = AST_CONTROL_CONGESTION;
2024                         break;
2025                 }
2026                 goto done;
2027         }
2028
2029         ast_set_callerid(chan, cid_num, cid_name, cid_num);
2030         ast_string_field_set(chan, language, language);
2031         ast_channel_inherit_variables(caller, chan);    
2032         pbx_builtin_setvar_helper(chan, "TRANSFERERNAME", caller->name);
2033                 
2034         if (ast_call(chan, data, timeout)) {
2035                 ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
2036         }
2037         
2038         ast_indicate(caller, AST_CONTROL_RINGING);
2039         /* support dialing of the featuremap disconnect code while performing an attended tranfer */
2040         ast_rwlock_rdlock(&features_lock);
2041         for (x = 0; x < FEATURES_COUNT; x++) {
2042                 if (strcasecmp(builtin_features[x].sname, "disconnect"))
2043                         continue;
2044
2045                 disconnect_code = builtin_features[x].exten;
2046                 len = strlen(disconnect_code) + 1;
2047                 dialed_code = alloca(len);
2048                 memset(dialed_code, 0, len);
2049                 break;
2050         }
2051         ast_rwlock_unlock(&features_lock);
2052         x = 0;
2053         started = ast_tvnow();
2054         to = timeout;
2055
2056         ast_poll_channel_add(caller, chan);
2057
2058         while (!((transferee && ast_check_hangup(transferee)) && (!igncallerstate && ast_check_hangup(caller))) && timeout && (chan->_state != AST_STATE_UP)) {
2059                 struct ast_frame *f = NULL;
2060
2061                 monitor_chans[0] = caller;
2062                 monitor_chans[1] = chan;
2063                 active_channel = ast_waitfor_n(monitor_chans, 2, &to);
2064
2065                 /* see if the timeout has been violated */
2066                 if(ast_tvdiff_ms(ast_tvnow(), started) > timeout) {
2067                         state = AST_CONTROL_UNHOLD;
2068                         ast_log(LOG_NOTICE, "We exceeded our AT-timeout\n");
2069                         break; /*doh! timeout*/
2070                 }
2071
2072                 if (!active_channel)
2073                         continue;
2074
2075                 if (chan && (chan == active_channel)){
2076                         f = ast_read(chan);
2077                         if (f == NULL) { /*doh! where'd he go?*/
2078                                 state = AST_CONTROL_HANGUP;
2079                                 res = 0;
2080                                 break;
2081                         }
2082                         
2083                         if (f->frametype == AST_FRAME_CONTROL || f->frametype == AST_FRAME_DTMF || f->frametype == AST_FRAME_TEXT) {
2084                                 if (f->subclass == AST_CONTROL_RINGING) {
2085                                         state = f->subclass;
2086                                         ast_verb(3, "%s is ringing\n", chan->name);
2087                                         ast_indicate(caller, AST_CONTROL_RINGING);
2088                                 } else if ((f->subclass == AST_CONTROL_BUSY) || (f->subclass == AST_CONTROL_CONGESTION)) {
2089                                         state = f->subclass;
2090                                         ast_verb(3, "%s is busy\n", chan->name);
2091                                         ast_indicate(caller, AST_CONTROL_BUSY);
2092                                         ast_frfree(f);
2093                                         f = NULL;
2094                                         break;
2095                                 } else if (f->subclass == AST_CONTROL_ANSWER) {
2096                                         /* This is what we are hoping for */
2097                                         state = f->subclass;
2098                                         ast_frfree(f);
2099                                         f = NULL;
2100                                         ready=1;
2101                                         break;
2102                                 } else if (f->subclass != -1) {
2103                                         ast_log(LOG_NOTICE, "Don't know what to do about control frame: %d\n", f->subclass);
2104                                 }
2105                                 /* else who cares */
2106                         }
2107
2108                 } else if (caller && (active_channel == caller)) {
2109                         f = ast_read(caller);
2110                         if (f == NULL) { /*doh! where'd he go?*/
2111                                 if (!igncallerstate) {
2112                                         if (ast_check_hangup(caller) && !ast_check_hangup(chan)) {
2113                                                 /* make this a blind transfer */
2114                                                 ready = 1;
2115                                                 break;
2116                                         }
2117                                         state = AST_CONTROL_HANGUP;
2118                                         res = 0;
2119                                         break;
2120                                 }
2121                         } else {
2122                         
2123                                 if (f->frametype == AST_FRAME_DTMF) {
2124                                         dialed_code[x++] = f->subclass;
2125                                         dialed_code[x] = '\0';
2126                                         if (strlen(dialed_code) == len) {
2127                                                 x = 0;
2128                                         } else if (x && strncmp(dialed_code, disconnect_code, x)) {
2129                                                 x = 0;
2130                                                 dialed_code[x] = '\0';
2131                                         }
2132                                         if (*dialed_code && !strcmp(dialed_code, disconnect_code)) {
2133                                                 /* Caller Canceled the call */
2134                                                 state = AST_CONTROL_UNHOLD;
2135                                                 ast_frfree(f);
2136                                                 f = NULL;
2137                                                 break;
2138                                         }
2139                                 }
2140                         }
2141                 }
2142                 if (f)
2143                         ast_frfree(f);
2144         } /* end while */
2145
2146         ast_poll_channel_del(caller, chan);
2147                 
2148 done:
2149         ast_indicate(caller, -1);
2150         if (chan && ready) {
2151                 if (chan->_state == AST_STATE_UP) 
2152                         state = AST_CONTROL_ANSWER;
2153                 res = 0;
2154         } else if (chan) {
2155                 res = -1;
2156                 ast_hangup(chan);
2157                 chan = NULL;
2158         } else {
2159                 res = -1;
2160         }
2161         
2162         if (outstate)
2163                 *outstate = state;
2164
2165         return chan;
2166 }
2167
2168 /*!
2169  * \brief return the first unlocked cdr in a possible chain
2170 */
2171 static struct ast_cdr *pick_unlocked_cdr(struct ast_cdr *cdr)
2172 {
2173         struct ast_cdr *cdr_orig = cdr;
2174         while (cdr) {
2175                 if (!ast_test_flag(cdr,AST_CDR_FLAG_LOCKED))
2176                         return cdr;
2177                 cdr = cdr->next;
2178         }
2179         return cdr_orig; /* everybody LOCKED or some other weirdness, like a NULL */
2180 }
2181
2182 /*!
2183  * \brief bridge the call and set CDR
2184  * \param chan,peer,config
2185  * 
2186  * Set start time, check for two channels,check if monitor on
2187  * check for feature activation, create new CDR
2188  * \retval res on success.
2189  * \retval -1 on failure to bridge.
2190 */
2191 int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast_bridge_config *config)
2192 {
2193         /* Copy voice back and forth between the two channels.  Give the peer
2194            the ability to transfer calls with '#<extension' syntax. */
2195         struct ast_frame *f;
2196         struct ast_channel *who;
2197         char chan_featurecode[FEATURE_MAX_LEN + 1]="";
2198         char peer_featurecode[FEATURE_MAX_LEN + 1]="";
2199         char orig_channame[AST_MAX_EXTENSION];
2200         char orig_peername[AST_MAX_EXTENSION];
2201         int res;
2202         int diff;
2203         int hasfeatures=0;
2204         int hadfeatures=0;
2205         int autoloopflag;
2206         struct ast_option_header *aoh;
2207         struct ast_bridge_config backup_config;
2208         struct ast_cdr *bridge_cdr = NULL;
2209         struct ast_cdr *orig_peer_cdr = NULL;
2210         struct ast_cdr *chan_cdr = pick_unlocked_cdr(chan->cdr); /* the proper chan cdr, if there are forked cdrs */
2211         struct ast_cdr *peer_cdr = pick_unlocked_cdr(peer->cdr); /* the proper chan cdr, if there are forked cdrs */
2212         struct ast_cdr *new_chan_cdr = NULL; /* the proper chan cdr, if there are forked cdrs */
2213         struct ast_cdr *new_peer_cdr = NULL; /* the proper chan cdr, if there are forked cdrs */
2214
2215         memset(&backup_config, 0, sizeof(backup_config));
2216
2217         config->start_time = ast_tvnow();
2218
2219         if (chan && peer) {
2220                 pbx_builtin_setvar_helper(chan, "BRIDGEPEER", peer->name);
2221                 pbx_builtin_setvar_helper(peer, "BRIDGEPEER", chan->name);
2222         } else if (chan)
2223                 pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", NULL);
2224
2225         if (monitor_ok) {
2226                 const char *monitor_exec;
2227                 struct ast_channel *src = NULL;
2228                 if (!monitor_app) { 
2229                         if (!(monitor_app = pbx_findapp("Monitor")))
2230                                 monitor_ok=0;
2231                 }
2232                 if ((monitor_exec = pbx_builtin_getvar_helper(chan, "AUTO_MONITOR"))) 
2233                         src = chan;
2234                 else if ((monitor_exec = pbx_builtin_getvar_helper(peer, "AUTO_MONITOR")))
2235                         src = peer;
2236                 if (monitor_app && src) {
2237                         char *tmp = ast_strdupa(monitor_exec);
2238                         pbx_exec(src, monitor_app, tmp);
2239                 }
2240         }
2241         
2242         set_config_flags(chan, peer, config);
2243         config->firstpass = 1;
2244
2245         /* Answer if need be */
2246         if (ast_answer(chan))
2247                 return -1;
2248
2249         ast_copy_string(orig_channame,chan->name,sizeof(orig_channame));
2250         ast_copy_string(orig_peername,peer->name,sizeof(orig_peername));
2251         orig_peer_cdr = peer_cdr;
2252         
2253         if (!chan_cdr || (chan_cdr && !ast_test_flag(chan_cdr, AST_CDR_FLAG_POST_DISABLED))) {
2254                 
2255                 if (chan_cdr) {
2256                         ast_set_flag(chan_cdr, AST_CDR_FLAG_MAIN);
2257                         ast_cdr_update(chan);
2258                         bridge_cdr = ast_cdr_dup(chan_cdr);
2259                         ast_copy_string(bridge_cdr->lastapp, chan->appl, sizeof(bridge_cdr->lastapp));
2260                         ast_copy_string(bridge_cdr->lastdata, chan->data, sizeof(bridge_cdr->lastdata));
2261                 } else {
2262                         /* better yet, in a xfer situation, find out why the chan cdr got zapped (pun unintentional) */
2263                         bridge_cdr = ast_cdr_alloc(); /* this should be really, really rare/impossible? */
2264                         ast_copy_string(bridge_cdr->channel, chan->name, sizeof(bridge_cdr->channel));
2265                         ast_copy_string(bridge_cdr->dstchannel, peer->name, sizeof(bridge_cdr->dstchannel));
2266                         ast_copy_string(bridge_cdr->uniqueid, chan->uniqueid, sizeof(bridge_cdr->uniqueid));
2267                         ast_copy_string(bridge_cdr->lastapp, chan->appl, sizeof(bridge_cdr->lastapp));
2268                         ast_copy_string(bridge_cdr->lastdata, chan->data, sizeof(bridge_cdr->lastdata));
2269                         ast_cdr_setcid(bridge_cdr, chan);
2270                         bridge_cdr->disposition = (chan->_state == AST_STATE_UP) ?  AST_CDR_ANSWERED : AST_CDR_NULL;
2271                         bridge_cdr->amaflags = chan->amaflags ? chan->amaflags :  ast_default_amaflags;
2272                         ast_copy_string(bridge_cdr->accountcode, chan->accountcode, sizeof(bridge_cdr->accountcode));
2273                         /* Destination information */
2274                         ast_copy_string(bridge_cdr->dst, chan->exten, sizeof(bridge_cdr->dst));
2275                         ast_copy_string(bridge_cdr->dcontext, chan->context, sizeof(bridge_cdr->dcontext));
2276                         if (peer_cdr) {
2277                                 bridge_cdr->start = peer_cdr->start;
2278                                 ast_copy_string(bridge_cdr->userfield, peer_cdr->userfield, sizeof(bridge_cdr->userfield));
2279                         } else {
2280                                 ast_cdr_start(bridge_cdr);
2281                         }
2282                 }
2283                 ast_debug(4,"bridge answer set, chan answer set\n");
2284                 /* peer_cdr->answer will be set when a macro runs on the peer;
2285                    in that case, the bridge answer will be delayed while the
2286                    macro plays on the peer channel. The peer answered the call
2287                    before the macro started playing. To the phone system,
2288                    this is billable time for the call, even tho the caller
2289                    hears nothing but ringing while the macro does its thing. */
2290                 if (peer_cdr && !ast_tvzero(peer_cdr->answer)) {
2291                         bridge_cdr->answer = peer_cdr->answer;
2292                         chan_cdr->answer = peer_cdr->answer;
2293                         bridge_cdr->disposition = peer_cdr->disposition;
2294                         chan_cdr->disposition = peer_cdr->disposition;
2295                 } else {
2296                         ast_cdr_answer(bridge_cdr);
2297                         ast_cdr_answer(chan_cdr); /* for the sake of cli status checks */
2298                 }
2299                 ast_set_flag(chan_cdr, AST_CDR_FLAG_BRIDGED);
2300                 if (peer_cdr) {
2301                         ast_set_flag(peer_cdr, AST_CDR_FLAG_BRIDGED);
2302                 }
2303         }
2304         for (;;) {
2305                 struct ast_channel *other;      /* used later */
2306                 
2307                 res = ast_channel_bridge(chan, peer, config, &f, &who);
2308
2309                 if (config->feature_timer) {
2310                         /* Update time limit for next pass */
2311                         diff = ast_tvdiff_ms(ast_tvnow(), config->start_time);
2312                         config->feature_timer -= diff;
2313                         if (hasfeatures) {
2314                                 /* Running on backup config, meaning a feature might be being
2315                                    activated, but that's no excuse to keep things going 
2316                                    indefinitely! */
2317                                 if (backup_config.feature_timer && ((backup_config.feature_timer -= diff) <= 0)) {
2318                                         ast_debug(1, "Timed out, realtime this time!\n");
2319                                         config->feature_timer = 0;
2320                                         who = chan;
2321                                         if (f)
2322                                                 ast_frfree(f);
2323                                         f = NULL;
2324                                         res = 0;
2325                                 } else if (config->feature_timer <= 0) {
2326                                         /* Not *really* out of time, just out of time for
2327                                            digits to come in for features. */
2328                                         ast_debug(1, "Timed out for feature!\n");
2329                                         if (!ast_strlen_zero(peer_featurecode)) {
2330                                                 ast_dtmf_stream(chan, peer, peer_featurecode, 0, 0);
2331                                                 memset(peer_featurecode, 0, sizeof(peer_featurecode));
2332                                         }
2333                                         if (!ast_strlen_zero(chan_featurecode)) {
2334                                                 ast_dtmf_stream(peer, chan, chan_featurecode, 0, 0);
2335                                                 memset(chan_featurecode, 0, sizeof(chan_featurecode));
2336                                         }
2337                                         if (f)
2338                                                 ast_frfree(f);
2339                                         hasfeatures = !ast_strlen_zero(chan_featurecode) || !ast_strlen_zero(peer_featurecode);
2340                                         if (!hasfeatures) {
2341                                                 /* Restore original (possibly time modified) bridge config */
2342                                                 memcpy(config, &backup_config, sizeof(struct ast_bridge_config));
2343                                                 memset(&backup_config, 0, sizeof(backup_config));
2344                                         }
2345                                         hadfeatures = hasfeatures;
2346                                         /* Continue as we were */
2347                                         continue;
2348                                 } else if (!f) {
2349                                         /* The bridge returned without a frame and there is a feature in progress.
2350                                          * However, we don't think the feature has quite yet timed out, so just
2351                                          * go back into the bridge. */
2352                                         continue;
2353                                 }
2354                         } else {
2355                                 if (config->feature_timer <=0) {
2356                                         /* We ran out of time */
2357                                         config->feature_timer = 0;
2358                                         who = chan;
2359                                         if (f)
2360                                                 ast_frfree(f);
2361                                         f = NULL;
2362                                         res = 0;
2363                                 }
2364                         }
2365                 }
2366                 if (res < 0) {
2367                         if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_test_flag(peer, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan) && !ast_check_hangup(peer))
2368                                 ast_log(LOG_WARNING, "Bridge failed on channels %s and %s\n", chan->name, peer->name);
2369                         goto before_you_go;
2370                 }
2371                 
2372                 if (!f || (f->frametype == AST_FRAME_CONTROL &&
2373                                 (f->subclass == AST_CONTROL_HANGUP || f->subclass == AST_CONTROL_BUSY || 
2374                                         f->subclass == AST_CONTROL_CONGESTION))) {
2375                         res = -1;
2376                         break;
2377                 }
2378                 /* many things should be sent to the 'other' channel */
2379                 other = (who == chan) ? peer : chan;
2380                 if (f->frametype == AST_FRAME_CONTROL) {
2381                         switch (f->subclass) {
2382                         case AST_CONTROL_RINGING:
2383                         case AST_CONTROL_FLASH:
2384                         case -1:
2385                                 ast_indicate(other, f->subclass);
2386                                 break;
2387                         case AST_CONTROL_HOLD:
2388                         case AST_CONTROL_UNHOLD:
2389                                 ast_indicate_data(other, f->subclass, f->data.ptr, f->datalen);
2390                                 break;
2391                         case AST_CONTROL_OPTION:
2392                                 aoh = f->data.ptr;
2393                                 /* Forward option Requests */
2394                                 if (aoh && aoh->flag == AST_OPTION_FLAG_REQUEST) {
2395                                         ast_channel_setoption(other, ntohs(aoh->option), aoh->data, 
2396                                                 f->datalen - sizeof(struct ast_option_header), 0);
2397                                 }
2398                                 break;
2399                         }
2400                 } else if (f->frametype == AST_FRAME_DTMF_BEGIN) {
2401                         /* eat it */
2402                 } else if (f->frametype == AST_FRAME_DTMF) {
2403                         char *featurecode;
2404                         int sense;
2405
2406                         hadfeatures = hasfeatures;
2407                         /* This cannot overrun because the longest feature is one shorter than our buffer */
2408                         if (who == chan) {
2409                                 sense = FEATURE_SENSE_CHAN;
2410                                 featurecode = chan_featurecode;
2411                         } else  {
2412                                 sense = FEATURE_SENSE_PEER;
2413                                 featurecode = peer_featurecode;
2414                         }
2415                         /*! append the event to featurecode. we rely on the string being zero-filled, and
2416                          * not overflowing it. 
2417                          * \todo XXX how do we guarantee the latter ?
2418                          */
2419                         featurecode[strlen(featurecode)] = f->subclass;
2420                         /* Get rid of the frame before we start doing "stuff" with the channels */
2421                         ast_frfree(f);
2422                         f = NULL;
2423                         config->feature_timer = backup_config.feature_timer;
2424                         res = ast_feature_interpret(chan, peer, config, featurecode, sense);
2425                         switch(res) {
2426                         case AST_FEATURE_RETURN_PASSDIGITS:
2427                                 ast_dtmf_stream(other, who, featurecode, 0, 0);
2428                                 /* Fall through */
2429                         case AST_FEATURE_RETURN_SUCCESS:
2430                                 memset(featurecode, 0, sizeof(chan_featurecode));
2431                                 break;
2432                         }
2433                         if (res >= AST_FEATURE_RETURN_PASSDIGITS) {
2434                                 res = 0;
2435                         } else 
2436                                 break;
2437                         hasfeatures = !ast_strlen_zero(chan_featurecode) || !ast_strlen_zero(peer_featurecode);
2438                         if (hadfeatures && !hasfeatures) {
2439                                 /* Restore backup */
2440                                 memcpy(config, &backup_config, sizeof(struct ast_bridge_config));
2441                                 memset(&backup_config, 0, sizeof(struct ast_bridge_config));
2442                         } else if (hasfeatures) {
2443                                 if (!hadfeatures) {
2444                                         /* Backup configuration */
2445                                         memcpy(&backup_config, config, sizeof(struct ast_bridge_config));
2446                                         /* Setup temporary config options */
2447                                         config->play_warning = 0;
2448                                         ast_clear_flag(&(config->features_caller), AST_FEATURE_PLAY_WARNING);
2449                                         ast_clear_flag(&(config->features_callee), AST_FEATURE_PLAY_WARNING);
2450                                         config->warning_freq = 0;
2451                                         config->warning_sound = NULL;
2452                                         config->end_sound = NULL;
2453                                         config->start_sound = NULL;
2454                                         config->firstpass = 0;
2455                                 }
2456                                 config->start_time = ast_tvnow();
2457                                 config->feature_timer = featuredigittimeout;
2458                                 ast_debug(1, "Set time limit to %ld\n", config->feature_timer);
2459                         }
2460                 }
2461                 if (f)
2462                         ast_frfree(f);
2463
2464         }
2465    before_you_go:
2466         if (res != AST_PBX_KEEPALIVE && config->end_bridge_callback) {
2467                 config->end_bridge_callback(config->end_bridge_callback_data);
2468         }
2469
2470         /* run the hangup exten on the chan object IFF it was NOT involved in a parking situation 
2471          * if it were, then chan belongs to a different thread now, and might have been hung up long
2472      * ago.
2473          */
2474         autoloopflag = ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP);
2475         ast_set_flag(chan, AST_FLAG_IN_AUTOLOOP);
2476         if (res != AST_PBX_KEEPALIVE && !ast_test_flag(&(config->features_caller),AST_FEATURE_NO_H_EXTEN) && ast_exists_extension(chan, chan->context, "h", 1, chan->cid.cid_num)) {
2477                 struct ast_cdr *swapper = NULL;
2478                 char savelastapp[AST_MAX_EXTENSION];
2479                 char savelastdata[AST_MAX_EXTENSION];
2480                 char save_exten[AST_MAX_EXTENSION];
2481                 int  save_prio;
2482                 int  found = 0; /* set if we find at least one match */
2483                 int  spawn_error = 0;
2484                 
2485                 if (bridge_cdr && ast_opt_end_cdr_before_h_exten) {
2486                         ast_cdr_end(bridge_cdr);
2487                 }
2488                 /* swap the bridge cdr and the chan cdr for a moment, and let the endbridge
2489                    dialplan code operate on it */
2490                 ast_channel_lock(chan);
2491                 if (bridge_cdr) {
2492                         swapper = chan->cdr;
2493                         ast_copy_string(savelastapp, bridge_cdr->lastapp, sizeof(bridge_cdr->lastapp));
2494                         ast_copy_string(savelastdata, bridge_cdr->lastdata, sizeof(bridge_cdr->lastdata));
2495                         chan->cdr = bridge_cdr;
2496                 }
2497                 ast_copy_string(save_exten, chan->exten, sizeof(save_exten));
2498                 save_prio = chan->priority;
2499                 ast_copy_string(chan->exten, "h", sizeof(chan->exten));
2500                 chan->priority = 1;
2501                 ast_channel_unlock(chan);
2502                 while ((spawn_error = ast_spawn_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num, &found, 1)) == 0) {
2503                         chan->priority++;
2504                 }
2505                 if (found && spawn_error) {
2506                         /* Something bad happened, or a hangup has been requested. */
2507                         ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", chan->context, chan->exten, chan->priority, chan->name);
2508                         ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", chan->context, chan->exten, chan->priority, chan->name);
2509                 }
2510                 /* swap it back */
2511                 ast_channel_lock(chan);
2512                 ast_copy_string(chan->exten, save_exten, sizeof(chan->exten));
2513                 chan->priority = save_prio;
2514                 if (bridge_cdr)
2515                         chan->cdr = swapper;
2516                 ast_set_flag(chan, AST_FLAG_BRIDGE_HANGUP_RUN);
2517                 ast_channel_unlock(chan);
2518                 /* protect the lastapp/lastdata against the effects of the hangup/dialplan code */
2519                 if (bridge_cdr) {
2520                         ast_copy_string(bridge_cdr->lastapp, savelastapp, sizeof(bridge_cdr->lastapp));
2521                         ast_copy_string(bridge_cdr->lastdata, savelastdata, sizeof(bridge_cdr->lastdata));
2522                 }
2523         }
2524         ast_set2_flag(chan, autoloopflag, AST_FLAG_IN_AUTOLOOP);
2525
2526         /* obey the NoCDR() wishes. -- move the DISABLED flag to the bridge CDR if it was set on the channel during the bridge... */
2527         if (res != AST_PBX_KEEPALIVE) {
2528                 new_chan_cdr = pick_unlocked_cdr(chan->cdr); /* the proper chan cdr, if there are forked cdrs */
2529                 if (bridge_cdr && new_chan_cdr && ast_test_flag(new_chan_cdr, AST_CDR_FLAG_POST_DISABLED))
2530                         ast_set_flag(bridge_cdr, AST_CDR_FLAG_POST_DISABLED);
2531         }
2532
2533         /* we can post the bridge CDR at this point */
2534         if (bridge_cdr) {
2535                 ast_cdr_end(bridge_cdr);
2536                 ast_cdr_detach(bridge_cdr);
2537         }
2538         
2539         /* do a specialized reset on the beginning channel
2540            CDR's, if they still exist, so as not to mess up
2541            issues in future bridges;
2542            
2543            Here are the rules of the game:
2544            1. The chan and peer channel pointers will not change
2545               during the life of the bridge.
2546            2. But, in transfers, the channel names will change.
2547               between the time the bridge is started, and the
2548               time the channel ends. 
2549               Usually, when a channel changes names, it will
2550               also change CDR pointers.
2551            3. Usually, only one of the two channels (chan or peer)
2552               will change names.
2553            4. Usually, if a channel changes names during a bridge,
2554               it is because of a transfer. Usually, in these situations,
2555               it is normal to see 2 bridges running simultaneously, and
2556               it is not unusual to see the two channels that change
2557               swapped between bridges.
2558            5. After a bridge occurs, we have 2 or 3 channels' CDRs
2559               to attend to; if the chan or peer changed names,
2560               we have the before and after attached CDR's.
2561            6. Parking has to be accounted for in the code:
2562               a. Parking will cause ast_bridge_call to return
2563                  either AST_PBX_NO_HANGUP_PEER or AST_PBX_NO_HANGUP_PEER_PARKED;
2564                          in the latter case, peer is (most likely) a bad
2565                          pointer, you can no longer deref it. If it does still
2566                          exist, it is under another's thread control, and
2567                          could be destroyed at any time.
2568           b. The same applies to AST_PBX_KEEPALIVE, in which
2569                      case, the chan ptr cannot be used, as another thread
2570                          owns it and may have destroyed the channel.
2571               c. In the former case, you need to check peer to see if it 
2572                  still exists before you deref it, and obtain a lock.
2573               d. In neither case should you do an ast_hangup(peer).
2574                   e. Do not overwrite the result code from ast_bridge_call.
2575         */
2576         
2577         if (res != AST_PBX_KEEPALIVE && new_chan_cdr) {
2578                 struct ast_channel *chan_ptr = NULL;
2579  
2580                 if (strcasecmp(orig_channame, chan->name) != 0) { 
2581                         /* old channel */
2582                         chan_ptr = ast_get_channel_by_name_locked(orig_channame);
2583                         if (chan_ptr) {
2584                                 if (!ast_bridged_channel(chan_ptr)) {
2585                                         struct ast_cdr *cur;
2586                                         for (cur = chan_ptr->cdr; cur; cur = cur->next) {
2587                                                 if (cur == chan_cdr) {
2588                                                         break;
2589                                                 }
2590                                         }
2591                                         if (cur)
2592                                                 ast_cdr_specialized_reset(chan_cdr,0);
2593                                 }
2594                                 ast_channel_unlock(chan_ptr);
2595                         }
2596                         /* new channel */
2597                         ast_cdr_specialized_reset(new_chan_cdr,0);
2598                 } else {
2599                         ast_cdr_specialized_reset(chan_cdr,0); /* nothing changed, reset the chan_cdr  */
2600                 }
2601         }
2602         
2603         if (res != AST_PBX_NO_HANGUP_PEER_PARKED) { /* if the peer was involved in a park, don't even touch it; it's probably gone */
2604                 struct ast_channel *chan_ptr = NULL;
2605                 new_peer_cdr = pick_unlocked_cdr(peer->cdr); /* the proper chan cdr, if there are forked cdrs */
2606                 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))
2607                         ast_set_flag(new_peer_cdr, AST_CDR_FLAG_POST_DISABLED); /* DISABLED is viral-- it will propagate across a bridge */
2608                 if (strcasecmp(orig_peername, peer->name) != 0) { 
2609                         /* old channel */
2610                         chan_ptr = ast_get_channel_by_name_locked(orig_peername);
2611                         if (chan_ptr) {
2612                                 if (!ast_bridged_channel(chan_ptr)) {
2613                                         struct ast_cdr *cur;
2614                                         for (cur = chan_ptr->cdr; cur; cur = cur->next) {
2615                                                 if (cur == peer_cdr) {
2616                                                         break;
2617                                                 }
2618                                         }
2619                                         if (cur)
2620                                                 ast_cdr_specialized_reset(peer_cdr,0);
2621                                 }
2622                                 ast_channel_unlock(chan_ptr);
2623                         }
2624                         /* new channel */
2625                         ast_cdr_specialized_reset(new_peer_cdr,0);
2626                 } else {
2627                         ast_cdr_specialized_reset(peer_cdr,0); /* nothing changed, reset the peer_cdr  */
2628                 }
2629         }
2630         return res;
2631 }
2632
2633 /*! \brief Output parking event to manager */
2634 static void post_manager_event(const char *s, struct parkeduser *pu)
2635 {
2636         manager_event(EVENT_FLAG_CALL, s,
2637                 "Exten: %s\r\n"
2638                 "Channel: %s\r\n"
2639                 "Parkinglot: %s\r\n"
2640                 "CallerIDNum: %s\r\n"
2641                 "CallerIDName: %s\r\n"
2642                 "UniqueID: %s\r\n\r\n",
2643                 pu->parkingexten, 
2644                 pu->chan->name,
2645                 pu->parkinglot->name,
2646                 S_OR(pu->chan->cid.cid_num, "<unknown>"),
2647                 S_OR(pu->chan->cid.cid_name, "<unknown>"),
2648                 pu->chan->uniqueid
2649                 );
2650 }
2651
2652 /*! \brief Run management on parkinglots, called once per parkinglot */
2653 int manage_parkinglot(struct ast_parkinglot *curlot, fd_set *rfds, fd_set *efds, fd_set *nrfds, fd_set *nefds, int *ms, int *max)
2654 {
2655
2656         struct parkeduser *pu;
2657         int res = 0;
2658         char parkingslot[AST_MAX_EXTENSION];
2659
2660         /* Lock parking list */
2661         AST_LIST_LOCK(&curlot->parkings);
2662         AST_LIST_TRAVERSE_SAFE_BEGIN(&curlot->parkings, pu, list) {
2663                 struct ast_channel *chan = pu->chan;    /* shorthand */
2664                 int tms;        /* timeout for this item */
2665                 int x;          /* fd index in channel */
2666                 struct ast_context *con;
2667
2668                 if (pu->notquiteyet) { /* Pretend this one isn't here yet */
2669                         continue;
2670                 }
2671                 tms = ast_tvdiff_ms(ast_tvnow(), pu->start);
2672                 if (tms > pu->parkingtime) {
2673                         /* Stop music on hold */
2674                         ast_indicate(pu->chan, AST_CONTROL_UNHOLD);
2675                         /* Get chan, exten from derived kludge */
2676                         if (pu->peername[0]) {
2677                                 char *peername = ast_strdupa(pu->peername);
2678                                 char *cp = strrchr(peername, '-');
2679                                 char peername_flat[AST_MAX_EXTENSION]; /* using something like DAHDI/52 for an extension name is NOT a good idea */
2680                                 int i;
2681
2682                                 if (cp) 
2683                                         *cp = 0;
2684                                 ast_copy_string(peername_flat,peername,sizeof(peername_flat));
2685                                 for(i=0; peername_flat[i] && i < AST_MAX_EXTENSION; i++) {
2686                                         if (peername_flat[i] == '/') 
2687                                                 peername_flat[i]= '0';
2688                                 }
2689                                 con = ast_context_find_or_create(NULL, NULL, pu->parkinglot->parking_con_dial, registrar);
2690                                 if (!con) {
2691                                         ast_log(LOG_ERROR, "Parking dial context '%s' does not exist and unable to create\n", pu->parkinglot->parking_con_dial);
2692                                 }
2693                                 if (con) {
2694                                         char returnexten[AST_MAX_EXTENSION];
2695                                         struct ast_datastore *features_datastore;
2696                                         struct ast_dial_features *dialfeatures = NULL;
2697
2698                                         ast_channel_lock(chan);
2699
2700                                         if ((features_datastore = ast_channel_datastore_find(chan, &dial_features_info, NULL)))
2701                                                 dialfeatures = features_datastore->data;
2702
2703                                         ast_channel_unlock(chan);
2704
2705                                         if (dialfeatures)
2706                                                 snprintf(returnexten, sizeof(returnexten), "%s,,%s", peername, dialfeatures->options);
2707                                         else /* Existing default */
2708                                                 snprintf(returnexten, sizeof(returnexten), "%s,,t", peername);
2709
2710                                         ast_add_extension2(con, 1, peername_flat, 1, NULL, NULL, "Dial", ast_strdup(returnexten), ast_free_ptr, registrar);
2711                                 }
2712                                 if (comebacktoorigin) {
2713                                         set_c_e_p(chan, pu->parkinglot->parking_con_dial, peername_flat, 1);
2714                                 } else {
2715                                         ast_log(LOG_WARNING, "now going to parkedcallstimeout,s,1 | ps is %d\n",pu->parkingnum);
2716                                         snprintf(parkingslot, sizeof(parkingslot), "%d", pu->parkingnum);
2717                                         pbx_builtin_setvar_helper(chan, "PARKINGSLOT", parkingslot);
2718                                         set_c_e_p(chan, "parkedcallstimeout", peername_flat, 1);
2719                                 }
2720                         } else {
2721                                 /* They've been waiting too long, send them back to where they came.  Theoretically they
2722                                    should have their original extensions and such, but we copy to be on the safe side */
2723                                 set_c_e_p(chan, pu->context, pu->exten, pu->priority);
2724                         }
2725                         post_manager_event("ParkedCallTimeOut", pu);
2726
2727                         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);
2728                         /* Start up the PBX, or hang them up */
2729                         if (ast_pbx_start(chan))  {
2730                                 ast_log(LOG_WARNING, "Unable to restart the PBX for user on '%s', hanging them up...\n", pu->chan->name);
2731                                 ast_hangup(chan);
2732                         }
2733                         /* And take them out of the parking lot */
2734                         con = ast_context_find(pu->parkinglot->parking_con);
2735                         if (con) {
2736                                 if (ast_context_remove_extension2(con, pu->parkingexten, 1, NULL, 0))
2737                                         ast_log(LOG_WARNING, "Whoa, failed to remove the parking extension!\n");
2738                                 else
2739                                         notify_metermaids(pu->parkingexten, curlot->parking_con, AST_DEVICE_NOT_INUSE);
2740                         } else
2741                                 ast_log(LOG_WARNING, "Whoa, no parking context?\n");
2742                         AST_LIST_REMOVE_CURRENT(list);
2743                 } else {        /* still within parking time, process descriptors */
2744                         for (x = 0; x < AST_MAX_FDS; x++) {
2745                                 struct ast_frame *f;
2746
2747                                 if ((chan->fds[x] == -1) || (!FD_ISSET(chan->fds[x], rfds) && !FD_ISSET(pu->chan->fds[x], efds))) 
2748                                         continue;
2749                                 
2750                                 if (FD_ISSET(chan->fds[x], efds))
2751                                         ast_set_flag(chan, AST_FLAG_EXCEPTION);
2752                                 else
2753                                         ast_clear_flag(chan, AST_FLAG_EXCEPTION);
2754                                 chan->fdno = x;
2755
2756                                 /* See if they need servicing */
2757                                 f = ast_read(pu->chan);
2758                                 /* Hangup? */
2759                                 if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass ==  AST_CONTROL_HANGUP))) {
2760                                         if (f)
2761                                                 ast_frfree(f);
2762                                         post_manager_event("ParkedCallGiveUp", pu);
2763
2764                                         /* There's a problem, hang them up*/
2765                                         ast_verb(2, "%s got tired of being parked\n", chan->name);
2766                                         ast_hangup(chan);
2767                                         /* And take them out of the parking lot */
2768                                         con = ast_context_find(curlot->parking_con);
2769                                         if (con) {
2770                                                 if (ast_context_remove_extension2(con, pu->parkingexten, 1, NULL, 0))
2771                                                         ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
2772                                                 else
2773                                                         notify_metermaids(pu->parkingexten, curlot->parking_con, AST_DEVICE_NOT_INUSE);
2774                                         } else
2775                                                 ast_log(LOG_WARNING, "Whoa, no parking context for parking lot %s?\n", curlot->name);
2776                                         AST_LIST_REMOVE_CURRENT(list);
2777                                         break;
2778                                 } else {
2779                                         /* XXX Maybe we could do something with packets, like dial "0" for operator or something XXX */
2780                                         ast_frfree(f);
2781                                         if (pu->moh_trys < 3 && !chan->generatordata) {
2782                                                 ast_debug(1, "MOH on parked call stopped by outside source.  Restarting on channel %s.\n", chan->name);
2783                                                 ast_indicate_data(chan, AST_CONTROL_HOLD, 
2784                                                         S_OR(curlot->mohclass, NULL),
2785                                                         (!ast_strlen_zero(curlot->mohclass) ? strlen(curlot->mohclass) + 1 : 0));
2786                                                 pu->moh_trys++;
2787                                         }
2788                                         goto std;       /* XXX Ick: jumping into an else statement??? XXX */
2789                                 }
2790                         } /* End for */
2791                         if (x >= AST_MAX_FDS) {
2792 std:                            for (x=0; x<AST_MAX_FDS; x++) { /* mark fds for next round */
2793                                         if (chan->fds[x] > -1) {
2794                                                 FD_SET(chan->fds[x], nrfds);
2795                                                 FD_SET(chan->fds[x], nefds);
2796                                                 if (chan->fds[x] > *max)
2797                                                         *max = chan->fds[x];
2798                                         }
2799                                 }
2800                                 /* Keep track of our shortest wait */
2801                                 if (tms < *ms || *ms < 0)
2802                                         *ms = tms;
2803                         }
2804                 }
2805         }
2806         AST_LIST_TRAVERSE_SAFE_END;
2807         AST_LIST_UNLOCK(&curlot->parkings);
2808         return res;
2809 }
2810
2811 /*! 
2812  * \brief Take care of parked calls and unpark them if needed 
2813  * \param ignore unused var.
2814  * 
2815  * Start inf loop, lock parking lot, check if any parked channels have gone above timeout
2816  * if so, remove channel from parking lot and return it to the extension that parked it.
2817  * Check if parked channel decided to hangup, wait until next FD via select().
2818 */
2819 static void *do_parking_thread(void *ignore)
2820 {
2821         fd_set rfds, efds;      /* results from previous select, to be preserved across loops. */
2822         fd_set nrfds, nefds;    /* args for the next select */
2823         FD_ZERO(&rfds);
2824         FD_ZERO(&efds);
2825
2826         for (;;) {
2827                 int res = 0;
2828                 int ms = -1;    /* select timeout, uninitialized */
2829                 int max = -1;   /* max fd, none there yet */
2830                 struct ao2_iterator iter;
2831                 struct ast_parkinglot *curlot;
2832                 FD_ZERO(&nrfds);
2833                 FD_ZERO(&nefds);
2834                 iter = ao2_iterator_init(parkinglots, 0);
2835
2836                 while ((curlot = ao2_iterator_next(&iter))) {
2837                         res = manage_parkinglot(curlot, &rfds, &efds, &nrfds, &nefds, &ms, &max);
2838                         ao2_ref(curlot, -1);
2839                 }
2840
2841                 rfds = nrfds;
2842                 efds = nefds;
2843                 {
2844                         struct timeval wait = ast_samp2tv(ms, 1000);
2845                         /* Wait for something to happen */
2846                         ast_select(max + 1, &rfds, NULL, &efds, (ms > -1) ? &wait : NULL);
2847                 }
2848                 pthread_testcancel();
2849         }
2850         return NULL;    /* Never reached */
2851 }
2852
2853 /*! \brief Find parkinglot by name */
2854 struct ast_parkinglot *find_parkinglot(const char *name)
2855 {
2856         struct ast_parkinglot *parkinglot = NULL;
2857         struct ast_parkinglot tmp_parkinglot;
2858         
2859         if (ast_strlen_zero(name))
2860                 return NULL;
2861
2862         ast_copy_string(tmp_parkinglot.name, name, sizeof(tmp_parkinglot.name));
2863
2864         parkinglot = ao2_find(parkinglots, &tmp_parkinglot, OBJ_POINTER);
2865
2866         if (parkinglot && option_debug)
2867                 ast_log(LOG_DEBUG, "Found Parkinglot: %s\n", parkinglot->name);
2868
2869         return parkinglot;
2870 }
2871
2872 AST_APP_OPTIONS(park_call_options, BEGIN_OPTIONS
2873         AST_APP_OPTION('r', AST_PARK_OPT_RINGING),
2874         AST_APP_OPTION('R', AST_PARK_OPT_RANDOMIZE),
2875         AST_APP_OPTION('s', AST_PARK_OPT_SILENCE),
2876 END_OPTIONS );
2877
2878 /*! \brief Park a call */
2879 static int park_call_exec(struct ast_channel *chan, void *data)
2880 {
2881         /* Cache the original channel name in case we get masqueraded in the middle
2882          * of a park--it is still theoretically possible for a transfer to happen before
2883          * we get here, but it is _really_ unlikely */
2884         char *orig_chan_name = ast_strdupa(chan->name);
2885         char orig_exten[AST_MAX_EXTENSION];
2886         int orig_priority = chan->priority;
2887
2888         /* Data is unused at the moment but could contain a parking
2889            lot context eventually */
2890         int res = 0;
2891
2892         char *parse = NULL;
2893         AST_DECLARE_APP_ARGS(app_args,
2894                 AST_APP_ARG(timeout);
2895                 AST_APP_ARG(return_con);
2896                 AST_APP_ARG(return_ext);
2897                 AST_APP_ARG(return_pri);
2898                 AST_APP_ARG(options);
2899         );
2900
2901         parse = ast_strdupa(data);
2902         AST_STANDARD_APP_ARGS(app_args, parse);
2903
2904         ast_copy_string(orig_exten, chan->exten, sizeof(orig_exten));
2905
2906         /* Setup the exten/priority to be s/1 since we don't know
2907            where this call should return */
2908         strcpy(chan->exten, "s");
2909         chan->priority = 1;
2910
2911         /* Answer if call is not up */
2912         if (chan->_state != AST_STATE_UP)
2913                 res = ast_answer(chan);
2914
2915         /* Sleep to allow VoIP streams to settle down */
2916         if (!res)
2917                 res = ast_safe_sleep(chan, 1000);
2918
2919         /* Park the call */
2920         if (!res) {
2921                 struct ast_park_call_args args = {
2922                         .orig_chan_name = orig_chan_name,
2923                 };
2924                 struct ast_flags flags = { 0 };
2925
2926                 if (parse) {
2927                         if (!ast_strlen_zero(app_args.timeout)) {
2928                                 if (sscanf(app_args.timeout, "%d", &args.timeout) != 1) {
2929                                         ast_log(LOG_WARNING, "Invalid timeout '%s' provided\n", app_args.timeout);
2930                                         args.timeout = 0;
2931                                 }
2932                         }
2933                         if (!ast_strlen_zero(app_args.return_con)) {
2934                                 args.return_con = app_args.return_con;
2935                         }
2936                         if (!ast_strlen_zero(app_args.return_ext)) {
2937                                 args.return_ext = app_args.return_ext;
2938                         }
2939                         if (!ast_strlen_zero(app_args.return_pri)) {
2940                                 if (sscanf(app_args.return_pri, "%d", &args.return_pri) != 1) {
2941                                         ast_log(LOG_WARNING, "Invalid priority '%s' specified\n", app_args.return_pri);
2942                                         args.return_pri = 0;
2943                                 }
2944                         }
2945                 }
2946
2947                 ast_app_parse_options(park_call_options, &flags, NULL, app_args.options);
2948                 args.flags = flags.flags;
2949
2950                 res = ast_park_call_full(chan, chan, &args);
2951                 /* Continue on in the dialplan */
2952                 if (res == 1) {
2953                         ast_copy_string(chan->exten, orig_exten, sizeof(chan->exten));
2954                         chan->priority = orig_priority;
2955                         res = 0;
2956                 } else if (!res)
2957                         res = AST_PBX_KEEPALIVE;
2958         }
2959
2960         return res;
2961 }
2962
2963 /*! \brief Pickup parked call */
2964 static int park_exec_full(struct ast_channel *chan, void *data, struct ast_parkinglot *parkinglot)
2965 {
2966         int res = 0;
2967         struct ast_channel *peer=NULL;
2968         struct parkeduser *pu;
2969         struct ast_context *con;
2970         int park = 0;
2971         struct ast_bridge_config config;
2972
2973         if (data)
2974                 park = atoi((char *)data);
2975
2976         parkinglot = find_parkinglot(findparkinglotname(chan));         
2977         if (!parkinglot)
2978                 parkinglot = default_parkinglot;
2979
2980         AST_LIST_LOCK(&parkinglot->parkings);
2981         AST_LIST_TRAVERSE_SAFE_BEGIN(&parkinglot->parkings, pu, list) {
2982                 if (!data || pu->parkingnum == park) {
2983                         if (pu->chan->pbx) { /* do not allow call to be picked up until the PBX thread is finished */
2984                                 AST_LIST_UNLOCK(&parkinglot->parkings);
2985                                 return -1;
2986                         }
2987                         AST_LIST_REMOVE_CURRENT(list);
2988                         break;
2989                 }
2990         }
2991         AST_LIST_TRAVERSE_SAFE_END
2992         AST_LIST_UNLOCK(&parkinglot->parkings);
2993
2994         if (pu) {
2995                 peer = pu->chan;
2996                 con = ast_context_find(parkinglot->parking_con);
2997                 if (con) {
2998                         if (ast_context_remove_extension2(con, pu->parkingexten, 1, NULL, 0))
2999                                 ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
3000                         else
3001                                 notify_metermaids(pu->parkingexten, parkinglot->parking_con, AST_DEVICE_NOT_INUSE);
3002                 } else
3003                         ast_log(LOG_WARNING, "Whoa, no parking context?\n");
3004
3005                 manager_event(EVENT_FLAG_CALL, "UnParkedCall",
3006                         "Exten: %s\r\n"
3007                         "Channel: %s\r\n"
3008                         "From: %s\r\n"
3009                         "CallerIDNum: %s\r\n"
3010                         "CallerIDName: %s\r\n",
3011                         pu->parkingexten, pu->chan->name, chan->name,
3012                         S_OR(pu->chan->cid.cid_num, "<unknown>"),
3013                         S_OR(pu->chan->cid.cid_name, "<unknown>")
3014                         );
3015
3016                 ast_free(pu);
3017         }
3018         /* JK02: it helps to answer the channel if not already up */
3019         if (chan->_state != AST_STATE_UP)
3020                 ast_answer(chan);
3021
3022         //XXX Why do we unlock here ?
3023         // uncomment it for now, till my setup with debug_threads and detect_deadlocks starts to complain
3024         //ASTOBJ_UNLOCK(parkinglot);
3025
3026         if (peer) {
3027                 /* Play a courtesy to the source(s) configured to prefix the bridge connecting */
3028                 
3029                 if (!ast_strlen_zero(courtesytone)) {
3030                         int error = 0;
3031                         ast_indicate(peer, AST_CONTROL_UNHOLD);
3032                         if (parkedplay == 0) {
3033                                 error = ast_stream_and_wait(chan, courtesytone, "");
3034                         } else if (parkedplay == 1) {
3035                                 error = ast_stream_and_wait(peer, courtesytone, "");
3036                         } else if (parkedplay == 2) {
3037                                 if (!ast_streamfile(chan, courtesytone, chan->language) &&
3038                                                 !ast_streamfile(peer, courtesytone, chan->language)) {
3039                                         /*! \todo XXX we would like to wait on both! */
3040                                         res = ast_waitstream(chan, "");
3041                                         if (res >= 0)
3042                                                 res = ast_waitstream(peer, "");
3043                                         if (res < 0)
3044                                                 error = 1;
3045                                 }
3046                         }
3047                         if (error) {
3048                                 ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
3049                                 ast_hangup(peer);
3050                                 return -1;
3051                         }
3052                 } else
3053                         ast_indicate(peer, AST_CONTROL_UNHOLD); 
3054
3055                 res = ast_channel_make_compatible(chan, peer);
3056                 if (res < 0) {
3057                         ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for bridge\n", chan->name, peer->name);
3058                         ast_hangup(peer);
3059                         return -1;
3060                 }
3061                 /* This runs sorta backwards, since we give the incoming channel control, as if it
3062                    were the person called. */
3063                 ast_verb(3, "Channel %s connected to parked call %d\n", chan->name, park);
3064
3065                 pbx_builtin_setvar_helper(chan, "PARKEDCHANNEL", peer->name);
3066                 ast_cdr_setdestchan(chan->cdr, peer->name);
3067                 memset(&config, 0, sizeof(struct ast_bridge_config));
3068                 if ((parkinglot->parkedcalltransfers == AST_FEATURE_FLAG_BYCALLEE) || (parkinglot->parkedcalltransfers == AST_FEATURE_FLAG_BYBOTH))
3069                         ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
3070                 if ((parkinglot->parkedcalltransfers == AST_FEATURE_FLAG_BYCALLER) || (parkinglot->parkedcalltransfers == AST_FEATURE_FLAG_BYBOTH))
3071                         ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
3072                 if ((parkinglot->parkedcallreparking == AST_FEATURE_FLAG_BYCALLEE) || (parkinglot->parkedcallreparking == AST_FEATURE_FLAG_BYBOTH))
3073                         ast_set_flag(&(config.features_callee), AST_FEATURE_PARKCALL);
3074                 if ((parkinglot->parkedcallreparking == AST_FEATURE_FLAG_BYCALLER) || (parkinglot->parkedcallreparking == AST_FEATURE_FLAG_BYBOTH))
3075                         ast_set_flag(&(config.features_caller), AST_FEATURE_PARKCALL);
3076                 res = ast_bridge_call(chan, peer, &config);
3077
3078                 pbx_builtin_setvar_helper(chan, "PARKEDCHANNEL", peer->name);
3079                 ast_cdr_setdestchan(chan->cdr, peer->name);
3080
3081                 /* Simulate the PBX hanging up */
3082                 if (res != AST_PBX_NO_HANGUP_PEER && res != AST_PBX_NO_HANGUP_PEER_PARKED)
3083                         ast_hangup(peer);
3084                 return res;
3085         } else {
3086                 /*! \todo XXX Play a message XXX */
3087                 if (ast_stream_and_wait(chan, "pbx-invalidpark", ""))
3088                         ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", "pbx-invalidpark", chan->name);
3089                 ast_verb(3, "Channel %s tried to talk to nonexistent parked call %d\n", chan->name, park);
3090                 res = -1;
3091         }
3092
3093         return res;
3094 }
3095
3096 static int park_exec(struct ast_channel *chan, void *data) 
3097 {
3098         return park_exec_full(chan, data, default_parkinglot);
3099 }
3100
3101 /*! \brief Unreference parkinglot object. If no more references,
3102         then go ahead and delete it */
3103 static void parkinglot_unref(struct ast_parkinglot *parkinglot) 
3104 {
3105         int refcount = ao2_ref(parkinglot, -1);
3106         if (option_debug > 2)
3107                 ast_log(LOG_DEBUG, "Multiparking: %s refcount now %d\n", parkinglot->name, refcount - 1);
3108 }
3109
3110 static struct ast_parkinglot *parkinglot_addref(struct ast_parkinglot *parkinglot)
3111 {
3112         int refcount = ao2_ref(parkinglot, +1);
3113         if (option_debug > 2)
3114                 ast_log(LOG_DEBUG, "Multiparking: %s refcount now %d\n", parkinglot->name, refcount + 1);
3115         return parkinglot;
3116 }
3117
3118 /*! \brief Allocate parking lot structure */
3119 static struct ast_parkinglot *create_parkinglot(char *name)
3120 {
3121         struct ast_parkinglot *newlot = (struct ast_parkinglot *) NULL;
3122
3123         if (!name)
3124                 return NULL;
3125
3126         newlot = ao2_alloc(sizeof(*newlot), parkinglot_destroy);
3127         if (!newlot)
3128                 return NULL;
3129         
3130         ast_copy_string(newlot->name, name, sizeof(newlot->name));
3131
3132         return newlot;
3133 }
3134
3135 /*! \brief Destroy a parking lot */
3136 static void parkinglot_destroy(void *obj)
3137 {
3138         struct ast_parkinglot *ruin = obj;
3139         struct ast_context *con;
3140         con = ast_context_find(ruin->parking_con);
3141         if (con)
3142                 ast_context_destroy(con, registrar);
3143         ao2_unlink(parkinglots, ruin);
3144 }
3145
3146 /*! \brief Build parkinglot from configuration and chain it in */
3147 static struct ast_parkinglot *build_parkinglot(char *name, struct ast_variable *var)
3148 {
3149         struct ast_parkinglot *parkinglot;
3150         struct ast_context *con = NULL;
3151
3152         struct ast_variable *confvar = var;
3153         int error = 0;
3154         int start = 0, end = 0;
3155         int oldparkinglot = 0;
3156
3157         parkinglot = find_parkinglot(name);
3158         if (parkinglot)
3159                 oldparkinglot = 1;
3160         else
3161                 parkinglot = create_parkinglot(name);
3162
3163         if (!parkinglot)
3164                 return NULL;
3165
3166         ao2_lock(parkinglot);
3167
3168         if (option_debug)
3169                 ast_log(LOG_DEBUG, "Building parking lot %s\n", name);
3170         
3171         /* Do some config stuff */
3172         while(confvar) {
3173                 if (!strcasecmp(confvar->name, "context")) {
3174                         ast_copy_string(parkinglot->parking_con, confvar->value, sizeof(parkinglot->parking_con));
3175                 } else if (!strcasecmp(confvar->name, "parkingtime")) {
3176                         if ((sscanf(confvar->value, "%d", &parkinglot->parkingtime) != 1) || (parkinglot->parkingtime < 1)) {
3177                                 ast_log(LOG_WARNING, "%s is not a valid parkingtime\n", confvar->value);
3178                                 parkinglot->parkingtime = DEFAULT_PARK_TIME;
3179                         } else
3180                                 parkinglot->parkingtime = parkinglot->parkingtime * 1000;
3181                 } else if (!strcasecmp(confvar->name, "parkpos")) {
3182                         if (sscanf(confvar->value, "%d-%d", &start, &end) != 2) {
3183                                 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);
3184                                 error = 1;
3185                         } else {
3186                                 parkinglot->parking_start = start;
3187                                 parkinglot->parking_stop = end;
3188                         }
3189                 } else if (!strcasecmp(confvar->name, "findslot")) {
3190                         parkinglot->parkfindnext = (!strcasecmp(confvar->value, "next"));
3191                 }
3192                 confvar = confvar->next;
3193         }
3194         /* make sure parkingtime is set if not specified */
3195         if (parkinglot->parkingtime == 0) {
3196                 parkinglot->parkingtime = DEFAULT_PARK_TIME;
3197         }
3198
3199         if (!var) {     /* Default parking lot */
3200                 ast_copy_string(parkinglot->parking_con, "parkedcalls", sizeof(parkinglot->parking_con));
3201                 ast_copy_string(parkinglot->parking_con_dial, "park-dial", sizeof(parkinglot->parking_con_dial));
3202                 ast_copy_string(parkinglot->mohclass, "default", sizeof(parkinglot->mohclass));
3203         }
3204
3205         /* Check for errors */
3206         if (ast_strlen_zero(parkinglot->parking_con)) {
3207                 ast_log(LOG_WARNING, "Parking lot %s lacks context\n", name);
3208                 error = 1;
3209         }
3210
3211         /* Create context */
3212         if (!error && !(con = ast_context_find_or_create(NULL, NULL, parkinglot->parking_con, registrar))) {
3213                 ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", parkinglot->parking_con);
3214                 error = 1;
3215         }
3216
3217         /* Add a parking extension into the context */
3218         if (!oldparkinglot) {
3219                 if (!ast_strlen_zero(ast_parking_ext())) {
3220                         if (ast_add_extension2(con, 1, ast_parking_ext(), 1, NULL, NULL, parkcall, strdup(""), ast_free, registrar) == -1)
3221                                 error = 1;
3222                 }
3223         }
3224
3225         ao2_unlock(parkinglot);
3226
3227         if (error) {
3228                 ast_log(LOG_WARNING, "Parking %s not open for business. Configuration error.\n", name);
3229                 parkinglot_destroy(parkinglot);
3230                 return NULL;
3231         }
3232         if (option_debug)
3233                 ast_log(LOG_DEBUG, "Parking %s now open for business. (start exten %d end %d)\n", name, start, end);
3234
3235
3236         /* Move it into the list, if it wasn't already there */
3237         if (!oldparkinglot) {
3238                 ao2_link(parkinglots, parkinglot);
3239         }
3240         parkinglot_unref(parkinglot);
3241
3242         return parkinglot;
3243 }
3244
3245
3246 /*! 
3247  * \brief Add parking hints for all defined parking lots 
3248  * \param context
3249  * \param start starting parkinglot number
3250  * \param stop ending parkinglot number
3251 */
3252 static void park_add_hints(char *context, int start, int stop)
3253 {
3254         int numext;
3255         char device[AST_MAX_EXTENSION];
3256         char exten[10];
3257
3258         for (numext = start; numext <= stop; numext++) {
3259                 snprintf(exten, sizeof(exten), "%d", numext);
3260                 snprintf(device, sizeof(device), "park:%s@%s", exten, context);
3261                 ast_add_extension(context, 1, exten, PRIORITY_HINT, NULL, NULL, device, NULL, NULL, registrar);
3262         }
3263 }
3264
3265 static int load_config(void) 
3266 {
3267         int start = 0, end = 0;
3268         int res;
3269         int i;
3270         struct ast_context *con = NULL;
3271         struct ast_config *cfg = NULL;
3272         struct ast_variable *var = NULL;
3273         struct feature_group *fg = NULL;
3274         struct ast_flags config_flags = { 0 };
3275         char old_parking_ext[AST_MAX_EXTENSION];
3276         char old_parking_con[AST_MAX_EXTENSION] = "";
3277         char *ctg; 
3278         static const char *categories[] = { 
3279                 /* Categories in features.conf that are not
3280                  * to be parsed as group categories
3281                  */
3282                 "general",
3283                 "featuremap",
3284                 "applicationmap"
3285         };
3286
3287         if (default_parkinglot) {
3288                 strcpy(old_parking_con, default_parkinglot->parking_con);
3289                 strcpy(old_parking_ext, parking_ext);
3290         } else {
3291                 default_parkinglot = build_parkinglot(DEFAULT_PARKINGLOT, NULL);
3292                 if (default_parkinglot) {
3293                         ao2_lock(default_parkinglot);
3294                         default_parkinglot->parking_start = 701;
3295                         default_parkinglot->parking_stop = 750;
3296                         default_parkinglot->parking_offset = 0;
3297                         default_parkinglot->parkfindnext = 0;
3298                         default_parkinglot->parkingtime = DEFAULT_PARK_TIME;
3299                         ao2_unlock(default_parkinglot);
3300                 }
3301         }
3302         if (default_parkinglot) {
3303                 if (option_debug)
3304                         ast_log(LOG_DEBUG, "Configuration of default parkinglot done.\n");
3305         } else {
3306                 ast_log(LOG_ERROR, "Configuration of default parkinglot failed.\n");
3307                 return -1;
3308         }
3309         
3310
3311         /* Reset to defaults */
3312         strcpy(parking_ext, "700");
3313         strcpy(pickup_ext, "*8");
3314         courtesytone[0] = '\0';
3315         strcpy(xfersound, "beep");
3316         strcpy(xferfailsound, "pbx-invalid");
3317         adsipark = 0;
3318         comebacktoorigin = 1;
3319
3320         default_parkinglot->parkaddhints = 0;
3321         default_parkinglot->parkedcalltransfers = 0;
3322         default_parkinglot->parkedcallreparking = 0;
3323
3324         transferdigittimeout = DEFAULT_TRANSFER_DIGIT_TIMEOUT;
3325         featuredigittimeout = DEFAULT_FEATURE_DIGIT_TIMEOUT;
3326         atxfernoanswertimeout = DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER;
3327         atxferloopdelay = DEFAULT_ATXFER_LOOP_DELAY;
3328         atxferdropcall = DEFAULT_ATXFER_DROP_CALL;
3329         atxfercallbackretries = DEFAULT_ATXFER_CALLBACK_RETRIES;
3330
3331         cfg = ast_config_load2("features.conf", "features", config_flags);
3332         if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
3333                 ast_log(LOG_WARNING,"Could not load features.conf\n");
3334                 return 0;
3335         }
3336         for (var = ast_variable_browse(cfg, "general"); var; var = var->next) {
3337                 if (!strcasecmp(var->name, "parkext")) {
3338                         ast_copy_string(parking_ext, var->value, sizeof(parking_ext));
3339                 } else if (!strcasecmp(var->name, "context")) {
3340                         ast_copy_string(default_parkinglot->parking_con, var->value, sizeof(default_parkinglot->parking_con));
3341                 } else if (!strcasecmp(var->name, "parkingtime")) {
3342                         if ((sscanf(var->value, "%d", &default_parkinglot->parkingtime) != 1) || (default_parkinglot->parkingtime < 1)) {
3343                                 ast_log(LOG_WARNING, "%s is not a valid parkingtime\n", var->value);
3344                                 default_parkinglot->parkingtime = DEFAULT_PARK_TIME;
3345                         } else
3346                                 default_parkinglot->parkingtime = default_parkinglot->parkingtime * 1000;
3347                 } else if (!strcasecmp(var->name, "parkpos")) {
3348                         if (sscanf(var->value, "%d-%d", &start, &end) != 2) {
3349                                 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);
3350                         } else if (default_parkinglot) {
3351                                 default_parkinglot->parking_start = start;
3352                                 default_parkinglot->parking_stop = end;
3353                         } else {
3354                                 ast_log(LOG_WARNING, "No default parking lot!\n");
3355                         }
3356                 } else if (!strcasecmp(var->name, "findslot")) {
3357                         default_parkinglot->parkfindnext = (!strcasecmp(var->value, "next"));
3358                 } else if (!strcasecmp(var->name, "parkinghints")) {
3359                         default_parkinglot->parkaddhints = ast_true(var->value);
3360                 } else if (!strcasecmp(var->name, "parkedcalltransfers")) {
3361                         if (!strcasecmp(var->value, "both"))
3362                                 default_parkinglot->parkedcalltransfers = AST_FEATURE_FLAG_BYBOTH;
3363                         else if (!strcasecmp(var->value, "caller"))
3364                                 default_parkinglot->parkedcalltransfers = AST_FEATURE_FLAG_BYCALLER;
3365                         else if (!strcasecmp(var->value, "callee"))
3366                                 default_parkinglot->parkedcalltransfers = AST_FEATURE_FLAG_BYCALLEE;
3367                 } else if (!strcasecmp(var->name, "parkedcallreparking")) {
3368                         if (!strcasecmp(var->value, "both"))
3369                                 default_parkinglot->parkedcallreparking = AST_FEATURE_FLAG_BYBOTH;
3370                         else if (!strcasecmp(var->value, "caller"))
3371                                 default_parkinglot->parkedcallreparking = AST_FEATURE_FLAG_BYCALLER;
3372                         else if (!strcasecmp(var->value, "callee"))
3373                                 default_parkinglot->parkedcallreparking = AST_FEATURE_FLAG_BYCALLEE;
3374                 } else if (!strcasecmp(var->name, "adsipark")) {
3375                         adsipark = ast_true(var->value);
3376                 } else if (!strcasecmp(var->name, "transferdigittimeout")) {
3377                         if ((sscanf(var->value, "%d", &transferdigittimeout) != 1) || (transferdigittimeout < 1)) {
3378                                 ast_log(LOG_WARNING, "%s is not a valid transferdigittimeout\n", var->value);
3379                                 transferdigittimeout = DEFAULT_TRANSFER_DIGIT_TIMEOUT;
3380                         } else
3381                                 transferdigittimeout = transferdigittimeout * 1000;
3382                 } else if (!strcasecmp(var->name, "featuredigittimeout")) {
3383                         if ((sscanf(var->value, "%d", &featuredigittimeout) != 1) || (featuredigittimeout < 1)) {
3384                                 ast_log(LOG_WARNING, "%s is not a valid featuredigittimeout\n", var->value);
3385                                 featuredigittimeout = DEFAULT_FEATURE_DIGIT_TIMEOUT;
3386                         }
3387                 } else if (!strcasecmp(var->name, "atxfernoanswertimeout")) {
3388                         if ((sscanf(var->value, "%d", &atxfernoanswertimeout) != 1) || (atxfernoanswertimeout < 1)) {
3389                                 ast_log(LOG_WARNING, "%s is not a valid atxfernoanswertimeout\n", var->value);
3390                                 atxfernoanswertimeout = DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER;
3391                         } else
3392                                 atxfernoanswertimeout = atxfernoanswertimeout * 1000;
3393                 } else if (!strcasecmp(var->name, "atxferloopdelay")) {
3394                         if ((sscanf(var->value, "%u", &atxferloopdelay) != 1)) {
3395                                 ast_log(LOG_WARNING, "%s is not a valid atxferloopdelay\n", var->value);
3396                                 atxferloopdelay = DEFAULT_ATXFER_LOOP_DELAY;
3397                         } else 
3398                                 atxferloopdelay *= 1000;
3399                 } else if (!strcasecmp(var->name, "atxferdropcall")) {
3400                         atxferdropcall = ast_true(var->value);
3401                 } else if (!strcasecmp(var->name, "atxfercallbackretries")) {
3402                         if ((sscanf(var->value, "%u", &atxferloopdelay) != 1)) {
3403                                 ast_log(LOG_WARNING, "%s is not a valid atxfercallbackretries\n", var->value);
3404                                 atxfercallbackretries = DEFAULT_ATXFER_CALLBACK_RETRIES;
3405        &n