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