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