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