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