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