8c0600e4898b94322a0469a9853a26404da76fec
[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
67 #define AST_MAX_WATCHERS 256
68
69 enum {
70         AST_FEATURE_FLAG_NEEDSDTMF = (1 << 0),
71         AST_FEATURE_FLAG_ONPEER =    (1 << 1),
72         AST_FEATURE_FLAG_ONSELF =    (1 << 2),
73         AST_FEATURE_FLAG_BYCALLEE =  (1 << 3),
74         AST_FEATURE_FLAG_BYCALLER =  (1 << 4),
75         AST_FEATURE_FLAG_BYBOTH  =   (3 << 3),
76 };
77
78 static char *parkedcall = "ParkedCall";
79
80 static int parkaddhints = 0;                               /*!< Add parking hints automatically */
81 static int parkedcalltransfers = 0;                        /*!< Enable DTMF based transfers on bridge when picking up parked calls */
82 static int parkedcallreparking = 0;                        /*!< Enable DTMF based parking on bridge when picking up parked calls */
83 static int parkingtime = DEFAULT_PARK_TIME;                /*!< No more than 45 seconds parked before you do something with them */
84 static char parking_con[AST_MAX_EXTENSION];                /*!< Context for which parking is made accessible */
85 static char parking_con_dial[AST_MAX_EXTENSION];           /*!< Context for dialback for parking (KLUDGE) */
86 static char parking_ext[AST_MAX_EXTENSION];                /*!< Extension you type to park the call */
87 static char pickup_ext[AST_MAX_EXTENSION];                 /*!< Call pickup extension */
88 static char parkmohclass[MAX_MUSICCLASS];                  /*!< Music class used for parking */
89 static int parking_start;                                  /*!< First available extension for parking */
90 static int parking_stop;                                   /*!< Last available extension for parking */
91
92 static char courtesytone[256];                             /*!< Courtesy tone */
93 static int parkedplay = 0;                                 /*!< Who to play the courtesy tone to */
94 static char xfersound[256];                                /*!< Call transfer sound */
95 static char xferfailsound[256];                            /*!< Call transfer failure sound */
96
97 static int parking_offset;
98 static int parkfindnext;
99
100 static int adsipark;
101
102 static int transferdigittimeout;
103 static int featuredigittimeout;
104 static int comebacktoorigin = 1;
105
106 static int atxfernoanswertimeout;
107
108 static char *registrar = "res_features";                   /*!< Registrar for operations */
109
110 /* module and CLI command definitions */
111 static char *synopsis = "Answer a parked call";
112
113 static char *descrip = "ParkedCall(exten):"
114 "Used to connect to a parked call.  This application is always\n"
115 "registered internally and does not need to be explicitly added\n"
116 "into the dialplan, although you should include the 'parkedcalls'\n"
117 "context.\n";
118
119 static char *parkcall = "Park";
120
121 static char *synopsis2 = "Park yourself";
122
123 static char *descrip2 = "Park():"
124 "Used to park yourself (typically in combination with a supervised\n"
125 "transfer to know the parking space). This application is always\n"
126 "registered internally and does not need to be explicitly added\n"
127 "into the dialplan, although you should include the 'parkedcalls'\n"
128 "context (or the context specified in features.conf).\n\n"
129 "If you set the PARKINGEXTEN variable to an extension in your\n"
130 "parking context, park() will park the call on that extension, unless\n"
131 "it already exists. In that case, execution will continue at next\n"
132 "priority.\n" ;
133
134 static struct ast_app *monitor_app = NULL;
135 static int monitor_ok = 1;
136
137 struct parkeduser {
138         struct ast_channel *chan;                   /*!< Parking channel */
139         struct timeval start;                       /*!< Time the parking started */
140         int parkingnum;                             /*!< Parking lot */
141         char parkingexten[AST_MAX_EXTENSION];       /*!< If set beforehand, parking extension used for this call */
142         char context[AST_MAX_CONTEXT];              /*!< Where to go if our parking time expires */
143         char exten[AST_MAX_EXTENSION];
144         int priority;
145         int parkingtime;                            /*!< Maximum length in parking lot before return */
146         int notquiteyet;
147         char peername[1024];
148         unsigned char moh_trys;
149         struct parkeduser *next;
150 };
151
152 static struct parkeduser *parkinglot;
153
154 AST_MUTEX_DEFINE_STATIC(parking_lock);  /*!< protects all static variables above */
155
156 static pthread_t parking_thread;
157
158 char *ast_parking_ext(void)
159 {
160         return parking_ext;
161 }
162
163 char *ast_pickup_ext(void)
164 {
165         return pickup_ext;
166 }
167
168 struct ast_bridge_thread_obj 
169 {
170         struct ast_bridge_config bconfig;
171         struct ast_channel *chan;
172         struct ast_channel *peer;
173 };
174
175 /*! \brief store context, priority and extension */
176 static void set_c_e_p(struct ast_channel *chan, const char *context, const char *ext, int pri)
177 {
178         ast_copy_string(chan->context, context, sizeof(chan->context));
179         ast_copy_string(chan->exten, ext, sizeof(chan->exten));
180         chan->priority = pri;
181 }
182
183 static void check_goto_on_transfer(struct ast_channel *chan) 
184 {
185         struct ast_channel *xferchan;
186         const char *val = pbx_builtin_getvar_helper(chan, "GOTO_ON_BLINDXFR");
187         char *x, *goto_on_transfer;
188         struct ast_frame *f;
189
190         if (ast_strlen_zero(val))
191                 return;
192
193         goto_on_transfer = ast_strdupa(val);
194
195         if (!(xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan->name)))
196                 return;
197
198         for (x = goto_on_transfer; x && *x; x++) {
199                 if (*x == '^')
200                         *x = '|';
201         }
202         /* Make formats okay */
203         xferchan->readformat = chan->readformat;
204         xferchan->writeformat = chan->writeformat;
205         ast_channel_masquerade(xferchan, chan);
206         ast_parseable_goto(xferchan, goto_on_transfer);
207         xferchan->_state = AST_STATE_UP;
208         ast_clear_flag(xferchan, AST_FLAGS_ALL);        
209         xferchan->_softhangup = 0;
210         if ((f = ast_read(xferchan))) {
211                 ast_frfree(f);
212                 f = NULL;
213                 ast_pbx_start(xferchan);
214         } else {
215                 ast_hangup(xferchan);
216         }
217 }
218
219 static struct ast_channel *ast_feature_request_and_dial(struct ast_channel *caller, const char *type, int format, void *data, int timeout, int *outstate, const char *cid_num, const char *cid_name);
220
221
222 static void *ast_bridge_call_thread(void *data) 
223 {
224         struct ast_bridge_thread_obj *tobj = data;
225
226         tobj->chan->appl = "Transferred Call";
227         tobj->chan->data = tobj->peer->name;
228         tobj->peer->appl = "Transferred Call";
229         tobj->peer->data = tobj->chan->name;
230         if (tobj->chan->cdr) {
231                 ast_cdr_reset(tobj->chan->cdr, NULL);
232                 ast_cdr_setdestchan(tobj->chan->cdr, tobj->peer->name);
233         }
234         if (tobj->peer->cdr) {
235                 ast_cdr_reset(tobj->peer->cdr, NULL);
236                 ast_cdr_setdestchan(tobj->peer->cdr, tobj->chan->name);
237         }
238
239         ast_bridge_call(tobj->peer, tobj->chan, &tobj->bconfig);
240         ast_hangup(tobj->chan);
241         ast_hangup(tobj->peer);
242         bzero(tobj, sizeof(*tobj)); /*! \todo XXX for safety */
243         free(tobj);
244         return NULL;
245 }
246
247 static void ast_bridge_call_thread_launch(void *data) 
248 {
249         pthread_t thread;
250         pthread_attr_t attr;
251         struct sched_param sched;
252
253         pthread_attr_init(&attr);
254         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
255         ast_pthread_create(&thread, &attr,ast_bridge_call_thread, data);
256         pthread_attr_destroy(&attr);
257         memset(&sched, 0, sizeof(sched));
258         pthread_setschedparam(thread, SCHED_RR, &sched);
259 }
260
261 static int adsi_announce_park(struct ast_channel *chan, char *parkingexten)
262 {
263         int res;
264         int justify[5] = {ADSI_JUST_CENT, ADSI_JUST_CENT, ADSI_JUST_CENT, ADSI_JUST_CENT};
265         char tmp[256];
266         char *message[5] = {NULL, NULL, NULL, NULL, NULL};
267
268         snprintf(tmp, sizeof(tmp), "Parked on %s", parkingexten);
269         message[0] = tmp;
270         res = ast_adsi_load_session(chan, NULL, 0, 1);
271         if (res == -1)
272                 return res;
273         return ast_adsi_print(chan, message, justify, 1);
274 }
275
276 /*! \brief Notify metermaids that we've changed an extension */
277 static void notify_metermaids(char *exten, char *context)
278 {
279         if (option_debug > 3)
280                 ast_log(LOG_DEBUG, "Notification of state change to metermaids %s@%s\n", exten, context);
281
282         /* Send notification to devicestate subsystem */
283         ast_device_state_changed("park:%s@%s", exten, context);
284         return;
285 }
286
287 /*! \brief metermaids callback from devicestate.c */
288 static enum ast_device_state metermaidstate(const char *data)
289 {
290         enum ast_device_state res = AST_DEVICE_INVALID;
291         char *context = ast_strdupa(data);
292         char *exten;
293
294         exten = strsep(&context, "@");
295         if (!context)
296                 return res;
297         
298         if (option_debug > 3)
299                 ast_log(LOG_DEBUG, "Checking state of exten %s in context %s\n", exten, context);
300
301         res = ast_exists_extension(NULL, context, exten, 1, NULL);
302
303         if (res == AST_DEVICE_UNKNOWN)
304                 return AST_DEVICE_NOT_INUSE;
305         else
306                 return AST_DEVICE_INUSE;
307 }
308
309 /*! \brief Park a call 
310         \note We put the user in the parking list, then wake up the parking thread to be sure it looks
311         after these channels too */
312 int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeout, int *extout)
313 {
314         struct parkeduser *pu, *cur;
315         int i, x = -1, parking_range;
316         struct ast_context *con;
317         const char *parkingexten;
318         
319         /* Allocate memory for parking data */
320         if (!(pu = ast_calloc(1, sizeof(*pu)))) 
321                 return -1;
322
323         /* Lock parking lot */
324         ast_mutex_lock(&parking_lock);
325         /* Check for channel variable PARKINGEXTEN */
326         parkingexten = pbx_builtin_getvar_helper(chan, "PARKINGEXTEN");
327         if (!ast_strlen_zero(parkingexten)) {
328                 if (ast_exists_extension(NULL, parking_con, parkingexten, 1, NULL)) {
329                         ast_log(LOG_WARNING, "Requested parking extension already exists: %s@%s\n", parkingexten, parking_con);
330                         return 0;       /* Continue execution if possible */
331                 }
332                 ast_copy_string(pu->parkingexten, parkingexten, sizeof(pu->parkingexten));
333         } else {
334                 /* Select parking space within range */
335                 parking_range = parking_stop - parking_start+1;
336                 for (i = 0; i < parking_range; i++) {
337                         x = (i + parking_offset) % parking_range + parking_start;
338                         cur = parkinglot;
339                         while(cur) {
340                                 if (cur->parkingnum == x) 
341                                         break;
342                                 cur = cur->next;
343                         }
344                         if (!cur)
345                                 break;
346                 }
347
348                 if (!(i < parking_range)) {
349                         ast_log(LOG_WARNING, "No more parking spaces\n");
350                         free(pu);
351                         ast_mutex_unlock(&parking_lock);
352                         return -1;
353                 }
354                 /* Set pointer for next parking */
355                 if (parkfindnext) 
356                         parking_offset = x - parking_start + 1;
357         }
358         
359         chan->appl = "Parked Call";
360         chan->data = NULL; 
361
362         pu->chan = chan;
363         
364         /* Put the parked channel on hold if we have two different channels */
365         if (chan != peer) {
366                 ast_indicate_data(pu->chan, AST_CONTROL_HOLD, 
367                         S_OR(parkmohclass, NULL),
368                         !ast_strlen_zero(parkmohclass) ? strlen(parkmohclass) + 1 : 0);
369         }
370         
371         pu->start = ast_tvnow();
372         pu->parkingnum = x;
373         pu->parkingtime = (timeout > 0) ? timeout : parkingtime;
374         if (extout)
375                 *extout = x;
376
377         if (peer) 
378                 ast_copy_string(pu->peername, peer->name, sizeof(pu->peername));
379
380         /* Remember what had been dialed, so that if the parking
381            expires, we try to come back to the same place */
382         ast_copy_string(pu->context, S_OR(chan->macrocontext, chan->context), sizeof(pu->context));
383         ast_copy_string(pu->exten, S_OR(chan->macroexten, chan->exten), sizeof(pu->exten));
384         pu->priority = chan->macropriority ? chan->macropriority : chan->priority;
385         pu->next = parkinglot;
386         parkinglot = pu;
387
388         /* If parking a channel directly, don't quiet yet get parking running on it */
389         if (peer == chan) 
390                 pu->notquiteyet = 1;
391         ast_mutex_unlock(&parking_lock);
392         /* Wake up the (presumably select()ing) thread */
393         pthread_kill(parking_thread, SIGURG);
394         if (option_verbose > 1) 
395                 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));
396
397         if (pu->parkingnum != -1)
398                 snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", x);
399         manager_event(EVENT_FLAG_CALL, "ParkedCall",
400                 "Exten: %s\r\n"
401                 "Channel: %s\r\n"
402                 "From: %s\r\n"
403                 "Timeout: %ld\r\n"
404                 "CallerIDNum: %s\r\n"
405                 "CallerIDName: %s\r\n",
406                 pu->parkingexten, pu->chan->name, peer ? peer->name : "",
407                 (long)pu->start.tv_sec + (long)(pu->parkingtime/1000) - (long)time(NULL),
408                 S_OR(pu->chan->cid.cid_num, "<unknown>"),
409                 S_OR(pu->chan->cid.cid_name, "<unknown>")
410                 );
411
412         if (peer && adsipark && ast_adsi_available(peer)) {
413                 adsi_announce_park(peer, pu->parkingexten);     /* Only supports parking numbers */
414                 ast_adsi_unload_session(peer);
415         }
416
417         con = ast_context_find(parking_con);
418         if (!con) 
419                 con = ast_context_create(NULL, parking_con, registrar);
420         if (!con)       /* Still no context? Bad */
421                 ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", parking_con);
422         else {          /* Add extension to context */
423                 if (!ast_add_extension2(con, 1, pu->parkingexten, 1, NULL, NULL, parkedcall, strdup(pu->parkingexten), ast_free, registrar))
424                         notify_metermaids(pu->parkingexten, parking_con);
425         }
426         /* Tell the peer channel the number of the parking space */
427         if (peer && pu->parkingnum != -1) /* Only say number if it's a number */
428                 ast_say_digits(peer, pu->parkingnum, "", peer->language);
429         if (pu->notquiteyet) {
430                 /* Wake up parking thread if we're really done */
431                 ast_indicate_data(pu->chan, AST_CONTROL_HOLD, 
432                         S_OR(parkmohclass, NULL),
433                         !ast_strlen_zero(parkmohclass) ? strlen(parkmohclass) + 1 : 0);
434                 pu->notquiteyet = 0;
435                 pthread_kill(parking_thread, SIGURG);
436         }
437         return 0;
438 }
439
440 int ast_masq_park_call(struct ast_channel *rchan, struct ast_channel *peer, int timeout, int *extout)
441 {
442         struct ast_channel *chan;
443         struct ast_frame *f;
444
445         /* Make a new, fake channel that we'll use to masquerade in the real one */
446         if (!(chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "Parked/%s",rchan->name))) {
447                 ast_log(LOG_WARNING, "Unable to create parked channel\n");
448                 return -1;
449         }
450
451         /* Make formats okay */
452         chan->readformat = rchan->readformat;
453         chan->writeformat = rchan->writeformat;
454         ast_channel_masquerade(chan, rchan);
455
456         /* Setup the extensions and such */
457         set_c_e_p(chan, rchan->context, rchan->exten, rchan->priority);
458
459         /* Make the masq execute */
460         f = ast_read(chan);
461         if (f)
462                 ast_frfree(f);
463
464         ast_park_call(chan, peer, timeout, extout);
465         return 0;
466 }
467
468
469 #define FEATURE_RETURN_HANGUP           -1
470 #define FEATURE_RETURN_SUCCESSBREAK      0
471 #define FEATURE_RETURN_PBX_KEEPALIVE    AST_PBX_KEEPALIVE
472 #define FEATURE_RETURN_NO_HANGUP_PEER   AST_PBX_NO_HANGUP_PEER
473 #define FEATURE_RETURN_PASSDIGITS        21
474 #define FEATURE_RETURN_STOREDIGITS       22
475 #define FEATURE_RETURN_SUCCESS           23
476
477 #define FEATURE_SENSE_CHAN      (1 << 0)
478 #define FEATURE_SENSE_PEER      (1 << 1)
479
480 /*! \brief
481  * set caller and callee according to the direction
482  */
483 static void set_peers(struct ast_channel **caller, struct ast_channel **callee,
484         struct ast_channel *peer, struct ast_channel *chan, int sense)
485 {
486         if (sense == FEATURE_SENSE_PEER) {
487                 *caller = peer;
488                 *callee = chan;
489         } else {
490                 *callee = peer;
491                 *caller = chan;
492         }
493 }
494
495 /*! \brief support routing for one touch call parking */
496 static int builtin_parkcall(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense)
497 {
498         struct ast_channel *parker;
499         struct ast_channel *parkee;
500         int res = 0;
501         struct ast_module_user *u;
502
503         u = ast_module_user_add(chan);
504
505         set_peers(&parker, &parkee, peer, chan, sense);
506         /* Setup the exten/priority to be s/1 since we don't know
507            where this call should return */
508         strcpy(chan->exten, "s");
509         chan->priority = 1;
510         if (chan->_state != AST_STATE_UP)
511                 res = ast_answer(chan);
512         if (!res)
513                 res = ast_safe_sleep(chan, 1000);
514         if (!res)
515                 res = ast_park_call(parkee, parker, 0, NULL);
516
517         ast_module_user_remove(u);
518
519         if (!res) {
520                 if (sense == FEATURE_SENSE_CHAN)
521                         res = AST_PBX_NO_HANGUP_PEER;
522                 else
523                         res = AST_PBX_KEEPALIVE;
524         }
525         return res;
526
527 }
528
529 static int builtin_automonitor(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense)
530 {
531         char *caller_chan_id = NULL, *callee_chan_id = NULL, *args = NULL, *touch_filename = NULL;
532         int x = 0;
533         size_t len;
534         struct ast_channel *caller_chan, *callee_chan;
535
536         if (!monitor_ok) {
537                 ast_log(LOG_ERROR,"Cannot record the call. The monitor application is disabled.\n");
538                 return -1;
539         }
540
541         if (!monitor_app && !(monitor_app = pbx_findapp("Monitor"))) {
542                 monitor_ok = 0;
543                 ast_log(LOG_ERROR,"Cannot record the call. The monitor application is disabled.\n");
544                 return -1;
545         }
546
547         set_peers(&caller_chan, &callee_chan, peer, chan, sense);
548
549         if (!ast_strlen_zero(courtesytone)) {
550                 if (ast_autoservice_start(callee_chan))
551                         return -1;
552                 if (ast_stream_and_wait(caller_chan, courtesytone, "")) {
553                         ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
554                         ast_autoservice_stop(callee_chan);
555                         return -1;
556                 }
557                 if (ast_autoservice_stop(callee_chan))
558                         return -1;
559         }
560         
561         if (callee_chan->monitor) {
562                 if (option_verbose > 3)
563                         ast_verbose(VERBOSE_PREFIX_3 "User hit '%s' to stop recording call.\n", code);
564                 ast_monitor_stop(callee_chan, 1);
565                 return FEATURE_RETURN_SUCCESS;
566         }
567
568         if (caller_chan && callee_chan) {
569                 const char *touch_format = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_FORMAT");
570                 const char *touch_monitor = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR");
571
572                 if (!touch_format)
573                         touch_format = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR_FORMAT");
574
575                 if (!touch_monitor)
576                         touch_monitor = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR");
577         
578                 if (touch_monitor) {
579                         len = strlen(touch_monitor) + 50;
580                         args = alloca(len);
581                         touch_filename = alloca(len);
582                         snprintf(touch_filename, len, "auto-%ld-%s", (long)time(NULL), touch_monitor);
583                         snprintf(args, len, "%s|%s|m", (touch_format) ? touch_format : "wav", touch_filename);
584                 } else {
585                         caller_chan_id = ast_strdupa(S_OR(caller_chan->cid.cid_num, caller_chan->name));
586                         callee_chan_id = ast_strdupa(S_OR(callee_chan->cid.cid_num, callee_chan->name));
587                         len = strlen(caller_chan_id) + strlen(callee_chan_id) + 50;
588                         args = alloca(len);
589                         touch_filename = alloca(len);
590                         snprintf(touch_filename, len, "auto-%ld-%s-%s", (long)time(NULL), caller_chan_id, callee_chan_id);
591                         snprintf(args, len, "%s|%s|m", S_OR(touch_format, "wav"), touch_filename);
592                 }
593
594                 for( x = 0; x < strlen(args); x++) {
595                         if (args[x] == '/')
596                                 args[x] = '-';
597                 }
598                 
599                 if (option_verbose > 3)
600                         ast_verbose(VERBOSE_PREFIX_3 "User hit '%s' to record call. filename: %s\n", code, args);
601
602                 pbx_exec(callee_chan, monitor_app, args);
603                 pbx_builtin_setvar_helper(callee_chan, "TOUCH_MONITOR_OUTPUT", touch_filename);
604                 pbx_builtin_setvar_helper(caller_chan, "TOUCH_MONITOR_OUTPUT", touch_filename);
605         
606                 return FEATURE_RETURN_SUCCESS;
607         }
608         
609         ast_log(LOG_NOTICE,"Cannot record the call. One or both channels have gone away.\n");   
610         return -1;
611 }
612
613 static int builtin_disconnect(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense)
614 {
615         if (option_verbose > 3)
616                 ast_verbose(VERBOSE_PREFIX_3 "User hit '%s' to disconnect call.\n", code);
617         return FEATURE_RETURN_HANGUP;
618 }
619
620 static int finishup(struct ast_channel *chan)
621 {
622         ast_indicate(chan, AST_CONTROL_UNHOLD);
623   
624         return ast_autoservice_stop(chan);
625 }
626
627 /*! \brief Find the context for the transfer */
628 static const char *real_ctx(struct ast_channel *transferer, struct ast_channel *transferee)
629 {
630         const char *s = pbx_builtin_getvar_helper(transferer, "TRANSFER_CONTEXT");
631         if (ast_strlen_zero(s))
632                 s = pbx_builtin_getvar_helper(transferee, "TRANSFER_CONTEXT");
633         if (ast_strlen_zero(s)) /* Use the non-macro context to transfer the call XXX ? */
634                 s = transferer->macrocontext;
635         if (ast_strlen_zero(s))
636                 s = transferer->context;
637         return s;  
638 }
639
640 static int builtin_blindtransfer(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense)
641 {
642         struct ast_channel *transferer;
643         struct ast_channel *transferee;
644         const char *transferer_real_context;
645         char xferto[256];
646         int res;
647
648         set_peers(&transferer, &transferee, peer, chan, sense);
649         transferer_real_context = real_ctx(transferer, transferee);
650         /* Start autoservice on chan while we talk to the originator */
651         ast_autoservice_start(transferee);
652         ast_indicate(transferee, AST_CONTROL_HOLD);
653
654         memset(xferto, 0, sizeof(xferto));
655         
656         /* Transfer */
657         res = ast_stream_and_wait(transferer, "pbx-transfer", AST_DIGIT_ANY);
658         if (res < 0) {
659                 finishup(transferee);
660                 return -1; /* error ? */
661         }
662         if (res > 0)    /* If they've typed a digit already, handle it */
663                 xferto[0] = (char) res;
664
665         ast_stopstream(transferer);
666         res = ast_app_dtget(transferer, transferer_real_context, xferto, sizeof(xferto), 100, transferdigittimeout);
667         if (res < 0) {  /* hangup, would be 0 for invalid and 1 for valid */
668                 finishup(transferee);
669                 return res;
670         }
671         if (!strcmp(xferto, ast_parking_ext())) {
672                 res = finishup(transferee);
673                 if (res)
674                         res = -1;
675                 else if (!ast_park_call(transferee, transferer, 0, NULL)) {     /* success */
676                         /* We return non-zero, but tell the PBX not to hang the channel when
677                            the thread dies -- We have to be careful now though.  We are responsible for 
678                            hanging up the channel, else it will never be hung up! */
679
680                         return (transferer == peer) ? AST_PBX_KEEPALIVE : AST_PBX_NO_HANGUP_PEER;
681                 } else {
682                         ast_log(LOG_WARNING, "Unable to park call %s\n", transferee->name);
683                 }
684                 /*! \todo XXX Maybe we should have another message here instead of invalid extension XXX */
685         } else if (ast_exists_extension(transferee, transferer_real_context, xferto, 1, transferer->cid.cid_num)) {
686                 pbx_builtin_setvar_helper(peer, "BLINDTRANSFER", chan->name);
687                 pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", peer->name);
688                 res=finishup(transferee);
689                 if (!transferee->pbx) {
690                         /* Doh!  Use our handy async_goto functions */
691                         if (option_verbose > 2) 
692                                 ast_verbose(VERBOSE_PREFIX_3 "Transferring %s to '%s' (context %s) priority 1\n"
693                                                                 ,transferee->name, xferto, transferer_real_context);
694                         if (ast_async_goto(transferee, transferer_real_context, xferto, 1))
695                                 ast_log(LOG_WARNING, "Async goto failed :-(\n");
696                         res = -1;
697                 } else {
698                         /* Set the channel's new extension, since it exists, using transferer context */
699                         set_c_e_p(transferee, transferer_real_context, xferto, 0);
700                 }
701                 check_goto_on_transfer(transferer);
702                 return res;
703         } else {
704                 if (option_verbose > 2) 
705                         ast_verbose(VERBOSE_PREFIX_3 "Unable to find extension '%s' in context '%s'\n", xferto, transferer_real_context);
706         }
707         if (ast_stream_and_wait(transferer, xferfailsound, AST_DIGIT_ANY) < 0 ) {
708                 finishup(transferee);
709                 return -1;
710         }
711         ast_stopstream(transferer);
712         res = finishup(transferee);
713         if (res) {
714                 if (option_verbose > 1)
715                         ast_verbose(VERBOSE_PREFIX_2 "Hungup during autoservice stop on '%s'\n", transferee->name);
716                 return res;
717         }
718         return FEATURE_RETURN_SUCCESS;
719 }
720
721 static int check_compat(struct ast_channel *c, struct ast_channel *newchan)
722 {
723         if (ast_channel_make_compatible(c, newchan) < 0) {
724                 ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n",
725                         c->name, newchan->name);
726                 ast_hangup(newchan);
727                 return -1;
728         }
729         return 0;
730 }
731
732 static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense)
733 {
734         struct ast_channel *transferer;
735         struct ast_channel *transferee;
736         const char *transferer_real_context;
737         char xferto[256] = "";
738         int res;
739         int outstate=0;
740         struct ast_channel *newchan;
741         struct ast_channel *xferchan;
742         struct ast_bridge_thread_obj *tobj;
743         struct ast_bridge_config bconfig;
744         struct ast_frame *f;
745         int l;
746
747         if (option_debug)
748                 ast_log(LOG_DEBUG, "Executing Attended Transfer %s, %s (sense=%d) \n", chan->name, peer->name, sense);
749         set_peers(&transferer, &transferee, peer, chan, sense);
750         transferer_real_context = real_ctx(transferer, transferee);
751         /* Start autoservice on chan while we talk to the originator */
752         ast_autoservice_start(transferee);
753         ast_indicate(transferee, AST_CONTROL_HOLD);
754         
755         /* Transfer */
756         res = ast_stream_and_wait(transferer, "pbx-transfer", AST_DIGIT_ANY);
757         if (res < 0) {
758                 finishup(transferee);
759                 return res;
760         }
761         if (res > 0) /* If they've typed a digit already, handle it */
762                 xferto[0] = (char) res;
763
764         /* this is specific of atxfer */
765         res = ast_app_dtget(transferer, transferer_real_context, xferto, sizeof(xferto), 100, transferdigittimeout);
766         if (res < 0) {  /* hangup, would be 0 for invalid and 1 for valid */
767                 finishup(transferee);
768                 return res;
769         }
770         if (res == 0) {
771                 ast_log(LOG_WARNING, "Did not read data.\n");
772                 finishup(transferee);
773                 if (ast_stream_and_wait(transferer, "beeperr", ""))
774                         return -1;
775                 return FEATURE_RETURN_SUCCESS;
776         }
777
778         /* valid extension, res == 1 */
779         if (!ast_exists_extension(transferer, transferer_real_context, xferto, 1, transferer->cid.cid_num)) {
780                 ast_log(LOG_WARNING, "Extension %s does not exist in context %s\n",xferto,transferer_real_context);
781                 finishup(transferee);
782                 if (ast_stream_and_wait(transferer, "beeperr", ""))
783                         return -1;
784                 return FEATURE_RETURN_SUCCESS;
785         }
786
787         l = strlen(xferto);
788         snprintf(xferto + l, sizeof(xferto) - l, "@%s/n", transferer_real_context);     /* append context */
789         newchan = ast_feature_request_and_dial(transferer, "Local", ast_best_codec(transferer->nativeformats),
790                 xferto, atxfernoanswertimeout, &outstate, transferer->cid.cid_num, transferer->cid.cid_name);
791         ast_indicate(transferer, -1);
792         if (!newchan) {
793                 finishup(transferee);
794                 /* any reason besides user requested cancel and busy triggers the failed sound */
795                 if (outstate != AST_CONTROL_UNHOLD && outstate != AST_CONTROL_BUSY &&
796                                 ast_stream_and_wait(transferer, xferfailsound, ""))
797                         return -1;
798                 return FEATURE_RETURN_SUCCESS;
799         }
800
801         if (check_compat(transferer, newchan))
802                 return -1;
803         memset(&bconfig,0,sizeof(struct ast_bridge_config));
804         ast_set_flag(&(bconfig.features_caller), AST_FEATURE_DISCONNECT);
805         ast_set_flag(&(bconfig.features_callee), AST_FEATURE_DISCONNECT);
806         res = ast_bridge_call(transferer, newchan, &bconfig);
807         if (newchan->_softhangup || newchan->_state != AST_STATE_UP || !transferer->_softhangup) {
808                 ast_hangup(newchan);
809                 if (ast_stream_and_wait(transferer, xfersound, ""))
810                         ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
811                 finishup(transferee);
812                 transferer->_softhangup = 0;
813                 return FEATURE_RETURN_SUCCESS;
814         }
815         
816         if (check_compat(transferee, newchan))
817                 return -1;
818
819         ast_indicate(transferee, AST_CONTROL_UNHOLD);
820         
821         if ((ast_autoservice_stop(transferee) < 0)
822            || (ast_waitfordigit(transferee, 100) < 0)
823            || (ast_waitfordigit(newchan, 100) < 0) 
824            || ast_check_hangup(transferee) 
825            || ast_check_hangup(newchan)) {
826                 ast_hangup(newchan);
827                 return -1;
828         }
829
830         xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "Transfered/%s", transferee->name);
831         if (!xferchan) {
832                 ast_hangup(newchan);
833                 return -1;
834         }
835         /* Make formats okay */
836         xferchan->readformat = transferee->readformat;
837         xferchan->writeformat = transferee->writeformat;
838         ast_channel_masquerade(xferchan, transferee);
839         ast_explicit_goto(xferchan, transferee->context, transferee->exten, transferee->priority);
840         xferchan->_state = AST_STATE_UP;
841         ast_clear_flag(xferchan, AST_FLAGS_ALL);        
842         xferchan->_softhangup = 0;
843
844         if ((f = ast_read(xferchan)))
845                 ast_frfree(f);
846
847         newchan->_state = AST_STATE_UP;
848         ast_clear_flag(newchan, AST_FLAGS_ALL); 
849         newchan->_softhangup = 0;
850
851         tobj = ast_calloc(1, sizeof(struct ast_bridge_thread_obj));
852         if (!tobj) {
853                 ast_hangup(xferchan);
854                 ast_hangup(newchan);
855                 return -1;
856         }
857         tobj->chan = xferchan;
858         tobj->peer = newchan;
859         tobj->bconfig = *config;
860
861         if (ast_stream_and_wait(newchan, xfersound, ""))
862                 ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
863         ast_bridge_call_thread_launch(tobj);
864         return -1;      /* XXX meaning the channel is bridged ? */
865 }
866
867
868 /* add atxfer and automon as undefined so you can only use em if you configure them */
869 #define FEATURES_COUNT (sizeof(builtin_features) / sizeof(builtin_features[0]))
870
871 struct ast_call_feature builtin_features[] = 
872  {
873         { AST_FEATURE_REDIRECT, "Blind Transfer", "blindxfer", "#", "#", builtin_blindtransfer, AST_FEATURE_FLAG_NEEDSDTMF, "" },
874         { AST_FEATURE_REDIRECT, "Attended Transfer", "atxfer", "", "", builtin_atxfer, AST_FEATURE_FLAG_NEEDSDTMF, "" },
875         { AST_FEATURE_AUTOMON, "One Touch Monitor", "automon", "", "", builtin_automonitor, AST_FEATURE_FLAG_NEEDSDTMF, "" },
876         { AST_FEATURE_DISCONNECT, "Disconnect Call", "disconnect", "*", "*", builtin_disconnect, AST_FEATURE_FLAG_NEEDSDTMF, "" },
877         { AST_FEATURE_PARKCALL, "Park Call", "parkcall", "", "", builtin_parkcall, AST_FEATURE_FLAG_NEEDSDTMF, "" },
878 };
879
880
881 static AST_LIST_HEAD_STATIC(feature_list,ast_call_feature);
882
883 /*! \brief register new feature into feature_list*/
884 void ast_register_feature(struct ast_call_feature *feature)
885 {
886         if (!feature) {
887                 ast_log(LOG_NOTICE,"You didn't pass a feature!\n");
888                 return;
889         }
890   
891         AST_LIST_LOCK(&feature_list);
892         AST_LIST_INSERT_HEAD(&feature_list,feature,feature_entry);
893         AST_LIST_UNLOCK(&feature_list);
894
895         if (option_verbose >= 2) 
896                 ast_verbose(VERBOSE_PREFIX_2 "Registered Feature '%s'\n",feature->sname);
897 }
898
899 /*! \brief unregister feature from feature_list */
900 void ast_unregister_feature(struct ast_call_feature *feature)
901 {
902         if (!feature)
903                 return;
904
905         AST_LIST_LOCK(&feature_list);
906         AST_LIST_REMOVE(&feature_list,feature,feature_entry);
907         AST_LIST_UNLOCK(&feature_list);
908         free(feature);
909 }
910
911 /*! \brief Remove all features in the list */
912 static void ast_unregister_features(void)
913 {
914         struct ast_call_feature *feature;
915
916         AST_LIST_LOCK(&feature_list);
917         while ((feature = AST_LIST_REMOVE_HEAD(&feature_list,feature_entry)))
918                 free(feature);
919         AST_LIST_UNLOCK(&feature_list);
920 }
921
922 /*! \brief find a feature by name */
923 static struct ast_call_feature *find_feature(char *name)
924 {
925         struct ast_call_feature *tmp;
926
927         AST_LIST_LOCK(&feature_list);
928         AST_LIST_TRAVERSE(&feature_list, tmp, feature_entry) {
929                 if (!strcasecmp(tmp->sname, name))
930                         break;
931         }
932         AST_LIST_UNLOCK(&feature_list);
933
934         return tmp;
935 }
936
937 /*! \brief exec an app by feature */
938 static int feature_exec_app(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense)
939 {
940         struct ast_app *app;
941         struct ast_call_feature *feature;
942         struct ast_channel *work, *idle;
943         int res;
944
945         AST_LIST_LOCK(&feature_list);
946         AST_LIST_TRAVERSE(&feature_list, feature, feature_entry) {
947                 if (!strcasecmp(feature->exten, code))
948                         break;
949         }
950         AST_LIST_UNLOCK(&feature_list);
951
952         if (!feature) { /* shouldn't ever happen! */
953                 ast_log(LOG_NOTICE, "Found feature before, but at execing we've lost it??\n");
954                 return -1; 
955         }
956
957         if (sense == FEATURE_SENSE_CHAN) {
958                 if (!ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLER))
959                         return FEATURE_RETURN_PASSDIGITS;
960                 if (ast_test_flag(feature, AST_FEATURE_FLAG_ONSELF)) {
961                         work = chan;
962                         idle = peer;
963                 } else {
964                         work = peer;
965                         idle = chan;
966                 }
967         } else {
968                 if (!ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLEE))
969                         return FEATURE_RETURN_PASSDIGITS;
970                 if (ast_test_flag(feature, AST_FEATURE_FLAG_ONSELF)) {
971                         work = peer;
972                         idle = chan;
973                 } else {
974                         work = chan;
975                         idle = peer;
976                 }
977         }
978
979         if (!(app = pbx_findapp(feature->app))) {
980                 ast_log(LOG_WARNING, "Could not find application (%s)\n", feature->app);
981                 return -2;
982         }
983
984         ast_autoservice_start(idle);
985         
986         if (!ast_strlen_zero(feature->moh_class))
987                 ast_moh_start(idle, feature->moh_class, NULL);
988
989         res = pbx_exec(work, app, feature->app_args);
990
991         if (!ast_strlen_zero(feature->moh_class))
992                 ast_moh_stop(idle);
993
994         ast_autoservice_stop(idle);
995
996         if (res == AST_PBX_KEEPALIVE)
997                 return FEATURE_RETURN_PBX_KEEPALIVE;
998         else if (res == AST_PBX_NO_HANGUP_PEER)
999                 return FEATURE_RETURN_NO_HANGUP_PEER;
1000         else if (res)
1001                 return FEATURE_RETURN_SUCCESSBREAK;
1002         
1003         return FEATURE_RETURN_SUCCESS;  /*! \todo XXX should probably return res */
1004 }
1005
1006 static void unmap_features(void)
1007 {
1008         int x;
1009         for (x = 0; x < FEATURES_COUNT; x++)
1010                 strcpy(builtin_features[x].exten, builtin_features[x].default_exten);
1011 }
1012
1013 static int remap_feature(const char *name, const char *value)
1014 {
1015         int x;
1016         int res = -1;
1017         for (x = 0; x < FEATURES_COUNT; x++) {
1018                 if (!strcasecmp(name, builtin_features[x].sname)) {
1019                         ast_copy_string(builtin_features[x].exten, value, sizeof(builtin_features[x].exten));
1020                         if (option_verbose > 1)
1021                                 ast_verbose(VERBOSE_PREFIX_2 "Remapping feature %s (%s) to sequence '%s'\n", builtin_features[x].fname, builtin_features[x].sname, builtin_features[x].exten);
1022                         res = 0;
1023                 } else if (!strcmp(value, builtin_features[x].exten)) 
1024                         ast_log(LOG_WARNING, "Sequence '%s' already mapped to function %s (%s) while assigning to %s\n", value, builtin_features[x].fname, builtin_features[x].sname, name);
1025         }
1026         return res;
1027 }
1028
1029 static int ast_feature_interpret(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense)
1030 {
1031         int x;
1032         struct ast_flags features;
1033         int res = FEATURE_RETURN_PASSDIGITS;
1034         struct ast_call_feature *feature;
1035         const char *dynamic_features=pbx_builtin_getvar_helper(chan,"DYNAMIC_FEATURES");
1036
1037         if (sense == FEATURE_SENSE_CHAN)
1038                 ast_copy_flags(&features, &(config->features_caller), AST_FLAGS_ALL);   
1039         else
1040                 ast_copy_flags(&features, &(config->features_callee), AST_FLAGS_ALL);   
1041         if (option_debug > 2)
1042                 ast_log(LOG_DEBUG, "Feature interpret: chan=%s, peer=%s, sense=%d, features=%d\n", chan->name, peer->name, sense, features.flags);
1043
1044         for (x=0; x < FEATURES_COUNT; x++) {
1045                 if ((ast_test_flag(&features, builtin_features[x].feature_mask)) &&
1046                     !ast_strlen_zero(builtin_features[x].exten)) {
1047                         /* Feature is up for consideration */
1048                         if (!strcmp(builtin_features[x].exten, code)) {
1049                                 res = builtin_features[x].operation(chan, peer, config, code, sense);
1050                                 break;
1051                         } else if (!strncmp(builtin_features[x].exten, code, strlen(code))) {
1052                                 if (res == FEATURE_RETURN_PASSDIGITS)
1053                                         res = FEATURE_RETURN_STOREDIGITS;
1054                         }
1055                 }
1056         }
1057
1058
1059         if (!ast_strlen_zero(dynamic_features)) {
1060                 char *tmp = ast_strdupa(dynamic_features);
1061                 char *tok;
1062
1063                 while ((tok = strsep(&tmp, "#")) != NULL) {
1064                         feature = find_feature(tok);
1065                         
1066                         if (feature) {
1067                                 /* Feature is up for consideration */
1068                                 if (!strcmp(feature->exten, code)) {
1069                                         if (option_verbose > 2)
1070                                                 ast_verbose(VERBOSE_PREFIX_3 " Feature Found: %s exten: %s\n",feature->sname, tok);
1071                                         res = feature->operation(chan, peer, config, code, sense);
1072                                         break;
1073                                 } else if (!strncmp(feature->exten, code, strlen(code))) {
1074                                         res = FEATURE_RETURN_STOREDIGITS;
1075                                 }
1076                         }
1077                 }
1078         }
1079         
1080         return res;
1081 }
1082
1083 static void set_config_flags(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config)
1084 {
1085         int x;
1086         
1087         ast_clear_flag(config, AST_FLAGS_ALL);  
1088         for (x = 0; x < FEATURES_COUNT; x++) {
1089                 if (ast_test_flag(builtin_features + x, AST_FEATURE_FLAG_NEEDSDTMF)) {
1090                         if (ast_test_flag(&(config->features_caller), builtin_features[x].feature_mask))
1091                                 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
1092
1093                         if (ast_test_flag(&(config->features_callee), builtin_features[x].feature_mask))
1094                                 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
1095                 }
1096         }
1097         
1098         if (chan && peer && !(ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_0) && ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_1))) {
1099                 const char *dynamic_features = pbx_builtin_getvar_helper(chan, "DYNAMIC_FEATURES");
1100
1101                 if (dynamic_features) {
1102                         char *tmp = ast_strdupa(dynamic_features);
1103                         char *tok;
1104                         struct ast_call_feature *feature;
1105
1106                         /* while we have a feature */
1107                         while ((tok = strsep(&tmp, "#"))) {
1108                                 if ((feature = find_feature(tok)) && ast_test_flag(feature, AST_FEATURE_FLAG_NEEDSDTMF)) {
1109                                         if (ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLER))
1110                                                 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
1111                                         if (ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLEE))
1112                                                 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
1113                                 }
1114                         }
1115                 }
1116         }
1117 }
1118
1119 /*! \todo XXX Check - this is very similar to the code in channel.c */
1120 static struct ast_channel *ast_feature_request_and_dial(struct ast_channel *caller, const char *type, int format, void *data, int timeout, int *outstate, const char *cid_num, const char *cid_name)
1121 {
1122         int state = 0;
1123         int cause = 0;
1124         int to;
1125         struct ast_channel *chan;
1126         struct ast_channel *monitor_chans[2];
1127         struct ast_channel *active_channel;
1128         int res = 0, ready = 0;
1129         
1130         if ((chan = ast_request(type, format, data, &cause))) {
1131                 ast_set_callerid(chan, cid_num, cid_name, cid_num);
1132                 ast_channel_inherit_variables(caller, chan);    
1133                 pbx_builtin_setvar_helper(chan, "TRANSFERERNAME", caller->name);
1134                 if (!ast_call(chan, data, timeout)) {
1135                         struct timeval started;
1136                         int x, len = 0;
1137                         char *disconnect_code = NULL, *dialed_code = NULL;
1138
1139                         ast_indicate(caller, AST_CONTROL_RINGING);
1140                         /* support dialing of the featuremap disconnect code while performing an attended tranfer */
1141                         for (x=0; x < FEATURES_COUNT; x++) {
1142                                 if (strcasecmp(builtin_features[x].sname, "disconnect"))
1143                                         continue;
1144
1145                                 disconnect_code = builtin_features[x].exten;
1146                                 len = strlen(disconnect_code) + 1;
1147                                 dialed_code = alloca(len);
1148                                 memset(dialed_code, 0, len);
1149                                 break;
1150                         }
1151                         x = 0;
1152                         started = ast_tvnow();
1153                         to = timeout;
1154                         while (!ast_check_hangup(caller) && timeout && (chan->_state != AST_STATE_UP)) {
1155                                 struct ast_frame *f = NULL;
1156
1157                                 monitor_chans[0] = caller;
1158                                 monitor_chans[1] = chan;
1159                                 active_channel = ast_waitfor_n(monitor_chans, 2, &to);
1160
1161                                 /* see if the timeout has been violated */
1162                                 if(ast_tvdiff_ms(ast_tvnow(), started) > timeout) {
1163                                         state = AST_CONTROL_UNHOLD;
1164                                         ast_log(LOG_NOTICE, "We exceeded our AT-timeout\n");
1165                                         break; /*doh! timeout*/
1166                                 }
1167
1168                                 if (!active_channel)
1169                                         continue;
1170
1171                                 if (chan && (chan == active_channel)){
1172                                         f = ast_read(chan);
1173                                         if (f == NULL) { /*doh! where'd he go?*/
1174                                                 state = AST_CONTROL_HANGUP;
1175                                                 res = 0;
1176                                                 break;
1177                                         }
1178                                         
1179                                         if (f->frametype == AST_FRAME_CONTROL || f->frametype == AST_FRAME_DTMF || f->frametype == AST_FRAME_TEXT) {
1180                                                 if (f->subclass == AST_CONTROL_RINGING) {
1181                                                         state = f->subclass;
1182                                                         if (option_verbose > 2)
1183                                                                 ast_verbose( VERBOSE_PREFIX_3 "%s is ringing\n", chan->name);
1184                                                         ast_indicate(caller, AST_CONTROL_RINGING);
1185                                                 } else if ((f->subclass == AST_CONTROL_BUSY) || (f->subclass == AST_CONTROL_CONGESTION)) {
1186                                                         state = f->subclass;
1187                                                         if (option_verbose > 2)
1188                                                                 ast_verbose( VERBOSE_PREFIX_3 "%s is busy\n", chan->name);
1189                                                         ast_indicate(caller, AST_CONTROL_BUSY);
1190                                                         ast_frfree(f);
1191                                                         f = NULL;
1192                                                         break;
1193                                                 } else if (f->subclass == AST_CONTROL_ANSWER) {
1194                                                         /* This is what we are hoping for */
1195                                                         state = f->subclass;
1196                                                         ast_frfree(f);
1197                                                         f = NULL;
1198                                                         ready=1;
1199                                                         break;
1200                                                 } else {
1201                                                         ast_log(LOG_NOTICE, "Don't know what to do about control frame: %d\n", f->subclass);
1202                                                 }
1203                                                 /* else who cares */
1204                                         }
1205
1206                                 } else if (caller && (active_channel == caller)) {
1207                                         f = ast_read(caller);
1208                                         if (f == NULL) { /*doh! where'd he go?*/
1209                                                 if (caller->_softhangup && !chan->_softhangup) {
1210                                                         /* make this a blind transfer */
1211                                                         ready = 1;
1212                                                         break;
1213                                                 }
1214                                                 state = AST_CONTROL_HANGUP;
1215                                                 res = 0;
1216                                                 break;
1217                                         }
1218                                         
1219                                         if (f->frametype == AST_FRAME_DTMF) {
1220                                                 dialed_code[x++] = f->subclass;
1221                                                 dialed_code[x] = '\0';
1222                                                 if (strlen(dialed_code) == len) {
1223                                                         x = 0;
1224                                                 } else if (x && strncmp(dialed_code, disconnect_code, x)) {
1225                                                         x = 0;
1226                                                         dialed_code[x] = '\0';
1227                                                 }
1228                                                 if (*dialed_code && !strcmp(dialed_code, disconnect_code)) {
1229                                                         /* Caller Canceled the call */
1230                                                         state = AST_CONTROL_UNHOLD;
1231                                                         ast_frfree(f);
1232                                                         f = NULL;
1233                                                         break;
1234                                                 }
1235                                         }
1236                                 }
1237                                 if (f)
1238                                         ast_frfree(f);
1239                         } /* end while */
1240                 } else
1241                         ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
1242         } else {
1243                 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
1244                 switch(cause) {
1245                 case AST_CAUSE_BUSY:
1246                         state = AST_CONTROL_BUSY;
1247                         break;
1248                 case AST_CAUSE_CONGESTION:
1249                         state = AST_CONTROL_CONGESTION;
1250                         break;
1251                 }
1252         }
1253         
1254         ast_indicate(caller, -1);
1255         if (chan && ready) {
1256                 if (chan->_state == AST_STATE_UP) 
1257                         state = AST_CONTROL_ANSWER;
1258                 res = 0;
1259         } else if(chan) {
1260                 res = -1;
1261                 ast_hangup(chan);
1262                 chan = NULL;
1263         } else {
1264                 res = -1;
1265         }
1266         
1267         if (outstate)
1268                 *outstate = state;
1269
1270         if (chan && res <= 0) {
1271                 if (chan->cdr || (chan->cdr = ast_cdr_alloc())) {
1272                         char tmp[256];
1273                         ast_cdr_init(chan->cdr, chan);
1274                         snprintf(tmp, 256, "%s/%s", type, (char *)data);
1275                         ast_cdr_setapp(chan->cdr,"Dial",tmp);
1276                         ast_cdr_update(chan);
1277                         ast_cdr_start(chan->cdr);
1278                         ast_cdr_end(chan->cdr);
1279                         /* If the cause wasn't handled properly */
1280                         if (ast_cdr_disposition(chan->cdr,chan->hangupcause))
1281                                 ast_cdr_failed(chan->cdr);
1282                 } else {
1283                         ast_log(LOG_WARNING, "Unable to create Call Detail Record\n");
1284                 }
1285         }
1286         
1287         return chan;
1288 }
1289
1290 int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast_bridge_config *config)
1291 {
1292         /* Copy voice back and forth between the two channels.  Give the peer
1293            the ability to transfer calls with '#<extension' syntax. */
1294         struct ast_frame *f;
1295         struct ast_channel *who;
1296         char chan_featurecode[FEATURE_MAX_LEN + 1]="";
1297         char peer_featurecode[FEATURE_MAX_LEN + 1]="";
1298         int res;
1299         int diff;
1300         int hasfeatures=0;
1301         int hadfeatures=0;
1302         struct ast_option_header *aoh;
1303         struct ast_bridge_config backup_config;
1304
1305         memset(&backup_config, 0, sizeof(backup_config));
1306
1307         config->start_time = ast_tvnow();
1308
1309         if (chan && peer) {
1310                 pbx_builtin_setvar_helper(chan, "BRIDGEPEER", peer->name);
1311                 pbx_builtin_setvar_helper(peer, "BRIDGEPEER", chan->name);
1312         } else if (chan)
1313                 pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", NULL);
1314
1315         if (monitor_ok) {
1316                 const char *monitor_exec;
1317                 struct ast_channel *src = NULL;
1318                 if (!monitor_app) { 
1319                         if (!(monitor_app = pbx_findapp("Monitor")))
1320                                 monitor_ok=0;
1321                 }
1322                 if ((monitor_exec = pbx_builtin_getvar_helper(chan, "AUTO_MONITOR"))) 
1323                         src = chan;
1324                 else if ((monitor_exec = pbx_builtin_getvar_helper(peer, "AUTO_MONITOR")))
1325                         src = peer;
1326                 if (monitor_app && src) {
1327                         char *tmp = ast_strdupa(monitor_exec);
1328                         pbx_exec(src, monitor_app, tmp);
1329                 }
1330         }
1331         
1332         set_config_flags(chan, peer, config);
1333         config->firstpass = 1;
1334
1335         /* Answer if need be */
1336         if (ast_answer(chan))
1337                 return -1;
1338         peer->appl = "Bridged Call";
1339         peer->data = chan->name;
1340
1341         /* copy the userfield from the B-leg to A-leg if applicable */
1342         if (chan->cdr && peer->cdr && !ast_strlen_zero(peer->cdr->userfield)) {
1343                 char tmp[256];
1344                 if (!ast_strlen_zero(chan->cdr->userfield)) {
1345                         snprintf(tmp, sizeof(tmp), "%s;%s", chan->cdr->userfield, peer->cdr->userfield);
1346                         ast_cdr_appenduserfield(chan, tmp);
1347                 } else
1348                         ast_cdr_setuserfield(chan, peer->cdr->userfield);
1349                 /* free the peer's cdr without ast_cdr_free complaining */
1350                 free(peer->cdr);
1351                 peer->cdr = NULL;
1352         }
1353         for (;;) {
1354                 struct ast_channel *other;      /* used later */
1355
1356                 res = ast_channel_bridge(chan, peer, config, &f, &who);
1357
1358                 if (config->feature_timer) {
1359                         /* Update time limit for next pass */
1360                         diff = ast_tvdiff_ms(ast_tvnow(), config->start_time);
1361                         config->feature_timer -= diff;
1362                         if (hasfeatures) {
1363                                 /* Running on backup config, meaning a feature might be being
1364                                    activated, but that's no excuse to keep things going 
1365                                    indefinitely! */
1366                                 if (backup_config.feature_timer && ((backup_config.feature_timer -= diff) <= 0)) {
1367                                         if (option_debug)
1368                                                 ast_log(LOG_DEBUG, "Timed out, realtime this time!\n");
1369                                         config->feature_timer = 0;
1370                                         who = chan;
1371                                         if (f)
1372                                                 ast_frfree(f);
1373                                         f = NULL;
1374                                         res = 0;
1375                                 } else if (config->feature_timer <= 0) {
1376                                         /* Not *really* out of time, just out of time for
1377                                            digits to come in for features. */
1378                                         if (option_debug)
1379                                                 ast_log(LOG_DEBUG, "Timed out for feature!\n");
1380                                         if (!ast_strlen_zero(peer_featurecode)) {
1381                                                 ast_dtmf_stream(chan, peer, peer_featurecode, 0);
1382                                                 memset(peer_featurecode, 0, sizeof(peer_featurecode));
1383                                         }
1384                                         if (!ast_strlen_zero(chan_featurecode)) {
1385                                                 ast_dtmf_stream(peer, chan, chan_featurecode, 0);
1386                                                 memset(chan_featurecode, 0, sizeof(chan_featurecode));
1387                                         }
1388                                         if (f)
1389                                                 ast_frfree(f);
1390                                         hasfeatures = !ast_strlen_zero(chan_featurecode) || !ast_strlen_zero(peer_featurecode);
1391                                         if (!hasfeatures) {
1392                                                 /* Restore original (possibly time modified) bridge config */
1393                                                 memcpy(config, &backup_config, sizeof(struct ast_bridge_config));
1394                                                 memset(&backup_config, 0, sizeof(backup_config));
1395                                         }
1396                                         hadfeatures = hasfeatures;
1397                                         /* Continue as we were */
1398                                         continue;
1399                                 } else if (!f) {
1400                                         /* The bridge returned without a frame and there is a feature in progress.
1401                                          * However, we don't think the feature has quite yet timed out, so just
1402                                          * go back into the bridge. */
1403                                         continue;
1404                                 }
1405                         } else {
1406                                 if (config->feature_timer <=0) {
1407                                         /* We ran out of time */
1408                                         config->feature_timer = 0;
1409                                         who = chan;
1410                                         if (f)
1411                                                 ast_frfree(f);
1412                                         f = NULL;
1413                                         res = 0;
1414                                 }
1415                         }
1416                 }
1417                 if (res < 0) {
1418                         ast_log(LOG_WARNING, "Bridge failed on channels %s and %s\n", chan->name, peer->name);
1419                         return -1;
1420                 }
1421                 
1422                 if (!f || (f->frametype == AST_FRAME_CONTROL &&
1423                                 (f->subclass == AST_CONTROL_HANGUP || f->subclass == AST_CONTROL_BUSY || 
1424                                         f->subclass == AST_CONTROL_CONGESTION ) ) ) {
1425                         res = -1;
1426                         break;
1427                 }
1428                 /* many things should be sent to the 'other' channel */
1429                 other = (who == chan) ? peer : chan;
1430                 if (f->frametype == AST_FRAME_CONTROL) {
1431                         if (f->subclass == AST_CONTROL_RINGING)
1432                                 ast_indicate(other, AST_CONTROL_RINGING);
1433                         else if (f->subclass == -1)
1434                                 ast_indicate(other, -1);
1435                         else if (f->subclass == AST_CONTROL_FLASH)
1436                                 ast_indicate(other, AST_CONTROL_FLASH);
1437                         else if (f->subclass == AST_CONTROL_OPTION) {
1438                                 aoh = f->data;
1439                                 /* Forward option Requests */
1440                                 if (aoh && aoh->flag == AST_OPTION_FLAG_REQUEST)
1441                                         ast_channel_setoption(other, ntohs(aoh->option), aoh->data, f->datalen - sizeof(struct ast_option_header), 0);
1442                         }
1443                 } else if (f->frametype == AST_FRAME_DTMF_BEGIN) {
1444                         /* eat it */
1445                 } else if (f->frametype == AST_FRAME_DTMF) {
1446                         char *featurecode;
1447                         int sense;
1448
1449                         hadfeatures = hasfeatures;
1450                         /* This cannot overrun because the longest feature is one shorter than our buffer */
1451                         if (who == chan) {
1452                                 sense = FEATURE_SENSE_CHAN;
1453                                 featurecode = chan_featurecode;
1454                         } else  {
1455                                 sense = FEATURE_SENSE_PEER;
1456                                 featurecode = peer_featurecode;
1457                         }
1458                         /*! append the event to featurecode. we rely on the string being zero-filled, and
1459                          * not overflowing it. 
1460                          * \todo XXX how do we guarantee the latter ?
1461                          */
1462                         featurecode[strlen(featurecode)] = f->subclass;
1463                         /* Get rid of the frame before we start doing "stuff" with the channels */
1464                         ast_frfree(f);
1465                         f = NULL;
1466                         config->feature_timer = backup_config.feature_timer;
1467                         res = ast_feature_interpret(chan, peer, config, featurecode, sense);
1468                         switch(res) {
1469                         case FEATURE_RETURN_PASSDIGITS:
1470                                 ast_dtmf_stream(other, who, featurecode, 0);
1471                                 /* Fall through */
1472                         case FEATURE_RETURN_SUCCESS:
1473                                 memset(featurecode, 0, sizeof(chan_featurecode));
1474                                 break;
1475                         }
1476                         if (res >= FEATURE_RETURN_PASSDIGITS) {
1477                                 res = 0;
1478                         } else 
1479                                 break;
1480                         hasfeatures = !ast_strlen_zero(chan_featurecode) || !ast_strlen_zero(peer_featurecode);
1481                         if (hadfeatures && !hasfeatures) {
1482                                 /* Restore backup */
1483                                 memcpy(config, &backup_config, sizeof(struct ast_bridge_config));
1484                                 memset(&backup_config, 0, sizeof(struct ast_bridge_config));
1485                         } else if (hasfeatures) {
1486                                 if (!hadfeatures) {
1487                                         /* Backup configuration */
1488                                         memcpy(&backup_config, config, sizeof(struct ast_bridge_config));
1489                                         /* Setup temporary config options */
1490                                         config->play_warning = 0;
1491                                         ast_clear_flag(&(config->features_caller), AST_FEATURE_PLAY_WARNING);
1492                                         ast_clear_flag(&(config->features_callee), AST_FEATURE_PLAY_WARNING);
1493                                         config->warning_freq = 0;
1494                                         config->warning_sound = NULL;
1495                                         config->end_sound = NULL;
1496                                         config->start_sound = NULL;
1497                                         config->firstpass = 0;
1498                                 }
1499                                 config->start_time = ast_tvnow();
1500                                 config->feature_timer = featuredigittimeout;
1501                                 if (option_debug)
1502                                         ast_log(LOG_DEBUG, "Set time limit to %ld\n", config->feature_timer);
1503                         }
1504                 }
1505                 if (f)
1506                         ast_frfree(f);
1507         }
1508         return res;
1509 }
1510
1511 static void post_manager_event(const char *s, char *parkingexten, struct ast_channel *chan)
1512 {
1513         manager_event(EVENT_FLAG_CALL, s,
1514                 "Exten: %s\r\n"
1515                 "Channel: %s\r\n"
1516                 "CallerIDNum: %s\r\n"
1517                 "CallerIDName: %s\r\n\r\n",
1518                 parkingexten, 
1519                 chan->name,
1520                 S_OR(chan->cid.cid_num, "<unknown>"),
1521                 S_OR(chan->cid.cid_name, "<unknown>")
1522                 );
1523 }
1524
1525 /*! \brief Take care of parked calls and unpark them if needed */
1526 static void *do_parking_thread(void *ignore)
1527 {
1528         char parkingslot[AST_MAX_EXTENSION];
1529         fd_set rfds, efds;      /* results from previous select, to be preserved across loops. */
1530
1531         FD_ZERO(&rfds);
1532         FD_ZERO(&efds);
1533
1534         for (;;) {
1535                 struct parkeduser *pu, *pl, *pt = NULL;
1536                 int ms = -1;    /* select timeout, uninitialized */
1537                 int max = -1;   /* max fd, none there yet */
1538                 fd_set nrfds, nefds;    /* args for the next select */
1539                 FD_ZERO(&nrfds);
1540                 FD_ZERO(&nefds);
1541
1542                 ast_mutex_lock(&parking_lock);
1543                 pl = NULL;
1544                 pu = parkinglot;
1545                 /* navigate the list with prev-cur pointers to support removals */
1546                 while (pu) {
1547                         struct ast_channel *chan = pu->chan;    /* shorthand */
1548                         int tms;        /* timeout for this item */
1549                         int x;          /* fd index in channel */
1550                         struct ast_context *con;
1551
1552                         if (pu->notquiteyet) { /* Pretend this one isn't here yet */
1553                                 pl = pu;
1554                                 pu = pu->next;
1555                                 continue;
1556                         }
1557                         tms = ast_tvdiff_ms(ast_tvnow(), pu->start);
1558                         if (tms > pu->parkingtime) {
1559                                 ast_indicate(chan, AST_CONTROL_UNHOLD);
1560                                 /* Get chan, exten from derived kludge */
1561                                 if (pu->peername[0]) {
1562                                         char *peername = ast_strdupa(pu->peername);
1563                                         char *cp = strrchr(peername, '-');
1564                                         if (cp) 
1565                                                 *cp = 0;
1566                                         con = ast_context_find(parking_con_dial);
1567                                         if (!con) {
1568                                                 con = ast_context_create(NULL, parking_con_dial, registrar);
1569                                                 if (!con)
1570                                                         ast_log(LOG_ERROR, "Parking dial context '%s' does not exist and unable to create\n", parking_con_dial);
1571                                         }
1572                                         if (con) {
1573                                                 char returnexten[AST_MAX_EXTENSION];
1574                                                 snprintf(returnexten, sizeof(returnexten), "%s||t", peername);
1575                                                 ast_add_extension2(con, 1, peername, 1, NULL, NULL, "Dial", strdup(returnexten), ast_free, registrar);
1576                                         }
1577                                         if (comebacktoorigin) { 
1578                                                 set_c_e_p(chan, parking_con_dial, peername, 1);
1579                                         } else {
1580                                                 ast_log(LOG_WARNING, "now going to parkedcallstimeout,s,1 | ps is %d\n",pu->parkingnum);
1581                                                 snprintf(parkingslot, sizeof(parkingslot), "%d", pu->parkingnum);
1582                                                 pbx_builtin_setvar_helper(pu->chan, "PARKINGSLOT", parkingslot);
1583                                                 set_c_e_p(chan, "parkedcallstimeout", peername, 1);
1584                                         }
1585                                 } else {
1586                                         /* They've been waiting too long, send them back to where they came.  Theoretically they
1587                                            should have their original extensions and such, but we copy to be on the safe side */
1588                                         set_c_e_p(chan, pu->context, pu->exten, pu->priority);
1589                                 }
1590
1591                                 post_manager_event("ParkedCallTimeOut", pu->parkingexten, chan);
1592
1593                                 if (option_verbose > 1) 
1594                                         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);
1595                                 /* Start up the PBX, or hang them up */
1596                                 if (ast_pbx_start(chan))  {
1597                                         ast_log(LOG_WARNING, "Unable to restart the PBX for user on '%s', hanging them up...\n", chan->name);
1598                                         ast_hangup(chan);
1599                                 }
1600                                 /* And take them out of the parking lot */
1601                                 if (pl) 
1602                                         pl->next = pu->next;
1603                                 else
1604                                         parkinglot = pu->next;
1605                                 pt = pu;
1606                                 pu = pu->next;
1607                                 con = ast_context_find(parking_con);
1608                                 if (con) {
1609                                         if (ast_context_remove_extension2(con, pt->parkingexten, 1, NULL))
1610                                                 ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
1611                                         else
1612                                                 notify_metermaids(pt->parkingexten, parking_con);
1613                                 } else
1614                                         ast_log(LOG_WARNING, "Whoa, no parking context?\n");
1615                                 free(pt);
1616                         } else {        /* still within parking time, process descriptors */
1617                                 for (x = 0; x < AST_MAX_FDS; x++) {
1618                                         struct ast_frame *f;
1619
1620                                         if (chan->fds[x] == -1 || (!FD_ISSET(chan->fds[x], &rfds) && !FD_ISSET(chan->fds[x], &efds)))
1621                                                 continue;       /* nothing on this descriptor */
1622
1623                                         if (FD_ISSET(chan->fds[x], &efds))
1624                                                 ast_set_flag(chan, AST_FLAG_EXCEPTION);
1625                                         else
1626                                                 ast_clear_flag(chan, AST_FLAG_EXCEPTION);
1627                                         chan->fdno = x;
1628
1629                                         /* See if they need servicing */
1630                                         f = ast_read(chan);
1631                                         if (!f || (f->frametype == AST_FRAME_CONTROL && f->subclass ==  AST_CONTROL_HANGUP)) {
1632                                                 if (f)
1633                                                         ast_frfree(f);
1634                                                 post_manager_event("ParkedCallGiveUp", pu->parkingexten, chan);
1635
1636                                                 /* There's a problem, hang them up*/
1637                                                 if (option_verbose > 1) 
1638                                                         ast_verbose(VERBOSE_PREFIX_2 "%s got tired of being parked\n", chan->name);
1639                                                 ast_hangup(chan);
1640                                                 /* And take them out of the parking lot */
1641                                                 if (pl) 
1642                                                         pl->next = pu->next;
1643                                                 else
1644                                                         parkinglot = pu->next;
1645                                                 pt = pu;
1646                                                 pu = pu->next;
1647                                                 con = ast_context_find(parking_con);
1648                                                 if (con) {
1649                                                         if (ast_context_remove_extension2(con, pt->parkingexten, 1, NULL))
1650                                                                 ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
1651                                                         else
1652                                                                 notify_metermaids(pt->parkingexten, parking_con);
1653                                                 } else
1654                                                         ast_log(LOG_WARNING, "Whoa, no parking context?\n");
1655                                                 free(pt);
1656                                                 break;
1657                                         } else {
1658                                                 /*! \todo XXX Maybe we could do something with packets, like dial "0" for operator or something XXX */
1659                                                 ast_frfree(f);
1660                                                 if (pu->moh_trys < 3 && !chan->generatordata) {
1661                                                         if (option_debug)
1662                                                                 ast_log(LOG_DEBUG, "MOH on parked call stopped by outside source.  Restarting.\n");
1663                                                         ast_indicate_data(pu->chan, AST_CONTROL_HOLD, 
1664                                                                 S_OR(parkmohclass, NULL),
1665                                                                 !ast_strlen_zero(parkmohclass) ? strlen(parkmohclass) + 1 : 0);
1666                                                         pu->moh_trys++;
1667                                                 }
1668                                                 goto std;       /*! \todo XXX Ick: jumping into an else statement??? XXX */
1669                                         }
1670
1671                                 } /* end for */
1672                                 if (x >= AST_MAX_FDS) {
1673 std:                                    for (x=0; x<AST_MAX_FDS; x++) { /* mark fds for next round */
1674                                                 if (chan->fds[x] > -1) {
1675                                                         FD_SET(chan->fds[x], &nrfds);
1676                                                         FD_SET(chan->fds[x], &nefds);
1677                                                         if (chan->fds[x] > max)
1678                                                                 max = chan->fds[x];
1679                                                 }
1680                                         }
1681                                         /* Keep track of our shortest wait */
1682                                         if (tms < ms || ms < 0)
1683                                                 ms = tms;
1684                                         pl = pu;
1685                                         pu = pu->next;
1686                                 }
1687                         }
1688                 } /* end while */
1689                 ast_mutex_unlock(&parking_lock);
1690                 rfds = nrfds;
1691                 efds = nefds;
1692                 {
1693                         struct timeval tv = ast_samp2tv(ms, 1000);
1694                         /* Wait for something to happen */
1695                         ast_select(max + 1, &rfds, NULL, &efds, (ms > -1) ? &tv : NULL);
1696                 }
1697                 pthread_testcancel();
1698         }
1699         return NULL;    /* Never reached */
1700 }
1701
1702 /*! \brief Park a call */
1703 static int park_call_exec(struct ast_channel *chan, void *data)
1704 {
1705         /* Data is unused at the moment but could contain a parking
1706            lot context eventually */
1707         int res = 0;
1708         struct ast_module_user *u;
1709
1710         u = ast_module_user_add(chan);
1711
1712         /* Setup the exten/priority to be s/1 since we don't know
1713            where this call should return */
1714         strcpy(chan->exten, "s");
1715         chan->priority = 1;
1716         /* Answer if call is not up */
1717         if (chan->_state != AST_STATE_UP)
1718                 res = ast_answer(chan);
1719         /* Sleep to allow VoIP streams to settle down */
1720         if (!res)
1721                 res = ast_safe_sleep(chan, 1000);
1722         /* Park the call */
1723         if (!res)
1724                 res = ast_park_call(chan, chan, 0, NULL);
1725
1726         ast_module_user_remove(u);
1727
1728         return !res ? AST_PBX_KEEPALIVE : res;
1729 }
1730
1731 /*! \brief Pickup parked call */
1732 static int park_exec(struct ast_channel *chan, void *data)
1733 {
1734         int res = 0;
1735         struct ast_module_user *u;
1736         struct ast_channel *peer=NULL;
1737         struct parkeduser *pu, *pl=NULL;
1738         struct ast_context *con;
1739         int park;
1740         struct ast_bridge_config config;
1741
1742         if (!data) {
1743                 ast_log(LOG_WARNING, "Parkedcall requires an argument (extension number)\n");
1744                 return -1;
1745         }
1746         
1747         u = ast_module_user_add(chan);
1748
1749         park = atoi((char *)data);
1750         ast_mutex_lock(&parking_lock);
1751         pu = parkinglot;
1752         while(pu) {
1753                 if (pu->parkingnum == park) {
1754                         if (pl)
1755                                 pl->next = pu->next;
1756                         else
1757                                 parkinglot = pu->next;
1758                         break;
1759                 }
1760                 pl = pu;
1761                 pu = pu->next;
1762         }
1763         ast_mutex_unlock(&parking_lock);
1764         if (pu) {
1765                 peer = pu->chan;
1766                 con = ast_context_find(parking_con);
1767                 if (con) {
1768                         if (ast_context_remove_extension2(con, pu->parkingexten, 1, NULL))
1769                                 ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
1770                         else
1771                                 notify_metermaids(pu->parkingexten, parking_con);
1772                 } else
1773                         ast_log(LOG_WARNING, "Whoa, no parking context?\n");
1774
1775                 manager_event(EVENT_FLAG_CALL, "UnParkedCall",
1776                         "Exten: %s\r\n"
1777                         "Channel: %s\r\n"
1778                         "From: %s\r\n"
1779                         "CallerIDNum: %s\r\n"
1780                         "CallerIDName: %s\r\n",
1781                         pu->parkingexten, pu->chan->name, chan->name,
1782                         S_OR(pu->chan->cid.cid_num, "<unknown>"),
1783                         S_OR(pu->chan->cid.cid_name, "<unknown>")
1784                         );
1785
1786                 free(pu);
1787         }
1788         /* JK02: it helps to answer the channel if not already up */
1789         if (chan->_state != AST_STATE_UP)
1790                 ast_answer(chan);
1791
1792         if (peer) {
1793                 /* Play a courtesy to the source(s) configured to prefix the bridge connecting */
1794                 
1795                 if (!ast_strlen_zero(courtesytone)) {
1796                         int error = 0;
1797                         ast_indicate(peer, AST_CONTROL_UNHOLD);
1798                         if (parkedplay == 0) {
1799                                 error = ast_stream_and_wait(chan, courtesytone, "");
1800                         } else if (parkedplay == 1) {
1801                                 error = ast_stream_and_wait(peer, courtesytone, "");
1802                         } else if (parkedplay == 2) {
1803                                 if (!ast_streamfile(chan, courtesytone, chan->language) &&
1804                                                 !ast_streamfile(peer, courtesytone, chan->language)) {
1805                                         /*! \todo XXX we would like to wait on both! */
1806                                         res = ast_waitstream(chan, "");
1807                                         if (res >= 0)
1808                                                 res = ast_waitstream(peer, "");
1809                                         if (res < 0)
1810                                                 error = 1;
1811                                 }
1812                         }
1813                         if (error) {
1814                                 ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
1815                                 ast_hangup(peer);
1816                                 return -1;
1817                         }
1818                 } else
1819                         ast_indicate(peer, AST_CONTROL_UNHOLD); 
1820
1821                 res = ast_channel_make_compatible(chan, peer);
1822                 if (res < 0) {
1823                         ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for bridge\n", chan->name, peer->name);
1824                         ast_hangup(peer);
1825                         return -1;
1826                 }
1827                 /* This runs sorta backwards, since we give the incoming channel control, as if it
1828                    were the person called. */
1829                 if (option_verbose > 2) 
1830                         ast_verbose(VERBOSE_PREFIX_3 "Channel %s connected to parked call %d\n", chan->name, park);
1831
1832                 memset(&config, 0, sizeof(struct ast_bridge_config));
1833                 if ((parkedcalltransfers == AST_FEATURE_FLAG_BYCALLEE) || (parkedcalltransfers == AST_FEATURE_FLAG_BYBOTH))
1834                         ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
1835                 if ((parkedcalltransfers == AST_FEATURE_FLAG_BYCALLER) || (parkedcalltransfers == AST_FEATURE_FLAG_BYBOTH))
1836                         ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
1837                 if ((parkedcallreparking == AST_FEATURE_FLAG_BYCALLEE) || (parkedcallreparking == AST_FEATURE_FLAG_BYBOTH))
1838                         ast_set_flag(&(config.features_callee), AST_FEATURE_PARKCALL);
1839                 if ((parkedcallreparking == AST_FEATURE_FLAG_BYCALLER) || (parkedcallreparking == AST_FEATURE_FLAG_BYBOTH))
1840                         ast_set_flag(&(config.features_caller), AST_FEATURE_PARKCALL);
1841                 res = ast_bridge_call(chan, peer, &config);
1842
1843                 pbx_builtin_setvar_helper(chan, "PARKEDCHANNEL", peer->name);
1844                 ast_cdr_setdestchan(chan->cdr, peer->name);
1845
1846                 /* Simulate the PBX hanging up */
1847                 if (res != AST_PBX_NO_HANGUP_PEER)
1848                         ast_hangup(peer);
1849                 return res;
1850         } else {
1851                 /*! \todo XXX Play a message XXX */
1852                 if (ast_stream_and_wait(chan, "pbx-invalidpark", ""))
1853                         ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", "pbx-invalidpark", chan->name);
1854                 if (option_verbose > 2) 
1855                         ast_verbose(VERBOSE_PREFIX_3 "Channel %s tried to talk to nonexistent parked call %d\n", chan->name, park);
1856                 res = -1;
1857         }
1858
1859         ast_module_user_remove(u);
1860
1861         return res;
1862 }
1863
1864 static int handle_showfeatures(int fd, int argc, char *argv[])
1865 {
1866         int i;
1867         int fcount;
1868         struct ast_call_feature *feature;
1869         char format[] = "%-25s %-7s %-7s\n";
1870
1871         ast_cli(fd, format, "Builtin Feature", "Default", "Current");
1872         ast_cli(fd, format, "---------------", "-------", "-------");
1873
1874         ast_cli(fd, format, "Pickup", "*8", ast_pickup_ext());          /* default hardcoded above, so we'll hardcode it here */
1875
1876         fcount = sizeof(builtin_features) / sizeof(builtin_features[0]);
1877
1878         for (i = 0; i < fcount; i++)
1879         {
1880                 ast_cli(fd, format, builtin_features[i].fname, builtin_features[i].default_exten, builtin_features[i].exten);
1881         }
1882         ast_cli(fd, "\n");
1883         ast_cli(fd, format, "Dynamic Feature", "Default", "Current");
1884         ast_cli(fd, format, "---------------", "-------", "-------");
1885         if (AST_LIST_EMPTY(&feature_list)) {
1886                 ast_cli(fd, "(none)\n");
1887         }
1888         else {
1889                 AST_LIST_LOCK(&feature_list);
1890                 AST_LIST_TRAVERSE(&feature_list, feature, feature_entry) {
1891                         ast_cli(fd, format, feature->sname, "no def", feature->exten);  
1892                 }
1893                 AST_LIST_UNLOCK(&feature_list);
1894         }
1895         ast_cli(fd, "\nCall parking\n");
1896         ast_cli(fd, "------------\n");
1897         ast_cli(fd,"%-20s:      %s\n", "Parking extension", parking_ext);
1898         ast_cli(fd,"%-20s:      %s\n", "Parking context", parking_con);
1899         ast_cli(fd,"%-20s:      %d-%d\n", "Parked call extensions", parking_start, parking_stop);
1900         ast_cli(fd,"\n");
1901         
1902         return RESULT_SUCCESS;
1903 }
1904
1905 static char showfeatures_help[] =
1906 "Usage: feature list\n"
1907 "       Lists currently configured features.\n";
1908
1909 static int handle_parkedcalls(int fd, int argc, char *argv[])
1910 {
1911         struct parkeduser *cur;
1912         int numparked = 0;
1913
1914         ast_cli(fd, "%4s %25s (%-15s %-12s %-4s) %-6s \n", "Num", "Channel"
1915                 , "Context", "Extension", "Pri", "Timeout");
1916
1917         ast_mutex_lock(&parking_lock);
1918
1919         for (cur = parkinglot; cur; cur = cur->next) {
1920                 ast_cli(fd, "%-10.10s %25s (%-15s %-12s %-4d) %6lds\n"
1921                         ,cur->parkingexten, cur->chan->name, cur->context, cur->exten
1922                         ,cur->priority, cur->start.tv_sec + (cur->parkingtime/1000) - time(NULL));
1923
1924                 numparked++;
1925         }
1926         ast_mutex_unlock(&parking_lock);
1927         ast_cli(fd, "%d parked call%s.\n", numparked, ESS(numparked));
1928
1929
1930         return RESULT_SUCCESS;
1931 }
1932
1933 static char showparked_help[] =
1934 "Usage: show parkedcalls\n"
1935 "       Lists currently parked calls.\n";
1936
1937 static struct ast_cli_entry cli_features[] = {
1938         { { "feature", "show", NULL },
1939         handle_showfeatures, "Lists configured features",
1940         showfeatures_help },
1941
1942         { { "show", "parkedcalls", NULL },
1943         handle_parkedcalls, "Lists parked calls",
1944         showparked_help },
1945 };
1946
1947 /*! \brief Dump lot status */
1948 static int manager_parking_status( struct mansession *s, const struct message *m)
1949 {
1950         struct parkeduser *cur;
1951         const char *id = astman_get_header(m, "ActionID");
1952         char idText[256] = "";
1953
1954         if (!ast_strlen_zero(id))
1955                 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
1956
1957         astman_send_ack(s, m, "Parked calls will follow");
1958
1959         ast_mutex_lock(&parking_lock);
1960
1961         for (cur = parkinglot; cur; cur = cur->next) {
1962                 astman_append(s, "Event: ParkedCall\r\n"
1963                         "Exten: %d\r\n"
1964                         "Channel: %s\r\n"
1965                         "From: %s\r\n"
1966                         "Timeout: %ld\r\n"
1967                         "CallerIDNum: %s\r\n"
1968                         "CallerIDName: %s\r\n"
1969                         "%s"
1970                         "\r\n",
1971                         cur->parkingnum, cur->chan->name, cur->peername,
1972                         (long) cur->start.tv_sec + (long) (cur->parkingtime / 1000) - (long) time(NULL),
1973                         S_OR(cur->chan->cid.cid_num, ""),       /* XXX in other places it is <unknown> */
1974                         S_OR(cur->chan->cid.cid_name, ""),
1975                         idText);
1976         }
1977
1978         astman_append(s,
1979                 "Event: ParkedCallsComplete\r\n"
1980                 "%s"
1981                 "\r\n",idText);
1982
1983         ast_mutex_unlock(&parking_lock);
1984
1985         return RESULT_SUCCESS;
1986 }
1987
1988 static char mandescr_park[] =
1989 "Description: Park a channel.\n"
1990 "Variables: (Names marked with * are required)\n"
1991 "       *Channel: Channel name to park\n"
1992 "       *Channel2: Channel to announce park info to (and return to if timeout)\n"
1993 "       Timeout: Number of milliseconds to wait before callback.\n";  
1994
1995 static int manager_park(struct mansession *s, const struct message *m)
1996 {
1997         const char *channel = astman_get_header(m, "Channel");
1998         const char *channel2 = astman_get_header(m, "Channel2");
1999         const char *timeout = astman_get_header(m, "Timeout");
2000         char buf[BUFSIZ];
2001         int to = 0;
2002         int res = 0;
2003         int parkExt = 0;
2004         struct ast_channel *ch1, *ch2;
2005
2006         if (ast_strlen_zero(channel)) {
2007                 astman_send_error(s, m, "Channel not specified");
2008                 return 0;
2009         }
2010
2011         if (ast_strlen_zero(channel2)) {
2012                 astman_send_error(s, m, "Channel2 not specified");
2013                 return 0;
2014         }
2015
2016         ch1 = ast_get_channel_by_name_locked(channel);
2017         if (!ch1) {
2018                 snprintf(buf, sizeof(buf), "Channel does not exist: %s", channel);
2019                 astman_send_error(s, m, buf);
2020                 return 0;
2021         }
2022
2023         ch2 = ast_get_channel_by_name_locked(channel2);
2024         if (!ch2) {
2025                 snprintf(buf, sizeof(buf), "Channel does not exist: %s", channel2);
2026                 astman_send_error(s, m, buf);
2027                 ast_channel_unlock(ch1);
2028                 return 0;
2029         }
2030
2031         if (!ast_strlen_zero(timeout)) {
2032                 sscanf(timeout, "%d", &to);
2033         }
2034
2035         res = ast_masq_park_call(ch1, ch2, to, &parkExt);
2036         if (!res) {
2037                 ast_softhangup(ch2, AST_SOFTHANGUP_EXPLICIT);
2038                 astman_send_ack(s, m, "Park successful");
2039         } else {
2040                 astman_send_error(s, m, "Park failure");
2041         }
2042
2043         ast_channel_unlock(ch1);
2044         ast_channel_unlock(ch2);
2045
2046         return 0;
2047 }
2048
2049
2050 int ast_pickup_call(struct ast_channel *chan)
2051 {
2052         struct ast_channel *cur = NULL;
2053         int res = -1;
2054
2055         while ( (cur = ast_channel_walk_locked(cur)) != NULL) {
2056                 if (!cur->pbx && 
2057                         (cur != chan) &&
2058                         (chan->pickupgroup & cur->callgroup) &&
2059                         ((cur->_state == AST_STATE_RINGING) ||
2060                          (cur->_state == AST_STATE_RING))) {
2061                                 break;
2062                 }
2063                 ast_channel_unlock(cur);
2064         }
2065         if (cur) {
2066                 if (option_debug)
2067                         ast_log(LOG_DEBUG, "Call pickup on chan '%s' by '%s'\n",cur->name, chan->name);
2068                 res = ast_answer(chan);
2069                 if (res)
2070                         ast_log(LOG_WARNING, "Unable to answer '%s'\n", chan->name);
2071                 res = ast_queue_control(chan, AST_CONTROL_ANSWER);
2072                 if (res)
2073                         ast_log(LOG_WARNING, "Unable to queue answer on '%s'\n", chan->name);
2074                 res = ast_channel_masquerade(cur, chan);
2075                 if (res)
2076                         ast_log(LOG_WARNING, "Unable to masquerade '%s' into '%s'\n", chan->name, cur->name);           /* Done */
2077                 ast_channel_unlock(cur);
2078         } else  {
2079                 if (option_debug)
2080                         ast_log(LOG_DEBUG, "No call pickup possible...\n");
2081         }
2082         return res;
2083 }
2084
2085 /*! \brief Add parking hints for all defined parking lots */
2086 static void park_add_hints(char *context, int start, int stop)
2087 {
2088         int numext;
2089         char device[AST_MAX_EXTENSION];
2090         char exten[10];
2091
2092         for (numext = start; numext <= stop; numext++) {
2093                 snprintf(exten, sizeof(exten), "%d", numext);
2094                 snprintf(device, sizeof(device), "park:%s@%s", exten, context);
2095                 ast_add_extension(context, 1, exten, PRIORITY_HINT, NULL, NULL, device, NULL, NULL, registrar);
2096         }
2097 }
2098
2099
2100 static int load_config(void) 
2101 {
2102         int start = 0, end = 0;
2103         int res;
2104         struct ast_context *con = NULL;
2105         struct ast_config *cfg = NULL;
2106         struct ast_variable *var = NULL;
2107         char old_parking_ext[AST_MAX_EXTENSION];
2108         char old_parking_con[AST_MAX_EXTENSION] = "";
2109
2110         if (!ast_strlen_zero(parking_con)) {
2111                 strcpy(old_parking_ext, parking_ext);
2112                 strcpy(old_parking_con, parking_con);
2113         } 
2114
2115         /* Reset to defaults */
2116         strcpy(parking_con, "parkedcalls");
2117         strcpy(parking_con_dial, "park-dial");
2118         strcpy(parking_ext, "700");
2119         strcpy(pickup_ext, "*8");
2120         strcpy(parkmohclass, "default");
2121         courtesytone[0] = '\0';
2122         strcpy(xfersound, "beep");
2123         strcpy(xferfailsound, "pbx-invalid");
2124         parking_start = 701;
2125         parking_stop = 750;
2126         parkfindnext = 0;
2127         adsipark = 0;
2128         comebacktoorigin = 1;
2129         parkaddhints = 0;
2130         parkedcalltransfers = 0;
2131         parkedcallreparking = 0;
2132
2133         transferdigittimeout = DEFAULT_TRANSFER_DIGIT_TIMEOUT;
2134         featuredigittimeout = DEFAULT_FEATURE_DIGIT_TIMEOUT;
2135         atxfernoanswertimeout = DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER;
2136
2137         cfg = ast_config_load("features.conf");
2138         if (!cfg) {
2139                 ast_log(LOG_WARNING,"Could not load features.conf\n");
2140                 return AST_MODULE_LOAD_DECLINE;
2141         }
2142         for (var = ast_variable_browse(cfg, "general"); var; var = var->next) {
2143                 if (!strcasecmp(var->name, "parkext")) {
2144                         ast_copy_string(parking_ext, var->value, sizeof(parking_ext));
2145                 } else if (!strcasecmp(var->name, "context")) {
2146                         ast_copy_string(parking_con, var->value, sizeof(parking_con));
2147                 } else if (!strcasecmp(var->name, "parkingtime")) {
2148                         if ((sscanf(var->value, "%d", &parkingtime) != 1) || (parkingtime < 1)) {
2149                                 ast_log(LOG_WARNING, "%s is not a valid parkingtime\n", var->value);
2150                                 parkingtime = DEFAULT_PARK_TIME;
2151                         } else
2152                                 parkingtime = parkingtime * 1000;
2153                 } else if (!strcasecmp(var->name, "parkpos")) {
2154                         if (sscanf(var->value, "%d-%d", &start, &end) != 2) {
2155                                 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);
2156                         } else {
2157                                 parking_start = start;
2158                                 parking_stop = end;
2159                         }
2160                 } else if (!strcasecmp(var->name, "findslot")) {
2161                         parkfindnext = (!strcasecmp(var->value, "next"));
2162                 } else if (!strcasecmp(var->name, "parkinghints")) {
2163                         parkaddhints = ast_true(var->value);
2164                 } else if (!strcasecmp(var->name, "parkedcalltransfers")) {
2165                         if (!strcasecmp(var->value, "both"))
2166                                 parkedcalltransfers = AST_FEATURE_FLAG_BYBOTH;
2167                         else if (!strcasecmp(var->value, "caller"))
2168                                 parkedcalltransfers = AST_FEATURE_FLAG_BYCALLER;
2169                         else if (!strcasecmp(var->value, "callee"))
2170                                 parkedcalltransfers = AST_FEATURE_FLAG_BYCALLEE;
2171                 } else if (!strcasecmp(var->name, "parkedcallreparking")) {
2172                         if (!strcasecmp(var->value, "both"))
2173                                 parkedcalltransfers = AST_FEATURE_FLAG_BYBOTH;
2174                         else if (!strcasecmp(var->value, "caller"))
2175                                 parkedcalltransfers = AST_FEATURE_FLAG_BYCALLER;
2176                         else if (!strcasecmp(var->value, "callee"))
2177                                 parkedcalltransfers = AST_FEATURE_FLAG_BYCALLEE;
2178                 } else if (!strcasecmp(var->name, "adsipark")) {
2179                         adsipark = ast_true(var->value);
2180                 } else if (!strcasecmp(var->name, "transferdigittimeout")) {
2181                         if ((sscanf(var->value, "%d", &transferdigittimeout) != 1) || (transferdigittimeout < 1)) {
2182                                 ast_log(LOG_WARNING, "%s is not a valid transferdigittimeout\n", var->value);
2183                                 transferdigittimeout = DEFAULT_TRANSFER_DIGIT_TIMEOUT;
2184                         } else
2185                                 transferdigittimeout = transferdigittimeout * 1000;
2186                 } else if (!strcasecmp(var->name, "featuredigittimeout")) {
2187                         if ((sscanf(var->value, "%d", &featuredigittimeout) != 1) || (featuredigittimeout < 1)) {
2188                                 ast_log(LOG_WARNING, "%s is not a valid featuredigittimeout\n", var->value);
2189                                 featuredigittimeout = DEFAULT_FEATURE_DIGIT_TIMEOUT;
2190                         }
2191                 } else if (!strcasecmp(var->name, "atxfernoanswertimeout")) {
2192                         if ((sscanf(var->value, "%d", &atxfernoanswertimeout) != 1) || (atxfernoanswertimeout < 1)) {
2193                                 ast_log(LOG_WARNING, "%s is not a valid atxfernoanswertimeout\n", var->value);
2194                                 atxfernoanswertimeout = DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER;
2195                         } else
2196                                 atxfernoanswertimeout = atxfernoanswertimeout * 1000;
2197                 } else if (!strcasecmp(var->name, "courtesytone")) {
2198                         ast_copy_string(courtesytone, var->value, sizeof(courtesytone));
2199                 }  else if (!strcasecmp(var->name, "parkedplay")) {
2200                         if (!strcasecmp(var->value, "both"))
2201                                 parkedplay = 2;
2202                         else if (!strcasecmp(var->value, "parked"))
2203                                 parkedplay = 1;
2204                         else
2205                                 parkedplay = 0;
2206                 } else if (!strcasecmp(var->name, "xfersound")) {
2207                         ast_copy_string(xfersound, var->value, sizeof(xfersound));
2208                 } else if (!strcasecmp(var->name, "xferfailsound")) {
2209                         ast_copy_string(xferfailsound, var->value, sizeof(xferfailsound));
2210                 } else if (!strcasecmp(var->name, "pickupexten")) {
2211                         ast_copy_string(pickup_ext, var->value, sizeof(pickup_ext));
2212                 } else if (!strcasecmp(var->name, "comebacktoorigin")) {
2213                         comebacktoorigin = ast_true(var->value);
2214                 } else if (!strcasecmp(var->name, "parkedmusicclass")) {
2215                         ast_copy_string(parkmohclass, var->value, sizeof(parkmohclass));
2216                 }
2217         }
2218
2219         unmap_features();
2220         for (var = ast_variable_browse(cfg, "featuremap"); var; var = var->next) {
2221                 if (remap_feature(var->name, var->value))
2222                         ast_log(LOG_NOTICE, "Unknown feature '%s'\n", var->name);
2223         }
2224
2225         /* Map a key combination to an application*/
2226         ast_unregister_features();
2227         for (var = ast_variable_browse(cfg, "applicationmap"); var; var = var->next) {
2228                 char *tmp_val = ast_strdupa(var->value);
2229                 char *exten, *activateon, *activatedby, *app, *app_args, *moh_class; 
2230                 struct ast_call_feature *feature;
2231
2232                 /* strsep() sets the argument to NULL if match not found, and it
2233                  * is safe to use it with a NULL argument, so we don't check
2234                  * between calls.
2235                  */
2236                 exten = strsep(&tmp_val,",");
2237                 activatedby = strsep(&tmp_val,",");
2238                 app = strsep(&tmp_val,",");
2239                 app_args = strsep(&tmp_val,",");
2240                 moh_class = strsep(&tmp_val,",");
2241
2242                 activateon = strsep(&activatedby, "/"); 
2243
2244                 /*! \todo XXX var_name or app_args ? */
2245                 if (ast_strlen_zero(app) || ast_strlen_zero(exten) || ast_strlen_zero(activateon) || ast_strlen_zero(var->name)) {
2246                         ast_log(LOG_NOTICE, "Please check the feature Mapping Syntax, either extension, name, or app aren't provided %s %s %s %s\n",
2247                                 app, exten, activateon, var->name);
2248                         continue;
2249                 }
2250
2251                 if ((feature = find_feature(var->name))) {
2252                         ast_log(LOG_WARNING, "Dynamic Feature '%s' specified more than once!\n", var->name);
2253                         continue;
2254                 }
2255                                 
2256                 if (!(feature = ast_calloc(1, sizeof(*feature))))
2257                         continue;                                       
2258
2259                 ast_copy_string(feature->sname, var->name, FEATURE_SNAME_LEN);
2260                 ast_copy_string(feature->app, app, FEATURE_APP_LEN);
2261                 ast_copy_string(feature->exten, exten, FEATURE_EXTEN_LEN);
2262                 
2263                 if (app_args) 
2264                         ast_copy_string(feature->app_args, app_args, FEATURE_APP_ARGS_LEN);
2265
2266                 if (moh_class)
2267                         ast_copy_string(feature->moh_class, moh_class, FEATURE_MOH_LEN);
2268                         
2269                 ast_copy_string(feature->exten, exten, sizeof(feature->exten));
2270                 feature->operation = feature_exec_app;
2271                 ast_set_flag(feature, AST_FEATURE_FLAG_NEEDSDTMF);
2272
2273                 /* Allow caller and calle to be specified for backwards compatability */
2274                 if (!strcasecmp(activateon, "self") || !strcasecmp(activateon, "caller"))
2275                         ast_set_flag(feature, AST_FEATURE_FLAG_ONSELF);
2276                 else if (!strcasecmp(activateon, "peer") || !strcasecmp(activateon, "callee"))
2277                         ast_set_flag(feature, AST_FEATURE_FLAG_ONPEER);
2278                 else {
2279                         ast_log(LOG_NOTICE, "Invalid 'ActivateOn' specification for feature '%s',"
2280                                 " must be 'self', or 'peer'\n", var->name);
2281                         continue;
2282                 }
2283
2284                 if (ast_strlen_zero(activatedby))
2285                         ast_set_flag(feature, AST_FEATURE_FLAG_BYBOTH);
2286                 else if (!strcasecmp(activatedby, "caller"))
2287                         ast_set_flag(feature, AST_FEATURE_FLAG_BYCALLER);
2288                 else if (!strcasecmp(activatedby, "callee"))
2289                         ast_set_flag(feature, AST_FEATURE_FLAG_BYCALLEE);
2290                 else if (!strcasecmp(activatedby, "both"))
2291                         ast_set_flag(feature, AST_FEATURE_FLAG_BYBOTH);
2292                 else {
2293                         ast_log(LOG_NOTICE, "Invalid 'ActivatedBy' specification for feature '%s',"
2294                                 " must be 'caller', or 'callee', or 'both'\n", var->name);
2295                         continue;
2296                 }
2297
2298                 ast_register_feature(feature);
2299                         
2300                 if (option_verbose >= 1)
2301                         ast_verbose(VERBOSE_PREFIX_2 "Mapping Feature '%s' to app '%s(%s)' with code '%s'\n", var->name, app, app_args, exten);  
2302         }        
2303         ast_config_destroy(cfg);
2304
2305         /* Remove the old parking extension */
2306         if (!ast_strlen_zero(old_parking_con) && (con = ast_context_find(old_parking_con)))     {
2307                 if(ast_context_remove_extension2(con, old_parking_ext, 1, registrar))
2308                                 notify_metermaids(old_parking_ext, old_parking_con);
2309                 if (option_debug)
2310                         ast_log(LOG_DEBUG, "Removed old parking extension %s@%s\n", old_parking_ext, old_parking_con);
2311         }
2312         
2313         if (!(con = ast_context_find(parking_con)) && !(con = ast_context_create(NULL, parking_con, registrar))) {
2314                 ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", parking_con);
2315                 return -1;
2316         }
2317         res = ast_add_extension2(con, 1, ast_parking_ext(), 1, NULL, NULL, parkcall, NULL, NULL, registrar);
2318         if (parkaddhints)
2319                 park_add_hints(parking_con, parking_start, parking_stop);
2320         if (!res)
2321                 notify_metermaids(ast_parking_ext(), parking_con);
2322         return res;
2323
2324 }
2325
2326 static int reload(void)
2327 {
2328         return load_config();
2329 }
2330
2331 static int load_module(void)
2332 {
2333         int res;
2334         
2335         memset(parking_ext, 0, sizeof(parking_ext));
2336         memset(parking_con, 0, sizeof(parking_con));
2337
2338         if ((res = load_config()))
2339                 return res;
2340         ast_cli_register_multiple(cli_features, sizeof(cli_features) / sizeof(struct ast_cli_entry));
2341         ast_pthread_create(&parking_thread, NULL, do_parking_thread, NULL);
2342         res = ast_register_application(parkedcall, park_exec, synopsis, descrip);
2343         if (!res)
2344                 res = ast_register_application(parkcall, park_call_exec, synopsis2, descrip2);
2345         if (!res) {
2346                 ast_manager_register("ParkedCalls", 0, manager_parking_status, "List parked calls" );
2347                 ast_manager_register2("Park", EVENT_FLAG_CALL, manager_park,
2348                         "Park a channel", mandescr_park); 
2349         }
2350
2351         res |= ast_devstate_prov_add("Park", metermaidstate);
2352
2353         return res;
2354 }
2355
2356
2357 static int unload_module(void)
2358 {
2359         ast_module_user_hangup_all();
2360
2361         ast_manager_unregister("ParkedCalls");
2362         ast_manager_unregister("Park");
2363         ast_cli_unregister_multiple(cli_features, sizeof(cli_features) / sizeof(struct ast_cli_entry));
2364         ast_unregister_application(parkcall);
2365         ast_devstate_prov_del("Park");
2366         return ast_unregister_application(parkedcall);
2367 }
2368
2369 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "Call Features Resource",
2370                 .load = load_module,
2371                 .unload = unload_module,
2372                 .reload = reload,
2373                );