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