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