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