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