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