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