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