I noted this on the dev list but got no response, so I just did it myself.
[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_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 res = -1;
1176         struct ast_call_feature *feature;
1177
1178         ast_rwlock_wrlock(&features_lock);
1179         if ((feature = find_feature(name))) {
1180                 ast_copy_string(feature->exten, value, sizeof(feature->exten));
1181                 res = 0;
1182         }
1183         ast_rwlock_unlock(&features_lock);
1184
1185         return res;
1186 }
1187
1188 static int ast_feature_interpret(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense)
1189 {
1190         int x;
1191         struct ast_flags features;
1192         int res = FEATURE_RETURN_PASSDIGITS;
1193         struct ast_call_feature *feature;
1194         const char *dynamic_features=pbx_builtin_getvar_helper(chan,"DYNAMIC_FEATURES");
1195         char *tmp, *tok;
1196
1197         if (sense == FEATURE_SENSE_CHAN)
1198                 ast_copy_flags(&features, &(config->features_caller), AST_FLAGS_ALL);   
1199         else
1200                 ast_copy_flags(&features, &(config->features_callee), AST_FLAGS_ALL);   
1201         if (option_debug > 2)
1202                 ast_log(LOG_DEBUG, "Feature interpret: chan=%s, peer=%s, sense=%d, features=%d\n", chan->name, peer->name, sense, features.flags);
1203
1204         ast_rwlock_rdlock(&features_lock);
1205         for (x = 0; x < FEATURES_COUNT; x++) {
1206                 if ((ast_test_flag(&features, builtin_features[x].feature_mask)) &&
1207                     !ast_strlen_zero(builtin_features[x].exten)) {
1208                         /* Feature is up for consideration */
1209                         if (!strcmp(builtin_features[x].exten, code)) {
1210                                 res = builtin_features[x].operation(chan, peer, config, code, sense);
1211                                 break;
1212                         } else if (!strncmp(builtin_features[x].exten, code, strlen(code))) {
1213                                 if (res == FEATURE_RETURN_PASSDIGITS)
1214                                         res = FEATURE_RETURN_STOREDIGITS;
1215                         }
1216                 }
1217         }
1218         ast_rwlock_unlock(&features_lock);
1219
1220         if (ast_strlen_zero(dynamic_features))
1221                 return res;
1222
1223         tmp = ast_strdupa(dynamic_features);
1224
1225         while ((tok = strsep(&tmp, "#"))) {
1226                 ast_rwlock_rdlock(&features_lock);
1227                 if (!(feature = find_feature(tok))) {
1228                         ast_rwlock_unlock(&features_lock);
1229                         continue;
1230                 }
1231                         
1232                 /* Feature is up for consideration */
1233                 if (!strcmp(feature->exten, code)) {
1234                         if (option_verbose > 2)
1235                                 ast_verbose(VERBOSE_PREFIX_3 " Feature Found: %s exten: %s\n",feature->sname, tok);
1236                         res = feature->operation(chan, peer, config, code, sense);
1237                         ast_rwlock_unlock(&features_lock);
1238                         break;
1239                 } else if (!strncmp(feature->exten, code, strlen(code)))
1240                         res = FEATURE_RETURN_STOREDIGITS;
1241
1242                 ast_rwlock_unlock(&features_lock);
1243         }
1244         
1245         return res;
1246 }
1247
1248 static void set_config_flags(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config)
1249 {
1250         int x;
1251         
1252         ast_clear_flag(config, AST_FLAGS_ALL);
1253
1254         ast_rwlock_rdlock(&features_lock);
1255         for (x = 0; x < FEATURES_COUNT; x++) {
1256                 if (!ast_test_flag(builtin_features + x, AST_FEATURE_FLAG_NEEDSDTMF))
1257                         continue;
1258
1259                 if (ast_test_flag(&(config->features_caller), builtin_features[x].feature_mask))
1260                         ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
1261
1262                 if (ast_test_flag(&(config->features_callee), builtin_features[x].feature_mask))
1263                         ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
1264         }
1265         ast_rwlock_unlock(&features_lock);
1266         
1267         if (chan && peer && !(ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_0) && ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_1))) {
1268                 const char *dynamic_features = pbx_builtin_getvar_helper(chan, "DYNAMIC_FEATURES");
1269
1270                 if (dynamic_features) {
1271                         char *tmp = ast_strdupa(dynamic_features);
1272                         char *tok;
1273                         struct ast_call_feature *feature;
1274
1275                         /* while we have a feature */
1276                         while ((tok = strsep(&tmp, "#"))) {
1277                                 ast_rwlock_rdlock(&features_lock);
1278                                 if ((feature = find_feature(tok)) && ast_test_flag(feature, AST_FEATURE_FLAG_NEEDSDTMF)) {
1279                                         if (ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLER))
1280                                                 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
1281                                         if (ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLEE))
1282                                                 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
1283                                 }
1284                                 ast_rwlock_unlock(&features_lock);
1285                         }
1286                 }
1287         }
1288 }
1289
1290 /*! \todo XXX Check - this is very similar to the code in channel.c */
1291 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)
1292 {
1293         int state = 0;
1294         int cause = 0;
1295         int to;
1296         struct ast_channel *chan;
1297         struct ast_channel *monitor_chans[2];
1298         struct ast_channel *active_channel;
1299         int res = 0, ready = 0;
1300         
1301         if ((chan = ast_request(type, format, data, &cause))) {
1302                 ast_set_callerid(chan, cid_num, cid_name, cid_num);
1303                 ast_channel_inherit_variables(caller, chan);    
1304                 pbx_builtin_setvar_helper(chan, "TRANSFERERNAME", caller->name);
1305                 if (!chan->cdr) {
1306                         chan->cdr=ast_cdr_alloc();
1307                         if (chan->cdr) {
1308                                 ast_cdr_init(chan->cdr, chan); /* initilize our channel's cdr */
1309                                 ast_cdr_start(chan->cdr);
1310                         }
1311                 }
1312                         
1313                 if (!ast_call(chan, data, timeout)) {
1314                         struct timeval started;
1315                         int x, len = 0;
1316                         char *disconnect_code = NULL, *dialed_code = NULL;
1317
1318                         ast_indicate(caller, AST_CONTROL_RINGING);
1319                         /* support dialing of the featuremap disconnect code while performing an attended tranfer */
1320                         ast_rwlock_rdlock(&features_lock);
1321                         for (x = 0; x < FEATURES_COUNT; x++) {
1322                                 if (strcasecmp(builtin_features[x].sname, "disconnect"))
1323                                         continue;
1324
1325                                 disconnect_code = builtin_features[x].exten;
1326                                 len = strlen(disconnect_code) + 1;
1327                                 dialed_code = alloca(len);
1328                                 memset(dialed_code, 0, len);
1329                                 break;
1330                         }
1331                         ast_rwlock_unlock(&features_lock);
1332                         x = 0;
1333                         started = ast_tvnow();
1334                         to = timeout;
1335                         while (!((transferee && transferee->_softhangup) && (!igncallerstate && ast_check_hangup(caller))) && timeout && (chan->_state != AST_STATE_UP)) {
1336                                 struct ast_frame *f = NULL;
1337
1338                                 monitor_chans[0] = caller;
1339                                 monitor_chans[1] = chan;
1340                                 active_channel = ast_waitfor_n(monitor_chans, 2, &to);
1341
1342                                 /* see if the timeout has been violated */
1343                                 if(ast_tvdiff_ms(ast_tvnow(), started) > timeout) {
1344                                         state = AST_CONTROL_UNHOLD;
1345                                         ast_log(LOG_NOTICE, "We exceeded our AT-timeout\n");
1346                                         break; /*doh! timeout*/
1347                                 }
1348
1349                                 if (!active_channel)
1350                                         continue;
1351
1352                                 if (chan && (chan == active_channel)){
1353                                         f = ast_read(chan);
1354                                         if (f == NULL) { /*doh! where'd he go?*/
1355                                                 state = AST_CONTROL_HANGUP;
1356                                                 res = 0;
1357                                                 break;
1358                                         }
1359                                         
1360                                         if (f->frametype == AST_FRAME_CONTROL || f->frametype == AST_FRAME_DTMF || f->frametype == AST_FRAME_TEXT) {
1361                                                 if (f->subclass == AST_CONTROL_RINGING) {
1362                                                         state = f->subclass;
1363                                                         if (option_verbose > 2)
1364                                                                 ast_verbose(VERBOSE_PREFIX_3 "%s is ringing\n", chan->name);
1365                                                         ast_indicate(caller, AST_CONTROL_RINGING);
1366                                                 } else if ((f->subclass == AST_CONTROL_BUSY) || (f->subclass == AST_CONTROL_CONGESTION)) {
1367                                                         state = f->subclass;
1368                                                         if (option_verbose > 2)
1369                                                                 ast_verbose(VERBOSE_PREFIX_3 "%s is busy\n", chan->name);
1370                                                         ast_indicate(caller, AST_CONTROL_BUSY);
1371                                                         ast_frfree(f);
1372                                                         f = NULL;
1373                                                         break;
1374                                                 } else if (f->subclass == AST_CONTROL_ANSWER) {
1375                                                         /* This is what we are hoping for */
1376                                                         state = f->subclass;
1377                                                         ast_frfree(f);
1378                                                         f = NULL;
1379                                                         ready=1;
1380                                                         break;
1381                                                 } else {
1382                                                         ast_log(LOG_NOTICE, "Don't know what to do about control frame: %d\n", f->subclass);
1383                                                 }
1384                                                 /* else who cares */
1385                                         }
1386
1387                                 } else if (caller && (active_channel == caller)) {
1388                                         f = ast_read(caller);
1389                                         if (f == NULL) { /*doh! where'd he go?*/
1390                                                 if (!igncallerstate) {
1391                                                         if (caller->_softhangup && !chan->_softhangup) {
1392                                                                 /* make this a blind transfer */
1393                                                                 ready = 1;
1394                                                                 break;
1395                                                         }
1396                                                         state = AST_CONTROL_HANGUP;
1397                                                         res = 0;
1398                                                         break;
1399                                                 }
1400                                         } else {
1401                                         
1402                                                 if (f->frametype == AST_FRAME_DTMF) {
1403                                                         dialed_code[x++] = f->subclass;
1404                                                         dialed_code[x] = '\0';
1405                                                         if (strlen(dialed_code) == len) {
1406                                                                 x = 0;
1407                                                         } else if (x && strncmp(dialed_code, disconnect_code, x)) {
1408                                                                 x = 0;
1409                                                                 dialed_code[x] = '\0';
1410                                                         }
1411                                                         if (*dialed_code && !strcmp(dialed_code, disconnect_code)) {
1412                                                                 /* Caller Canceled the call */
1413                                                                 state = AST_CONTROL_UNHOLD;
1414                                                                 ast_frfree(f);
1415                                                                 f = NULL;
1416                                                                 break;
1417                                                         }
1418                                                 }
1419                                         }
1420                                 }
1421                                 if (f)
1422                                         ast_frfree(f);
1423                         } /* end while */
1424                 } else
1425                         ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
1426         } else {
1427                 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
1428                 switch(cause) {
1429                 case AST_CAUSE_BUSY:
1430                         state = AST_CONTROL_BUSY;
1431                         break;
1432                 case AST_CAUSE_CONGESTION:
1433                         state = AST_CONTROL_CONGESTION;
1434                         break;
1435                 }
1436         }
1437         
1438         ast_indicate(caller, -1);
1439         if (chan && ready) {
1440                 if (chan->_state == AST_STATE_UP) 
1441                         state = AST_CONTROL_ANSWER;
1442                 res = 0;
1443         } else if(chan) {
1444                 res = -1;
1445                 ast_hangup(chan);
1446                 chan = NULL;
1447         } else {
1448                 res = -1;
1449         }
1450         
1451         if (outstate)
1452                 *outstate = state;
1453
1454         if (chan && res <= 0) {
1455                 if (chan->cdr || (chan->cdr = ast_cdr_alloc())) {
1456                         char tmp[256];
1457                         ast_cdr_init(chan->cdr, chan);
1458                         snprintf(tmp, 256, "%s/%s", type, (char *)data);
1459                         ast_cdr_setapp(chan->cdr,"Dial",tmp);
1460                         ast_cdr_update(chan);
1461                         ast_cdr_start(chan->cdr);
1462                         ast_cdr_end(chan->cdr);
1463                         /* If the cause wasn't handled properly */
1464                         if (ast_cdr_disposition(chan->cdr,chan->hangupcause))
1465                                 ast_cdr_failed(chan->cdr);
1466                 } else {
1467                         ast_log(LOG_WARNING, "Unable to create Call Detail Record\n");
1468                 }
1469         }
1470         
1471         return chan;
1472 }
1473
1474 int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast_bridge_config *config)
1475 {
1476         /* Copy voice back and forth between the two channels.  Give the peer
1477            the ability to transfer calls with '#<extension' syntax. */
1478         struct ast_frame *f;
1479         struct ast_channel *who;
1480         char chan_featurecode[FEATURE_MAX_LEN + 1]="";
1481         char peer_featurecode[FEATURE_MAX_LEN + 1]="";
1482         int res;
1483         int diff;
1484         int hasfeatures=0;
1485         int hadfeatures=0;
1486         struct ast_option_header *aoh;
1487         struct ast_bridge_config backup_config;
1488         struct ast_cdr *bridge_cdr;
1489
1490         memset(&backup_config, 0, sizeof(backup_config));
1491
1492         config->start_time = ast_tvnow();
1493
1494         if (chan && peer) {
1495                 pbx_builtin_setvar_helper(chan, "BRIDGEPEER", peer->name);
1496                 pbx_builtin_setvar_helper(peer, "BRIDGEPEER", chan->name);
1497         } else if (chan)
1498                 pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", NULL);
1499
1500         if (monitor_ok) {
1501                 const char *monitor_exec;
1502                 struct ast_channel *src = NULL;
1503                 if (!monitor_app) { 
1504                         if (!(monitor_app = pbx_findapp("Monitor")))
1505                                 monitor_ok=0;
1506                 }
1507                 if ((monitor_exec = pbx_builtin_getvar_helper(chan, "AUTO_MONITOR"))) 
1508                         src = chan;
1509                 else if ((monitor_exec = pbx_builtin_getvar_helper(peer, "AUTO_MONITOR")))
1510                         src = peer;
1511                 if (monitor_app && src) {
1512                         char *tmp = ast_strdupa(monitor_exec);
1513                         pbx_exec(src, monitor_app, tmp);
1514                 }
1515         }
1516         
1517         set_config_flags(chan, peer, config);
1518         config->firstpass = 1;
1519
1520         /* Answer if need be */
1521         if (ast_answer(chan))
1522                 return -1;
1523         peer->appl = "Bridged Call";
1524         peer->data = chan->name;
1525
1526         /* copy the userfield from the B-leg to A-leg if applicable */
1527         if (chan->cdr && peer->cdr && !ast_strlen_zero(peer->cdr->userfield)) {
1528                 char tmp[256];
1529                 if (!ast_strlen_zero(chan->cdr->userfield)) {
1530                         snprintf(tmp, sizeof(tmp), "%s;%s", chan->cdr->userfield, peer->cdr->userfield);
1531                         ast_cdr_appenduserfield(chan, tmp);
1532                 } else
1533                         ast_cdr_setuserfield(chan, peer->cdr->userfield);
1534                 /* free the peer's cdr without ast_cdr_free complaining */
1535                 free(peer->cdr);
1536                 peer->cdr = NULL;
1537         }
1538
1539         for (;;) {
1540                 struct ast_channel *other;      /* used later */
1541
1542                 res = ast_channel_bridge(chan, peer, config, &f, &who);
1543
1544                 if (config->feature_timer) {
1545                         /* Update time limit for next pass */
1546                         diff = ast_tvdiff_ms(ast_tvnow(), config->start_time);
1547                         config->feature_timer -= diff;
1548                         if (hasfeatures) {
1549                                 /* Running on backup config, meaning a feature might be being
1550                                    activated, but that's no excuse to keep things going 
1551                                    indefinitely! */
1552                                 if (backup_config.feature_timer && ((backup_config.feature_timer -= diff) <= 0)) {
1553                                         if (option_debug)
1554                                                 ast_log(LOG_DEBUG, "Timed out, realtime this time!\n");
1555                                         config->feature_timer = 0;
1556                                         who = chan;
1557                                         if (f)
1558                                                 ast_frfree(f);
1559                                         f = NULL;
1560                                         res = 0;
1561                                 } else if (config->feature_timer <= 0) {
1562                                         /* Not *really* out of time, just out of time for
1563                                            digits to come in for features. */
1564                                         if (option_debug)
1565                                                 ast_log(LOG_DEBUG, "Timed out for feature!\n");
1566                                         if (!ast_strlen_zero(peer_featurecode)) {
1567                                                 ast_dtmf_stream(chan, peer, peer_featurecode, 0);
1568                                                 memset(peer_featurecode, 0, sizeof(peer_featurecode));
1569                                         }
1570                                         if (!ast_strlen_zero(chan_featurecode)) {
1571                                                 ast_dtmf_stream(peer, chan, chan_featurecode, 0);
1572                                                 memset(chan_featurecode, 0, sizeof(chan_featurecode));
1573                                         }
1574                                         if (f)
1575                                                 ast_frfree(f);
1576                                         hasfeatures = !ast_strlen_zero(chan_featurecode) || !ast_strlen_zero(peer_featurecode);
1577                                         if (!hasfeatures) {
1578                                                 /* Restore original (possibly time modified) bridge config */
1579                                                 memcpy(config, &backup_config, sizeof(struct ast_bridge_config));
1580                                                 memset(&backup_config, 0, sizeof(backup_config));
1581                                         }
1582                                         hadfeatures = hasfeatures;
1583                                         /* Continue as we were */
1584                                         continue;
1585                                 } else if (!f) {
1586                                         /* The bridge returned without a frame and there is a feature in progress.
1587                                          * However, we don't think the feature has quite yet timed out, so just
1588                                          * go back into the bridge. */
1589                                         continue;
1590                                 }
1591                         } else {
1592                                 if (config->feature_timer <=0) {
1593                                         /* We ran out of time */
1594                                         config->feature_timer = 0;
1595                                         who = chan;
1596                                         if (f)
1597                                                 ast_frfree(f);
1598                                         f = NULL;
1599                                         res = 0;
1600                                 }
1601                         }
1602                 }
1603                 if (res < 0) {
1604                         ast_log(LOG_WARNING, "Bridge failed on channels %s and %s\n", chan->name, peer->name);
1605                         return -1;
1606                 }
1607                 
1608                 if (!f || (f->frametype == AST_FRAME_CONTROL &&
1609                                 (f->subclass == AST_CONTROL_HANGUP || f->subclass == AST_CONTROL_BUSY || 
1610                                         f->subclass == AST_CONTROL_CONGESTION))) {
1611                         res = -1;
1612                         break;
1613                 }
1614                 /* many things should be sent to the 'other' channel */
1615                 other = (who == chan) ? peer : chan;
1616                 if (f->frametype == AST_FRAME_CONTROL) {
1617                         if (f->subclass == AST_CONTROL_RINGING)
1618                                 ast_indicate(other, AST_CONTROL_RINGING);
1619                         else if (f->subclass == -1)
1620                                 ast_indicate(other, -1);
1621                         else if (f->subclass == AST_CONTROL_FLASH)
1622                                 ast_indicate(other, AST_CONTROL_FLASH);
1623                         else if (f->subclass == AST_CONTROL_OPTION) {
1624                                 aoh = f->data;
1625                                 /* Forward option Requests */
1626                                 if (aoh && aoh->flag == AST_OPTION_FLAG_REQUEST)
1627                                         ast_channel_setoption(other, ntohs(aoh->option), aoh->data, f->datalen - sizeof(struct ast_option_header), 0);
1628                         }
1629                 } else if (f->frametype == AST_FRAME_DTMF_BEGIN) {
1630                         /* eat it */
1631                 } else if (f->frametype == AST_FRAME_DTMF) {
1632                         char *featurecode;
1633                         int sense;
1634
1635                         hadfeatures = hasfeatures;
1636                         /* This cannot overrun because the longest feature is one shorter than our buffer */
1637                         if (who == chan) {
1638                                 sense = FEATURE_SENSE_CHAN;
1639                                 featurecode = chan_featurecode;
1640                         } else  {
1641                                 sense = FEATURE_SENSE_PEER;
1642                                 featurecode = peer_featurecode;
1643                         }
1644                         /*! append the event to featurecode. we rely on the string being zero-filled, and
1645                          * not overflowing it. 
1646                          * \todo XXX how do we guarantee the latter ?
1647                          */
1648                         featurecode[strlen(featurecode)] = f->subclass;
1649                         /* Get rid of the frame before we start doing "stuff" with the channels */
1650                         ast_frfree(f);
1651                         f = NULL;
1652                         config->feature_timer = backup_config.feature_timer;
1653                         res = ast_feature_interpret(chan, peer, config, featurecode, sense);
1654                         switch(res) {
1655                         case FEATURE_RETURN_PASSDIGITS:
1656                                 ast_dtmf_stream(other, who, featurecode, 0);
1657                                 /* Fall through */
1658                         case FEATURE_RETURN_SUCCESS:
1659                                 memset(featurecode, 0, sizeof(chan_featurecode));
1660                                 break;
1661                         }
1662                         if (res >= FEATURE_RETURN_PASSDIGITS) {
1663                                 res = 0;
1664                         } else 
1665                                 break;
1666                         hasfeatures = !ast_strlen_zero(chan_featurecode) || !ast_strlen_zero(peer_featurecode);
1667                         if (hadfeatures && !hasfeatures) {
1668                                 /* Restore backup */
1669                                 memcpy(config, &backup_config, sizeof(struct ast_bridge_config));
1670                                 memset(&backup_config, 0, sizeof(struct ast_bridge_config));
1671                         } else if (hasfeatures) {
1672                                 if (!hadfeatures) {
1673                                         /* Backup configuration */
1674                                         memcpy(&backup_config, config, sizeof(struct ast_bridge_config));
1675                                         /* Setup temporary config options */
1676                                         config->play_warning = 0;
1677                                         ast_clear_flag(&(config->features_caller), AST_FEATURE_PLAY_WARNING);
1678                                         ast_clear_flag(&(config->features_callee), AST_FEATURE_PLAY_WARNING);
1679                                         config->warning_freq = 0;
1680                                         config->warning_sound = NULL;
1681                                         config->end_sound = NULL;
1682                                         config->start_sound = NULL;
1683                                         config->firstpass = 0;
1684                                 }
1685                                 config->start_time = ast_tvnow();
1686                                 config->feature_timer = featuredigittimeout;
1687                                 if (option_debug)
1688                                         ast_log(LOG_DEBUG, "Set time limit to %ld\n", config->feature_timer);
1689                         }
1690                 }
1691                 if (f)
1692                         ast_frfree(f);
1693
1694         }
1695         /* arrange the cdrs */
1696         bridge_cdr = ast_cdr_alloc();
1697         if (bridge_cdr) {
1698                 if (chan->cdr && peer->cdr) { /* both of them? merge */
1699                         ast_cdr_init(bridge_cdr,chan); /* seems more logicaller to use the  destination as a base, but, really, it's random */
1700                         ast_cdr_start(bridge_cdr); /* now is the time to start */
1701                         
1702                         /* absorb the channel cdr */
1703                         ast_cdr_merge(bridge_cdr, chan->cdr);
1704                         ast_cdr_discard(chan->cdr); /* no posting these guys */
1705                         
1706                         /* absorb the peer cdr */
1707                         ast_cdr_merge(bridge_cdr, peer->cdr);
1708                         ast_cdr_discard(peer->cdr); /* no posting these guys */
1709                         peer->cdr = NULL;
1710                         chan->cdr = bridge_cdr; /* make this available to the rest of the world via the chan while the call is in progress */
1711                 } else if (chan->cdr) {
1712                         /* take the cdr from the channel - literally */
1713                         ast_cdr_init(bridge_cdr,chan);
1714                         /* absorb this data */
1715                         ast_cdr_merge(bridge_cdr, chan->cdr);
1716                         ast_cdr_discard(chan->cdr); /* no posting these guys */
1717                         chan->cdr = bridge_cdr; /* make this available to the rest of the world via the chan while the call is in progress */
1718                 } else if (peer->cdr) {
1719                         /* take the cdr from the peer - literally */
1720                         ast_cdr_init(bridge_cdr,peer);
1721                         /* absorb this data */
1722                         ast_cdr_merge(bridge_cdr, peer->cdr);
1723                         ast_cdr_discard(peer->cdr); /* no posting these guys */
1724                         peer->cdr = NULL;
1725                         peer->cdr = bridge_cdr; /* make this available to the rest of the world via the chan while the call is in progress */
1726                 } else {
1727                         /* make up a new cdr */
1728                         ast_cdr_init(bridge_cdr,chan); /* eh, just pick one of them */
1729                         chan->cdr = bridge_cdr; /*  */
1730                 }
1731                 if (ast_strlen_zero(bridge_cdr->dstchannel)) {
1732                         if (strcmp(bridge_cdr->channel, peer->name) != 0)
1733                                 ast_cdr_setdestchan(bridge_cdr, peer->name);
1734                         else
1735                                 ast_cdr_setdestchan(bridge_cdr, chan->name);
1736                 }
1737         }
1738         return res;
1739 }
1740
1741 /*! \brief Output parking event to manager */
1742 static void post_manager_event(const char *s, struct parkeduser *pu)
1743 {
1744         manager_event(EVENT_FLAG_CALL, s,
1745                 "Exten: %s\r\n"
1746                 "Channel: %s\r\n"
1747                 "CallerIDNum: %s\r\n"
1748                 "CallerIDName: %s\r\n\r\n",
1749                 pu->parkingexten, 
1750                 pu->chan->name,
1751                 S_OR(pu->chan->cid.cid_num, "<unknown>"),
1752                 S_OR(pu->chan->cid.cid_name, "<unknown>")
1753                 );
1754 }
1755
1756 /*! \brief Take care of parked calls and unpark them if needed */
1757 static void *do_parking_thread(void *ignore)
1758 {
1759         char parkingslot[AST_MAX_EXTENSION];
1760         fd_set rfds, efds;      /* results from previous select, to be preserved across loops. */
1761
1762         FD_ZERO(&rfds);
1763         FD_ZERO(&efds);
1764
1765         for (;;) {
1766                 struct parkeduser *pu, *pl, *pt = NULL;
1767                 int ms = -1;    /* select timeout, uninitialized */
1768                 int max = -1;   /* max fd, none there yet */
1769                 fd_set nrfds, nefds;    /* args for the next select */
1770                 FD_ZERO(&nrfds);
1771                 FD_ZERO(&nefds);
1772
1773                 ast_mutex_lock(&parking_lock);
1774                 pl = NULL;
1775                 pu = parkinglot;
1776                 /* navigate the list with prev-cur pointers to support removals */
1777                 while (pu) {
1778                         struct ast_channel *chan = pu->chan;    /* shorthand */
1779                         int tms;        /* timeout for this item */
1780                         int x;          /* fd index in channel */
1781                         struct ast_context *con;
1782
1783                         if (pu->notquiteyet) { /* Pretend this one isn't here yet */
1784                                 pl = pu;
1785                                 pu = pu->next;
1786                                 continue;
1787                         }
1788                         tms = ast_tvdiff_ms(ast_tvnow(), pu->start);
1789                         if (tms > pu->parkingtime) {
1790                                 ast_indicate(chan, AST_CONTROL_UNHOLD);
1791                                 /* Get chan, exten from derived kludge */
1792                                 if (pu->peername[0]) {
1793                                         char *peername = ast_strdupa(pu->peername);
1794                                         char *cp = strrchr(peername, '-');
1795                                         if (cp) 
1796                                                 *cp = 0;
1797                                         con = ast_context_find(parking_con_dial);
1798                                         if (!con) {
1799                                                 con = ast_context_create(NULL, parking_con_dial, registrar);
1800                                                 if (!con)
1801                                                         ast_log(LOG_ERROR, "Parking dial context '%s' does not exist and unable to create\n", parking_con_dial);
1802                                         }
1803                                         if (con) {
1804                                                 char returnexten[AST_MAX_EXTENSION];
1805                                                 snprintf(returnexten, sizeof(returnexten), "%s||t", peername);
1806                                                 ast_add_extension2(con, 1, peername, 1, NULL, NULL, "Dial", strdup(returnexten), ast_free, registrar);
1807                                         }
1808                                         if (comebacktoorigin) { 
1809                                                 set_c_e_p(chan, parking_con_dial, peername, 1);
1810                                         } else {
1811                                                 ast_log(LOG_WARNING, "now going to parkedcallstimeout,s,1 | ps is %d\n",pu->parkingnum);
1812                                                 snprintf(parkingslot, sizeof(parkingslot), "%d", pu->parkingnum);
1813                                                 pbx_builtin_setvar_helper(pu->chan, "PARKINGSLOT", parkingslot);
1814                                                 set_c_e_p(chan, "parkedcallstimeout", peername, 1);
1815                                         }
1816                                 } else {
1817                                         /* They've been waiting too long, send them back to where they came.  Theoretically they
1818                                            should have their original extensions and such, but we copy to be on the safe side */
1819                                         set_c_e_p(chan, pu->context, pu->exten, pu->priority);
1820                                 }
1821
1822                                 post_manager_event("ParkedCallTimeOut", pu);
1823
1824                                 if (option_verbose > 1) 
1825                                         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);
1826                                 /* Start up the PBX, or hang them up */
1827                                 if (ast_pbx_start(chan))  {
1828                                         ast_log(LOG_WARNING, "Unable to restart the PBX for user on '%s', hanging them up...\n", chan->name);
1829                                         ast_hangup(chan);
1830                                 }
1831                                 /* And take them out of the parking lot */
1832                                 if (pl) 
1833                                         pl->next = pu->next;
1834                                 else
1835                                         parkinglot = pu->next;
1836                                 pt = pu;
1837                                 pu = pu->next;
1838                                 con = ast_context_find(parking_con);
1839                                 if (con) {
1840                                         if (ast_context_remove_extension2(con, pt->parkingexten, 1, NULL))
1841                                                 ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
1842                                         else
1843                                                 notify_metermaids(pt->parkingexten, parking_con);
1844                                 } else
1845                                         ast_log(LOG_WARNING, "Whoa, no parking context?\n");
1846                                 free(pt);
1847                         } else {        /* still within parking time, process descriptors */
1848                                 for (x = 0; x < AST_MAX_FDS; x++) {
1849                                         struct ast_frame *f;
1850
1851                                         if (chan->fds[x] == -1 || (!FD_ISSET(chan->fds[x], &rfds) && !FD_ISSET(chan->fds[x], &efds)))
1852                                                 continue;       /* nothing on this descriptor */
1853
1854                                         if (FD_ISSET(chan->fds[x], &efds))
1855                                                 ast_set_flag(chan, AST_FLAG_EXCEPTION);
1856                                         else
1857                                                 ast_clear_flag(chan, AST_FLAG_EXCEPTION);
1858                                         chan->fdno = x;
1859
1860                                         /* See if they need servicing */
1861                                         f = ast_read(chan);
1862                                         if (!f || (f->frametype == AST_FRAME_CONTROL && f->subclass ==  AST_CONTROL_HANGUP)) {
1863                                                 if (f)
1864                                                         ast_frfree(f);
1865                                                 post_manager_event("ParkedCallGiveUp", pu);
1866
1867                                                 /* There's a problem, hang them up*/
1868                                                 if (option_verbose > 1) 
1869                                                         ast_verbose(VERBOSE_PREFIX_2 "%s got tired of being parked\n", chan->name);
1870                                                 ast_hangup(chan);
1871                                                 /* And take them out of the parking lot */
1872                                                 if (pl) 
1873                                                         pl->next = pu->next;
1874                                                 else
1875                                                         parkinglot = pu->next;
1876                                                 pt = pu;
1877                                                 pu = pu->next;
1878                                                 con = ast_context_find(parking_con);
1879                                                 if (con) {
1880                                                         if (ast_context_remove_extension2(con, pt->parkingexten, 1, NULL))
1881                                                                 ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
1882                                                         else
1883                                                                 notify_metermaids(pt->parkingexten, parking_con);
1884                                                 } else
1885                                                         ast_log(LOG_WARNING, "Whoa, no parking context?\n");
1886                                                 free(pt);
1887                                                 break;
1888                                         } else {
1889                                                 /*! \todo XXX Maybe we could do something with packets, like dial "0" for operator or something XXX */
1890                                                 ast_frfree(f);
1891                                                 if (pu->moh_trys < 3 && !chan->generatordata) {
1892                                                         if (option_debug)
1893                                                                 ast_log(LOG_DEBUG, "MOH on parked call stopped by outside source.  Restarting.\n");
1894                                                         ast_indicate_data(chan, AST_CONTROL_HOLD, 
1895                                                                 S_OR(parkmohclass, NULL),
1896                                                                 !ast_strlen_zero(parkmohclass) ? strlen(parkmohclass) + 1 : 0);
1897                                                         pu->moh_trys++;
1898                                                 }
1899                                                 goto std;       /*! \todo XXX Ick: jumping into an else statement??? XXX */
1900                                         }
1901
1902                                 } /* end for */
1903                                 if (x >= AST_MAX_FDS) {
1904 std:                                    for (x=0; x<AST_MAX_FDS; x++) { /* mark fds for next round */
1905                                                 if (chan->fds[x] > -1) {
1906                                                         FD_SET(chan->fds[x], &nrfds);
1907                                                         FD_SET(chan->fds[x], &nefds);
1908                                                         if (chan->fds[x] > max)
1909                                                                 max = chan->fds[x];
1910                                                 }
1911                                         }
1912                                         /* Keep track of our shortest wait */
1913                                         if (tms < ms || ms < 0)
1914                                                 ms = tms;
1915                                         pl = pu;
1916                                         pu = pu->next;
1917                                 }
1918                         }
1919                 } /* end while */
1920                 ast_mutex_unlock(&parking_lock);
1921                 rfds = nrfds;
1922                 efds = nefds;
1923                 {
1924                         struct timeval tv = ast_samp2tv(ms, 1000);
1925                         /* Wait for something to happen */
1926                         ast_select(max + 1, &rfds, NULL, &efds, (ms > -1) ? &tv : NULL);
1927                 }
1928                 pthread_testcancel();
1929         }
1930         return NULL;    /* Never reached */
1931 }
1932
1933 /*! \brief Park a call */
1934 static int park_call_exec(struct ast_channel *chan, void *data)
1935 {
1936         /* Data is unused at the moment but could contain a parking
1937            lot context eventually */
1938         int res = 0;
1939         struct ast_module_user *u;
1940
1941         u = ast_module_user_add(chan);
1942
1943         /* Setup the exten/priority to be s/1 since we don't know
1944            where this call should return */
1945         strcpy(chan->exten, "s");
1946         chan->priority = 1;
1947         /* Answer if call is not up */
1948         if (chan->_state != AST_STATE_UP)
1949                 res = ast_answer(chan);
1950         /* Sleep to allow VoIP streams to settle down */
1951         if (!res)
1952                 res = ast_safe_sleep(chan, 1000);
1953         /* Park the call */
1954         if (!res)
1955                 res = ast_park_call(chan, chan, 0, NULL);
1956
1957         ast_module_user_remove(u);
1958
1959         return !res ? AST_PBX_KEEPALIVE : res;
1960 }
1961
1962 /*! \brief Pickup parked call */
1963 static int park_exec(struct ast_channel *chan, void *data)
1964 {
1965         int res = 0;
1966         struct ast_module_user *u;
1967         struct ast_channel *peer=NULL;
1968         struct parkeduser *pu, *pl=NULL;
1969         struct ast_context *con;
1970
1971         int park;
1972         struct ast_bridge_config config;
1973
1974         if (!data) {
1975                 ast_log(LOG_WARNING, "Parkedcall requires an argument (extension number)\n");
1976                 return -1;
1977         }
1978         
1979         u = ast_module_user_add(chan);
1980
1981         park = atoi((char *)data);
1982         ast_mutex_lock(&parking_lock);
1983         pu = parkinglot;
1984         while(pu) {
1985                 if (pu->parkingnum == park) {
1986                         if (pl)
1987                                 pl->next = pu->next;
1988                         else
1989                                 parkinglot = pu->next;
1990                         break;
1991                 }
1992                 pl = pu;
1993                 pu = pu->next;
1994         }
1995         ast_mutex_unlock(&parking_lock);
1996         if (pu) {
1997                 peer = pu->chan;
1998                 con = ast_context_find(parking_con);
1999                 if (con) {
2000                         if (ast_context_remove_extension2(con, pu->parkingexten, 1, NULL))
2001                                 ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
2002                         else
2003                                 notify_metermaids(pu->parkingexten, parking_con);
2004                 } else
2005                         ast_log(LOG_WARNING, "Whoa, no parking context?\n");
2006
2007                 manager_event(EVENT_FLAG_CALL, "UnParkedCall",
2008                         "Exten: %s\r\n"
2009                         "Channel: %s\r\n"
2010                         "From: %s\r\n"
2011                         "CallerIDNum: %s\r\n"
2012                         "CallerIDName: %s\r\n",
2013                         pu->parkingexten, pu->chan->name, chan->name,
2014                         S_OR(pu->chan->cid.cid_num, "<unknown>"),
2015                         S_OR(pu->chan->cid.cid_name, "<unknown>")
2016                         );
2017
2018                 free(pu);
2019         }
2020         /* JK02: it helps to answer the channel if not already up */
2021         if (chan->_state != AST_STATE_UP)
2022                 ast_answer(chan);
2023
2024         if (peer) {
2025                 /* Play a courtesy to the source(s) configured to prefix the bridge connecting */
2026                 
2027                 if (!ast_strlen_zero(courtesytone)) {
2028                         int error = 0;
2029                         ast_indicate(peer, AST_CONTROL_UNHOLD);
2030                         if (parkedplay == 0) {
2031                                 error = ast_stream_and_wait(chan, courtesytone, "");
2032                         } else if (parkedplay == 1) {
2033                                 error = ast_stream_and_wait(peer, courtesytone, "");
2034                         } else if (parkedplay == 2) {
2035                                 if (!ast_streamfile(chan, courtesytone, chan->language) &&
2036                                                 !ast_streamfile(peer, courtesytone, chan->language)) {
2037                                         /*! \todo XXX we would like to wait on both! */
2038                                         res = ast_waitstream(chan, "");
2039                                         if (res >= 0)
2040                                                 res = ast_waitstream(peer, "");
2041                                         if (res < 0)
2042                                                 error = 1;
2043                                 }
2044                         }
2045                         if (error) {
2046                                 ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
2047                                 ast_hangup(peer);
2048                                 return -1;
2049                         }
2050                 } else
2051                         ast_indicate(peer, AST_CONTROL_UNHOLD); 
2052
2053                 res = ast_channel_make_compatible(chan, peer);
2054                 if (res < 0) {
2055                         ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for bridge\n", chan->name, peer->name);
2056                         ast_hangup(peer);
2057                         return -1;
2058                 }
2059                 /* This runs sorta backwards, since we give the incoming channel control, as if it
2060                    were the person called. */
2061                 if (option_verbose > 2) 
2062                         ast_verbose(VERBOSE_PREFIX_3 "Channel %s connected to parked call %d\n", chan->name, park);
2063
2064                 pbx_builtin_setvar_helper(chan, "PARKEDCHANNEL", peer->name);
2065                 ast_cdr_setdestchan(chan->cdr, peer->name);
2066                 memset(&config, 0, sizeof(struct ast_bridge_config));
2067                 if ((parkedcalltransfers == AST_FEATURE_FLAG_BYCALLEE) || (parkedcalltransfers == AST_FEATURE_FLAG_BYBOTH))
2068                         ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
2069                 if ((parkedcalltransfers == AST_FEATURE_FLAG_BYCALLER) || (parkedcalltransfers == AST_FEATURE_FLAG_BYBOTH))
2070                         ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
2071                 if ((parkedcallreparking == AST_FEATURE_FLAG_BYCALLEE) || (parkedcallreparking == AST_FEATURE_FLAG_BYBOTH))
2072                         ast_set_flag(&(config.features_callee), AST_FEATURE_PARKCALL);
2073                 if ((parkedcallreparking == AST_FEATURE_FLAG_BYCALLER) || (parkedcallreparking == AST_FEATURE_FLAG_BYBOTH))
2074                         ast_set_flag(&(config.features_caller), AST_FEATURE_PARKCALL);
2075                 res = ast_bridge_call(chan, peer, &config);
2076
2077                 pbx_builtin_setvar_helper(chan, "PARKEDCHANNEL", peer->name);
2078                 ast_cdr_setdestchan(chan->cdr, peer->name);
2079
2080                 /* Simulate the PBX hanging up */
2081                 if (res != AST_PBX_NO_HANGUP_PEER)
2082                         ast_hangup(peer);
2083                 return res;
2084         } else {
2085                 /*! \todo XXX Play a message XXX */
2086                 if (ast_stream_and_wait(chan, "pbx-invalidpark", ""))
2087                         ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", "pbx-invalidpark", chan->name);
2088                 if (option_verbose > 2) 
2089                         ast_verbose(VERBOSE_PREFIX_3 "Channel %s tried to talk to nonexistent parked call %d\n", chan->name, park);
2090                 res = -1;
2091         }
2092
2093         ast_module_user_remove(u);
2094
2095         return res;
2096 }
2097
2098 static int handle_showfeatures(int fd, int argc, char *argv[])
2099 {
2100         int i;
2101         struct ast_call_feature *feature;
2102         char format[] = "%-25s %-7s %-7s\n";
2103
2104         ast_cli(fd, format, "Builtin Feature", "Default", "Current");
2105         ast_cli(fd, format, "---------------", "-------", "-------");
2106
2107         ast_cli(fd, format, "Pickup", "*8", ast_pickup_ext());          /* default hardcoded above, so we'll hardcode it here */
2108
2109         ast_rwlock_rdlock(&features_lock);
2110         for (i = 0; i < FEATURES_COUNT; i++)
2111                 ast_cli(fd, format, builtin_features[i].fname, builtin_features[i].default_exten, builtin_features[i].exten);
2112         ast_rwlock_unlock(&features_lock);
2113
2114         ast_cli(fd, "\n");
2115         ast_cli(fd, format, "Dynamic Feature", "Default", "Current");
2116         ast_cli(fd, format, "---------------", "-------", "-------");
2117         if (AST_LIST_EMPTY(&feature_list))
2118                 ast_cli(fd, "(none)\n");
2119         else {
2120                 AST_LIST_LOCK(&feature_list);
2121                 AST_LIST_TRAVERSE(&feature_list, feature, feature_entry)
2122                         ast_cli(fd, format, feature->sname, "no def", feature->exten);  
2123                 AST_LIST_UNLOCK(&feature_list);
2124         }
2125         ast_cli(fd, "\nCall parking\n");
2126         ast_cli(fd, "------------\n");
2127         ast_cli(fd,"%-20s:      %s\n", "Parking extension", parking_ext);
2128         ast_cli(fd,"%-20s:      %s\n", "Parking context", parking_con);
2129         ast_cli(fd,"%-20s:      %d-%d\n", "Parked call extensions", parking_start, parking_stop);
2130         ast_cli(fd,"\n");
2131         
2132         return RESULT_SUCCESS;
2133 }
2134
2135 static char mandescr_bridge[] =
2136 "Description: Bridge together two channels already in the PBX\n"
2137 "Variables: ( Headers marked with * are required )\n"
2138 "   *Channel1: Channel to Bridge to Channel2\n"
2139 "   *Channel2: Channel to Bridge to Channel1\n"
2140 "        Tone: (Yes|No) Play courtesy tone to Channel 2\n"
2141 "\n";
2142
2143 static void do_bridge_masquerade(struct ast_channel *chan, struct ast_channel *tmpchan)
2144 {
2145         ast_moh_stop(chan);
2146         ast_mutex_lock(&chan->lock);
2147         ast_setstate(tmpchan, chan->_state);
2148         tmpchan->readformat = chan->readformat;
2149         tmpchan->writeformat = chan->writeformat;
2150         ast_channel_masquerade(tmpchan, chan);
2151         ast_mutex_lock(&tmpchan->lock);
2152         ast_do_masquerade(tmpchan);
2153         /* when returning from bridge, the channel will continue at the next priority */
2154         ast_explicit_goto(tmpchan, chan->context, chan->exten, chan->priority + 1);
2155         ast_mutex_unlock(&tmpchan->lock);
2156         ast_mutex_unlock(&chan->lock);
2157 }
2158
2159 static int action_bridge(struct mansession *s, const struct message *m)
2160 {
2161         const char *channela = astman_get_header(m, "Channel1");
2162         const char *channelb = astman_get_header(m, "Channel2");
2163         const char *playtone = astman_get_header(m, "Tone");
2164         struct ast_channel *chana = NULL, *chanb = NULL;
2165         struct ast_channel *tmpchana = NULL, *tmpchanb = NULL;
2166         struct ast_bridge_thread_obj *tobj = NULL;
2167
2168         /* make sure valid channels were specified */
2169         if (!ast_strlen_zero(channela) && !ast_strlen_zero(channelb)) {
2170                 chana = ast_get_channel_by_name_prefix_locked(channela, strlen(channela));
2171                 chanb = ast_get_channel_by_name_prefix_locked(channelb, strlen(channelb));
2172                 if (chana)
2173                         ast_mutex_unlock(&chana->lock);
2174                 if (chanb)
2175                         ast_mutex_unlock(&chanb->lock);
2176
2177                 /* send errors if any of the channels could not be found/locked */
2178                 if (!chana) {
2179                         char buf[256];
2180                         snprintf(buf, sizeof(buf), "Channel1 does not exists: %s", channela);
2181                         astman_send_error(s, m, buf);
2182                         return 0;
2183                 }
2184                 if (!chanb) {
2185                         char buf[256];
2186                         snprintf(buf, sizeof(buf), "Channel2 does not exists: %s", channelb);
2187                         astman_send_error(s, m, buf);
2188                         return 0;
2189                 }
2190         } else {
2191                 astman_send_error(s, m, "Missing channel parameter in request");
2192                 return 0;
2193         }
2194
2195         /* Answer the channels if needed */
2196         if (chana->_state != AST_STATE_UP)
2197                 ast_answer(chana);
2198         if (chanb->_state != AST_STATE_UP)
2199                 ast_answer(chanb);
2200
2201         /* create the placeholder channels and grab the other channels */
2202         if (!(tmpchana = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL, 
2203                 NULL, NULL, 0, "Bridge/%s", chana->name))) {
2204                 astman_send_error(s, m, "Unable to create temporary channel!");
2205                 return 1;
2206         }
2207
2208         if (!(tmpchana = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL, 
2209                 NULL, NULL, 0, "Bridge/%s", chanb->name))) {
2210                 astman_send_error(s, m, "Unable to create temporary channels!");
2211                 ast_channel_free(tmpchana);
2212                 return 1;
2213         }
2214
2215         do_bridge_masquerade(chana, tmpchana);
2216         do_bridge_masquerade(chanb, tmpchanb);
2217         
2218         /* make the channels compatible, send error if we fail doing so */
2219         if (ast_channel_make_compatible(tmpchana, tmpchanb)) {
2220                 ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for manager bridge\n", tmpchana->name, tmpchanb->name);
2221                 astman_send_error(s, m, "Could not make channels compatible for manager bridge");
2222                 ast_hangup(tmpchana);
2223                 ast_hangup(tmpchanb);
2224                 return 1;
2225         }
2226
2227         /* setup the bridge thread object and start the bridge */
2228         if (!(tobj = ast_calloc(1, sizeof(*tobj)))) {
2229                 ast_log(LOG_WARNING, "Unable to spawn a new bridge thread on %s and %s: %s\n", tmpchana->name, tmpchanb->name, strerror(errno));
2230                 astman_send_error(s, m, "Unable to spawn a new bridge thread");
2231                 ast_hangup(tmpchana);
2232                 ast_hangup(tmpchanb);
2233                 return 1;
2234         }
2235
2236         tobj->chan = tmpchana;
2237         tobj->peer = tmpchanb;
2238         tobj->return_to_pbx = 1;
2239         
2240         if (ast_true(playtone)) {
2241                 if (!ast_strlen_zero(xfersound) && !ast_streamfile(tmpchanb, xfersound, tmpchanb->language)) {
2242                         if (ast_waitstream(tmpchanb, "") < 0)
2243                                 ast_log(LOG_WARNING, "Failed to play a courtesy tone on chan %s\n", tmpchanb->name);
2244                 }
2245         }
2246
2247         ast_bridge_call_thread_launch(tobj);
2248
2249         astman_send_ack(s, m, "Launched bridge thread with success");
2250
2251         return 0;
2252 }
2253
2254 static char showfeatures_help[] =
2255 "Usage: feature list\n"
2256 "       Lists currently configured features.\n";
2257
2258 static int handle_parkedcalls(int fd, int argc, char *argv[])
2259 {
2260         struct parkeduser *cur;
2261         int numparked = 0;
2262
2263         ast_cli(fd, "%4s %25s (%-15s %-12s %-4s) %-6s \n", "Num", "Channel"
2264                 , "Context", "Extension", "Pri", "Timeout");
2265
2266         ast_mutex_lock(&parking_lock);
2267
2268         for (cur = parkinglot; cur; cur = cur->next) {
2269                 ast_cli(fd, "%-10.10s %25s (%-15s %-12s %-4d) %6lds\n"
2270                         ,cur->parkingexten, cur->chan->name, cur->context, cur->exten
2271                         ,cur->priority, cur->start.tv_sec + (cur->parkingtime/1000) - time(NULL));
2272
2273                 numparked++;
2274         }
2275         ast_mutex_unlock(&parking_lock);
2276         ast_cli(fd, "%d parked call%s.\n", numparked, ESS(numparked));
2277
2278
2279         return RESULT_SUCCESS;
2280 }
2281
2282 static char showparked_help[] =
2283 "Usage: show parkedcalls\n"
2284 "       Lists currently parked calls.\n";
2285
2286 static struct ast_cli_entry cli_features[] = {
2287         { { "feature", "show", NULL },
2288         handle_showfeatures, "Lists configured features",
2289         showfeatures_help },
2290
2291         { { "show", "parkedcalls", NULL },
2292         handle_parkedcalls, "Lists parked calls",
2293         showparked_help },
2294 };
2295
2296 /*! \brief Dump lot status */
2297 static int manager_parking_status(struct mansession *s, const struct message *m)
2298 {
2299         struct parkeduser *cur;
2300         const char *id = astman_get_header(m, "ActionID");
2301         char idText[256] = "";
2302
2303         if (!ast_strlen_zero(id))
2304                 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
2305
2306         astman_send_ack(s, m, "Parked calls will follow");
2307
2308         ast_mutex_lock(&parking_lock);
2309
2310         for (cur = parkinglot; cur; cur = cur->next) {
2311                 astman_append(s, "Event: ParkedCall\r\n"
2312                         "Exten: %d\r\n"
2313                         "Channel: %s\r\n"
2314                         "From: %s\r\n"
2315                         "Timeout: %ld\r\n"
2316                         "CallerIDNum: %s\r\n"
2317                         "CallerIDName: %s\r\n"
2318                         "%s"
2319                         "\r\n",
2320                         cur->parkingnum, cur->chan->name, cur->peername,
2321                         (long) cur->start.tv_sec + (long) (cur->parkingtime / 1000) - (long) time(NULL),
2322                         S_OR(cur->chan->cid.cid_num, ""),       /* XXX in other places it is <unknown> */
2323                         S_OR(cur->chan->cid.cid_name, ""),
2324                         idText);
2325         }
2326
2327         astman_append(s,
2328                 "Event: ParkedCallsComplete\r\n"
2329                 "%s"
2330                 "\r\n",idText);
2331
2332         ast_mutex_unlock(&parking_lock);
2333
2334         return RESULT_SUCCESS;
2335 }
2336
2337 static char mandescr_park[] =
2338 "Description: Park a channel.\n"
2339 "Variables: (Names marked with * are required)\n"
2340 "       *Channel: Channel name to park\n"
2341 "       *Channel2: Channel to announce park info to (and return to if timeout)\n"
2342 "       Timeout: Number of milliseconds to wait before callback.\n";  
2343
2344 static int manager_park(struct mansession *s, const struct message *m)
2345 {
2346         const char *channel = astman_get_header(m, "Channel");
2347         const char *channel2 = astman_get_header(m, "Channel2");
2348         const char *timeout = astman_get_header(m, "Timeout");
2349         char buf[BUFSIZ];
2350         int to = 0;
2351         int res = 0;
2352         int parkExt = 0;
2353         struct ast_channel *ch1, *ch2;
2354
2355         if (ast_strlen_zero(channel)) {
2356                 astman_send_error(s, m, "Channel not specified");
2357                 return 0;
2358         }
2359
2360         if (ast_strlen_zero(channel2)) {
2361                 astman_send_error(s, m, "Channel2 not specified");
2362                 return 0;
2363         }
2364
2365         ch1 = ast_get_channel_by_name_locked(channel);
2366         if (!ch1) {
2367                 snprintf(buf, sizeof(buf), "Channel does not exist: %s", channel);
2368                 astman_send_error(s, m, buf);
2369                 return 0;
2370         }
2371
2372         ch2 = ast_get_channel_by_name_locked(channel2);
2373         if (!ch2) {
2374                 snprintf(buf, sizeof(buf), "Channel does not exist: %s", channel2);
2375                 astman_send_error(s, m, buf);
2376                 ast_channel_unlock(ch1);
2377                 return 0;
2378         }
2379
2380         if (!ast_strlen_zero(timeout)) {
2381                 sscanf(timeout, "%d", &to);
2382         }
2383
2384         res = ast_masq_park_call(ch1, ch2, to, &parkExt);
2385         if (!res) {
2386                 ast_softhangup(ch2, AST_SOFTHANGUP_EXPLICIT);
2387                 astman_send_ack(s, m, "Park successful");
2388         } else {
2389                 astman_send_error(s, m, "Park failure");
2390         }
2391
2392         ast_channel_unlock(ch1);
2393         ast_channel_unlock(ch2);
2394
2395         return 0;
2396 }
2397
2398
2399 int ast_pickup_call(struct ast_channel *chan)
2400 {
2401         struct ast_channel *cur = NULL;
2402         int res = -1;
2403
2404         while ((cur = ast_channel_walk_locked(cur)) != NULL) {
2405                 if (!cur->pbx && 
2406                         (cur != chan) &&
2407                         (chan->pickupgroup & cur->callgroup) &&
2408                         ((cur->_state == AST_STATE_RINGING) ||
2409                          (cur->_state == AST_STATE_RING))) {
2410                                 break;
2411                 }
2412                 ast_channel_unlock(cur);
2413         }
2414         if (cur) {
2415                 if (option_debug)
2416                         ast_log(LOG_DEBUG, "Call pickup on chan '%s' by '%s'\n",cur->name, chan->name);
2417                 res = ast_answer(chan);
2418                 if (res)
2419                         ast_log(LOG_WARNING, "Unable to answer '%s'\n", chan->name);
2420                 res = ast_queue_control(chan, AST_CONTROL_ANSWER);
2421                 if (res)
2422                         ast_log(LOG_WARNING, "Unable to queue answer on '%s'\n", chan->name);
2423                 res = ast_channel_masquerade(cur, chan);
2424                 if (res)
2425                         ast_log(LOG_WARNING, "Unable to masquerade '%s' into '%s'\n", chan->name, cur->name);           /* Done */
2426                 ast_channel_unlock(cur);
2427         } else  {
2428                 if (option_debug)
2429                         ast_log(LOG_DEBUG, "No call pickup possible...\n");
2430         }
2431         return res;
2432 }
2433
2434 /*! \brief Add parking hints for all defined parking lots */
2435 static void park_add_hints(char *context, int start, int stop)
2436 {
2437         int numext;
2438         char device[AST_MAX_EXTENSION];
2439         char exten[10];
2440
2441         for (numext = start; numext <= stop; numext++) {
2442                 snprintf(exten, sizeof(exten), "%d", numext);
2443                 snprintf(device, sizeof(device), "park:%s@%s", exten, context);
2444                 ast_add_extension(context, 1, exten, PRIORITY_HINT, NULL, NULL, device, NULL, NULL, registrar);
2445         }
2446 }
2447
2448
2449 static int load_config(void) 
2450 {
2451         int start = 0, end = 0;
2452         int res;
2453         struct ast_context *con = NULL;
2454         struct ast_config *cfg = NULL;
2455         struct ast_variable *var = NULL;
2456         char old_parking_ext[AST_MAX_EXTENSION];
2457         char old_parking_con[AST_MAX_EXTENSION] = "";
2458
2459         if (!ast_strlen_zero(parking_con)) {
2460                 strcpy(old_parking_ext, parking_ext);
2461                 strcpy(old_parking_con, parking_con);
2462         } 
2463
2464         /* Reset to defaults */
2465         strcpy(parking_con, "parkedcalls");
2466         strcpy(parking_con_dial, "park-dial");
2467         strcpy(parking_ext, "700");
2468         strcpy(pickup_ext, "*8");
2469         strcpy(parkmohclass, "default");
2470         courtesytone[0] = '\0';
2471         strcpy(xfersound, "beep");
2472         strcpy(xferfailsound, "pbx-invalid");
2473         parking_start = 701;
2474         parking_stop = 750;
2475         parkfindnext = 0;
2476         adsipark = 0;
2477         comebacktoorigin = 1;
2478         parkaddhints = 0;
2479         parkedcalltransfers = 0;
2480         parkedcallreparking = 0;
2481
2482         transferdigittimeout = DEFAULT_TRANSFER_DIGIT_TIMEOUT;
2483         featuredigittimeout = DEFAULT_FEATURE_DIGIT_TIMEOUT;
2484         atxfernoanswertimeout = DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER;
2485         atxferloopdelay = DEFAULT_ATXFER_LOOP_DELAY;
2486         atxferdropcall = DEFAULT_ATXFER_DROP_CALL;
2487         atxfercallbackretries = DEFAULT_ATXFER_CALLBACK_RETRIES;
2488
2489         cfg = ast_config_load("features.conf");
2490         if (!cfg) {
2491                 ast_log(LOG_WARNING,"Could not load features.conf\n");
2492                 return AST_MODULE_LOAD_DECLINE;
2493         }
2494         for (var = ast_variable_browse(cfg, "general"); var; var = var->next) {
2495                 if (!strcasecmp(var->name, "parkext")) {
2496                         ast_copy_string(parking_ext, var->value, sizeof(parking_ext));
2497                 } else if (!strcasecmp(var->name, "context")) {
2498                         ast_copy_string(parking_con, var->value, sizeof(parking_con));
2499                 } else if (!strcasecmp(var->name, "parkingtime")) {
2500                         if ((sscanf(var->value, "%d", &parkingtime) != 1) || (parkingtime < 1)) {
2501                                 ast_log(LOG_WARNING, "%s is not a valid parkingtime\n", var->value);
2502                                 parkingtime = DEFAULT_PARK_TIME;
2503                         } else
2504                                 parkingtime = parkingtime * 1000;
2505                 } else if (!strcasecmp(var->name, "parkpos")) {
2506                         if (sscanf(var->value, "%d-%d", &start, &end) != 2) {
2507                                 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);
2508                         } else {
2509                                 parking_start = start;
2510                                 parking_stop = end;
2511                         }
2512                 } else if (!strcasecmp(var->name, "findslot")) {
2513                         parkfindnext = (!strcasecmp(var->value, "next"));
2514                 } else if (!strcasecmp(var->name, "parkinghints")) {
2515                         parkaddhints = ast_true(var->value);
2516                 } else if (!strcasecmp(var->name, "parkedcalltransfers")) {
2517                         if (!strcasecmp(var->value, "both"))
2518                                 parkedcalltransfers = AST_FEATURE_FLAG_BYBOTH;
2519                         else if (!strcasecmp(var->value, "caller"))
2520                                 parkedcalltransfers = AST_FEATURE_FLAG_BYCALLER;
2521                         else if (!strcasecmp(var->value, "callee"))
2522                                 parkedcalltransfers = AST_FEATURE_FLAG_BYCALLEE;
2523                 } else if (!strcasecmp(var->name, "parkedcallreparking")) {
2524                         if (!strcasecmp(var->value, "both"))
2525                                 parkedcalltransfers = AST_FEATURE_FLAG_BYBOTH;
2526                         else if (!strcasecmp(var->value, "caller"))
2527                                 parkedcalltransfers = AST_FEATURE_FLAG_BYCALLER;
2528                         else if (!strcasecmp(var->value, "callee"))
2529                                 parkedcalltransfers = AST_FEATURE_FLAG_BYCALLEE;
2530                 } else if (!strcasecmp(var->name, "adsipark")) {
2531                         adsipark = ast_true(var->value);
2532                 } else if (!strcasecmp(var->name, "transferdigittimeout")) {
2533                         if ((sscanf(var->value, "%d", &transferdigittimeout) != 1) || (transferdigittimeout < 1)) {
2534                                 ast_log(LOG_WARNING, "%s is not a valid transferdigittimeout\n", var->value);
2535                                 transferdigittimeout = DEFAULT_TRANSFER_DIGIT_TIMEOUT;
2536                         } else
2537                                 transferdigittimeout = transferdigittimeout * 1000;
2538                 } else if (!strcasecmp(var->name, "featuredigittimeout")) {
2539                         if ((sscanf(var->value, "%d", &featuredigittimeout) != 1) || (featuredigittimeout < 1)) {
2540                                 ast_log(LOG_WARNING, "%s is not a valid featuredigittimeout\n", var->value);
2541                                 featuredigittimeout = DEFAULT_FEATURE_DIGIT_TIMEOUT;
2542                         }
2543                 } else if (!strcasecmp(var->name, "atxfernoanswertimeout")) {
2544                         if ((sscanf(var->value, "%d", &atxfernoanswertimeout) != 1) || (atxfernoanswertimeout < 1)) {
2545                                 ast_log(LOG_WARNING, "%s is not a valid atxfernoanswertimeout\n", var->value);
2546                                 atxfernoanswertimeout = DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER;
2547                         } else
2548                                 atxfernoanswertimeout = atxfernoanswertimeout * 1000;
2549                 } else if (!strcasecmp(var->name, "atxferloopdelay")) {
2550                         if ((sscanf(var->value, "%u", &atxferloopdelay) != 1)) {
2551                                 ast_log(LOG_WARNING, "%s is not a valid atxferloopdelay\n", var->value);
2552                                 atxferloopdelay = DEFAULT_ATXFER_LOOP_DELAY;
2553                         } else 
2554                                 atxferloopdelay *= 1000;
2555                 } else if (!strcasecmp(var->name, "atxferdropcall")) {
2556                         atxferdropcall = ast_true(var->value);
2557                 } else if (!strcasecmp(var->name, "atxfercallbackretries")) {
2558                         if ((sscanf(var->value, "%u", &atxferloopdelay) != 1)) {
2559                                 ast_log(LOG_WARNING, "%s is not a valid atxfercallbackretries\n", var->value);
2560                                 atxfercallbackretries = DEFAULT_ATXFER_CALLBACK_RETRIES;
2561                         }
2562                 } else if (!strcasecmp(var->name, "courtesytone")) {
2563                         ast_copy_string(courtesytone, var->value, sizeof(courtesytone));
2564                 }  else if (!strcasecmp(var->name, "parkedplay")) {
2565                         if (!strcasecmp(var->value, "both"))
2566                                 parkedplay = 2;
2567                         else if (!strcasecmp(var->value, "parked"))
2568                                 parkedplay = 1;
2569                         else
2570                                 parkedplay = 0;
2571                 } else if (!strcasecmp(var->name, "xfersound")) {
2572                         ast_copy_string(xfersound, var->value, sizeof(xfersound));
2573                 } else if (!strcasecmp(var->name, "xferfailsound")) {
2574                         ast_copy_string(xferfailsound, var->value, sizeof(xferfailsound));
2575                 } else if (!strcasecmp(var->name, "pickupexten")) {
2576                         ast_copy_string(pickup_ext, var->value, sizeof(pickup_ext));
2577                 } else if (!strcasecmp(var->name, "comebacktoorigin")) {
2578                         comebacktoorigin = ast_true(var->value);
2579                 } else if (!strcasecmp(var->name, "parkedmusicclass")) {
2580                         ast_copy_string(parkmohclass, var->value, sizeof(parkmohclass));
2581                 }
2582         }
2583
2584         unmap_features();
2585         for (var = ast_variable_browse(cfg, "featuremap"); var; var = var->next) {
2586                 if (remap_feature(var->name, var->value))
2587                         ast_log(LOG_NOTICE, "Unknown feature '%s'\n", var->name);
2588         }
2589
2590         /* Map a key combination to an application*/
2591         ast_unregister_features();
2592         for (var = ast_variable_browse(cfg, "applicationmap"); var; var = var->next) {
2593                 char *tmp_val = ast_strdupa(var->value);
2594                 char *exten, *activateon, *activatedby, *app, *app_args, *moh_class; 
2595                 struct ast_call_feature *feature;
2596
2597                 /* strsep() sets the argument to NULL if match not found, and it
2598                  * is safe to use it with a NULL argument, so we don't check
2599                  * between calls.
2600                  */
2601                 exten = strsep(&tmp_val,",");
2602                 activatedby = strsep(&tmp_val,",");
2603                 app = strsep(&tmp_val,",");
2604                 app_args = strsep(&tmp_val,",");
2605                 moh_class = strsep(&tmp_val,",");
2606
2607                 activateon = strsep(&activatedby, "/"); 
2608
2609                 /*! \todo XXX var_name or app_args ? */
2610                 if (ast_strlen_zero(app) || ast_strlen_zero(exten) || ast_strlen_zero(activateon) || ast_strlen_zero(var->name)) {
2611                         ast_log(LOG_NOTICE, "Please check the feature Mapping Syntax, either extension, name, or app aren't provided %s %s %s %s\n",
2612                                 app, exten, activateon, var->name);
2613                         continue;
2614                 }
2615
2616                 if ((feature = find_feature(var->name))) {
2617                         ast_log(LOG_WARNING, "Dynamic Feature '%s' specified more than once!\n", var->name);
2618                         continue;
2619                 }
2620                                 
2621                 if (!(feature = ast_calloc(1, sizeof(*feature))))
2622                         continue;                                       
2623
2624                 ast_copy_string(feature->sname, var->name, FEATURE_SNAME_LEN);
2625                 ast_copy_string(feature->app, app, FEATURE_APP_LEN);
2626                 ast_copy_string(feature->exten, exten, FEATURE_EXTEN_LEN);
2627                 
2628                 if (app_args) 
2629                         ast_copy_string(feature->app_args, app_args, FEATURE_APP_ARGS_LEN);
2630
2631                 if (moh_class)
2632                         ast_copy_string(feature->moh_class, moh_class, FEATURE_MOH_LEN);
2633                         
2634                 ast_copy_string(feature->exten, exten, sizeof(feature->exten));
2635                 feature->operation = feature_exec_app;
2636                 ast_set_flag(feature, AST_FEATURE_FLAG_NEEDSDTMF);
2637
2638                 /* Allow caller and calle to be specified for backwards compatability */
2639                 if (!strcasecmp(activateon, "self") || !strcasecmp(activateon, "caller"))
2640                         ast_set_flag(feature, AST_FEATURE_FLAG_ONSELF);
2641                 else if (!strcasecmp(activateon, "peer") || !strcasecmp(activateon, "callee"))
2642                         ast_set_flag(feature, AST_FEATURE_FLAG_ONPEER);
2643                 else {
2644                         ast_log(LOG_NOTICE, "Invalid 'ActivateOn' specification for feature '%s',"
2645                                 " must be 'self', or 'peer'\n", var->name);
2646                         continue;
2647                 }
2648
2649                 if (ast_strlen_zero(activatedby))
2650                         ast_set_flag(feature, AST_FEATURE_FLAG_BYBOTH);
2651                 else if (!strcasecmp(activatedby, "caller"))
2652                         ast_set_flag(feature, AST_FEATURE_FLAG_BYCALLER);
2653                 else if (!strcasecmp(activatedby, "callee"))
2654                         ast_set_flag(feature, AST_FEATURE_FLAG_BYCALLEE);
2655                 else if (!strcasecmp(activatedby, "both"))
2656                         ast_set_flag(feature, AST_FEATURE_FLAG_BYBOTH);
2657                 else {
2658                         ast_log(LOG_NOTICE, "Invalid 'ActivatedBy' specification for feature '%s',"
2659                                 " must be 'caller', or 'callee', or 'both'\n", var->name);
2660                         continue;
2661                 }
2662
2663                 ast_register_feature(feature);
2664                         
2665                 if (option_verbose >= 1)
2666                         ast_verbose(VERBOSE_PREFIX_2 "Mapping Feature '%s' to app '%s(%s)' with code '%s'\n", var->name, app, app_args, exten);  
2667         }        
2668         ast_config_destroy(cfg);
2669
2670         /* Remove the old parking extension */
2671         if (!ast_strlen_zero(old_parking_con) && (con = ast_context_find(old_parking_con)))     {
2672                 if(ast_context_remove_extension2(con, old_parking_ext, 1, registrar))
2673                                 notify_metermaids(old_parking_ext, old_parking_con);
2674                 if (option_debug)
2675                         ast_log(LOG_DEBUG, "Removed old parking extension %s@%s\n", old_parking_ext, old_parking_con);
2676         }
2677         
2678         if (!(con = ast_context_find(parking_con)) && !(con = ast_context_create(NULL, parking_con, registrar))) {
2679                 ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", parking_con);
2680                 return -1;
2681         }
2682         res = ast_add_extension2(con, 1, ast_parking_ext(), 1, NULL, NULL, parkcall, NULL, NULL, registrar);
2683         if (parkaddhints)
2684                 park_add_hints(parking_con, parking_start, parking_stop);
2685         if (!res)
2686                 notify_metermaids(ast_parking_ext(), parking_con);
2687         return res;
2688
2689 }
2690
2691 static char *app_bridge = "Bridge";
2692 static char *bridge_synopsis = "Bridge two channels";
2693 static char *bridge_descrip =
2694 "Usage: Bridge(channel[|options])\n"
2695 "       Allows the ability to bridge two channels via the dialplan.\n"
2696 "The current channel is bridged to the specified 'channel'.\n"
2697 "The following options are supported:\n"
2698 "   p - Play a courtesy tone to 'channel'.\n"
2699 "BRIDGERESULT dial plan variable will contain SUCCESS, FAILURE, LOOP, NONEXISTENT or INCOMPATIBLE.\n";
2700
2701 enum {
2702         BRIDGE_OPT_PLAYTONE = (1 << 0),
2703 };
2704
2705 AST_APP_OPTIONS(bridge_exec_options, BEGIN_OPTIONS
2706         AST_APP_OPTION('p', BRIDGE_OPT_PLAYTONE)
2707 END_OPTIONS );
2708
2709 static int bridge_exec(struct ast_channel *chan, void *data)
2710 {
2711         struct ast_module_user *u;
2712         struct ast_channel *current_dest_chan, *final_dest_chan;
2713         char *tmp_data  = NULL;
2714         struct ast_flags opts = { 0, };
2715         struct ast_bridge_config bconfig = { { 0, }, };
2716
2717         AST_DECLARE_APP_ARGS(args,
2718                 AST_APP_ARG(dest_chan);
2719                 AST_APP_ARG(options);
2720         );
2721         
2722         if (ast_strlen_zero(data)) {
2723                 ast_log(LOG_WARNING, "Bridge require at least 1 argument specifying the other end of the bridge\n");
2724                 return -1;
2725         }
2726         
2727         u = ast_module_user_add(chan);
2728
2729         tmp_data = ast_strdupa(data);
2730         AST_STANDARD_APP_ARGS(args, tmp_data);
2731         if (!ast_strlen_zero(args.options))
2732                 ast_app_parse_options(bridge_exec_options, &opts, NULL, args.options);
2733
2734         /* avoid bridge with ourselves */
2735         if (!strncmp(chan->name, args.dest_chan, 
2736                 strlen(chan->name) < strlen(args.dest_chan) ? 
2737                 strlen(chan->name) : strlen(args.dest_chan))) {
2738                 ast_log(LOG_WARNING, "Unable to bridge channel %s with itself\n", chan->name);
2739                 manager_event(EVENT_FLAG_CALL, "BridgeExec",
2740                                         "Response: Failed\r\n"
2741                                         "Reason: Unable to bridge channel to itself\r\n"
2742                                         "Channel1: %s\r\n"
2743                                         "Channel2: %s\r\n",
2744                                         chan->name, args.dest_chan);
2745                 pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "LOOP");
2746                 ast_module_user_remove(u);
2747                 return 0;
2748         }
2749
2750         /* make sure we have a valid end point */
2751         if (!(current_dest_chan = ast_get_channel_by_name_prefix_locked(args.dest_chan, 
2752                 strlen(args.dest_chan)))) {
2753                 ast_log(LOG_WARNING, "Bridge failed because channel %s does not exists or we "
2754                         "cannot get its lock\n", args.dest_chan);
2755                 manager_event(EVENT_FLAG_CALL, "BridgeExec",
2756                                         "Response: Failed\r\n"
2757                                         "Reason: Cannot grab end point\r\n"
2758                                         "Channel1: %s\r\n"
2759                                         "Channel2: %s\r\n", chan->name, args.dest_chan);
2760                 pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "NONEXISTENT");
2761                 ast_module_user_remove(u);
2762                 return 0;
2763         }
2764         ast_mutex_unlock(&current_dest_chan->lock);
2765
2766         /* answer the channel if needed */
2767         if (current_dest_chan->_state != AST_STATE_UP)
2768                 ast_answer(current_dest_chan);
2769
2770         /* try to allocate a place holder where current_dest_chan will be placed */
2771         if (!(final_dest_chan = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL, 
2772                 NULL, NULL, 0, "Bridge/%s", current_dest_chan->name))) {
2773                 ast_log(LOG_WARNING, "Cannot create placeholder channel for chan %s\n", args.dest_chan);
2774                 manager_event(EVENT_FLAG_CALL, "BridgeExec",
2775                                         "Response: Failed\r\n"
2776                                         "Reason: cannot create placeholder\r\n"
2777                                         "Channel1: %s\r\n"
2778                                         "Channel2: %s\r\n", chan->name, args.dest_chan);
2779         }
2780         do_bridge_masquerade(current_dest_chan, final_dest_chan);
2781
2782         /* now current_dest_chan is a ZOMBIE and with softhangup set to 1 and final_dest_chan is our end point */
2783         /* try to make compatible, send error if we fail */
2784         if (ast_channel_make_compatible(chan, final_dest_chan) < 0) {
2785                 ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for bridge\n", chan->name, final_dest_chan->name);
2786                 manager_event(EVENT_FLAG_CALL, "BridgeExec",
2787                                         "Response: Failed\r\n"
2788                                         "Reason: Could not make channels compatible for bridge\r\n"
2789                                         "Channel1: %s\r\n"
2790                                         "Channel2: %s\r\n", chan->name, final_dest_chan->name);
2791                 ast_hangup(final_dest_chan); /* may be we should return this channel to the PBX? */
2792                 pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "INCOMPATIBLE");
2793                 ast_module_user_remove(u);
2794                 return 0;
2795         }
2796
2797         /* Report that the bridge will be successfull */
2798         manager_event(EVENT_FLAG_CALL, "BridgeExec",
2799                                 "Response: Success\r\n"
2800                                 "Channel1: %s\r\n"
2801                                 "Channel2: %s\r\n", chan->name, final_dest_chan->name);
2802
2803         /* we have 2 valid channels to bridge, now it is just a matter of setting up the bridge config and starting the bridge */       
2804         if (ast_test_flag(&opts, BRIDGE_OPT_PLAYTONE) && !ast_strlen_zero(xfersound)) {
2805                 if (!ast_streamfile(final_dest_chan, xfersound, final_dest_chan->language)) {
2806                         if (ast_waitstream(final_dest_chan, "") < 0)
2807                                 ast_log(LOG_WARNING, "Failed to play courtesy tone on %s\n", final_dest_chan->name);
2808                 }
2809         }
2810         
2811         /* do the bridge */
2812         ast_bridge_call(chan, final_dest_chan, &bconfig);
2813
2814         /* the bridge has ended, set BRIDGERESULT to SUCCESS. If the other channel has not been hung up, return it to the PBX */
2815         pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "SUCCESS");
2816         if (!ast_check_hangup(final_dest_chan)) {
2817                 if (option_debug) {
2818                         ast_log(LOG_DEBUG, "starting new PBX in %s,%s,%d for chan %s\n", 
2819                         final_dest_chan->context, final_dest_chan->exten, 
2820                         final_dest_chan->priority, final_dest_chan->name);
2821                 }
2822
2823                 if (ast_pbx_start(final_dest_chan) != AST_PBX_SUCCESS) {
2824                         ast_log(LOG_WARNING, "FAILED continuing PBX on dest chan %s\n", final_dest_chan->name);
2825                         ast_hangup(final_dest_chan);
2826                 } else if (option_debug)
2827                         ast_log(LOG_DEBUG, "SUCCESS continuing PBX on chan %s\n", final_dest_chan->name);
2828         } else {
2829                 if (option_debug)
2830                         ast_log(LOG_DEBUG, "hangup chan %s since the other endpoint has hung up\n", final_dest_chan->name);
2831                 ast_hangup(final_dest_chan);
2832         }
2833
2834         ast_module_user_remove(u);
2835
2836         return 0;
2837 }
2838
2839 static int reload(void)
2840 {
2841         return load_config();
2842 }
2843
2844 static int load_module(void)
2845 {
2846         int res;
2847
2848         ast_register_application(app_bridge, bridge_exec, bridge_synopsis, bridge_descrip);     
2849
2850         memset(parking_ext, 0, sizeof(parking_ext));
2851         memset(parking_con, 0, sizeof(parking_con));
2852
2853         if ((res = load_config()))
2854                 return res;
2855         ast_cli_register_multiple(cli_features, sizeof(cli_features) / sizeof(struct ast_cli_entry));
2856         ast_pthread_create(&parking_thread, NULL, do_parking_thread, NULL);
2857         res = ast_register_application(parkedcall, park_exec, synopsis, descrip);
2858         if (!res)
2859                 res = ast_register_application(parkcall, park_call_exec, synopsis2, descrip2);
2860         if (!res) {
2861                 ast_manager_register("ParkedCalls", 0, manager_parking_status, "List parked calls");
2862                 ast_manager_register2("Park", EVENT_FLAG_CALL, manager_park,
2863                         "Park a channel", mandescr_park); 
2864                 ast_manager_register2("Bridge", EVENT_FLAG_COMMAND, action_bridge, "Bridge two channels already in the PBX", mandescr_bridge);
2865         }
2866
2867         res |= ast_devstate_prov_add("Park", metermaidstate);
2868
2869         return res;
2870 }
2871
2872
2873 static int unload_module(void)
2874 {
2875         ast_module_user_hangup_all();
2876
2877         ast_manager_unregister("ParkedCalls");
2878         ast_manager_unregister("Bridge");
2879         ast_manager_unregister("Park");
2880         ast_cli_unregister_multiple(cli_features, sizeof(cli_features) / sizeof(struct ast_cli_entry));
2881         ast_unregister_application(parkcall);
2882         ast_unregister_application(app_bridge);
2883         ast_devstate_prov_del("Park");
2884         return ast_unregister_application(parkedcall);
2885 }
2886
2887 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "Call Features Resource",
2888                 .load = load_module,