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