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