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