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