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