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