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