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