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