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