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