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