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