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