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