remove extra comma typo
[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"
2368                 "UniqueID: %s\r\n\r\n",
2369                 pu->parkingexten, 
2370                 pu->chan->name,
2371                 pu->parkinglot->name,
2372                 S_OR(pu->chan->cid.cid_num, "<unknown>"),
2373                 S_OR(pu->chan->cid.cid_name, "<unknown>"),
2374                 pu->chan->uniqueid
2375                 );
2376 }
2377
2378 /*! \brief Run management on parkinglots, collad once per parkinglot */
2379 int manage_parkinglot(struct ast_parkinglot *curlot, fd_set *rfds, fd_set *efds, fd_set *nrfds, fd_set *nefds, int *ms, int *max)
2380 {
2381
2382         struct parkeduser *pu;
2383         int res = 0;
2384         char parkingslot[AST_MAX_EXTENSION];
2385
2386         /* TODO: I believe this reference increase is not necessary since the iterator in the calling function already did so */
2387         //parkinglot_addref(curlot);
2388         /* Lock parking list */
2389         AST_LIST_LOCK(&curlot->parkings);
2390         AST_LIST_TRAVERSE_SAFE_BEGIN(&curlot->parkings, pu, list) {
2391                 struct ast_channel *chan = pu->chan;    /* shorthand */
2392                 int tms;        /* timeout for this item */
2393                 int x;          /* fd index in channel */
2394                 struct ast_context *con;
2395
2396                 if (pu->notquiteyet) { /* Pretend this one isn't here yet */
2397                         continue;
2398                 }
2399                 tms = ast_tvdiff_ms(ast_tvnow(), pu->start);
2400                 if (tms > pu->parkingtime) {
2401                         /* Stop music on hold */
2402                         ast_indicate(pu->chan, AST_CONTROL_UNHOLD);
2403                         /* Get chan, exten from derived kludge */
2404                         if (pu->peername[0]) {
2405                                 char *peername = ast_strdupa(pu->peername);
2406                                 char *cp = strrchr(peername, '-');
2407                                 char peername_flat[AST_MAX_EXTENSION]; /* using something like DAHDI/52 for an extension name is NOT a good idea */
2408                                 int i;
2409
2410                                 if (cp) 
2411                                         *cp = 0;
2412                                 ast_copy_string(peername_flat,peername,sizeof(peername_flat));
2413                                 for(i=0; peername_flat[i] && i < AST_MAX_EXTENSION; i++) {
2414                                         if (peername_flat[i] == '/') 
2415                                                 peername_flat[i]= '0';
2416                                 }
2417                                 con = ast_context_find_or_create(NULL, NULL, pu->parkinglot->parking_con_dial, registrar);
2418                                 if (!con) {
2419                                         ast_log(LOG_ERROR, "Parking dial context '%s' does not exist and unable to create\n", pu->parkinglot->parking_con_dial);
2420                                 }
2421                                 if (con) {
2422                                         char returnexten[AST_MAX_EXTENSION];
2423                                         struct ast_datastore *features_datastore;
2424                                         struct ast_dial_features *dialfeatures = NULL;
2425
2426                                         ast_channel_lock(chan);
2427
2428                                         if ((features_datastore = ast_channel_datastore_find(chan, &dial_features_info, NULL)))
2429                                                 dialfeatures = features_datastore->data;
2430
2431                                         ast_channel_unlock(chan);
2432
2433                                         if (dialfeatures)
2434                                                 snprintf(returnexten, sizeof(returnexten), "%s,,%s", peername, dialfeatures->options);
2435                                         else /* Existing default */
2436                                                 snprintf(returnexten, sizeof(returnexten), "%s,,t", peername);
2437
2438                                         ast_add_extension2(con, 1, peername_flat, 1, NULL, NULL, "Dial", ast_strdup(returnexten), ast_free_ptr, registrar);
2439                                 }
2440                                 if (comebacktoorigin) {
2441                                         set_c_e_p(chan, pu->parkinglot->parking_con_dial, peername_flat, 1);
2442                                 } else {
2443                                         ast_log(LOG_WARNING, "now going to parkedcallstimeout,s,1 | ps is %d\n",pu->parkingnum);
2444                                         snprintf(parkingslot, sizeof(parkingslot), "%d", pu->parkingnum);
2445                                         pbx_builtin_setvar_helper(chan, "PARKINGSLOT", parkingslot);
2446                                         set_c_e_p(chan, "parkedcallstimeout", peername_flat, 1);
2447                                 }
2448                         } else {
2449                                 /* They've been waiting too long, send them back to where they came.  Theoretically they
2450                                    should have their original extensions and such, but we copy to be on the safe side */
2451                                 set_c_e_p(chan, pu->context, pu->exten, pu->priority);
2452                         }
2453                         post_manager_event("ParkedCallTimeOut", pu);
2454
2455                         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);
2456                         /* Start up the PBX, or hang them up */
2457                         if (ast_pbx_start(chan))  {
2458                                 ast_log(LOG_WARNING, "Unable to restart the PBX for user on '%s', hanging them up...\n", pu->chan->name);
2459                                 ast_hangup(chan);
2460                         }
2461                         /* And take them out of the parking lot */
2462                         con = ast_context_find(pu->parkinglot->parking_con);
2463                         if (con) {
2464                                 if (ast_context_remove_extension2(con, pu->parkingexten, 1, NULL, 0))
2465                                         ast_log(LOG_WARNING, "Whoa, failed to remove the parking extension!\n");
2466                                 else
2467                                         notify_metermaids(pu->parkingexten, curlot->parking_con, AST_DEVICE_NOT_INUSE);
2468                         } else
2469                                 ast_log(LOG_WARNING, "Whoa, no parking context?\n");
2470                         AST_LIST_REMOVE_CURRENT(list);
2471                         parkinglot_unref(curlot);
2472                 } else {        /* still within parking time, process descriptors */
2473                         for (x = 0; x < AST_MAX_FDS; x++) {
2474                                 struct ast_frame *f;
2475
2476                                 if ((chan->fds[x] == -1) || (!FD_ISSET(chan->fds[x], rfds) && !FD_ISSET(pu->chan->fds[x], efds))) 
2477                                         continue;
2478                                 
2479                                 if (FD_ISSET(chan->fds[x], efds))
2480                                         ast_set_flag(chan, AST_FLAG_EXCEPTION);
2481                                 else
2482                                         ast_clear_flag(chan, AST_FLAG_EXCEPTION);
2483                                 chan->fdno = x;
2484
2485                                 /* See if they need servicing */
2486                                 f = ast_read(pu->chan);
2487                                 /* Hangup? */
2488                                 if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass ==  AST_CONTROL_HANGUP))) {
2489                                         if (f)
2490                                                 ast_frfree(f);
2491                                         post_manager_event("ParkedCallGiveUp", pu);
2492
2493                                         /* There's a problem, hang them up*/
2494                                         ast_verb(2, "%s got tired of being parked\n", chan->name);
2495                                         ast_hangup(chan);
2496                                         /* And take them out of the parking lot */
2497                                         con = ast_context_find(curlot->parking_con);
2498                                         if (con) {
2499                                                 if (ast_context_remove_extension2(con, pu->parkingexten, 1, NULL, 0))
2500                                                         ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
2501                                                 else
2502                                                         notify_metermaids(pu->parkingexten, curlot->parking_con, AST_DEVICE_NOT_INUSE);
2503                                         } else
2504                                                 ast_log(LOG_WARNING, "Whoa, no parking context for parking lot %s?\n", curlot->name);
2505                                         AST_LIST_REMOVE_CURRENT(list);
2506                                         parkinglot_unref(curlot);
2507                                         break;
2508                                 } else {
2509                                         /* XXX Maybe we could do something with packets, like dial "0" for operator or something XXX */
2510                                         ast_frfree(f);
2511                                         if (pu->moh_trys < 3 && !chan->generatordata) {
2512                                                 ast_debug(1, "MOH on parked call stopped by outside source.  Restarting on channel %s.\n", chan->name);
2513                                                 ast_indicate_data(chan, AST_CONTROL_HOLD, 
2514                                                         S_OR(curlot->mohclass, NULL),
2515                                                         (!ast_strlen_zero(curlot->mohclass) ? strlen(curlot->mohclass) + 1 : 0));
2516                                                 pu->moh_trys++;
2517                                         }
2518                                         goto std;       /* XXX Ick: jumping into an else statement??? XXX */
2519                                 }
2520                         } /* End for */
2521                         if (x >= AST_MAX_FDS) {
2522 std:                            for (x=0; x<AST_MAX_FDS; x++) { /* mark fds for next round */
2523                                         if (chan->fds[x] > -1) {
2524                                                 FD_SET(chan->fds[x], nrfds);
2525                                                 FD_SET(chan->fds[x], nefds);
2526                                                 if (chan->fds[x] > *max)
2527                                                         *max = chan->fds[x];
2528                                         }
2529                                 }
2530                                 /* Keep track of our shortest wait */
2531                                 if (tms < *ms || *ms < 0)
2532                                         *ms = tms;
2533                         }
2534                 }
2535         }
2536         AST_LIST_TRAVERSE_SAFE_END;
2537         AST_LIST_UNLOCK(&curlot->parkings);
2538         return res;
2539 }
2540
2541 /*! 
2542  * \brief Take care of parked calls and unpark them if needed 
2543  * \param ignore unused var.
2544  * 
2545  * Start inf loop, lock parking lot, check if any parked channels have gone above timeout
2546  * if so, remove channel from parking lot and return it to the extension that parked it.
2547  * Check if parked channel decided to hangup, wait until next FD via select().
2548 */
2549 static void *do_parking_thread(void *ignore)
2550 {
2551         fd_set rfds, efds;      /* results from previous select, to be preserved across loops. */
2552         fd_set nrfds, nefds;    /* args for the next select */
2553         FD_ZERO(&rfds);
2554         FD_ZERO(&efds);
2555
2556         for (;;) {
2557                 int res = 0;
2558                 int ms = -1;    /* select timeout, uninitialized */
2559                 int max = -1;   /* max fd, none there yet */
2560                 struct ao2_iterator iter;
2561                 struct ast_parkinglot *curlot;
2562                 FD_ZERO(&nrfds);
2563                 FD_ZERO(&nefds);
2564                 iter = ao2_iterator_init(parkinglots, 0);
2565
2566                 while ((curlot = ao2_iterator_next(&iter))) {
2567                         res = manage_parkinglot(curlot, &rfds, &efds, &nrfds, &nefds, &ms, &max);
2568                         ao2_ref(curlot, -1);
2569                 }
2570
2571                 rfds = nrfds;
2572                 efds = nefds;
2573                 {
2574                         struct timeval wait = ast_samp2tv(ms, 1000);
2575                         /* Wait for something to happen */
2576                         ast_select(max + 1, &rfds, NULL, &efds, (ms > -1) ? &wait : NULL);
2577                 }
2578                 pthread_testcancel();
2579         }
2580         return NULL;    /* Never reached */
2581 }
2582
2583 /*! \brief Find parkinglot by name */
2584 struct ast_parkinglot *find_parkinglot(const char *name)
2585 {
2586         struct ast_parkinglot *parkinglot = NULL;
2587         struct ast_parkinglot tmp_parkinglot;
2588         
2589         if (ast_strlen_zero(name))
2590                 return NULL;
2591
2592         ast_copy_string(tmp_parkinglot.name, name, sizeof(tmp_parkinglot.name));
2593
2594         parkinglot = ao2_find(parkinglots, &tmp_parkinglot, OBJ_POINTER);
2595
2596         if (parkinglot && option_debug)
2597                 ast_log(LOG_DEBUG, "Found Parkinglot: %s\n", parkinglot->name);
2598
2599         return parkinglot;
2600 }
2601
2602 AST_APP_OPTIONS(park_call_options, BEGIN_OPTIONS
2603         AST_APP_OPTION('r', AST_PARK_OPT_RINGING),
2604         AST_APP_OPTION('R', AST_PARK_OPT_RANDOMIZE),
2605 END_OPTIONS );
2606
2607 /*! \brief Park a call */
2608 static int park_call_exec(struct ast_channel *chan, void *data)
2609 {
2610         /* Cache the original channel name in case we get masqueraded in the middle
2611          * of a park--it is still theoretically possible for a transfer to happen before
2612          * we get here, but it is _really_ unlikely */
2613         char *orig_chan_name = ast_strdupa(chan->name);
2614         char orig_exten[AST_MAX_EXTENSION];
2615         int orig_priority = chan->priority;
2616
2617         /* Data is unused at the moment but could contain a parking
2618            lot context eventually */
2619         int res = 0;
2620
2621         char *parse = NULL;
2622         AST_DECLARE_APP_ARGS(app_args,
2623                 AST_APP_ARG(timeout);
2624                 AST_APP_ARG(return_con);
2625                 AST_APP_ARG(return_ext);
2626                 AST_APP_ARG(return_pri);
2627                 AST_APP_ARG(options);
2628         );
2629
2630         if (!ast_strlen_zero(data)) {
2631                 parse = ast_strdupa(data);
2632                 AST_STANDARD_APP_ARGS(app_args, parse);
2633         }
2634
2635         ast_copy_string(orig_exten, chan->exten, sizeof(orig_exten));
2636
2637         /* Setup the exten/priority to be s/1 since we don't know
2638            where this call should return */
2639         strcpy(chan->exten, "s");
2640         chan->priority = 1;
2641
2642         /* Answer if call is not up */
2643         if (chan->_state != AST_STATE_UP)
2644                 res = ast_answer(chan);
2645
2646         /* Sleep to allow VoIP streams to settle down */
2647         if (!res)
2648                 res = ast_safe_sleep(chan, 1000);
2649
2650         /* Park the call */
2651         if (!res) {
2652                 struct ast_park_call_args args = {
2653                         .orig_chan_name = orig_chan_name,
2654                 };
2655                 struct ast_flags flags = { 0 };
2656
2657                 if (parse && !ast_strlen_zero(app_args.timeout)) {
2658                         if (sscanf(app_args.timeout, "%d", &args.timeout) != 1) {
2659                                 ast_log(LOG_WARNING, "Invalid timeout '%s' provided\n", app_args.timeout);
2660                                 args.timeout = 0;
2661                         }
2662                 }
2663
2664                 args.return_con = app_args.return_con;
2665                 args.return_ext = app_args.return_ext;
2666                 if (parse && !ast_strlen_zero(app_args.return_pri)) {
2667                         if (sscanf(app_args.return_pri, "%d", &args.return_pri) != 1) {
2668                                 ast_log(LOG_WARNING, "Invalid priority '%s' specified\n", app_args.return_pri);
2669                                 args.return_pri = 0;
2670                         }
2671                 }
2672
2673                 ast_app_parse_options(park_call_options, &flags, NULL, NULL);
2674                 args.flags = flags.flags;
2675
2676                 res = ast_park_call_full(chan, chan, &args);
2677                 /* Continue on in the dialplan */
2678                 if (res == 1) {
2679                         ast_copy_string(chan->exten, orig_exten, sizeof(chan->exten));
2680                         chan->priority = orig_priority;
2681                         res = 0;
2682                 } else if (!res)
2683                         res = AST_PBX_KEEPALIVE;
2684         }
2685
2686         return res;
2687 }
2688
2689 /*! \brief Pickup parked call */
2690 static int park_exec_full(struct ast_channel *chan, void *data, struct ast_parkinglot *parkinglot)
2691 {
2692         int res = 0;
2693         struct ast_channel *peer=NULL;
2694         struct parkeduser *pu;
2695         struct ast_context *con;
2696         int park = 0;
2697         struct ast_bridge_config config;
2698
2699         if (data)
2700                 park = atoi((char *)data);
2701
2702         parkinglot = find_parkinglot(findparkinglotname(chan));         
2703         if (!parkinglot)
2704                 parkinglot = default_parkinglot;
2705
2706         AST_LIST_LOCK(&parkinglot->parkings);
2707         AST_LIST_TRAVERSE_SAFE_BEGIN(&parkinglot->parkings, pu, list) {
2708                 if (!data || pu->parkingnum == park) {
2709                         AST_LIST_REMOVE_CURRENT(list);
2710                         break;
2711                 }
2712         }
2713         AST_LIST_TRAVERSE_SAFE_END
2714         AST_LIST_UNLOCK(&parkinglot->parkings);
2715
2716         if (pu) {
2717                 peer = pu->chan;
2718                 con = ast_context_find(parkinglot->parking_con);
2719                 if (con) {
2720                         if (ast_context_remove_extension2(con, pu->parkingexten, 1, NULL, 0))
2721                                 ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
2722                         else
2723                                 notify_metermaids(pu->parkingexten, parkinglot->parking_con, AST_DEVICE_NOT_INUSE);
2724                 } else
2725                         ast_log(LOG_WARNING, "Whoa, no parking context?\n");
2726
2727                 manager_event(EVENT_FLAG_CALL, "UnParkedCall",
2728                         "Exten: %s\r\n"
2729                         "Channel: %s\r\n"
2730                         "From: %s\r\n"
2731                         "CallerIDNum: %s\r\n"
2732                         "CallerIDName: %s\r\n",
2733                         pu->parkingexten, pu->chan->name, chan->name,
2734                         S_OR(pu->chan->cid.cid_num, "<unknown>"),
2735                         S_OR(pu->chan->cid.cid_name, "<unknown>")
2736                         );
2737
2738                 ast_free(pu);
2739         }
2740         /* JK02: it helps to answer the channel if not already up */
2741         if (chan->_state != AST_STATE_UP)
2742                 ast_answer(chan);
2743
2744         //XXX Why do we unlock here ?
2745         // uncomment it for now, till my setup with debug_threads and detect_deadlocks starts to complain
2746         //ASTOBJ_UNLOCK(parkinglot);
2747
2748         if (peer) {
2749                 /* Play a courtesy to the source(s) configured to prefix the bridge connecting */
2750                 
2751                 if (!ast_strlen_zero(courtesytone)) {
2752                         int error = 0;
2753                         ast_indicate(peer, AST_CONTROL_UNHOLD);
2754                         if (parkedplay == 0) {
2755                                 error = ast_stream_and_wait(chan, courtesytone, "");
2756                         } else if (parkedplay == 1) {
2757                                 error = ast_stream_and_wait(peer, courtesytone, "");
2758                         } else if (parkedplay == 2) {
2759                                 if (!ast_streamfile(chan, courtesytone, chan->language) &&
2760                                                 !ast_streamfile(peer, courtesytone, chan->language)) {
2761                                         /*! \todo XXX we would like to wait on both! */
2762                                         res = ast_waitstream(chan, "");
2763                                         if (res >= 0)
2764                                                 res = ast_waitstream(peer, "");
2765                                         if (res < 0)
2766                                                 error = 1;
2767                                 }
2768                         }
2769                         if (error) {
2770                                 ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
2771                                 ast_hangup(peer);
2772                                 return -1;
2773                         }
2774                 } else
2775                         ast_indicate(peer, AST_CONTROL_UNHOLD); 
2776
2777                 res = ast_channel_make_compatible(chan, peer);
2778                 if (res < 0) {
2779                         ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for bridge\n", chan->name, peer->name);
2780                         ast_hangup(peer);
2781                         return -1;
2782                 }
2783                 /* This runs sorta backwards, since we give the incoming channel control, as if it
2784                    were the person called. */
2785                 ast_verb(3, "Channel %s connected to parked call %d\n", chan->name, park);
2786
2787                 pbx_builtin_setvar_helper(chan, "PARKEDCHANNEL", peer->name);
2788                 ast_cdr_setdestchan(chan->cdr, peer->name);
2789                 memset(&config, 0, sizeof(struct ast_bridge_config));
2790                 if ((parkinglot->parkedcalltransfers == AST_FEATURE_FLAG_BYCALLEE) || (parkinglot->parkedcalltransfers == AST_FEATURE_FLAG_BYBOTH))
2791                         ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
2792                 if ((parkinglot->parkedcalltransfers == AST_FEATURE_FLAG_BYCALLER) || (parkinglot->parkedcalltransfers == AST_FEATURE_FLAG_BYBOTH))
2793                         ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
2794                 if ((parkinglot->parkedcallreparking == AST_FEATURE_FLAG_BYCALLEE) || (parkinglot->parkedcallreparking == AST_FEATURE_FLAG_BYBOTH))
2795                         ast_set_flag(&(config.features_callee), AST_FEATURE_PARKCALL);
2796                 if ((parkinglot->parkedcallreparking == AST_FEATURE_FLAG_BYCALLER) || (parkinglot->parkedcallreparking == AST_FEATURE_FLAG_BYBOTH))
2797                         ast_set_flag(&(config.features_caller), AST_FEATURE_PARKCALL);
2798                 res = ast_bridge_call(chan, peer, &config);
2799
2800                 pbx_builtin_setvar_helper(chan, "PARKEDCHANNEL", peer->name);
2801                 ast_cdr_setdestchan(chan->cdr, peer->name);
2802
2803                 /* Simulate the PBX hanging up */
2804                 if (res != AST_PBX_NO_HANGUP_PEER)
2805                         ast_hangup(peer);
2806                 return res;
2807         } else {
2808                 /*! \todo XXX Play a message XXX */
2809                 if (ast_stream_and_wait(chan, "pbx-invalidpark", ""))
2810                         ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", "pbx-invalidpark", chan->name);
2811                 ast_verb(3, "Channel %s tried to talk to nonexistent parked call %d\n", chan->name, park);
2812                 res = -1;
2813         }
2814
2815         return res;
2816 }
2817
2818 static int park_exec(struct ast_channel *chan, void *data) 
2819 {
2820         return park_exec_full(chan, data, default_parkinglot);
2821 }
2822
2823 /*! \brief Unreference parkinglot object. If no more references,
2824         then go ahead and delete it */
2825 static void parkinglot_unref(struct ast_parkinglot *parkinglot) 
2826 {
2827         int refcount = ao2_ref(parkinglot, -1);
2828         if (option_debug > 2)
2829                 ast_log(LOG_DEBUG, "Multiparking: %s refcount now %d\n", parkinglot->name, refcount - 1);
2830 }
2831
2832 static struct ast_parkinglot *parkinglot_addref(struct ast_parkinglot *parkinglot)
2833 {
2834         int refcount = ao2_ref(parkinglot, +1);
2835         if (option_debug > 2)
2836                 ast_log(LOG_DEBUG, "Multiparking: %s refcount now %d\n", parkinglot->name, refcount + 1);
2837         return parkinglot;
2838 }
2839
2840 /*! \brief Allocate parking lot structure */
2841 static struct ast_parkinglot *create_parkinglot(char *name)
2842 {
2843         struct ast_parkinglot *newlot = (struct ast_parkinglot *) NULL;
2844
2845         if (!name)
2846                 return NULL;
2847
2848         newlot = ao2_alloc(sizeof(*newlot), parkinglot_destroy);
2849         if (!newlot)
2850                 return NULL;
2851         
2852         ast_copy_string(newlot->name, name, sizeof(newlot->name));
2853
2854         return newlot;
2855 }
2856
2857 /*! \brief Destroy a parking lot */
2858 static void parkinglot_destroy(void *obj)
2859 {
2860         struct ast_parkinglot *ruin = obj;
2861         struct ast_context *con;
2862         con = ast_context_find(ruin->parking_con);
2863         if (con)
2864                 ast_context_destroy(con, registrar);
2865         ao2_unlink(parkinglots, ruin);
2866 }
2867
2868 /*! \brief Build parkinglot from configuration and chain it in */
2869 static struct ast_parkinglot *build_parkinglot(char *name, struct ast_variable *var)
2870 {
2871         struct ast_parkinglot *parkinglot;
2872         struct ast_context *con = NULL;
2873
2874         struct ast_variable *confvar = var;
2875         int error = 0;
2876         int start = 0, end = 0;
2877         int oldparkinglot = 0;
2878
2879         parkinglot = find_parkinglot(name);
2880         if (parkinglot)
2881                 oldparkinglot = 1;
2882         else
2883                 parkinglot = create_parkinglot(name);
2884
2885         if (!parkinglot)
2886                 return NULL;
2887
2888         ao2_lock(parkinglot);
2889
2890         if (option_debug)
2891                 ast_log(LOG_DEBUG, "Building parking lot %s\n", name);
2892         
2893         /* Do some config stuff */
2894         while(confvar) {
2895                 if (!strcasecmp(confvar->name, "context")) {
2896                         ast_copy_string(parkinglot->parking_con, confvar->value, sizeof(parkinglot->parking_con));
2897                 } else if (!strcasecmp(confvar->name, "parkingtime")) {
2898                         if ((sscanf(confvar->value, "%d", &parkinglot->parkingtime) != 1) || (parkinglot->parkingtime < 1)) {
2899                                 ast_log(LOG_WARNING, "%s is not a valid parkingtime\n", confvar->value);
2900                                 parkinglot->parkingtime = DEFAULT_PARK_TIME;
2901                         } else
2902                                 parkinglot->parkingtime = parkinglot->parkingtime * 1000;
2903                 } else if (!strcasecmp(confvar->name, "parkpos")) {
2904                         if (sscanf(confvar->value, "%d-%d", &start, &end) != 2) {
2905                                 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);
2906                                 error = 1;
2907                         } else {
2908                                 parkinglot->parking_start = start;
2909                                 parkinglot->parking_stop = end;
2910                         }
2911                 } else if (!strcasecmp(confvar->name, "findslot")) {
2912                         parkinglot->parkfindnext = (!strcasecmp(confvar->value, "next"));
2913                 }
2914                 confvar = confvar->next;
2915         }
2916         /* make sure parkingtime is set if not specified */
2917         if (parkinglot->parkingtime == 0) {
2918                 parkinglot->parkingtime = DEFAULT_PARK_TIME;
2919         }
2920
2921         if (!var) {     /* Default parking lot */
2922                 ast_copy_string(parkinglot->parking_con, "parkedcalls", sizeof(parkinglot->parking_con));
2923                 ast_copy_string(parkinglot->parking_con_dial, "park-dial", sizeof(parkinglot->parking_con_dial));
2924                 ast_copy_string(parkinglot->mohclass, "default", sizeof(parkinglot->mohclass));
2925         }
2926
2927         /* Check for errors */
2928         if (ast_strlen_zero(parkinglot->parking_con)) {
2929                 ast_log(LOG_WARNING, "Parking lot %s lacks context\n", name);
2930                 error = 1;
2931         }
2932
2933         /* Create context */
2934         if (!error && !(con = ast_context_find_or_create(NULL, NULL, parkinglot->parking_con, registrar))) {
2935                 ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", parkinglot->parking_con);
2936                 error = 1;
2937         }
2938
2939         /* Add a parking extension into the context */
2940         if (!oldparkinglot) {
2941                 if (!ast_strlen_zero(ast_parking_ext())) {
2942                         if (ast_add_extension2(con, 1, ast_parking_ext(), 1, NULL, NULL, parkcall, strdup(""), ast_free, registrar) == -1)
2943                                 error = 1;
2944                 }
2945         }
2946
2947         ao2_unlock(parkinglot);
2948
2949         if (error) {
2950                 ast_log(LOG_WARNING, "Parking %s not open for business. Configuration error.\n", name);
2951                 parkinglot_destroy(parkinglot);
2952                 return NULL;
2953         }
2954         if (option_debug)
2955                 ast_log(LOG_DEBUG, "Parking %s now open for business. (start exten %d end %d)\n", name, start, end);
2956
2957
2958         /* Move it into the list, if it wasn't already there */
2959         if (!oldparkinglot) {
2960                 ao2_link(parkinglots, parkinglot);
2961         }
2962         parkinglot_unref(parkinglot);
2963
2964         return parkinglot;
2965 }
2966
2967
2968 /*! 
2969  * \brief Add parking hints for all defined parking lots 
2970  * \param context
2971  * \param start starting parkinglot number
2972  * \param stop ending parkinglot number
2973 */
2974 static void park_add_hints(char *context, int start, int stop)
2975 {
2976         int numext;
2977         char device[AST_MAX_EXTENSION];
2978         char exten[10];
2979
2980         for (numext = start; numext <= stop; numext++) {
2981                 snprintf(exten, sizeof(exten), "%d", numext);
2982                 snprintf(device, sizeof(device), "park:%s@%s", exten, context);
2983                 ast_add_extension(context, 1, exten, PRIORITY_HINT, NULL, NULL, device, NULL, NULL, registrar);
2984         }
2985 }
2986
2987 static int load_config(void) 
2988 {
2989         int start = 0, end = 0;
2990         int res;
2991         int i;
2992         struct ast_context *con = NULL;
2993         struct ast_config *cfg = NULL;
2994         struct ast_variable *var = NULL;
2995         struct feature_group *fg = NULL;
2996         struct ast_flags config_flags = { 0 };
2997         char old_parking_ext[AST_MAX_EXTENSION];
2998         char old_parking_con[AST_MAX_EXTENSION] = "";
2999         char *ctg; 
3000         static const char *categories[] = { 
3001                 /* Categories in features.conf that are not
3002                  * to be parsed as group categories
3003                  */
3004                 "general",
3005                 "featuremap",
3006                 "applicationmap"
3007         };
3008
3009         if (default_parkinglot) {
3010                 strcpy(old_parking_con, default_parkinglot->parking_con);
3011                 strcpy(old_parking_ext, parking_ext);
3012         } else {
3013                 default_parkinglot = build_parkinglot(DEFAULT_PARKINGLOT, NULL);
3014                 if (default_parkinglot) {
3015                         ao2_lock(default_parkinglot);
3016                         default_parkinglot->parking_start = 701;
3017                         default_parkinglot->parking_stop = 750;
3018                         default_parkinglot->parking_offset = 0;
3019                         default_parkinglot->parkfindnext = 0;
3020                         default_parkinglot->parkingtime = DEFAULT_PARK_TIME;
3021                         ao2_unlock(default_parkinglot);
3022                 }
3023         }
3024         if (default_parkinglot) {
3025                 if (option_debug)
3026                         ast_log(LOG_DEBUG, "Configuration of default parkinglot done.\n");
3027         } else {
3028                 ast_log(LOG_ERROR, "Configuration of default parkinglot failed.\n");
3029                 return -1;
3030         }
3031         
3032
3033         /* Reset to defaults */
3034         strcpy(parking_ext, "700");
3035         strcpy(pickup_ext, "*8");
3036         courtesytone[0] = '\0';
3037         strcpy(xfersound, "beep");
3038         strcpy(xferfailsound, "pbx-invalid");
3039         adsipark = 0;
3040         comebacktoorigin = 1;
3041
3042         default_parkinglot->parkaddhints = 0;
3043         default_parkinglot->parkedcalltransfers = 0;
3044         default_parkinglot->parkedcallreparking = 0;
3045
3046         transferdigittimeout = DEFAULT_TRANSFER_DIGIT_TIMEOUT;
3047         featuredigittimeout = DEFAULT_FEATURE_DIGIT_TIMEOUT;
3048         atxfernoanswertimeout = DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER;
3049         atxferloopdelay = DEFAULT_ATXFER_LOOP_DELAY;
3050         atxferdropcall = DEFAULT_ATXFER_DROP_CALL;
3051         atxfercallbackretries = DEFAULT_ATXFER_CALLBACK_RETRIES;
3052
3053         cfg = ast_config_load2("features.conf", "features", config_flags);
3054         if (!cfg) {
3055                 ast_log(LOG_WARNING,"Could not load features.conf\n");
3056                 return 0;
3057         }
3058         for (var = ast_variable_browse(cfg, "general"); var; var = var->next) {
3059                 if (!strcasecmp(var->name, "parkext")) {
3060                         ast_copy_string(parking_ext, var->value, sizeof(parking_ext));
3061                 } else if (!strcasecmp(var->name, "context")) {
3062                         ast_copy_string(default_parkinglot->parking_con, var->value, sizeof(default_parkinglot->parking_con));
3063                 } else if (!strcasecmp(var->name, "parkingtime")) {
3064                         if ((sscanf(var->value, "%d", &default_parkinglot->parkingtime) != 1) || (default_parkinglot->parkingtime < 1)) {
3065                                 ast_log(LOG_WARNING, "%s is not a valid parkingtime\n", var->value);
3066                                 default_parkinglot->parkingtime = DEFAULT_PARK_TIME;
3067                         } else
3068                                 default_parkinglot->parkingtime = default_parkinglot->parkingtime * 1000;
3069                 } else if (!strcasecmp(var->name, "parkpos")) {
3070                         if (sscanf(var->value, "%d-%d", &start, &end) != 2) {
3071                                 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);
3072                         } else if (default_parkinglot) {
3073                                 default_parkinglot->parking_start = start;
3074                                 default_parkinglot->parking_stop = end;
3075                         } else {
3076                                 ast_log(LOG_WARNING, "No default parking lot!\n");
3077                         }
3078                 } else if (!strcasecmp(var->name, "findslot")) {
3079                         default_parkinglot->parkfindnext = (!strcasecmp(var->value, "next"));
3080                 } else if (!strcasecmp(var->name, "parkinghints")) {
3081                         default_parkinglot->parkaddhints = ast_true(var->value);
3082                 } else if (!strcasecmp(var->name, "parkedcalltransfers")) {
3083                         if (!strcasecmp(var->value, "both"))
3084                                 default_parkinglot->parkedcalltransfers = AST_FEATURE_FLAG_BYBOTH;
3085                         else if (!strcasecmp(var->value, "caller"))
3086                                 default_parkinglot->parkedcalltransfers = AST_FEATURE_FLAG_BYCALLER;
3087                         else if (!strcasecmp(var->value, "callee"))
3088                                 default_parkinglot->parkedcalltransfers = AST_FEATURE_FLAG_BYCALLEE;
3089                 } else if (!strcasecmp(var->name, "parkedcallreparking")) {
3090                         if (!strcasecmp(var->value, "both"))
3091                                 default_parkinglot->parkedcallreparking = AST_FEATURE_FLAG_BYBOTH;
3092                         else if (!strcasecmp(var->value, "caller"))
3093                                 default_parkinglot->parkedcallreparking = AST_FEATURE_FLAG_BYCALLER;
3094                         else if (!strcasecmp(var->value, "callee"))
3095                                 default_parkinglot->parkedcallreparking = AST_FEATURE_FLAG_BYCALLEE;
3096                 } else if (!strcasecmp(var->name, "adsipark")) {
3097                         adsipark = ast_true(var->value);
3098                 } else if (!strcasecmp(var->name, "transferdigittimeout")) {
3099                         if ((sscanf(var->value, "%d", &transferdigittimeout) != 1) || (transferdigittimeout < 1)) {
3100                                 ast_log(LOG_WARNING, "%s is not a valid transferdigittimeout\n", var->value);
3101                                 transferdigittimeout = DEFAULT_TRANSFER_DIGIT_TIMEOUT;
3102                         } else
3103                                 transferdigittimeout = transferdigittimeout * 1000;
3104                 } else if (!strcasecmp(var->name, "featuredigittimeout")) {
3105                         if ((sscanf(var->value, "%d", &featuredigittimeout) != 1) || (featuredigittimeout < 1)) {
3106                                 ast_log(LOG_WARNING, "%s is not a valid featuredigittimeout\n", var->value);
3107                                 featuredigittimeout = DEFAULT_FEATURE_DIGIT_TIMEOUT;
3108                         }
3109                 } else if (!strcasecmp(var->name, "atxfernoanswertimeout")) {
3110                         if ((sscanf(var->value, "%d", &atxfernoanswertimeout) != 1) || (atxfernoanswertimeout < 1)) {
3111                                 ast_log(LOG_WARNING, "%s is not a valid atxfernoanswertimeout\n", var->value);
3112                                 atxfernoanswertimeout = DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER;
3113                         } else
3114                                 atxfernoanswertimeout = atxfernoanswertimeout * 1000;
3115                 } else if (!strcasecmp(var->name, "atxferloopdelay")) {
3116                         if ((sscanf(var->value, "%u", &atxferloopdelay) != 1)) {
3117                                 ast_log(LOG_WARNING, "%s is not a valid atxferloopdelay\n", var->value);
3118                                 atxferloopdelay = DEFAULT_ATXFER_LOOP_DELAY;
3119                         } else 
3120                                 atxferloopdelay *= 1000;
3121                 } else if (!strcasecmp(var->name, "atxferdropcall")) {
3122                         atxferdropcall = ast_true(var->value);
3123                 } else if (!strcasecmp(var->name, "atxfercallbackretries")) {
3124                         if ((sscanf(var->value, "%u", &atxferloopdelay) != 1)) {
3125                                 ast_log(LOG_WARNING, "%s is not a valid atxfercallbackretries\n", var->value);
3126                                 atxfercallbackretries = DEFAULT_ATXFER_CALLBACK_RETRIES;
3127                         }
3128                 } else if (!strcasecmp(var->name, "courtesytone")) {
3129                         ast_copy_string(courtesytone, var->value, sizeof(courtesytone));
3130                 }  else if (!strcasecmp(var->name, "parkedplay")) {
3131                         if (!strcasecmp(var->value, "both"))
3132                                 parkedplay = 2;
3133                         else if (!strcasecmp(var->value, "parked"))
3134                                 parkedplay = 1;
3135                         else
3136                                 parkedplay = 0;
3137                 } else if (!strcasecmp(var->name, "xfersound")) {
3138                         ast_copy_string(xfersound, var->value, sizeof(xfersound));
3139                 } else if (!strcasecmp(var->name, "xferfailsound")) {
3140                         ast_copy_string(xferfailsound, var->value, sizeof(xferfailsound));
3141                 } else if (!strcasecmp(var->name, "pickupexten")) {
3142                         ast_copy_string(pickup_ext, var->value, sizeof(pickup_ext));
3143                 } else if (!strcasecmp(var->name, "comebacktoorigin")) {
3144                         comebacktoorigin = ast_true(var->value);
3145                 } else if (!strcasecmp(var->name, "parkedmusicclass")) {
3146                         ast_copy_string(default_parkinglot->mohclass, var->value, sizeof(default_parkinglot->mohclass));
3147                 }
3148         }
3149
3150         unmap_features();
3151         for (var = ast_variable_browse(cfg, "featuremap"); var; var = var->next) {
3152                 if (remap_feature(var->name, var->value))
3153                         ast_log(LOG_NOTICE, "Unknown feature '%s'\n", var->name);
3154         }
3155
3156         /* Map a key combination to an application*/
3157         ast_unregister_features();
3158         for (var = ast_variable_browse(cfg, "applicationmap"); var; var = var->next) {
3159                 char *tmp_val = ast_strdupa(var->value);
3160                 char *exten, *activateon, *activatedby, *app, *app_args, *moh_class; 
3161                 struct ast_call_feature *feature;
3162
3163                 /* strsep() sets the argument to NULL if match not found, and it
3164                  * is safe to use it with a NULL argument, so we don't check
3165                  * between calls.
3166                  */
3167                 exten = strsep(&tmp_val,",");
3168                 activatedby = strsep(&tmp_val,",");
3169                 app = strsep(&tmp_val,",");
3170                 app_args = strsep(&tmp_val,",");
3171                 moh_class = strsep(&tmp_val,",");
3172
3173                 activateon = strsep(&activatedby, "/"); 
3174
3175                 /*! \todo XXX var_name or app_args ? */
3176                 if (ast_strlen_zero(app) || ast_strlen_zero(exten) || ast_strlen_zero(activateon) || ast_strlen_zero(var->name)) {
3177                         ast_log(LOG_NOTICE, "Please check the feature Mapping Syntax, either extension, name, or app aren't provided %s %s %s %s\n",
3178                                 app, exten, activateon, var->name);
3179                         continue;
3180                 }
3181
3182                 AST_LIST_LOCK(&feature_list);
3183                 if ((feature = find_dynamic_feature(var->name))) {
3184                         AST_LIST_UNLOCK(&feature_list);
3185                         ast_log(LOG_WARNING, "Dynamic Feature '%s' specified more than once!\n", var->name);
3186                         continue;
3187                 }
3188                 AST_LIST_UNLOCK(&feature_list);
3189                                 
3190                 if (!(feature = ast_calloc(1, sizeof(*feature))))
3191                         continue;                                       
3192
3193                 ast_copy_string(feature->sname, var->name, FEATURE_SNAME_LEN);
3194                 ast_copy_string(feature->app, app, FEATURE_APP_LEN);
3195                 ast_copy_string(feature->exten, exten, FEATURE_EXTEN_LEN);
3196                 
3197                 if (app_args) 
3198                         ast_copy_string(feature->app_args, app_args, FEATURE_APP_ARGS_LEN);
3199
3200                 if (moh_class)
3201                         ast_copy_string(feature->moh_class, moh_class, FEATURE_MOH_LEN);
3202                         
3203                 ast_copy_string(feature->exten, exten, sizeof(feature->exten));
3204                 feature->operation = feature_exec_app;
3205                 ast_set_flag(feature, AST_FEATURE_FLAG_NEEDSDTMF);
3206
3207                 /* Allow caller and calle to be specified for backwards compatability */
3208                 if (!strcasecmp(activateon, "self") || !strcasecmp(activateon, "caller"))
3209                         ast_set_flag(feature, AST_FEATURE_FLAG_ONSELF);
3210                 else if (!strcasecmp(activateon, "peer") || !strcasecmp(activateon, "callee"))
3211                         ast_set_flag(feature, AST_FEATURE_FLAG_ONPEER);
3212                 else {
3213                         ast_log(LOG_NOTICE, "Invalid 'ActivateOn' specification for feature '%s',"
3214                                 " must be 'self', or 'peer'\n", var->name);
3215                         continue;
3216                 }
3217
3218                 if (ast_strlen_zero(activatedby))
3219                         ast_set_flag(feature, AST_FEATURE_FLAG_BYBOTH);
3220                 else if (!strcasecmp(activatedby, "caller"))
3221                         ast_set_flag(feature, AST_FEATURE_FLAG_BYCALLER);
3222                 else if (!strcasecmp(activatedby, "callee"))
3223                         ast_set_flag(feature, AST_FEATURE_FLAG_BYCALLEE);
3224                 else if (!strcasecmp(activatedby, "both"))
3225                         ast_set_flag(feature, AST_FEATURE_FLAG_BYBOTH);
3226                 else {
3227                         ast_log(LOG_NOTICE, "Invalid 'ActivatedBy' specification for feature '%s',"
3228                                 " must be 'caller', or 'callee', or 'both'\n", var->name);
3229                         continue;
3230                 }
3231
3232                 ast_register_feature(feature);
3233                         
3234                 ast_verb(2, "Mapping Feature '%s' to app '%s(%s)' with code '%s'\n", var->name, app, app_args, exten);
3235         }
3236
3237         ast_unregister_groups();
3238         AST_RWLIST_WRLOCK(&feature_groups);
3239
3240         ctg = NULL;
3241         while ((ctg = ast_category_browse(cfg, ctg))) {
3242                 /* Is this a parkinglot definition ? */
3243                 if (!strncasecmp(ctg, "parkinglot_", strlen("parkinglot_"))) {
3244                         ast_debug(2, "Found configuration section %s, assume parking context\n", ctg);
3245                         if(!build_parkinglot(ctg, ast_variable_browse(cfg, ctg)))
3246                                 ast_log(LOG_ERROR, "Could not build parking lot %s. Configuration error.\n", ctg);
3247                         else
3248                                 ast_debug(1, "Configured parking context %s\n", ctg);
3249                         continue;       
3250                 }
3251                 /* No, check if it's a group */
3252                 for (i = 0; i < ARRAY_LEN(categories); i++) {
3253                         if (!strcasecmp(categories[i], ctg))
3254                                 break;
3255                 }
3256
3257                 if (i < ARRAY_LEN(categories)) 
3258                         continue;
3259
3260                 if (!(fg = register_group(ctg)))
3261                         continue;
3262
3263                 for (var = ast_variable_browse(cfg, ctg); var; var = var->next) {
3264                         struct ast_call_feature *feature;
3265
3266                         AST_LIST_LOCK(&feature_list);
3267                         if(!(feature = find_dynamic_feature(var->name)) && 
3268                            !(feature = ast_find_call_feature(var->name))) {
3269                                 AST_LIST_UNLOCK(&feature_list);
3270                                 ast_log(LOG_WARNING, "Feature '%s' was not found.\n", var->name);
3271                                 continue;
3272                         }
3273                         AST_LIST_UNLOCK(&feature_list);
3274
3275                         register_group_feature(fg, var->value, feature);
3276                 }
3277         }
3278
3279         AST_RWLIST_UNLOCK(&feature_groups);
3280
3281         ast_config_destroy(cfg);
3282
3283         /* Remove the old parking extension */
3284         if (!ast_strlen_zero(old_parking_con) && (con = ast_context_find(old_parking_con)))     {
3285                 if(ast_context_remove_extension2(con, old_parking_ext, 1, registrar, 0))
3286                                 notify_metermaids(old_parking_ext, old_parking_con, AST_DEVICE_NOT_INUSE);
3287                 ast_debug(1, "Removed old parking extension %s@%s\n", old_parking_ext, old_parking_con);
3288         }
3289         
3290         if (!(con = ast_context_find_or_create(NULL, NULL, default_parkinglot->parking_con, registrar))) {
3291                 ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", default_parkinglot->parking_con);
3292                 return -1;
3293         }
3294         res = ast_add_extension2(con, 1, ast_parking_ext(), 1, NULL, NULL, parkcall, NULL, NULL, registrar);
3295         if (default_parkinglot->parkaddhints)
3296                 park_add_hints(default_parkinglot->parking_con, default_parkinglot->parking_start, default_parkinglot->parking_stop);
3297         if (!res)
3298                 notify_metermaids(ast_parking_ext(), default_parkinglot->parking_con, AST_DEVICE_INUSE);
3299         return res;
3300
3301 }
3302
3303 /*!
3304  * \brief CLI command to list configured features
3305  * \param e
3306  * \param cmd
3307  * \param a
3308  *
3309  * \retval CLI_SUCCESS on success.
3310  * \retval NULL when tab completion is used.
3311  */
3312 static char *handle_feature_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
3313 {
3314         int i;
3315         struct ast_call_feature *feature;
3316         struct ao2_iterator iter;
3317         struct ast_parkinglot *curlot;
3318 #define HFS_FORMAT "%-25s %-7s %-7s\n"
3319
3320         switch (cmd) {
3321         
3322         case CLI_INIT:
3323                 e->command = "features show";
3324                 e->usage =
3325                         "Usage: features show\n"
3326                         "       Lists configured features\n";
3327                 return NULL;
3328         case CLI_GENERATE:
3329                 return NULL;
3330         }
3331
3332         ast_cli(a->fd, HFS_FORMAT, "Builtin Feature", "Default", "Current");
3333         ast_cli(a->fd, HFS_FORMAT, "---------------", "-------", "-------");
3334
3335         ast_cli(a->fd, HFS_FORMAT, "Pickup", "*8", ast_pickup_ext());          /* default hardcoded above, so we'll hardcode it here */
3336
3337         ast_rwlock_rdlock(&features_lock);
3338         for (i = 0; i < FEATURES_COUNT; i++)
3339                 ast_cli(a->fd, HFS_FORMAT, builtin_features[i].fname, builtin_features[i].default_exten, builtin_features[i].exten);
3340         ast_rwlock_unlock(&features_lock);
3341
3342         ast_cli(a->fd, "\n");
3343         ast_cli(a->fd, HFS_FORMAT, "Dynamic Feature", "Default", "Current");
3344         ast_cli(a->fd, HFS_FORMAT, "---------------", "-------", "-------");
3345         if (AST_LIST_EMPTY(&feature_list))
3346                 ast_cli(a->fd, "(none)\n");
3347         else {
3348                 AST_LIST_LOCK(&feature_list);
3349                 AST_LIST_TRAVERSE(&feature_list, feature, feature_entry)
3350                         ast_cli(a->fd, HFS_FORMAT, feature->sname, "no def", feature->exten);
3351                 AST_LIST_UNLOCK(&feature_list);
3352         }
3353
3354         // loop through all the parking lots
3355         iter = ao2_iterator_init(parkinglots, 0);
3356
3357         while ((curlot = ao2_iterator_next(&iter))) {
3358                 ast_cli(a->fd, "\nCall parking (Parking lot: %s)\n", curlot->name);
3359                 ast_cli(a->fd, "------------\n");
3360                 ast_cli(a->fd,"%-22s:      %s\n", "Parking extension", parking_ext);
3361                 ast_cli(a->fd,"%-22s:      %s\n", "Parking context", curlot->parking_con);
3362                 ast_cli(a->fd,"%-22s:      %d-%d\n", "Parked call extensions", curlot->parking_start, curlot->parking_stop);
3363                 ast_cli(a->fd,"\n");
3364                 ao2_ref(curlot, -1);
3365         }
3366
3367
3368         return CLI_SUCCESS;
3369 }
3370
3371 int ast_features_reload(void)
3372 {
3373         int res;
3374         /* Release parking lot list */
3375         //ASTOBJ_CONTAINER_MARKALL(&parkinglots);
3376         // TODO: I don't think any marking is necessary
3377
3378         /* Reload configuration */
3379         res = load_config();
3380         
3381         //ASTOBJ_CONTAINER_PRUNE_MARKED(&parkinglots, parkinglot_destroy);
3382         return res;
3383 }
3384
3385 static char *handle_features_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
3386 {
3387         switch (cmd) {  
3388         case CLI_INIT:
3389                 e->command = "features reload";
3390                 e->usage =
3391                         "Usage: features reload\n"
3392                         "       Reloads configured call features from features.conf\n";
3393                 return NULL;
3394         case CLI_GENERATE:
3395                 return NULL;
3396         }
3397         ast_features_reload();
3398
3399         return CLI_SUCCESS;
3400 }
3401
3402 static char mandescr_bridge[] =
3403 "Description: Bridge together two channels already in the PBX\n"
3404 "Variables: ( Headers marked with * are required )\n"
3405 "   *Channel1: Channel to Bridge to Channel2\n"
3406 "   *Channel2: Channel to Bridge to Channel1\n"
3407 "        Tone: (Yes|No) Play courtesy tone to Chann