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