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