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