Merged revisions 107646 via svnmerge from
[asterisk/asterisk.git] / main / features.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2008, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file
20  *
21  * \brief Routines implementing call features as call pickup, parking and transfer
22  *
23  * \author Mark Spencer <markster@digium.com> 
24  */
25
26 #include "asterisk.h"
27
28 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
29
30 #include "asterisk/_private.h"
31
32 #include <pthread.h>
33 #include <sys/time.h>
34 #include <sys/signal.h>
35 #include <netinet/in.h>
36
37 #include "asterisk/lock.h"
38 #include "asterisk/file.h"
39 #include "asterisk/channel.h"
40 #include "asterisk/pbx.h"
41 #include "asterisk/causes.h"
42 #include "asterisk/module.h"
43 #include "asterisk/translate.h"
44 #include "asterisk/app.h"
45 #include "asterisk/say.h"
46 #include "asterisk/features.h"
47 #include "asterisk/musiconhold.h"
48 #include "asterisk/config.h"
49 #include "asterisk/cli.h"
50 #include "asterisk/manager.h"
51 #include "asterisk/utils.h"
52 #include "asterisk/adsi.h"
53 #include "asterisk/devicestate.h"
54 #include "asterisk/monitor.h"
55 #include "asterisk/audiohook.h"
56 #include "asterisk/global_datastores.h"
57
58 #define DEFAULT_PARK_TIME 45000
59 #define DEFAULT_TRANSFER_DIGIT_TIMEOUT 3000
60 #define DEFAULT_FEATURE_DIGIT_TIMEOUT 500
61 #define DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER 15000
62 #define DEFAULT_ATXFER_DROP_CALL 0
63 #define DEFAULT_ATXFER_LOOP_DELAY 10000
64 #define DEFAULT_ATXFER_CALLBACK_RETRIES 2
65
66 #define AST_MAX_WATCHERS 256
67
68 enum {
69         AST_FEATURE_FLAG_NEEDSDTMF = (1 << 0),
70         AST_FEATURE_FLAG_ONPEER =    (1 << 1),
71         AST_FEATURE_FLAG_ONSELF =    (1 << 2),
72         AST_FEATURE_FLAG_BYCALLEE =  (1 << 3),
73         AST_FEATURE_FLAG_BYCALLER =  (1 << 4),
74         AST_FEATURE_FLAG_BYBOTH  =   (3 << 3),
75 };
76
77 struct feature_group_exten {
78         AST_LIST_ENTRY(feature_group_exten) entry;
79         AST_DECLARE_STRING_FIELDS(
80                 AST_STRING_FIELD(exten);
81         );
82         struct ast_call_feature *feature;
83 };
84
85 struct feature_group {
86         AST_LIST_ENTRY(feature_group) entry;
87         AST_DECLARE_STRING_FIELDS(
88                 AST_STRING_FIELD(gname);
89         );
90         AST_LIST_HEAD_NOLOCK(, feature_group_exten) features;
91 };
92
93 static AST_RWLIST_HEAD_STATIC(feature_groups, feature_group);
94
95 static char *parkedcall = "ParkedCall";
96
97 static int parkaddhints = 0;                               /*!< Add parking hints automatically */
98 static int parkedcalltransfers = 0;                        /*!< Enable DTMF based transfers on bridge when picking up parked calls */
99 static int parkedcallreparking = 0;                        /*!< Enable DTMF based parking on bridge when picking up parked calls */
100 static int parkingtime = DEFAULT_PARK_TIME;                /*!< No more than 45 seconds parked before you do something with them */
101 static char parking_con[AST_MAX_EXTENSION];                /*!< Context for which parking is made accessible */
102 static char parking_con_dial[AST_MAX_EXTENSION];           /*!< Context for dialback for parking (KLUDGE) */
103 static char parking_ext[AST_MAX_EXTENSION];                /*!< Extension you type to park the call */
104 static char pickup_ext[AST_MAX_EXTENSION];                 /*!< Call pickup extension */
105 static char parkmohclass[MAX_MUSICCLASS];                  /*!< Music class used for parking */
106 static int parking_start;                                  /*!< First available extension for parking */
107 static int parking_stop;                                   /*!< Last available extension for parking */
108
109 static char courtesytone[256];                             /*!< Courtesy tone */
110 static int parkedplay = 0;                                 /*!< Who to play the courtesy tone to */
111 static char xfersound[256];                                /*!< Call transfer sound */
112 static char xferfailsound[256];                            /*!< Call transfer failure sound */
113
114 static int parking_offset;
115 static int parkfindnext;
116
117 static int adsipark;
118
119 static int transferdigittimeout;
120 static int featuredigittimeout;
121 static int comebacktoorigin = 1;
122
123 static int atxfernoanswertimeout;
124 static unsigned int atxferdropcall;
125 static unsigned int atxferloopdelay;
126 static unsigned int atxfercallbackretries;
127
128 static char *registrar = "features";               /*!< Registrar for operations */
129
130 /* module and CLI command definitions */
131 static char *synopsis = "Answer a parked call";
132
133 static char *descrip = "ParkedCall(exten): "
134 "Used to connect to a parked call.  This application is always\n"
135 "registered internally and does not need to be explicitly added\n"
136 "into the dialplan, although you should include the 'parkedcalls'\n"
137 "context.  If no extension is provided, then the first available\n"
138 "parked call will be acquired.\n";
139
140 static char *parkcall = "Park";
141
142 static char *synopsis2 = "Park yourself";
143
144 static char *descrip2 = "Park(): "
145 "Used to park yourself (typically in combination with a supervised\n"
146 "transfer to know the parking space). This application is always\n"
147 "registered internally and does not need to be explicitly added\n"
148 "into the dialplan, although you should include the 'parkedcalls'\n"
149 "context (or the context specified in features.conf).\n\n"
150 "If you set the PARKINGEXTEN variable to an extension in your\n"
151 "parking context, Park() will park the call on that extension, unless\n"
152 "it already exists. In that case, execution will continue at next\n"
153 "priority.\n" ;
154
155 static struct ast_app *monitor_app = NULL;
156 static int monitor_ok = 1;
157
158 static struct ast_app *mixmonitor_app = NULL;
159 static int mixmonitor_ok = 1;
160
161 static struct ast_app *stopmixmonitor_app = NULL;
162 static int stopmixmonitor_ok = 1;
163
164 struct parkeduser {
165         struct ast_channel *chan;                   /*!< Parking channel */
166         struct timeval start;                       /*!< Time the parking started */
167         int parkingnum;                             /*!< Parking lot */
168         char parkingexten[AST_MAX_EXTENSION];       /*!< If set beforehand, parking extension used for this call */
169         char context[AST_MAX_CONTEXT];              /*!< Where to go if our parking time expires */
170         char exten[AST_MAX_EXTENSION];
171         int priority;
172         int parkingtime;                            /*!< Maximum length in parking lot before return */
173         int notquiteyet;
174         char peername[1024];
175         unsigned char moh_trys;
176         AST_LIST_ENTRY(parkeduser) list;
177 };
178
179 static AST_LIST_HEAD_STATIC(parkinglot, parkeduser);
180
181 static pthread_t parking_thread;
182
183 const char *ast_parking_ext(void)
184 {
185         return parking_ext;
186 }
187
188 const char *ast_pickup_ext(void)
189 {
190         return pickup_ext;
191 }
192
193 struct ast_bridge_thread_obj 
194 {
195         struct ast_bridge_config bconfig;
196         struct ast_channel *chan;
197         struct ast_channel *peer;
198         unsigned int return_to_pbx:1;
199 };
200
201
202
203 /*!
204  * \brief store context, extension and priority 
205  * \param chan, context, ext, pri
206 */
207 static void set_c_e_p(struct ast_channel *chan, const char *context, const char *ext, int pri)
208 {
209         ast_copy_string(chan->context, context, sizeof(chan->context));
210         ast_copy_string(chan->exten, ext, sizeof(chan->exten));
211         chan->priority = pri;
212 }
213
214 /*!
215  * \brief Check goto on transfer
216  * \param chan
217  *
218  * Check if channel has 'GOTO_ON_BLINDXFR' set, if not exit.
219  * When found make sure the types are compatible. Check if channel is valid
220  * if so start the new channel else hangup the call. 
221 */
222 static void check_goto_on_transfer(struct ast_channel *chan) 
223 {
224         struct ast_channel *xferchan;
225         const char *val = pbx_builtin_getvar_helper(chan, "GOTO_ON_BLINDXFR");
226         char *x, *goto_on_transfer;
227         struct ast_frame *f;
228
229         if (ast_strlen_zero(val))
230                 return;
231
232         goto_on_transfer = ast_strdupa(val);
233
234         if (!(xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, chan->name)))
235                 return;
236
237         for (x = goto_on_transfer; x && *x; x++) {
238                 if (*x == '^')
239                         *x = '|';
240         }
241         /* Make formats okay */
242         xferchan->readformat = chan->readformat;
243         xferchan->writeformat = chan->writeformat;
244         ast_channel_masquerade(xferchan, chan);
245         ast_parseable_goto(xferchan, goto_on_transfer);
246         xferchan->_state = AST_STATE_UP;
247         ast_clear_flag(xferchan, AST_FLAGS_ALL);        
248         xferchan->_softhangup = 0;
249         if ((f = ast_read(xferchan))) {
250                 ast_frfree(f);
251                 f = NULL;
252                 ast_pbx_start(xferchan);
253         } else {
254                 ast_hangup(xferchan);
255         }
256 }
257
258 static struct ast_channel *ast_feature_request_and_dial(struct ast_channel *caller, struct ast_channel *transferee, const char *type, int format, void *data, int timeout, int *outstate, const char *cid_num, const char *cid_name, int igncallerstate, const char *language);
259
260 /*!
261  * \brief bridge the call 
262  * \param data thread bridge.
263  *
264  * Set Last Data for respective channels, reset cdr for channels
265  * bridge call, check if we're going back to dialplan
266  * if not hangup both legs of the call
267 */
268 static void *ast_bridge_call_thread(void *data) 
269 {
270         struct ast_bridge_thread_obj *tobj = data;
271         int res;
272
273         tobj->chan->appl = !tobj->return_to_pbx ? "Transferred Call" : "ManagerBridge";
274         tobj->chan->data = tobj->peer->name;
275         tobj->peer->appl = !tobj->return_to_pbx ? "Transferred Call" : "ManagerBridge";
276         tobj->peer->data = tobj->chan->name;
277
278         if (tobj->chan->cdr) {
279                 ast_cdr_reset(tobj->chan->cdr, NULL);
280                 ast_cdr_setdestchan(tobj->chan->cdr, tobj->peer->name);
281         }
282         if (tobj->peer->cdr) {
283                 ast_cdr_reset(tobj->peer->cdr, NULL);
284                 ast_cdr_setdestchan(tobj->peer->cdr, tobj->chan->name);
285         }
286
287         ast_bridge_call(tobj->peer, tobj->chan, &tobj->bconfig);
288
289         if (tobj->return_to_pbx) {
290                 if (!ast_check_hangup(tobj->peer)) {
291                         ast_log(LOG_VERBOSE, "putting peer %s into PBX again\n", tobj->peer->name);
292                         res = ast_pbx_start(tobj->peer);
293                         if (res != AST_PBX_SUCCESS)
294                                 ast_log(LOG_WARNING, "FAILED continuing PBX on peer %s\n", tobj->peer->name);
295                 } else
296                         ast_hangup(tobj->peer);
297                 if (!ast_check_hangup(tobj->chan)) {
298                         ast_log(LOG_VERBOSE, "putting chan %s into PBX again\n", tobj->chan->name);
299                         res = ast_pbx_start(tobj->chan);
300                         if (res != AST_PBX_SUCCESS)
301                                 ast_log(LOG_WARNING, "FAILED continuing PBX on chan %s\n", tobj->chan->name);
302                 } else
303                         ast_hangup(tobj->chan);
304         } else {
305                 ast_hangup(tobj->chan);
306                 ast_hangup(tobj->peer);
307         }
308
309         ast_free(tobj);
310
311         return NULL;
312 }
313
314 /*!
315  * \brief create thread for the parked call
316  * \param data
317  *
318  * Create thread and attributes, call ast_bridge_call_thread
319 */
320 static void ast_bridge_call_thread_launch(void *data) 
321 {
322         pthread_t thread;
323         pthread_attr_t attr;
324         struct sched_param sched;
325
326         pthread_attr_init(&attr);
327         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
328         ast_pthread_create(&thread, &attr,ast_bridge_call_thread, data);
329         pthread_attr_destroy(&attr);
330         memset(&sched, 0, sizeof(sched));
331         pthread_setschedparam(thread, SCHED_RR, &sched);
332 }
333
334 /*!
335  * \brief Announce call parking by ADSI
336  * \param chan .
337  * \param parkingexten .
338  * Create message to show for ADSI, display message.
339  * \retval 0 on success.
340  * \retval -1 on failure.
341 */
342 static int adsi_announce_park(struct ast_channel *chan, char *parkingexten)
343 {
344         int res;
345         int justify[5] = {ADSI_JUST_CENT, ADSI_JUST_CENT, ADSI_JUST_CENT, ADSI_JUST_CENT};
346         char tmp[256];
347         char *message[5] = {NULL, NULL, NULL, NULL, NULL};
348
349         snprintf(tmp, sizeof(tmp), "Parked on %s", parkingexten);
350         message[0] = tmp;
351         res = ast_adsi_load_session(chan, NULL, 0, 1);
352         if (res == -1)
353                 return res;
354         return ast_adsi_print(chan, message, justify, 1);
355 }
356
357 /*! \brief Notify metermaids that we've changed an extension */
358 static void notify_metermaids(const char *exten, char *context, enum ast_device_state state)
359 {
360         ast_debug(4, "Notification of state change to metermaids %s@%s\n to state '%s'", 
361                 exten, context, devstate2str(state));
362
363         ast_devstate_changed(state, "park:%s@%s", exten, context);
364 }
365
366 /*! \brief metermaids callback from devicestate.c */
367 static enum ast_device_state metermaidstate(const char *data)
368 {
369         char *context;
370         char *exten;
371
372         context = ast_strdupa(data);
373
374         exten = strsep(&context, "@");
375         if (!context)
376                 return AST_DEVICE_INVALID;
377         
378         ast_debug(4, "Checking state of exten %s in context %s\n", exten, context);
379
380         if (!ast_exists_extension(NULL, context, exten, 1, NULL))
381                 return AST_DEVICE_NOT_INUSE;
382
383         return AST_DEVICE_INUSE;
384 }
385
386 /* Park a call */
387 static int park_call_full(struct ast_channel *chan, struct ast_channel *peer, int timeout, int *extout, char *orig_chan_name)
388 {
389         struct parkeduser *pu, *cur;
390         int i, x = -1, parking_range;
391         struct ast_context *con;
392         const char *parkingexten;
393         
394         /* Allocate memory for parking data */
395         if (!(pu = ast_calloc(1, sizeof(*pu)))) 
396                 return -1;
397
398         /* Lock parking lot */
399         AST_LIST_LOCK(&parkinglot);
400         /* Check for channel variable PARKINGEXTEN */
401         parkingexten = pbx_builtin_getvar_helper(chan, "PARKINGEXTEN");
402         if (!ast_strlen_zero(parkingexten)) {
403                 if (ast_exists_extension(NULL, parking_con, parkingexten, 1, NULL)) {
404                         AST_LIST_UNLOCK(&parkinglot);
405                         ast_free(pu);
406                         ast_log(LOG_WARNING, "Requested parking extension already exists: %s@%s\n", parkingexten, parking_con);
407                         return 1;       /* Continue execution if possible */
408                 }
409                 ast_copy_string(pu->parkingexten, parkingexten, sizeof(pu->parkingexten));
410                 x = atoi(parkingexten);
411         } else {
412                 /* Select parking space within range */
413                 parking_range = parking_stop - parking_start+1;
414                 for (i = 0; i < parking_range; i++) {
415                         x = (i + parking_offset) % parking_range + parking_start;
416                         AST_LIST_TRAVERSE(&parkinglot, cur, list) {
417                                 if (cur->parkingnum == x)
418                                         break;
419                         }
420                         if (!cur)
421                                 break;
422                 }
423
424                 if (!(i < parking_range)) {
425                         ast_log(LOG_WARNING, "No more parking spaces\n");
426                         ast_free(pu);
427                         AST_LIST_UNLOCK(&parkinglot);
428                         return -1;
429                 }
430                 /* Set pointer for next parking */
431                 if (parkfindnext) 
432                         parking_offset = x - parking_start + 1;
433         }
434         
435         chan->appl = "Parked Call";
436         chan->data = NULL; 
437
438         pu->chan = chan;
439         
440         /* Put the parked channel on hold if we have two different channels */
441         if (chan != peer) {
442                 ast_indicate_data(pu->chan, AST_CONTROL_HOLD, 
443                         S_OR(parkmohclass, NULL),
444                         !ast_strlen_zero(parkmohclass) ? strlen(parkmohclass) + 1 : 0);
445         }
446         
447         pu->start = ast_tvnow();
448         pu->parkingnum = x;
449         pu->parkingtime = (timeout > 0) ? timeout : parkingtime;
450         if (extout)
451                 *extout = x;
452
453         if (peer) 
454                 ast_copy_string(pu->peername, peer->name, sizeof(pu->peername));
455
456         /* Remember what had been dialed, so that if the parking
457            expires, we try to come back to the same place */
458         ast_copy_string(pu->context, S_OR(chan->macrocontext, chan->context), sizeof(pu->context));
459         ast_copy_string(pu->exten, S_OR(chan->macroexten, chan->exten), sizeof(pu->exten));
460         pu->priority = chan->macropriority ? chan->macropriority : chan->priority;
461         AST_LIST_INSERT_TAIL(&parkinglot, pu, list);
462
463         /* If parking a channel directly, don't quiet yet get parking running on it */
464         if (peer == chan) 
465                 pu->notquiteyet = 1;
466         AST_LIST_UNLOCK(&parkinglot);
467         /* Wake up the (presumably select()ing) thread */
468         pthread_kill(parking_thread, SIGURG);
469         ast_verb(2, "Parked %s on %d@%s. Will timeout back to extension [%s] %s, %d in %d seconds\n", pu->chan->name, pu->parkingnum, parking_con, pu->context, pu->exten, pu->priority, (pu->parkingtime/1000));
470
471         if (pu->parkingnum != -1)
472                 snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", x);
473         manager_event(EVENT_FLAG_CALL, "ParkedCall",
474                 "Exten: %s\r\n"
475                 "Channel: %s\r\n"
476                 "From: %s\r\n"
477                 "Timeout: %ld\r\n"
478                 "CallerIDNum: %s\r\n"
479                 "CallerIDName: %s\r\n",
480                 pu->parkingexten, pu->chan->name, peer ? peer->name : "",
481                 (long)pu->start.tv_sec + (long)(pu->parkingtime/1000) - (long)time(NULL),
482                 S_OR(pu->chan->cid.cid_num, "<unknown>"),
483                 S_OR(pu->chan->cid.cid_name, "<unknown>")
484                 );
485
486         if (peer && adsipark && ast_adsi_available(peer)) {
487                 adsi_announce_park(peer, pu->parkingexten);     /* Only supports parking numbers */
488                 ast_adsi_unload_session(peer);
489         }
490
491         con = ast_context_find_or_create(NULL, NULL, parking_con, registrar);
492         if (!con)       /* Still no context? Bad */
493                 ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", parking_con);
494         /* Tell the peer channel the number of the parking space */
495         if (peer && ((pu->parkingnum != -1 && ast_strlen_zero(orig_chan_name)) || !strcasecmp(peer->name, orig_chan_name))) { /* Only say number if it's a number and the channel hasn't been masqueraded away */
496                 /* If a channel is masqueraded into peer while playing back the parking slot number do not continue playing it back. This is the case if an attended transfer occurs. */
497                 ast_set_flag(peer, AST_FLAG_MASQ_NOSTREAM);
498                 ast_say_digits(peer, pu->parkingnum, "", peer->language);
499                 ast_clear_flag(peer, AST_FLAG_MASQ_NOSTREAM);
500         }
501         if (con) {
502                 if (!ast_add_extension2(con, 1, pu->parkingexten, 1, NULL, NULL, parkedcall, ast_strdup(pu->parkingexten), ast_free_ptr, registrar))
503                         notify_metermaids(pu->parkingexten, parking_con, AST_DEVICE_INUSE);
504         }
505         if (pu->notquiteyet) {
506                 /* Wake up parking thread if we're really done */
507                 ast_indicate_data(pu->chan, AST_CONTROL_HOLD, 
508                         S_OR(parkmohclass, NULL),
509                         !ast_strlen_zero(parkmohclass) ? strlen(parkmohclass) + 1 : 0);
510                 pu->notquiteyet = 0;
511                 pthread_kill(parking_thread, SIGURG);
512         }
513         return 0;
514 }
515
516 /*! \brief Park a call */
517 int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeout, int *extout)
518 {
519         return park_call_full(chan, peer, timeout, extout, NULL);
520 }
521
522 /* Park call via masquraded channel */
523 int ast_masq_park_call(struct ast_channel *rchan, struct ast_channel *peer, int timeout, int *extout)
524 {
525         struct ast_channel *chan;
526         struct ast_frame *f;
527         char *orig_chan_name = NULL;
528
529         /* Make a new, fake channel that we'll use to masquerade in the real one */
530         if (!(chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, rchan->accountcode, rchan->exten, rchan->context, rchan->amaflags, "Parked/%s",rchan->name))) {
531                 ast_log(LOG_WARNING, "Unable to create parked channel\n");
532                 return -1;
533         }
534
535         /* Make formats okay */
536         chan->readformat = rchan->readformat;
537         chan->writeformat = rchan->writeformat;
538         ast_channel_masquerade(chan, rchan);
539
540         /* Setup the extensions and such */
541         set_c_e_p(chan, rchan->context, rchan->exten, rchan->priority);
542
543         /* Make the masq execute */
544         if ((f = ast_read(chan)))
545                 ast_frfree(f);
546
547         orig_chan_name = ast_strdupa(chan->name);
548
549         park_call_full(chan, peer, timeout, extout, orig_chan_name);
550
551         return 0;
552 }
553
554
555 #define FEATURE_RETURN_HANGUP           -1
556 #define FEATURE_RETURN_SUCCESSBREAK      0
557 #define FEATURE_RETURN_PBX_KEEPALIVE    AST_PBX_KEEPALIVE
558 #define FEATURE_RETURN_NO_HANGUP_PEER   AST_PBX_NO_HANGUP_PEER
559 #define FEATURE_RETURN_PASSDIGITS        21
560 #define FEATURE_RETURN_STOREDIGITS       22
561 #define FEATURE_RETURN_SUCCESS           23
562 #define FEATURE_RETURN_KEEPTRYING    24
563
564 #define FEATURE_SENSE_CHAN      (1 << 0)
565 #define FEATURE_SENSE_PEER      (1 << 1)
566
567 /*! 
568  * \brief set caller and callee according to the direction 
569  * \param caller, callee, peer, chan, sense
570  *
571  * Detect who triggered feature and set callee/caller variables accordingly
572 */
573 static void set_peers(struct ast_channel **caller, struct ast_channel **callee,
574         struct ast_channel *peer, struct ast_channel *chan, int sense)
575 {
576         if (sense == FEATURE_SENSE_PEER) {
577                 *caller = peer;
578                 *callee = chan;
579         } else {
580                 *callee = peer;
581                 *caller = chan;
582         }
583 }
584
585 /*! 
586  * \brief support routing for one touch call parking
587  * \param chan channel parking call
588  * \param peer channel to be parked
589  * \param config unsed
590  * \param code unused
591  * \param sense feature options
592  *
593  * \param data
594  * Setup channel, set return exten,priority to 's,1'
595  * answer chan, sleep chan, park call
596 */
597 static int builtin_parkcall(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
598 {
599         struct ast_channel *parker;
600         struct ast_channel *parkee;
601         int res = 0;
602
603         set_peers(&parker, &parkee, peer, chan, sense);
604         /* Setup the exten/priority to be s/1 since we don't know
605            where this call should return */
606         strcpy(chan->exten, "s");
607         chan->priority = 1;
608         if (chan->_state != AST_STATE_UP)
609                 res = ast_answer(chan);
610         if (!res)
611                 res = ast_safe_sleep(chan, 1000);
612         if (!res)
613                 res = ast_park_call(parkee, parker, 0, NULL);
614
615         if (!res) {
616                 if (sense == FEATURE_SENSE_CHAN)
617                         res = AST_PBX_NO_HANGUP_PEER;
618                 else
619                         res = AST_PBX_KEEPALIVE;
620         }
621         return res;
622
623 }
624
625 /*!
626  * \brief Monitor a channel by DTMF
627  * \param chan channel requesting monitor
628  * \param peer channel to be monitored
629  * \param config
630  * \param code
631  * \param sense feature options
632  *
633  * \param data
634  * Check monitor app enabled, setup channels, both caller/callee chans not null
635  * get TOUCH_MONITOR variable for filename if exists, exec monitor app.
636  * \retval FEATURE_RETURN_SUCCESS on success.
637  * \retval -1 on error.
638 */
639 static int builtin_automonitor(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
640 {
641         char *caller_chan_id = NULL, *callee_chan_id = NULL, *args = NULL, *touch_filename = NULL;
642         int x = 0;
643         size_t len;
644         struct ast_channel *caller_chan, *callee_chan;
645
646         if (!monitor_ok) {
647                 ast_log(LOG_ERROR,"Cannot record the call. The monitor application is disabled.\n");
648                 return -1;
649         }
650
651         if (!monitor_app && !(monitor_app = pbx_findapp("Monitor"))) {
652                 monitor_ok = 0;
653                 ast_log(LOG_ERROR,"Cannot record the call. The monitor application is disabled.\n");
654                 return -1;
655         }
656
657         set_peers(&caller_chan, &callee_chan, peer, chan, sense);
658
659         if (!ast_strlen_zero(courtesytone)) {
660                 if (ast_autoservice_start(callee_chan))
661                         return -1;
662                 if (ast_stream_and_wait(caller_chan, courtesytone, "")) {
663                         ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
664                         ast_autoservice_stop(callee_chan);
665                         return -1;
666                 }
667                 if (ast_autoservice_stop(callee_chan))
668                         return -1;
669         }
670         
671         if (callee_chan->monitor) {
672                 ast_verb(4, "User hit '%s' to stop recording call.\n", code);
673                 callee_chan->monitor->stop(callee_chan, 1);
674                 return FEATURE_RETURN_SUCCESS;
675         }
676
677         if (caller_chan && callee_chan) {
678                 const char *touch_format = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_FORMAT");
679                 const char *touch_monitor = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR");
680                 const char *touch_monitor_prefix = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_PREFIX");
681
682                 if (!touch_format)
683                         touch_format = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR_FORMAT");
684
685                 if (!touch_monitor)
686                         touch_monitor = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR");
687         
688                 if (!touch_monitor_prefix)
689                         touch_monitor_prefix = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR_PREFIX");
690         
691                 if (touch_monitor) {
692                         len = strlen(touch_monitor) + 50;
693                         args = alloca(len);
694                         touch_filename = alloca(len);
695                         snprintf(touch_filename, len, "%s-%ld-%s", S_OR(touch_monitor_prefix, "auto"), (long)time(NULL), touch_monitor);
696                         snprintf(args, len, "%s,%s,m", S_OR(touch_format, "wav"), touch_filename);
697                 } else {
698                         caller_chan_id = ast_strdupa(S_OR(caller_chan->cid.cid_num, caller_chan->name));
699                         callee_chan_id = ast_strdupa(S_OR(callee_chan->cid.cid_num, callee_chan->name));
700                         len = strlen(caller_chan_id) + strlen(callee_chan_id) + 50;
701                         args = alloca(len);
702                         touch_filename = alloca(len);
703                         snprintf(touch_filename, len, "%s-%ld-%s-%s", S_OR(touch_monitor_prefix, "auto"), (long)time(NULL), caller_chan_id, callee_chan_id);
704                         snprintf(args, len, "%s,%s,m", S_OR(touch_format, "wav"), touch_filename);
705                 }
706
707                 for(x = 0; x < strlen(args); x++) {
708                         if (args[x] == '/')
709                                 args[x] = '-';
710                 }
711                 
712                 ast_verb(4, "User hit '%s' to record call. filename: %s\n", code, args);
713
714                 pbx_exec(callee_chan, monitor_app, args);
715                 pbx_builtin_setvar_helper(callee_chan, "TOUCH_MONITOR_OUTPUT", touch_filename);
716                 pbx_builtin_setvar_helper(caller_chan, "TOUCH_MONITOR_OUTPUT", touch_filename);
717         
718                 return FEATURE_RETURN_SUCCESS;
719         }
720         
721         ast_log(LOG_NOTICE,"Cannot record the call. One or both channels have gone away.\n");   
722         return -1;
723 }
724
725 static int builtin_automixmonitor(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
726 {
727         char *caller_chan_id = NULL, *callee_chan_id = NULL, *args = NULL, *touch_filename = NULL;
728         int x = 0;
729         size_t len;
730         struct ast_channel *caller_chan, *callee_chan;
731         const char *mixmonitor_spy_type = "MixMonitor";
732         int count = 0;
733
734         if (!mixmonitor_ok) {
735                 ast_log(LOG_ERROR,"Cannot record the call. The mixmonitor application is disabled.\n");
736                 return -1;
737         }
738
739         if (!(mixmonitor_app = pbx_findapp("MixMonitor"))) {
740                 mixmonitor_ok = 0;
741                 ast_log(LOG_ERROR,"Cannot record the call. The mixmonitor application is disabled.\n");
742                 return -1;
743         }
744
745         set_peers(&caller_chan, &callee_chan, peer, chan, sense);
746
747         if (!ast_strlen_zero(courtesytone)) {
748                 if (ast_autoservice_start(callee_chan))
749                         return -1;
750                 if (ast_stream_and_wait(caller_chan, courtesytone, "")) {
751                         ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
752                         ast_autoservice_stop(callee_chan);
753                         return -1;
754                 }
755                 if (ast_autoservice_stop(callee_chan))
756                         return -1;
757         }
758
759         ast_channel_lock(callee_chan);
760         count = ast_channel_audiohook_count_by_source(callee_chan, mixmonitor_spy_type, AST_AUDIOHOOK_TYPE_SPY);
761         ast_channel_unlock(callee_chan);
762
763         // This means a mixmonitor is attached to the channel, running or not is unknown.
764         if (count > 0) {
765                 
766                 ast_verb(3, "User hit '%s' to stop recording call.\n", code);
767
768                 //Make sure they are running
769                 ast_channel_lock(callee_chan);
770                 count = ast_channel_audiohook_count_by_source_running(callee_chan, mixmonitor_spy_type, AST_AUDIOHOOK_TYPE_SPY);
771                 ast_channel_unlock(callee_chan);
772                 if (count > 0) {
773                         if (!stopmixmonitor_ok) {
774                                 ast_log(LOG_ERROR,"Cannot stop recording the call. The stopmixmonitor application is disabled.\n");
775                                 return -1;
776                         }
777                         if (!(stopmixmonitor_app = pbx_findapp("StopMixMonitor"))) {
778                                 stopmixmonitor_ok = 0;
779                                 ast_log(LOG_ERROR,"Cannot stop recording the call. The stopmixmonitor application is disabled.\n");
780                                 return -1;
781                         } else {
782                                 pbx_exec(callee_chan, stopmixmonitor_app, "");
783                                 return FEATURE_RETURN_SUCCESS;
784                         }
785                 }
786                 
787                 ast_log(LOG_WARNING,"Stopped MixMonitors are attached to the channel.\n");      
788         }                       
789
790         if (caller_chan && callee_chan) {
791                 const char *touch_format = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MIXMONITOR_FORMAT");
792                 const char *touch_monitor = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MIXMONITOR");
793
794                 if (!touch_format)
795                         touch_format = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MIXMONITOR_FORMAT");
796
797                 if (!touch_monitor)
798                         touch_monitor = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MIXMONITOR");
799
800                 if (touch_monitor) {
801                         len = strlen(touch_monitor) + 50;
802                         args = alloca(len);
803                         touch_filename = alloca(len);
804                         snprintf(touch_filename, len, "auto-%ld-%s", (long)time(NULL), touch_monitor);
805                         snprintf(args, len, "%s.%s,b", touch_filename, (touch_format) ? touch_format : "wav");
806                 } else {
807                         caller_chan_id = ast_strdupa(S_OR(caller_chan->cid.cid_num, caller_chan->name));
808                         callee_chan_id = ast_strdupa(S_OR(callee_chan->cid.cid_num, callee_chan->name));
809                         len = strlen(caller_chan_id) + strlen(callee_chan_id) + 50;
810                         args = alloca(len);
811                         touch_filename = alloca(len);
812                         snprintf(touch_filename, len, "auto-%ld-%s-%s", (long)time(NULL), caller_chan_id, callee_chan_id);
813                         snprintf(args, len, "%s.%s,b", touch_filename, S_OR(touch_format, "wav"));
814                 }
815
816                 for( x = 0; x < strlen(args); x++) {
817                         if (args[x] == '/')
818                                 args[x] = '-';
819                 }
820
821                 ast_verb(3, "User hit '%s' to record call. filename: %s\n", code, touch_filename);
822
823                 pbx_exec(callee_chan, mixmonitor_app, args);
824                 pbx_builtin_setvar_helper(callee_chan, "TOUCH_MIXMONITOR_OUTPUT", touch_filename);
825                 pbx_builtin_setvar_helper(caller_chan, "TOUCH_MIXMONITOR_OUTPUT", touch_filename);
826                 return FEATURE_RETURN_SUCCESS;
827         
828         }
829
830         ast_log(LOG_NOTICE,"Cannot record the call. One or both channels have gone away.\n");
831         return -1;
832
833 }
834
835 static int builtin_disconnect(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
836 {
837         ast_verb(4, "User hit '%s' to disconnect call.\n", code);
838         return FEATURE_RETURN_HANGUP;
839 }
840
841 static int finishup(struct ast_channel *chan)
842 {
843         ast_indicate(chan, AST_CONTROL_UNHOLD);
844
845         return ast_autoservice_stop(chan);
846 }
847
848 /*!
849  * \brief Find the context for the transfer
850  * \param transferer
851  * \param transferee
852  * 
853  * Grab the TRANSFER_CONTEXT, if fails try grabbing macrocontext.
854  * \return a context string
855 */
856 static const char *real_ctx(struct ast_channel *transferer, struct ast_channel *transferee)
857 {
858         const char *s = pbx_builtin_getvar_helper(transferer, "TRANSFER_CONTEXT");
859         if (ast_strlen_zero(s)) {
860                 s = pbx_builtin_getvar_helper(transferee, "TRANSFER_CONTEXT");
861         }
862         if (ast_strlen_zero(s)) { /* Use the non-macro context to transfer the call XXX ? */
863                 s = transferer->macrocontext;
864         }
865         if (ast_strlen_zero(s)) {
866                 s = transferer->context;
867         }
868         return s;  
869 }
870
871 /*!
872  * \brief Blind transfer user to another extension
873  * \param chan channel to be transfered
874  * \param peer channel initiated blind transfer
875  * \param config
876  * \param code
877  * \param data
878  * \param sense  feature options
879  * 
880  * Place chan on hold, check if transferred to parkinglot extension,
881  * otherwise check extension exists and transfer caller.
882  * \retval FEATURE_RETURN_SUCCESS.
883  * \retval -1 on failure.
884 */
885 static int builtin_blindtransfer(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
886 {
887         struct ast_channel *transferer;
888         struct ast_channel *transferee;
889         const char *transferer_real_context;
890         char xferto[256];
891         int res;
892
893         set_peers(&transferer, &transferee, peer, chan, sense);
894         transferer_real_context = real_ctx(transferer, transferee);
895         /* Start autoservice on chan while we talk to the originator */
896         ast_autoservice_start(transferee);
897         ast_indicate(transferee, AST_CONTROL_HOLD);
898
899         memset(xferto, 0, sizeof(xferto));
900         
901         /* Transfer */
902         res = ast_stream_and_wait(transferer, "pbx-transfer", AST_DIGIT_ANY);
903         if (res < 0) {
904                 finishup(transferee);
905                 return -1; /* error ? */
906         }
907         if (res > 0)    /* If they've typed a digit already, handle it */
908                 xferto[0] = (char) res;
909
910         ast_stopstream(transferer);
911         res = ast_app_dtget(transferer, transferer_real_context, xferto, sizeof(xferto), 100, transferdigittimeout);
912         if (res < 0) {  /* hangup, would be 0 for invalid and 1 for valid */
913                 finishup(transferee);
914                 return res;
915         }
916         if (!strcmp(xferto, ast_parking_ext())) {
917                 res = finishup(transferee);
918                 if (res)
919                         res = -1;
920                 else if (!ast_park_call(transferee, transferer, 0, NULL)) {     /* success */
921                         /* We return non-zero, but tell the PBX not to hang the channel when
922                            the thread dies -- We have to be careful now though.  We are responsible for 
923                            hanging up the channel, else it will never be hung up! */
924
925                         return (transferer == peer) ? AST_PBX_KEEPALIVE : AST_PBX_NO_HANGUP_PEER;
926                 } else {
927                         ast_log(LOG_WARNING, "Unable to park call %s\n", transferee->name);
928                 }
929                 /*! \todo XXX Maybe we should have another message here instead of invalid extension XXX */
930         } else if (ast_exists_extension(transferee, transferer_real_context, xferto, 1, transferer->cid.cid_num)) {
931                 pbx_builtin_setvar_helper(peer, "BLINDTRANSFER", transferee->name);
932                 pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", peer->name);
933                 res=finishup(transferee);
934                 if (!transferer->cdr) {
935                         transferer->cdr=ast_cdr_alloc();
936                         if (transferer) {
937                                 ast_cdr_init(transferer->cdr, transferer); /* initilize our channel's cdr */
938                                 ast_cdr_start(transferer->cdr);
939                         }
940                 }
941                 if (transferer->cdr) {
942                         ast_cdr_setdestchan(transferer->cdr, transferee->name);
943                         ast_cdr_setapp(transferer->cdr, "BLINDTRANSFER","");
944                 }
945                 if (!transferee->pbx) {
946                         /* Doh!  Use our handy async_goto functions */
947                         ast_verb(3, "Transferring %s to '%s' (context %s) priority 1\n"
948                                                                 ,transferee->name, xferto, transferer_real_context);
949                         if (ast_async_goto(transferee, transferer_real_context, xferto, 1))
950                                 ast_log(LOG_WARNING, "Async goto failed :-(\n");
951                 } else {
952                         /* Set the channel's new extension, since it exists, using transferer context */
953                         set_c_e_p(transferee, transferer_real_context, xferto, 0);
954                 }
955                 check_goto_on_transfer(transferer);
956                 return res;
957         } else {
958                 ast_verb(3, "Unable to find extension '%s' in context '%s'\n", xferto, transferer_real_context);
959         }
960         if (ast_stream_and_wait(transferer, xferfailsound, AST_DIGIT_ANY) < 0) {
961                 finishup(transferee);
962                 return -1;
963         }
964         ast_stopstream(transferer);
965         res = finishup(transferee);
966         if (res) {
967                 ast_verb(2, "Hungup during autoservice stop on '%s'\n", transferee->name);
968                 return res;
969         }
970         return FEATURE_RETURN_SUCCESS;
971 }
972
973 /*!
974  * \brief make channels compatible
975  * \param c
976  * \param newchan
977  * \retval 0 on success.
978  * \retval -1 on failure.
979 */
980 static int check_compat(struct ast_channel *c, struct ast_channel *newchan)
981 {
982         if (ast_channel_make_compatible(c, newchan) < 0) {
983                 ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n",
984                         c->name, newchan->name);
985                 ast_hangup(newchan);
986                 return -1;
987         }
988         return 0;
989 }
990
991 /*!
992  * \brief Attended transfer
993  * \param chan transfered user
994  * \param peer person transfering call
995  * \param config
996  * \param code
997  * \param sense feature options
998  * 
999  * \param data
1000  * Get extension to transfer to, if you cannot generate channel (or find extension) 
1001  * return to host channel. After called channel answered wait for hangup of transferer,
1002  * bridge call between transfer peer (taking them off hold) to attended transfer channel.
1003  *
1004  * \return -1 on failure
1005 */
1006 static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
1007 {
1008         struct ast_channel *transferer;
1009         struct ast_channel *transferee;
1010         const char *transferer_real_context;
1011         char xferto[256] = "";
1012         int res;
1013         int outstate=0;
1014         struct ast_channel *newchan;
1015         struct ast_channel *xferchan;
1016         struct ast_bridge_thread_obj *tobj;
1017         struct ast_bridge_config bconfig;
1018         struct ast_frame *f;
1019         int l;
1020
1021         ast_debug(1, "Executing Attended Transfer %s, %s (sense=%d) \n", chan->name, peer->name, sense);
1022         set_peers(&transferer, &transferee, peer, chan, sense);
1023         transferer_real_context = real_ctx(transferer, transferee);
1024         /* Start autoservice on chan while we talk to the originator */
1025         ast_autoservice_start(transferee);
1026         ast_indicate(transferee, AST_CONTROL_HOLD);
1027         
1028         /* Transfer */
1029         res = ast_stream_and_wait(transferer, "pbx-transfer", AST_DIGIT_ANY);
1030         if (res < 0) {
1031                 finishup(transferee);
1032                 return res;
1033         }
1034         if (res > 0) /* If they've typed a digit already, handle it */
1035                 xferto[0] = (char) res;
1036
1037         /* this is specific of atxfer */
1038         res = ast_app_dtget(transferer, transferer_real_context, xferto, sizeof(xferto), 100, transferdigittimeout);
1039         if (res < 0) {  /* hangup, would be 0 for invalid and 1 for valid */
1040                 finishup(transferee);
1041                 return res;
1042         }
1043         if (res == 0) {
1044                 ast_log(LOG_WARNING, "Did not read data.\n");
1045                 finishup(transferee);
1046                 if (ast_stream_and_wait(transferer, "beeperr", ""))
1047                         return -1;
1048                 return FEATURE_RETURN_SUCCESS;
1049         }
1050
1051         /* valid extension, res == 1 */
1052         if (!ast_exists_extension(transferer, transferer_real_context, xferto, 1, transferer->cid.cid_num)) {
1053                 ast_log(LOG_WARNING, "Extension %s does not exist in context %s\n",xferto,transferer_real_context);
1054                 finishup(transferee);
1055                 if (ast_stream_and_wait(transferer, "beeperr", ""))
1056                         return -1;
1057                 return FEATURE_RETURN_SUCCESS;
1058         }
1059
1060         l = strlen(xferto);
1061         snprintf(xferto + l, sizeof(xferto) - l, "@%s/n", transferer_real_context);     /* append context */
1062         newchan = ast_feature_request_and_dial(transferer, transferee, "Local", ast_best_codec(transferer->nativeformats),
1063                 xferto, atxfernoanswertimeout, &outstate, transferer->cid.cid_num, transferer->cid.cid_name, 1, transferer->language);
1064
1065         if (!ast_check_hangup(transferer)) {
1066                 /* Transferer is up - old behaviour */
1067                 ast_indicate(transferer, -1);
1068                 if (!newchan) {
1069                         finishup(transferee);
1070                         /* any reason besides user requested cancel and busy triggers the failed sound */
1071                         if (outstate != AST_CONTROL_UNHOLD && outstate != AST_CONTROL_BUSY &&
1072                                 ast_stream_and_wait(transferer, xferfailsound, ""))
1073                                 return -1;
1074                         if (ast_stream_and_wait(transferer, xfersound, ""))
1075                                 ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
1076                         return FEATURE_RETURN_SUCCESS;
1077                 }
1078
1079                 if (check_compat(transferer, newchan)) {
1080                         /* we do mean transferee here, NOT transferer */
1081                         finishup(transferee);
1082                         return -1;
1083                 }
1084                 memset(&bconfig,0,sizeof(struct ast_bridge_config));
1085                 ast_set_flag(&(bconfig.features_caller), AST_FEATURE_DISCONNECT);
1086                 ast_set_flag(&(bconfig.features_callee), AST_FEATURE_DISCONNECT);
1087                 res = ast_bridge_call(transferer, newchan, &bconfig);
1088                 if (ast_check_hangup(newchan) || !ast_check_hangup(transferer)) {
1089                         ast_hangup(newchan);
1090                         if (ast_stream_and_wait(transferer, xfersound, ""))
1091                                 ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
1092                         finishup(transferee);
1093                         transferer->_softhangup = 0;
1094                         return FEATURE_RETURN_SUCCESS;
1095                 }
1096                 if (check_compat(transferee, newchan)) {
1097                         finishup(transferee);
1098                         return -1;
1099                 }
1100                 ast_indicate(transferee, AST_CONTROL_UNHOLD);
1101
1102                 if ((ast_autoservice_stop(transferee) < 0)
1103                  || (ast_waitfordigit(transferee, 100) < 0)
1104                  || (ast_waitfordigit(newchan, 100) < 0)
1105                  || ast_check_hangup(transferee)
1106                  || ast_check_hangup(newchan)) {
1107                         ast_hangup(newchan);
1108                         return -1;
1109                 }
1110                 xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Transfered/%s", transferee->name);
1111                 if (!xferchan) {
1112                         ast_hangup(newchan);
1113                         return -1;
1114                 }
1115                 /* Make formats okay */
1116                 xferchan->visible_indication = transferer->visible_indication;
1117                 xferchan->readformat = transferee->readformat;
1118                 xferchan->writeformat = transferee->writeformat;
1119                 ast_channel_masquerade(xferchan, transferee);
1120                 ast_explicit_goto(xferchan, transferee->context, transferee->exten, transferee->priority);
1121                 xferchan->_state = AST_STATE_UP;
1122                 ast_clear_flag(xferchan, AST_FLAGS_ALL);
1123                 xferchan->_softhangup = 0;
1124                 if ((f = ast_read(xferchan)))
1125                         ast_frfree(f);
1126                 newchan->_state = AST_STATE_UP;
1127                 ast_clear_flag(newchan, AST_FLAGS_ALL);
1128                 newchan->_softhangup = 0;
1129                 if (!(tobj = ast_calloc(1, sizeof(*tobj)))) {
1130                         ast_hangup(xferchan);
1131                         ast_hangup(newchan);
1132                         return -1;
1133                 }
1134                 tobj->chan = newchan;
1135                 tobj->peer = xferchan;
1136                 tobj->bconfig = *config;
1137
1138                 if (ast_stream_and_wait(newchan, xfersound, ""))
1139                         ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
1140                 ast_bridge_call_thread_launch(tobj);
1141                 return -1;      /* XXX meaning the channel is bridged ? */
1142         } else if (!ast_check_hangup(transferee)) {
1143                 /* act as blind transfer */
1144                 if (ast_autoservice_stop(transferee) < 0) {
1145                         ast_hangup(newchan);
1146                         return -1;
1147                 }
1148
1149                 if (!newchan) {
1150                         unsigned int tries = 0;
1151                         char *transferer_tech, *transferer_name = ast_strdupa(transferer->name);
1152
1153                         transferer_tech = strsep(&transferer_name, "/");
1154                         transferer_name = strsep(&transferer_name, "-");
1155
1156                         if (ast_strlen_zero(transferer_name) || ast_strlen_zero(transferer_tech)) {
1157                                 ast_log(LOG_WARNING, "Transferer has invalid channel name: '%s'\n", transferer->name);
1158                                 if (ast_stream_and_wait(transferee, "beeperr", ""))
1159                                         return -1;
1160                                 return FEATURE_RETURN_SUCCESS;
1161                         }
1162
1163                         ast_log(LOG_NOTICE, "We're trying to call %s/%s\n", transferer_tech, transferer_name);
1164                         newchan = ast_feature_request_and_dial(transferee, NULL, transferer_tech, ast_best_codec(transferee->nativeformats),
1165                                 transferer_name, atxfernoanswertimeout, &outstate, transferee->cid.cid_num, transferee->cid.cid_name, 0, transferer->language);
1166                         while (!newchan && !atxferdropcall && tries < atxfercallbackretries) {
1167                                 /* Trying to transfer again */
1168                                 ast_autoservice_start(transferee);
1169                                 ast_indicate(transferee, AST_CONTROL_HOLD);
1170
1171                                 newchan = ast_feature_request_and_dial(transferer, transferee, "Local", ast_best_codec(transferer->nativeformats),
1172                                         xferto, atxfernoanswertimeout, &outstate, transferer->cid.cid_num, transferer->cid.cid_name, 1, transferer->language);
1173                                 if (ast_autoservice_stop(transferee) < 0) {
1174                                         if (newchan)
1175                                                 ast_hangup(newchan);
1176                                         return -1;
1177                                 }
1178                                 if (!newchan) {
1179                                         /* Transfer failed, sleeping */
1180                                         ast_debug(1, "Sleeping for %d ms before callback.\n", atxferloopdelay);
1181                                         ast_safe_sleep(transferee, atxferloopdelay);
1182                                         ast_debug(1, "Trying to callback...\n");
1183                                         newchan = ast_feature_request_and_dial(transferee, NULL, transferer_tech, ast_best_codec(transferee->nativeformats),
1184                                                 transferer_name, atxfernoanswertimeout, &outstate, transferee->cid.cid_num, transferee->cid.cid_name, 0, transferer->language);
1185                                 }
1186                                 tries++;
1187                         }
1188                 }
1189                 if (!newchan)
1190                         return -1;
1191
1192                 /* newchan is up, we should prepare transferee and bridge them */
1193                 if (check_compat(transferee, newchan)) {
1194                         finishup(transferee);
1195                         return -1;
1196                 }
1197                 ast_indicate(transferee, AST_CONTROL_UNHOLD);
1198
1199                 if ((ast_waitfordigit(transferee, 100) < 0)
1200                    || (ast_waitfordigit(newchan, 100) < 0)
1201                    || ast_check_hangup(transferee)
1202                    || ast_check_hangup(newchan)) {
1203                         ast_hangup(newchan);
1204                         return -1;
1205                 }
1206
1207                 xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Transfered/%s", transferee->name);
1208                 if (!xferchan) {
1209                         ast_hangup(newchan);
1210                         return -1;
1211                 }
1212                 /* Make formats okay */
1213                 xferchan->visible_indication = transferer->visible_indication;
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_or_create(NULL, NULL, parking_con_dial, registrar);
2232                                         if (!con)
2233                                                 ast_log(LOG_ERROR, "Parking dial context '%s' does not exist and unable to create\n", parking_con_dial);
2234                                         if (con) {
2235                                                 char returnexten[AST_MAX_EXTENSION];
2236                                                 struct ast_datastore *features_datastore;
2237                                                 struct ast_dial_features *dialfeatures = NULL;
2238
2239                                                 ast_channel_lock(chan);
2240
2241                                                 if ((features_datastore = ast_channel_datastore_find(chan, &dial_features_info, NULL)))
2242                                                         dialfeatures = features_datastore->data;
2243
2244                                                 ast_channel_unlock(chan);
2245
2246                                                 if (dialfeatures)
2247                                                         snprintf(returnexten, sizeof(returnexten), "%s,,%s", peername, dialfeatures->options);
2248                                                 else /* Existing default */
2249                                                         snprintf(returnexten, sizeof(returnexten), "%s,,t", peername);
2250
2251                                                 ast_add_extension2(con, 1, peername_flat, 1, NULL, NULL, "Dial", ast_strdup(returnexten), ast_free_ptr, registrar);
2252                                         }
2253                                         if (comebacktoorigin) {
2254                                                 set_c_e_p(chan, parking_con_dial, peername_flat, 1);
2255                                         } else {
2256                                                 ast_log(LOG_WARNING, "now going to parkedcallstimeout,s,1 | ps is %d\n",pu->parkingnum);
2257                                                 snprintf(parkingslot, sizeof(parkingslot), "%d", pu->parkingnum);
2258                                                 pbx_builtin_setvar_helper(pu->chan, "PARKINGSLOT", parkingslot);
2259                                                 set_c_e_p(chan, "parkedcallstimeout", peername_flat, 1);
2260                                         }
2261                                 } else {
2262                                         /* They've been waiting too long, send them back to where they came.  Theoretically they
2263                                            should have their original extensions and such, but we copy to be on the safe side */
2264                                         set_c_e_p(chan, pu->context, pu->exten, pu->priority);
2265                                 }
2266
2267                                 post_manager_event("ParkedCallTimeOut", pu);
2268
2269                                 ast_verb(2, "Timeout for %s parked on %d. Returning to %s,%s,%d\n", chan->name, pu->parkingnum, chan->context, chan->exten, chan->priority);
2270                                 /* Start up the PBX, or hang them up */
2271                                 if (ast_pbx_start(chan))  {
2272                                         ast_log(LOG_WARNING, "Unable to restart the PBX for user on '%s', hanging them up...\n", chan->name);
2273                                         ast_hangup(chan);
2274                                 }
2275                                 /* And take them out of the parking lot */
2276                                 AST_LIST_REMOVE_CURRENT(list);
2277                                 con = ast_context_find(parking_con);
2278                                 if (con) {
2279                                         if (ast_context_remove_extension2(con, pu->parkingexten, 1, NULL))
2280                                                 ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
2281                                         else
2282                                                 notify_metermaids(pu->parkingexten, parking_con, AST_DEVICE_NOT_INUSE);
2283                                 } else
2284                                         ast_log(LOG_WARNING, "Whoa, no parking context?\n");
2285                                 ast_free(pu);
2286                         } else {        /* still within parking time, process descriptors */
2287                                 for (x = 0; x < AST_MAX_FDS; x++) {
2288                                         struct ast_frame *f;
2289
2290                                         if (chan->fds[x] == -1 || (!FD_ISSET(chan->fds[x], &rfds) && !FD_ISSET(chan->fds[x], &efds)))
2291                                                 continue;       /* nothing on this descriptor */
2292
2293                                         if (FD_ISSET(chan->fds[x], &efds))
2294                                                 ast_set_flag(chan, AST_FLAG_EXCEPTION);
2295                                         else
2296                                                 ast_clear_flag(chan, AST_FLAG_EXCEPTION);
2297                                         chan->fdno = x;
2298
2299                                         /* See if they need servicing */
2300                                         f = ast_read(chan);
2301                                         if (!f || (f->frametype == AST_FRAME_CONTROL && f->subclass ==  AST_CONTROL_HANGUP)) {
2302                                                 if (f)
2303                                                         ast_frfree(f);
2304                                                 post_manager_event("ParkedCallGiveUp", pu);
2305
2306                                                 /* There's a problem, hang them up*/
2307                                                 ast_verb(2, "%s got tired of being parked\n", chan->name);
2308                                                 ast_hangup(chan);
2309                                                 /* And take them out of the parking lot */
2310                                                 AST_LIST_REMOVE_CURRENT(list);
2311                                                 con = ast_context_find(parking_con);
2312                                                 if (con) {
2313                                                         if (ast_context_remove_extension2(con, pu->parkingexten, 1, NULL))
2314                                                                 ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
2315                                                         else
2316                                                                 notify_metermaids(pu->parkingexten, parking_con, AST_DEVICE_NOT_INUSE);
2317                                                 } else
2318                                                         ast_log(LOG_WARNING, "Whoa, no parking context?\n");
2319                                                 ast_free(pu);
2320                                                 break;
2321                                         } else {
2322                                                 /*! \todo XXX Maybe we could do something with packets, like dial "0" for operator or something XXX */
2323                                                 ast_frfree(f);
2324                                                 if (pu->moh_trys < 3 && !chan->generatordata) {
2325                                                         ast_debug(1, "MOH on parked call stopped by outside source.  Restarting.\n");
2326                                                         ast_indicate_data(chan, AST_CONTROL_HOLD, 
2327                                                                 S_OR(parkmohclass, NULL),
2328                                                                 !ast_strlen_zero(parkmohclass) ? strlen(parkmohclass) + 1 : 0);
2329                                                         pu->moh_trys++;
2330                                                 }
2331                                                 goto std;       /*! \todo XXX Ick: jumping into an else statement??? XXX */
2332                                         }
2333
2334                                 } /* end for */
2335                                 if (x >= AST_MAX_FDS) {
2336 std:                                    for (x=0; x<AST_MAX_FDS; x++) { /* mark fds for next round */
2337                                                 if (chan->fds[x] > -1) {
2338                                                         FD_SET(chan->fds[x], &nrfds);
2339                                                         FD_SET(chan->fds[x], &nefds);
2340                                                         if (chan->fds[x] > max)
2341                                                                 max = chan->fds[x];
2342                                                 }
2343                                         }
2344                                         /* Keep track of our shortest wait */
2345                                         if (tms < ms || ms < 0)
2346                                                 ms = tms;
2347                                 }
2348                         }
2349                 } /* end while */
2350                 AST_LIST_TRAVERSE_SAFE_END
2351                 AST_LIST_UNLOCK(&parkinglot);
2352                 rfds = nrfds;
2353                 efds = nefds;
2354                 {
2355                         struct timeval tv = ast_samp2tv(ms, 1000);
2356                         /* Wait for something to happen */
2357                         ast_select(max + 1, &rfds, NULL, &efds, (ms > -1) ? &tv : NULL);
2358                 }
2359                 pthread_testcancel();
2360         }
2361         return NULL;    /* Never reached */
2362 }
2363
2364 /*! \brief Park a call */
2365 static int park_call_exec(struct ast_channel *chan, void *data)
2366 {
2367         /* Cache the original channel name in case we get masqueraded in the middle
2368          * of a park--it is still theoretically possible for a transfer to happen before
2369          * we get here, but it is _really_ unlikely */
2370         char *orig_chan_name = ast_strdupa(chan->name);
2371         char orig_exten[AST_MAX_EXTENSION];
2372         int orig_priority = chan->priority;
2373
2374         /* Data is unused at the moment but could contain a parking
2375            lot context eventually */
2376         int res = 0;
2377
2378         ast_copy_string(orig_exten, chan->exten, sizeof(orig_exten));
2379
2380         /* Setup the exten/priority to be s/1 since we don't know
2381            where this call should return */
2382         strcpy(chan->exten, "s");
2383         chan->priority = 1;
2384         /* Answer if call is not up */
2385         if (chan->_state != AST_STATE_UP)
2386                 res = ast_answer(chan);
2387         /* Sleep to allow VoIP streams to settle down */
2388         if (!res)
2389                 res = ast_safe_sleep(chan, 1000);
2390         /* Park the call */
2391         if (!res) {
2392                 res = park_call_full(chan, chan, 0, NULL, orig_chan_name);
2393                 /* Continue on in the dialplan */
2394                 if (res == 1) {
2395                         ast_copy_string(chan->exten, orig_exten, sizeof(chan->exten));
2396                         chan->priority = orig_priority;
2397                         res = 0;
2398                 } else if (!res)
2399                         res = AST_PBX_KEEPALIVE;
2400         }
2401
2402         return res;
2403 }
2404
2405 /*! \brief Pickup parked call */
2406 static int park_exec(struct ast_channel *chan, void *data)
2407 {
2408         int res = 0;
2409         struct ast_channel *peer=NULL;
2410         struct parkeduser *pu;
2411         struct ast_context *con;
2412         int park = 0;
2413         struct ast_bridge_config config;
2414
2415         if (data)
2416                 park = atoi((char *)data);
2417
2418         AST_LIST_LOCK(&parkinglot);
2419         AST_LIST_TRAVERSE_SAFE_BEGIN(&parkinglot, pu, list) {
2420                 if (!data || pu->parkingnum == park) {
2421                         AST_LIST_REMOVE_CURRENT(list);
2422                         break;
2423                 }
2424         }
2425         AST_LIST_TRAVERSE_SAFE_END
2426         AST_LIST_UNLOCK(&parkinglot);
2427
2428         if (pu) {
2429                 peer = pu->chan;
2430                 con = ast_context_find(parking_con);
2431                 if (con) {
2432                         if (ast_context_remove_extension2(con, pu->parkingexten, 1, NULL))
2433                                 ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
2434                         else
2435                                 notify_metermaids(pu->parkingexten, parking_con, AST_DEVICE_NOT_INUSE);
2436                 } else
2437                         ast_log(LOG_WARNING, "Whoa, no parking context?\n");
2438
2439                 manager_event(EVENT_FLAG_CALL, "UnParkedCall",
2440                         "Exten: %s\r\n"
2441                         "Channel: %s\r\n"
2442                         "From: %s\r\n"
2443                         "CallerIDNum: %s\r\n"
2444                         "CallerIDName: %s\r\n",
2445                         pu->parkingexten, pu->chan->name, chan->name,
2446                         S_OR(pu->chan->cid.cid_num, "<unknown>"),
2447                         S_OR(pu->chan->cid.cid_name, "<unknown>")
2448                         );
2449
2450                 ast_free(pu);
2451         }
2452         /* JK02: it helps to answer the channel if not already up */
2453         if (chan->_state != AST_STATE_UP)
2454                 ast_answer(chan);
2455
2456         if (peer) {
2457                 /* Play a courtesy to the source(s) configured to prefix the bridge connecting */
2458                 
2459                 if (!ast_strlen_zero(courtesytone)) {
2460                         int error = 0;
2461                         ast_indicate(peer, AST_CONTROL_UNHOLD);
2462                         if (parkedplay == 0) {
2463                                 error = ast_stream_and_wait(chan, courtesytone, "");
2464                         } else if (parkedplay == 1) {
2465                                 error = ast_stream_and_wait(peer, courtesytone, "");
2466                         } else if (parkedplay == 2) {
2467                                 if (!ast_streamfile(chan, courtesytone, chan->language) &&
2468                                                 !ast_streamfile(peer, courtesytone, chan->language)) {
2469                                         /*! \todo XXX we would like to wait on both! */
2470                                         res = ast_waitstream(chan, "");
2471                                         if (res >= 0)
2472                                                 res = ast_waitstream(peer, "");
2473                                         if (res < 0)
2474                                                 error = 1;
2475                                 }
2476                         }
2477                         if (error) {
2478                                 ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
2479                                 ast_hangup(peer);
2480                                 return -1;
2481                         }
2482                 } else
2483                         ast_indicate(peer, AST_CONTROL_UNHOLD); 
2484
2485                 res = ast_channel_make_compatible(chan, peer);
2486                 if (res < 0) {
2487                         ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for bridge\n", chan->name, peer->name);
2488                         ast_hangup(peer);
2489                         return -1;
2490                 }
2491                 /* This runs sorta backwards, since we give the incoming channel control, as if it
2492                    were the person called. */
2493                 ast_verb(3, "Channel %s connected to parked call %d\n", chan->name, park);
2494
2495                 pbx_builtin_setvar_helper(chan, "PARKEDCHANNEL", peer->name);
2496                 ast_cdr_setdestchan(chan->cdr, peer->name);
2497                 memset(&config, 0, sizeof(struct ast_bridge_config));
2498                 if ((parkedcalltransfers == AST_FEATURE_FLAG_BYCALLEE) || (parkedcalltransfers == AST_FEATURE_FLAG_BYBOTH))
2499                         ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
2500                 if ((parkedcalltransfers == AST_FEATURE_FLAG_BYCALLER) || (parkedcalltransfers == AST_FEATURE_FLAG_BYBOTH))
2501                         ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
2502                 if ((parkedcallreparking == AST_FEATURE_FLAG_BYCALLEE) || (parkedcallreparking == AST_FEATURE_FLAG_BYBOTH))
2503                         ast_set_flag(&(config.features_callee), AST_FEATURE_PARKCALL);
2504                 if ((parkedcallreparking == AST_FEATURE_FLAG_BYCALLER) || (parkedcallreparking == AST_FEATURE_FLAG_BYBOTH))
2505                         ast_set_flag(&(config.features_caller), AST_FEATURE_PARKCALL);
2506                 res = ast_bridge_call(chan, peer, &config);
2507
2508                 pbx_builtin_setvar_helper(chan, "PARKEDCHANNEL", peer->name);
2509                 ast_cdr_setdestchan(chan->cdr, peer->name);
2510
2511                 /* Simulate the PBX hanging up */
2512                 if (res != AST_PBX_NO_HANGUP_PEER)
2513                         ast_hangup(peer);
2514                 return res;
2515         } else {
2516                 /*! \todo XXX Play a message XXX */
2517                 if (ast_stream_and_wait(chan, "pbx-invalidpark", ""))
2518                         ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", "pbx-invalidpark", chan->name);
2519                 ast_verb(3, "Channel %s tried to talk to nonexistent parked call %d\n", chan->name, park);
2520                 res = -1;
2521         }
2522
2523         return res;
2524 }
2525
2526 /*! 
2527  * \brief Add parking hints for all defined parking lots 
2528  * \param context
2529  * \param start starting parkinglot number
2530  * \param stop ending parkinglot number
2531 */
2532 static void park_add_hints(char *context, int start, int stop)
2533 {
2534         int numext;
2535         char device[AST_MAX_EXTENSION];
2536         char exten[10];
2537
2538         for (numext = start; numext <= stop; numext++) {
2539                 snprintf(exten, sizeof(exten), "%d", numext);
2540                 snprintf(device, sizeof(device), "park:%s@%s", exten, context);
2541                 ast_add_extension(context, 1, exten, PRIORITY_HINT, NULL, NULL, device, NULL, NULL, registrar);
2542         }
2543 }
2544
2545 static int load_config(void) 
2546 {
2547         int start = 0, end = 0;
2548         int res;
2549         int i;
2550         struct ast_context *con = NULL;
2551         struct ast_config *cfg = NULL;
2552         struct ast_variable *var = NULL;
2553         struct feature_group *fg = NULL;
2554         struct ast_flags config_flags = { 0 };
2555         char old_parking_ext[AST_MAX_EXTENSION];
2556         char old_parking_con[AST_MAX_EXTENSION] = "";
2557         char *ctg; 
2558         static const char *categories[] = { 
2559                 /* Categories in features.conf that are not
2560                  * to be parsed as group categories
2561                  */
2562                 "general",
2563                 "featuremap",
2564                 "applicationmap"
2565         };
2566
2567         if (!ast_strlen_zero(parking_con)) {
2568                 strcpy(old_parking_ext, parking_ext);
2569                 strcpy(old_parking_con, parking_con);
2570         } 
2571
2572         /* Reset to defaults */
2573         strcpy(parking_con, "parkedcalls");
2574         strcpy(parking_con_dial, "park-dial");
2575         strcpy(parking_ext, "700");
2576         strcpy(pickup_ext, "*8");
2577         strcpy(parkmohclass, "default");
2578         courtesytone[0] = '\0';
2579         strcpy(xfersound, "beep");
2580         strcpy(xferfailsound, "pbx-invalid");
2581         parking_start = 701;
2582         parking_stop = 750;
2583         parkfindnext = 0;
2584         adsipark = 0;
2585         comebacktoorigin = 1;
2586         parkaddhints = 0;
2587         parkedcalltransfers = 0;
2588         parkedcallreparking = 0;
2589
2590         transferdigittimeout = DEFAULT_TRANSFER_DIGIT_TIMEOUT;
2591         featuredigittimeout = DEFAULT_FEATURE_DIGIT_TIMEOUT;
2592         atxfernoanswertimeout = DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER;
2593         atxferloopdelay = DEFAULT_ATXFER_LOOP_DELAY;
2594         atxferdropcall = DEFAULT_ATXFER_DROP_CALL;
2595         atxfercallbackretries = DEFAULT_ATXFER_CALLBACK_RETRIES;
2596
2597         cfg = ast_config_load("features.conf", config_flags);
2598         if (!cfg) {
2599                 ast_log(LOG_WARNING,"Could not load features.conf\n");
2600                 return 0;
2601         }
2602         for (var = ast_variable_browse(cfg, "general"); var; var = var->next) {
2603                 if (!strcasecmp(var->name, "parkext")) {
2604                         ast_copy_string(parking_ext, var->value, sizeof(parking_ext));
2605                 } else if (!strcasecmp(var->name, "context")) {
2606                         ast_copy_string(parking_con, var->value, sizeof(parking_con));
2607                 } else if (!strcasecmp(var->name, "parkingtime")) {
2608                         if ((sscanf(var->value, "%d", &parkingtime) != 1) || (parkingtime < 1)) {
2609                                 ast_log(LOG_WARNING, "%s is not a valid parkingtime\n", var->value);
2610                                 parkingtime = DEFAULT_PARK_TIME;
2611                         } else
2612                                 parkingtime = parkingtime * 1000;
2613                 } else if (!strcasecmp(var->name, "parkpos")) {
2614                         if (sscanf(var->value, "%d-%d", &start, &end) != 2) {
2615                                 ast_log(LOG_WARNING, "Format for parking positions is a-b, where a and b are numbers at line %d of features.conf\n", var->lineno);
2616                         } else {
2617                                 parking_start = start;
2618                                 parking_stop = end;
2619                         }
2620                 } else if (!strcasecmp(var->name, "findslot")) {
2621                         parkfindnext = (!strcasecmp(var->value, "next"));
2622                 } else if (!strcasecmp(var->name, "parkinghints")) {
2623                         parkaddhints = ast_true(var->value);
2624                 } else if (!strcasecmp(var->name, "parkedcalltransfers")) {
2625                         if (!strcasecmp(var->value, "both"))
2626                                 parkedcalltransfers = AST_FEATURE_FLAG_BYBOTH;
2627                         else if (!strcasecmp(var->value, "caller"))
2628                                 parkedcalltransfers = AST_FEATURE_FLAG_BYCALLER;
2629                         else if (!strcasecmp(var->value, "callee"))
2630                                 parkedcalltransfers = AST_FEATURE_FLAG_BYCALLEE;
2631                 } else if (!strcasecmp(var->name, "parkedcallreparking")) {
2632                         if (!strcasecmp(var->value, "both"))
2633                                 parkedcalltransfers = AST_FEATURE_FLAG_BYBOTH;
2634                         else if (!strcasecmp(var->value, "caller"))
2635                                 parkedcalltransfers = AST_FEATURE_FLAG_BYCALLER;
2636                         else if (!strcasecmp(var->value, "callee"))
2637                                 parkedcalltransfers = AST_FEATURE_FLAG_BYCALLEE;
2638                 } else if (!strcasecmp(var->name, "adsipark")) {
2639                         adsipark = ast_true(var->value);
2640                 } else if (!strcasecmp(var->name, "transferdigittimeout")) {
2641                         if ((sscanf(var->value, "%d", &transferdigittimeout) != 1) || (transferdigittimeout < 1)) {
2642                                 ast_log(LOG_WARNING, "%s is not a valid transferdigittimeout\n", var->value);
2643                                 transferdigittimeout = DEFAULT_TRANSFER_DIGIT_TIMEOUT;
2644                         } else
2645                                 transferdigittimeout = transferdigittimeout * 1000;
2646                 } else if (!strcasecmp(var->name, "featuredigittimeout")) {
2647                         if ((sscanf(var->value, "%d", &featuredigittimeout) != 1) || (featuredigittimeout < 1)) {
2648                                 ast_log(LOG_WARNING, "%s is not a valid featuredigittimeout\n", var->value);
2649                                 featuredigittimeout = DEFAULT_FEATURE_DIGIT_TIMEOUT;
2650                         }
2651                 } else if (!strcasecmp(var->name, "atxfernoanswertimeout")) {
2652                         if ((sscanf(var->value, "%d", &atxfernoanswertimeout) != 1) || (atxfernoanswertimeout < 1)) {
2653                                 ast_log(LOG_WARNING, "%s is not a valid atxfernoanswertimeout\n", var->value);
2654                                 atxfernoanswertimeout = DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER;
2655                         } else
2656                                 atxfernoanswertimeout = atxfernoanswertimeout * 1000;
2657                 } else if (!strcasecmp(var->name, "atxferloopdelay")) {
2658                         if ((sscanf(var->value, "%u", &atxferloopdelay) != 1)) {
2659                                 ast_log(LOG_WARNING, "%s is not a valid atxferloopdelay\n", var->value);
2660                                 atxferloopdelay = DEFAULT_ATXFER_LOOP_DELAY;
2661                         } else 
2662                                 atxferloopdelay *= 1000;
2663                 } else if (!strcasecmp(var->name, "atxferdropcall")) {
2664                         atxferdropcall = ast_true(var->value);
2665                 } else if (!strcasecmp(var->name, "atxfercallbackretries")) {
2666                         if ((sscanf(var->value, "%u", &atxferloopdelay) != 1)) {
2667                                 ast_log(LOG_WARNING, "%s is not a valid atxfercallbackretries\n", var->value);
2668                                 atxfercallbackretries = DEFAULT_ATXFER_CALLBACK_RETRIES;
2669                         }
2670                 } else if (!strcasecmp(var->name, "courtesytone")) {
2671                         ast_copy_string(courtesytone, var->value, sizeof(courtesytone));
2672                 }  else if (!strcasecmp(var->name, "parkedplay")) {
2673                         if (!strcasecmp(var->value, "both"))
2674                                 parkedplay = 2;
2675                         else if (!strcasecmp(var->value, "parked"))
2676                                 parkedplay = 1;
2677                         else
2678                                 parkedplay = 0;
2679                 } else if (!strcasecmp(var->name, "xfersound")) {
2680                         ast_copy_string(xfersound, var->value, sizeof(xfersound));
2681                 } else if (!strcasecmp(var->name, "xferfailsound")) {
2682                         ast_copy_string(xferfailsound, var->value, sizeof(xferfailsound));
2683                 } else if (!strcasecmp(var->name, "pickupexten")) {
2684                         ast_copy_string(pickup_ext, var->value, sizeof(pickup_ext));
2685                 } else if (!strcasecmp(var->name, "comebacktoorigin")) {
2686                         comebacktoorigin = ast_true(var->value);
2687                 } else if (!strcasecmp(var->name, "parkedmusicclass")) {
2688                         ast_copy_string(parkmohclass, var->value, sizeof(parkmohclass));
2689                 }
2690         }
2691
2692         unmap_features();
2693         for (var = ast_variable_browse(cfg, "featuremap"); var; var = var->next) {
2694                 if (remap_feature(var->name, var->value))
2695                         ast_log(LOG_NOTICE, "Unknown feature '%s'\n", var->name);
2696         }
2697
2698         /* Map a key combination to an application*/
2699         ast_unregister_features();
2700         for (var = ast_variable_browse(cfg, "applicationmap"); var; var = var->next) {
2701                 char *tmp_val = ast_strdupa(var->value);
2702                 char *exten, *activateon, *activatedby, *app, *app_args, *moh_class; 
2703                 struct ast_call_feature *feature;
2704
2705                 /* strsep() sets the argument to NULL if match not found, and it
2706                  * is safe to use it with a NULL argument, so we don't check
2707                  * between calls.
2708                  */
2709                 exten = strsep(&tmp_val,",");
2710                 activatedby = strsep(&tmp_val,",");
2711                 app = strsep(&tmp_val,",");
2712                 app_args = strsep(&tmp_val,",");
2713                 moh_class = strsep(&tmp_val,",");
2714
2715                 activateon = strsep(&activatedby, "/"); 
2716
2717                 /*! \todo XXX var_name or app_args ? */
2718                 if (ast_strlen_zero(app) || ast_strlen_zero(exten) || ast_strlen_zero(activateon) || ast_strlen_zero(var->name)) {
2719                         ast_log(LOG_NOTICE, "Please check the feature Mapping Syntax, either extension, name, or app aren't provided %s %s %s %s\n",
2720                                 app, exten, activateon, var->name);
2721                         continue;
2722                 }
2723
2724                 AST_LIST_LOCK(&feature_list);
2725                 if ((feature = find_dynamic_feature(var->name))) {
2726                         AST_LIST_UNLOCK(&feature_list);
2727                         ast_log(LOG_WARNING, "Dynamic Feature '%s' specified more than once!\n", var->name);
2728                         continue;
2729                 }
2730                 AST_LIST_UNLOCK(&feature_list);
2731                                 
2732                 if (!(feature = ast_calloc(1, sizeof(*feature))))
2733                         continue;                                       
2734
2735                 ast_copy_string(feature->sname, var->name, FEATURE_SNAME_LEN);
2736                 ast_copy_string(feature->app, app, FEATURE_APP_LEN);
2737                 ast_copy_string(feature->exten, exten, FEATURE_EXTEN_LEN);
2738                 
2739                 if (app_args) 
2740                         ast_copy_string(feature->app_args, app_args, FEATURE_APP_ARGS_LEN);
2741
2742                 if (moh_class)
2743                         ast_copy_string(feature->moh_class, moh_class, FEATURE_MOH_LEN);
2744                         
2745                 ast_copy_string(feature->exten, exten, sizeof(feature->exten));
2746                 feature->operation = feature_exec_app;
2747                 ast_set_flag(feature, AST_FEATURE_FLAG_NEEDSDTMF);
2748
2749                 /* Allow caller and calle to be specified for backwards compatability */
2750                 if (!strcasecmp(activateon, "self") || !strcasecmp(activateon, "caller"))
2751                         ast_set_flag(feature, AST_FEATURE_FLAG_ONSELF);
2752                 else if (!strcasecmp(activateon, "peer") || !strcasecmp(activateon, "callee"))
2753                         ast_set_flag(feature, AST_FEATURE_FLAG_ONPEER);
2754                 else {
2755                         ast_log(LOG_NOTICE, "Invalid 'ActivateOn' specification for feature '%s',"
2756                                 " must be 'self', or 'peer'\n", var->name);
2757                         continue;
2758                 }
2759
2760                 if (ast_strlen_zero(activatedby))
2761                         ast_set_flag(feature, AST_FEATURE_FLAG_BYBOTH);
2762                 else if (!strcasecmp(activatedby, "caller"))
2763                         ast_set_flag(feature, AST_FEATURE_FLAG_BYCALLER);
2764                 else if (!strcasecmp(activatedby, "callee"))
2765                         ast_set_flag(feature, AST_FEATURE_FLAG_BYCALLEE);
2766                 else if (!strcasecmp(activatedby, "both"))
2767                         ast_set_flag(feature, AST_FEATURE_FLAG_BYBOTH);
2768                 else {
2769                         ast_log(LOG_NOTICE, "Invalid 'ActivatedBy' specification for feature '%s',"
2770                                 " must be 'caller', or 'callee', or 'both'\n", var->name);
2771                         continue;
2772                 }
2773
2774                 ast_register_feature(feature);
2775                         
2776                 ast_verb(2, "Mapping Feature '%s' to app '%s(%s)' with code '%s'\n", var->name, app, app_args, exten);
2777         }
2778
2779         ast_unregister_groups();
2780         AST_RWLIST_WRLOCK(&feature_groups);
2781
2782         ctg = NULL;
2783         while ((ctg = ast_category_browse(cfg, ctg))) {
2784                 for (i = 0; i < ARRAY_LEN(categories); i++) {
2785                         if (!strcasecmp(categories[i], ctg))
2786                                 break;
2787                 }
2788
2789                 if (i < ARRAY_LEN(categories)) 
2790                         continue;
2791
2792                 if (!(fg = register_group(ctg)))
2793                         continue;
2794
2795                 for (var = ast_variable_browse(cfg, ctg); var; var = var->next) {
2796                         struct ast_call_feature *feature;
2797
2798                         AST_LIST_LOCK(&feature_list);
2799                         if(!(feature = find_dynamic_feature(var->name)) && 
2800                            !(feature = ast_find_call_feature(var->name))) {
2801                                 AST_LIST_UNLOCK(&feature_list);
2802                                 ast_log(LOG_WARNING, "Feature '%s' was not found.\n", var->name);
2803                                 continue;
2804                         }
2805                         AST_LIST_UNLOCK(&feature_list);
2806
2807                         register_group_feature(fg, var->value, feature);
2808                 }
2809         }
2810
2811         AST_RWLIST_UNLOCK(&feature_groups);
2812
2813         ast_config_destroy(cfg);
2814
2815         /* Remove the old parking extension */
2816         if (!ast_strlen_zero(old_parking_con) && (con = ast_context_find(old_parking_con)))     {
2817                 if(ast_context_remove_extension2(con, old_parking_ext, 1, registrar))
2818                                 notify_metermaids(old_parking_ext, old_parking_con, AST_DEVICE_NOT_INUSE);
2819                 ast_debug(1, "Removed old parking extension %s@%s\n", old_parking_ext, old_parking_con);
2820         }
2821         
2822         if (!(con = ast_context_find_or_create(NULL, NULL, parking_con, registrar))) {
2823                 ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", parking_con);
2824                 return -1;
2825         }
2826         res = ast_add_extension2(con, 1, ast_parking_ext(), 1, NULL, NULL, parkcall, NULL, NULL, registrar);
2827         if (parkaddhints)
2828                 park_add_hints(parking_con, parking_start, parking_stop);
2829         if (!res)
2830                 notify_metermaids(ast_parking_ext(), parking_con, AST_DEVICE_INUSE);
2831         return res;
2832
2833 }
2834
2835 /*!
2836  * \brief CLI command to list configured features
2837  * \param e
2838  * \param cmd
2839  * \param a
2840  *
2841  * \retval CLI_SUCCESS on success.
2842  * \retval NULL when tab completion is used.
2843  */
2844 static char *handle_feature_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2845 {
2846         int i;
2847         struct ast_call_feature *feature;
2848         char format[] = "%-25s %-7s %-7s\n";
2849
2850         switch (cmd) {
2851         
2852         case CLI_INIT:
2853                 e->command = "features show";
2854                 e->usage =
2855                         "Usage: features show\n"
2856                         "       Lists configured features\n";
2857                 return NULL;
2858         case CLI_GENERATE:
2859                 return NULL;
2860         }
2861
2862         ast_cli(a->fd, format, "Builtin Feature", "Default", "Current");
2863         ast_cli(a->fd, format, "---------------", "-------", "-------");
2864
2865         ast_cli(a->fd, format, "Pickup", "*8", ast_pickup_ext());          /* default hardcoded above, so we'll hardcode it here */
2866
2867         ast_rwlock_rdlock(&features_lock);
2868         for (i = 0; i < FEATURES_COUNT; i++)
2869                 ast_cli(a->fd, format, builtin_features[i].fname, builtin_features[i].default_exten, builtin_features[i].exten);
2870         ast_rwlock_unlock(&features_lock);
2871
2872         ast_cli(a->fd, "\n");
2873         ast_cli(a->fd, format, "Dynamic Feature", "Default", "Current");
2874         ast_cli(a->fd, format, "---------------", "-------", "-------");
2875         if (AST_LIST_EMPTY(&feature_list))
2876                 ast_cli(a->fd, "(none)\n");
2877         else {
2878                 AST_LIST_LOCK(&feature_list);
2879                 AST_LIST_TRAVERSE(&feature_list, feature, feature_entry)
2880                         ast_cli(a->fd, format, feature->sname, "no def", feature->exten);
2881                 AST_LIST_UNLOCK(&feature_list);
2882         }
2883         ast_cli(a->fd, "\nCall parking\n");
2884         ast_cli(a->fd, "------------\n");
2885         ast_cli(a->fd,"%-20s:      %s\n", "Parking extension", parking_ext);
2886         ast_cli(a->fd,"%-20s:      %s\n", "Parking context", parking_con);
2887         ast_cli(a->fd,"%-20s:      %d-%d\n", "Parked call extensions", parking_start, parking_stop);
2888         ast_cli(a->fd,"\n");
2889
2890         return CLI_SUCCESS;
2891 }
2892
2893 int ast_features_reload(void)
2894 {
2895         load_config();
2896
2897         return RESULT_SUCCESS;
2898 }
2899
2900 static char *handle_features_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2901 {
2902         switch (cmd) {  
2903         case CLI_INIT:
2904                 e->command = "features reload";
2905                 e->usage =
2906                         "Usage: features reload\n"
2907                         "       Reloads configured call features from features.conf\n";
2908                 return NULL;
2909         case CLI_GENERATE:
2910                 return NULL;
2911         }
2912         load_config();
2913
2914         return CLI_SUCCESS;
2915 }
2916
2917 static char mandescr_bridge[] =
2918 "Description: Bridge together two channels already in the PBX\n"
2919 "Variables: ( Headers marked with * are required )\n"
2920 "   *Channel1: Channel to Bridge to Channel2\n"
2921 "   *Channel2: Channel to Bridge to Channel1\n"
2922 "        Tone: (Yes|No) Play courtesy tone to Channel 2\n"
2923 "\n";
2924
2925 /*!
2926  * \brief Actual bridge
2927  * \param chan
2928  * \param tmpchan
2929  * 
2930  * Stop hold music, lock both channels, masq channels,
2931  * after bridge return channel to next priority.
2932 */
2933 static void do_bridge_masquerade(struct ast_channel *chan, struct ast_channel *tmpchan)
2934 {
2935         ast_moh_stop(chan);
2936         ast_channel_lock(chan);
2937         ast_setstate(tmpchan, chan->_state);
2938         tmpchan->readformat = chan->readformat;
2939         tmpchan->writeformat = chan->writeformat;
2940         ast_channel_masquerade(tmpchan, chan);
2941         ast_channel_lock(tmpchan);
2942         ast_do_masquerade(tmpchan);
2943         /* when returning from bridge, the channel will continue at the next priority */
2944         ast_explicit_goto(tmpchan, chan->context, chan->exten, chan->priority + 1);
2945         ast_channel_unlock(tmpchan);
2946         ast_channel_unlock(chan);
2947 }
2948
2949 /*!
2950  * \brief Bridge channels together
2951  * \param s
2952  * \param m