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