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