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