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