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