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