more replaceemnt of dup code with functions.
[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         if ((ast_app_dtget(transferer, transferer_real_context, xferto, sizeof(xferto), 100, transferdigittimeout))) {
672                 cid_num = transferer->cid.cid_num;
673                 cid_name = transferer->cid.cid_name;
674                 if (ast_exists_extension(transferer, transferer_real_context,xferto, 1, cid_num)) {
675                         snprintf(dialstr, sizeof(dialstr), "%s@%s/n", xferto, transferer_real_context);
676                         newchan = ast_feature_request_and_dial(transferer, "Local", ast_best_codec(transferer->nativeformats), dialstr, 15000, &outstate, cid_num, cid_name);
677                         ast_indicate(transferer, -1);
678                         if (newchan) {
679                                 res = ast_channel_make_compatible(transferer, newchan);
680                                 if (res < 0) {
681                                         ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", transferer->name, newchan->name);
682                                         ast_hangup(newchan);
683                                         return -1;
684                                 }
685                                 memset(&bconfig,0,sizeof(struct ast_bridge_config));
686                                 ast_set_flag(&(bconfig.features_caller), AST_FEATURE_DISCONNECT);
687                                 ast_set_flag(&(bconfig.features_callee), AST_FEATURE_DISCONNECT);
688                                 res = ast_bridge_call(transferer,newchan,&bconfig);
689                                 if (newchan->_softhangup || newchan->_state != AST_STATE_UP || !transferer->_softhangup) {
690                                         ast_hangup(newchan);
691                                         if (f) {
692                                                 ast_frfree(f);
693                                                 f = NULL;
694                                         }
695                                         if (!ast_strlen_zero(xfersound) && !ast_streamfile(transferer, xfersound, transferer->language)) {
696                                                 if (ast_waitstream(transferer, "") < 0) {
697                                                         ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
698                                                 }
699                                         }
700                                         ast_moh_stop(transferee);
701                                         ast_autoservice_stop(transferee);
702                                         ast_indicate(transferee, AST_CONTROL_UNHOLD);
703                                         transferer->_softhangup = 0;
704                                         return FEATURE_RETURN_SUCCESS;
705                                 }
706                                 
707                                 res = ast_channel_make_compatible(transferee, newchan);
708                                 if (res < 0) {
709                                         ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", transferee->name, newchan->name);
710                                         ast_hangup(newchan);
711                                         return -1;
712                                 }
713                                 
714                                 
715                                 ast_moh_stop(transferee);
716                                 
717                                 if ((ast_autoservice_stop(transferee) < 0)
718                                    || (ast_waitfordigit(transferee, 100) < 0)
719                                    || (ast_waitfordigit(newchan, 100) < 0) 
720                                    || ast_check_hangup(transferee) 
721                                    || ast_check_hangup(newchan)) {
722                                         ast_hangup(newchan);
723                                         res = -1;
724                                         return -1;
725                                 }
726
727                                 if ((xferchan = ast_channel_alloc(0))) {
728                                         ast_string_field_build(xferchan, name, "Transfered/%s", transferee->name);
729                                         /* Make formats okay */
730                                         xferchan->readformat = transferee->readformat;
731                                         xferchan->writeformat = transferee->writeformat;
732                                         ast_channel_masquerade(xferchan, transferee);
733                                         ast_explicit_goto(xferchan, transferee->context, transferee->exten, transferee->priority);
734                                         xferchan->_state = AST_STATE_UP;
735                                         ast_clear_flag(xferchan, AST_FLAGS_ALL);        
736                                         xferchan->_softhangup = 0;
737
738                                         if ((f = ast_read(xferchan))) {
739                                                 ast_frfree(f);
740                                                 f = NULL;
741                                         }
742                                         
743                                 } else {
744                                         ast_hangup(newchan);
745                                         return -1;
746                                 }
747
748                                 newchan->_state = AST_STATE_UP;
749                                 ast_clear_flag(newchan, AST_FLAGS_ALL); 
750                                 newchan->_softhangup = 0;
751                                 
752                                 if ((tobj = ast_calloc(1, sizeof(*tobj)))) {
753                                         tobj->chan = xferchan;
754                                         tobj->peer = newchan;
755                                         tobj->bconfig = *config;
756         
757                                         if (!ast_strlen_zero(xfersound) && !ast_streamfile(newchan, xfersound, newchan->language) &&
758                                                         ast_waitstream(newchan, "") < 0) {
759                                                 ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
760                                         }
761                                         ast_bridge_call_thread_launch(tobj);
762                                 } else {
763                                         ast_hangup(xferchan);
764                                         ast_hangup(newchan);
765                                 }
766                                 return -1;
767                                 
768                         } else {
769                                 ast_moh_stop(transferee);
770                                 ast_autoservice_stop(transferee);
771                                 ast_indicate(transferee, AST_CONTROL_UNHOLD);
772                                 /* any reason besides user requested cancel and busy triggers the failed sound */
773                                 if (outstate != AST_CONTROL_UNHOLD && outstate != AST_CONTROL_BUSY && !ast_strlen_zero(xferfailsound)) {
774                                         res = ast_streamfile(transferer, xferfailsound, transferer->language);
775                                         if (!res && (ast_waitstream(transferer, "") < 0)) {
776                                                 return -1;
777                                         }
778                                 }
779                                 return FEATURE_RETURN_SUCCESS;
780                         }
781                 } else {
782                         ast_log(LOG_WARNING, "Extension %s does not exist in context %s\n",xferto,transferer_real_context);
783                         ast_moh_stop(transferee);
784                         ast_autoservice_stop(transferee);
785                         ast_indicate(transferee, AST_CONTROL_UNHOLD);
786                         res = ast_streamfile(transferer, "beeperr", transferer->language);
787                         if (!res && (ast_waitstream(transferer, "") < 0)) {
788                                 return -1;
789                         }
790                 }
791         }  else {
792                 ast_log(LOG_WARNING, "Did not read data.\n");
793                 res = ast_streamfile(transferer, "beeperr", transferer->language);
794                 if (ast_waitstream(transferer, "") < 0) {
795                         return -1;
796                 }
797         }
798         ast_moh_stop(transferee);
799         ast_autoservice_stop(transferee);
800         ast_indicate(transferee, AST_CONTROL_UNHOLD);
801
802         return FEATURE_RETURN_SUCCESS;
803 }
804
805
806 /* add atxfer and automon as undefined so you can only use em if you configure them */
807 #define FEATURES_COUNT (sizeof(builtin_features) / sizeof(builtin_features[0]))
808
809 struct ast_call_feature builtin_features[] = 
810  {
811         { AST_FEATURE_REDIRECT, "Blind Transfer", "blindxfer", "#", "#", builtin_blindtransfer, AST_FEATURE_FLAG_NEEDSDTMF },
812         { AST_FEATURE_REDIRECT, "Attended Transfer", "atxfer", "", "", builtin_atxfer, AST_FEATURE_FLAG_NEEDSDTMF },
813         { AST_FEATURE_AUTOMON, "One Touch Monitor", "automon", "", "", builtin_automonitor, AST_FEATURE_FLAG_NEEDSDTMF },
814         { AST_FEATURE_DISCONNECT, "Disconnect Call", "disconnect", "*", "*", builtin_disconnect, AST_FEATURE_FLAG_NEEDSDTMF },
815 };
816
817
818 static AST_LIST_HEAD(feature_list,ast_call_feature) feature_list;
819
820 /*! \brief register new feature into feature_list*/
821 void ast_register_feature(struct ast_call_feature *feature)
822 {
823         if (!feature) {
824                 ast_log(LOG_NOTICE,"You didn't pass a feature!\n");
825                 return;
826         }
827   
828         AST_LIST_LOCK(&feature_list);
829         AST_LIST_INSERT_HEAD(&feature_list,feature,feature_entry);
830         AST_LIST_UNLOCK(&feature_list);
831
832         if (option_verbose >= 2) 
833                 ast_verbose(VERBOSE_PREFIX_2 "Registered Feature '%s'\n",feature->sname);
834 }
835
836 /*! \brief unregister feature from feature_list */
837 void ast_unregister_feature(struct ast_call_feature *feature)
838 {
839         if (!feature)
840                 return;
841
842         AST_LIST_LOCK(&feature_list);
843         AST_LIST_REMOVE(&feature_list,feature,feature_entry);
844         AST_LIST_UNLOCK(&feature_list);
845         free(feature);
846 }
847
848 static void ast_unregister_features(void)
849 {
850         struct ast_call_feature *feature;
851
852         AST_LIST_LOCK(&feature_list);
853         while ((feature = AST_LIST_REMOVE_HEAD(&feature_list,feature_entry)))
854                 free(feature);
855         AST_LIST_UNLOCK(&feature_list);
856 }
857
858 /*! \brief find a feature by name */
859 static struct ast_call_feature *find_feature(char *name)
860 {
861         struct ast_call_feature *tmp;
862
863         AST_LIST_LOCK(&feature_list);
864         AST_LIST_TRAVERSE(&feature_list, tmp, feature_entry) {
865                 if (!strcasecmp(tmp->sname, name))
866                         break;
867         }
868         AST_LIST_UNLOCK(&feature_list);
869
870         return tmp;
871 }
872
873 /*! \brief exec an app by feature */
874 static int feature_exec_app(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense)
875 {
876         struct ast_app *app;
877         struct ast_call_feature *feature;
878         int res;
879
880         AST_LIST_LOCK(&feature_list);
881         AST_LIST_TRAVERSE(&feature_list,feature,feature_entry) {
882                 if (!strcasecmp(feature->exten,code))
883                         break;
884         }
885         AST_LIST_UNLOCK(&feature_list);
886
887         if (!feature) { /* shouldn't ever happen! */
888                 ast_log(LOG_NOTICE, "Found feature before, but at execing we've lost it??\n");
889                 return -1; 
890         }
891         
892         app = pbx_findapp(feature->app);
893         if (app) {
894                 struct ast_channel *work = ast_test_flag(feature,AST_FEATURE_FLAG_CALLEE) ? peer : chan;
895                 res = pbx_exec(work, app, feature->app_args);
896                 if (res < 0)
897                         return res; 
898         } else {
899                 ast_log(LOG_WARNING, "Could not find application (%s)\n", feature->app);
900                 return -2;
901         }
902         
903         return FEATURE_RETURN_SUCCESS;  /* XXX should probably return res */
904 }
905
906 static void unmap_features(void)
907 {
908         int x;
909         for (x = 0; x < FEATURES_COUNT; x++)
910                 strcpy(builtin_features[x].exten, builtin_features[x].default_exten);
911 }
912
913 static int remap_feature(const char *name, const char *value)
914 {
915         int x;
916         int res = -1;
917         for (x = 0; x < FEATURES_COUNT; x++) {
918                 if (!strcasecmp(name, builtin_features[x].sname)) {
919                         ast_copy_string(builtin_features[x].exten, value, sizeof(builtin_features[x].exten));
920                         if (option_verbose > 1)
921                                 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);
922                         res = 0;
923                 } else if (!strcmp(value, builtin_features[x].exten)) 
924                         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);
925         }
926         return res;
927 }
928
929 static int ast_feature_interpret(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense)
930 {
931         int x;
932         struct ast_flags features;
933         int res = FEATURE_RETURN_PASSDIGITS;
934         struct ast_call_feature *feature;
935         const char *dynamic_features=pbx_builtin_getvar_helper(chan,"DYNAMIC_FEATURES");
936
937         if (sense == FEATURE_SENSE_CHAN)
938                 ast_copy_flags(&features, &(config->features_caller), AST_FLAGS_ALL);   
939         else
940                 ast_copy_flags(&features, &(config->features_callee), AST_FLAGS_ALL);   
941         ast_log(LOG_DEBUG, "Feature interpret: chan=%s, peer=%s, sense=%d, features=%d\n", chan->name, peer->name, sense, features.flags);
942
943         for (x=0; x < FEATURES_COUNT; x++) {
944                 if ((ast_test_flag(&features, builtin_features[x].feature_mask)) &&
945                     !ast_strlen_zero(builtin_features[x].exten)) {
946                         /* Feature is up for consideration */
947                         if (!strcmp(builtin_features[x].exten, code)) {
948                                 res = builtin_features[x].operation(chan, peer, config, code, sense);
949                                 break;
950                         } else if (!strncmp(builtin_features[x].exten, code, strlen(code))) {
951                                 if (res == FEATURE_RETURN_PASSDIGITS)
952                                         res = FEATURE_RETURN_STOREDIGITS;
953                         }
954                 }
955         }
956
957
958         if (!ast_strlen_zero(dynamic_features)) {
959                 char *tmp = ast_strdupa(dynamic_features);
960                 char *tok;
961
962                 if (!tmp)
963                         return res;
964                 
965                 while ((tok = strsep(&tmp, "#")) != NULL) {
966                         feature = find_feature(tok);
967                         
968                         if (feature) {
969                                 /* Feature is up for consideration */
970                                 if (!strcmp(feature->exten, code)) {
971                                         if (option_verbose > 2)
972                                                 ast_verbose(VERBOSE_PREFIX_3 " Feature Found: %s exten: %s\n",feature->sname, tok);
973                                         res = feature->operation(chan, peer, config, code, sense);
974                                         break;
975                                 } else if (!strncmp(feature->exten, code, strlen(code))) {
976                                         res = FEATURE_RETURN_STOREDIGITS;
977                                 }
978                         }
979                 }
980         }
981         
982         return res;
983 }
984
985 static void set_config_flags(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config)
986 {
987         int x;
988         
989         ast_clear_flag(config, AST_FLAGS_ALL);  
990         for (x = 0; x < FEATURES_COUNT; x++) {
991                 if (ast_test_flag(builtin_features + x, AST_FEATURE_FLAG_NEEDSDTMF)) {
992                         if (ast_test_flag(&(config->features_caller), builtin_features[x].feature_mask))
993                                 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
994
995                         if (ast_test_flag(&(config->features_callee), builtin_features[x].feature_mask))
996                                 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
997                 }
998         }
999         
1000         if (chan && peer && !(ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_0) && ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_1))) {
1001                 const char *dynamic_features = pbx_builtin_getvar_helper(chan, "DYNAMIC_FEATURES");
1002
1003                 if (dynamic_features) {
1004                         char *tmp = ast_strdupa(dynamic_features);
1005                         char *tok;
1006                         struct ast_call_feature *feature;
1007
1008                         if (!tmp)       /* no memory */
1009                                 return;
1010
1011                         /* while we have a feature */
1012                         while (NULL != (tok = strsep(&tmp, "#"))) {
1013                                 if ((feature = find_feature(tok)) && ast_test_flag(feature, AST_FEATURE_FLAG_NEEDSDTMF)) {
1014                                         if (ast_test_flag(feature, AST_FEATURE_FLAG_CALLER))
1015                                                 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
1016                                         if (ast_test_flag(feature, AST_FEATURE_FLAG_CALLEE))
1017                                                 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
1018                                 }
1019                         }
1020                 }
1021         }
1022 }
1023
1024 /* XXX this is very similar to the code in channel.c */
1025 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)
1026 {
1027         int state = 0;
1028         int cause = 0;
1029         int to;
1030         struct ast_channel *chan;
1031         struct ast_channel *monitor_chans[2];
1032         struct ast_channel *active_channel;
1033         int res = 0, ready = 0;
1034         
1035         if ((chan = ast_request(type, format, data, &cause))) {
1036                 ast_set_callerid(chan, cid_num, cid_name, cid_num);
1037                 ast_channel_inherit_variables(caller, chan);    
1038                 if (!ast_call(chan, data, timeout)) {
1039                         struct timeval started;
1040                         int x, len = 0;
1041                         char *disconnect_code = NULL, *dialed_code = NULL;
1042
1043                         ast_indicate(caller, AST_CONTROL_RINGING);
1044                         /* support dialing of the featuremap disconnect code while performing an attended tranfer */
1045                         for (x=0; x < FEATURES_COUNT; x++) {
1046                                 if (strcasecmp(builtin_features[x].sname, "disconnect"))
1047                                         continue;
1048
1049                                 disconnect_code = builtin_features[x].exten;
1050                                 len = strlen(disconnect_code) + 1;
1051                                 dialed_code = alloca(len);
1052                                 memset(dialed_code, 0, len);
1053                                 break;
1054                         }
1055                         x = 0;
1056                         started = ast_tvnow();
1057                         to = timeout;
1058                         while (!ast_check_hangup(caller) && timeout && (chan->_state != AST_STATE_UP)) {
1059                                 struct ast_frame *f = NULL;
1060
1061                                 monitor_chans[0] = caller;
1062                                 monitor_chans[1] = chan;
1063                                 active_channel = ast_waitfor_n(monitor_chans, 2, &to);
1064
1065                                 /* see if the timeout has been violated */
1066                                 if(ast_tvdiff_ms(ast_tvnow(), started) > timeout) {
1067                                         state = AST_CONTROL_UNHOLD;
1068                                         ast_log(LOG_NOTICE, "We exceeded our AT-timeout\n");
1069                                         break; /*doh! timeout*/
1070                                 }
1071
1072                                 if (!active_channel)
1073                                         continue;
1074
1075                                 if (chan && (chan == active_channel)){
1076                                         f = ast_read(chan);
1077                                         if (f == NULL) { /*doh! where'd he go?*/
1078                                                 state = AST_CONTROL_HANGUP;
1079                                                 res = 0;
1080                                                 break;
1081                                         }
1082                                         
1083                                         if (f->frametype == AST_FRAME_CONTROL || f->frametype == AST_FRAME_DTMF || f->frametype == AST_FRAME_TEXT) {
1084                                                 if (f->subclass == AST_CONTROL_RINGING) {
1085                                                         state = f->subclass;
1086                                                         if (option_verbose > 2)
1087                                                                 ast_verbose( VERBOSE_PREFIX_3 "%s is ringing\n", chan->name);
1088                                                         ast_indicate(caller, AST_CONTROL_RINGING);
1089                                                 } else if ((f->subclass == AST_CONTROL_BUSY) || (f->subclass == AST_CONTROL_CONGESTION)) {
1090                                                         state = f->subclass;
1091                                                         if (option_verbose > 2)
1092                                                                 ast_verbose( VERBOSE_PREFIX_3 "%s is busy\n", chan->name);
1093                                                         ast_indicate(caller, AST_CONTROL_BUSY);
1094                                                         ast_frfree(f);
1095                                                         f = NULL;
1096                                                         break;
1097                                                 } else if (f->subclass == AST_CONTROL_ANSWER) {
1098                                                         /* This is what we are hoping for */
1099                                                         state = f->subclass;
1100                                                         ast_frfree(f);
1101                                                         f = NULL;
1102                                                         ready=1;
1103                                                         break;
1104                                                 } else {
1105                                                         ast_log(LOG_NOTICE, "Don't know what to do about control frame: %d\n", f->subclass);
1106                                                 }
1107                                                 /* else who cares */
1108                                         }
1109
1110                                 } else if (caller && (active_channel == caller)) {
1111                                         f = ast_read(caller);
1112                                         if (f == NULL) { /*doh! where'd he go?*/
1113                                                 if (caller->_softhangup && !chan->_softhangup) {
1114                                                         /* make this a blind transfer */
1115                                                         ready = 1;
1116                                                         break;
1117                                                 }
1118                                                 state = AST_CONTROL_HANGUP;
1119                                                 res = 0;
1120                                                 break;
1121                                         }
1122                                         
1123                                         if (f->frametype == AST_FRAME_DTMF) {
1124                                                 dialed_code[x++] = f->subclass;
1125                                                 dialed_code[x] = '\0';
1126                                                 if (strlen(dialed_code) == len) {
1127                                                         x = 0;
1128                                                 } else if (x && strncmp(dialed_code, disconnect_code, x)) {
1129                                                         x = 0;
1130                                                         dialed_code[x] = '\0';
1131                                                 }
1132                                                 if (*dialed_code && !strcmp(dialed_code, disconnect_code)) {
1133                                                         /* Caller Canceled the call */
1134                                                         state = AST_CONTROL_UNHOLD;
1135                                                         ast_frfree(f);
1136                                                         f = NULL;
1137                                                         break;
1138                                                 }
1139                                         }
1140                                 }
1141                                 if (f)
1142                                         ast_frfree(f);
1143                         } /* end while */
1144                 } else
1145                         ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
1146         } else {
1147                 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
1148                 switch(cause) {
1149                 case AST_CAUSE_BUSY:
1150                         state = AST_CONTROL_BUSY;
1151                         break;
1152                 case AST_CAUSE_CONGESTION:
1153                         state = AST_CONTROL_CONGESTION;
1154                         break;
1155                 }
1156         }
1157         
1158         ast_indicate(caller, -1);
1159         if (chan && ready) {
1160                 if (chan->_state == AST_STATE_UP) 
1161                         state = AST_CONTROL_ANSWER;
1162                 res = 0;
1163         } else if(chan) {
1164                 res = -1;
1165                 ast_hangup(chan);
1166                 chan = NULL;
1167         } else {
1168                 res = -1;
1169         }
1170         
1171         if (outstate)
1172                 *outstate = state;
1173
1174         if (chan && res <= 0) {
1175                 if (chan->cdr || (chan->cdr = ast_cdr_alloc())) {
1176                         char tmp[256];
1177                         ast_cdr_init(chan->cdr, chan);
1178                         snprintf(tmp, 256, "%s/%s", type, (char *)data);
1179                         ast_cdr_setapp(chan->cdr,"Dial",tmp);
1180                         ast_cdr_update(chan);
1181                         ast_cdr_start(chan->cdr);
1182                         ast_cdr_end(chan->cdr);
1183                         /* If the cause wasn't handled properly */
1184                         if (ast_cdr_disposition(chan->cdr,chan->hangupcause))
1185                                 ast_cdr_failed(chan->cdr);
1186                 } else {
1187                         ast_log(LOG_WARNING, "Unable to create Call Detail Record\n");
1188                 }
1189         }
1190         
1191         return chan;
1192 }
1193
1194 int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast_bridge_config *config)
1195 {
1196         /* Copy voice back and forth between the two channels.  Give the peer
1197            the ability to transfer calls with '#<extension' syntax. */
1198         struct ast_frame *f;
1199         struct ast_channel *who;
1200         char chan_featurecode[FEATURE_MAX_LEN + 1]="";
1201         char peer_featurecode[FEATURE_MAX_LEN + 1]="";
1202         int res;
1203         int diff;
1204         int hasfeatures=0;
1205         int hadfeatures=0;
1206         struct ast_option_header *aoh;
1207         struct timeval start = { 0 , 0 };
1208         struct ast_bridge_config backup_config;
1209
1210         memset(&backup_config, 0, sizeof(backup_config));
1211
1212         config->start_time = ast_tvnow();
1213
1214         if (chan && peer) {
1215                 pbx_builtin_setvar_helper(chan, "BRIDGEPEER", peer->name);
1216                 pbx_builtin_setvar_helper(peer, "BRIDGEPEER", chan->name);
1217         } else if (chan)
1218                 pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", NULL);
1219
1220         if (monitor_ok) {
1221                 const char *monitor_exec;
1222                 struct ast_channel *src = NULL;
1223                 if (!monitor_app) { 
1224                         if (!(monitor_app = pbx_findapp("Monitor")))
1225                                 monitor_ok=0;
1226                 }
1227                 if ((monitor_exec = pbx_builtin_getvar_helper(chan, "AUTO_MONITOR"))) 
1228                         src = chan;
1229                 else if ((monitor_exec = pbx_builtin_getvar_helper(peer, "AUTO_MONITOR")))
1230                         src = peer;
1231                 if (monitor_app && src) {
1232                         char *tmp = ast_strdupa(monitor_exec);
1233                         if (tmp) {
1234                                 pbx_exec(src, monitor_app, tmp);
1235                         } else {
1236                                 ast_log(LOG_ERROR, "Monitor failed: out of memory\n");
1237                         }
1238                 }
1239         }
1240         
1241         set_config_flags(chan, peer, config);
1242         config->firstpass = 1;
1243
1244         /* Answer if need be */
1245         if (ast_answer(chan))
1246                 return -1;
1247         peer->appl = "Bridged Call";
1248         peer->data = chan->name;
1249
1250         /* copy the userfield from the B-leg to A-leg if applicable */
1251         if (chan->cdr && peer->cdr && !ast_strlen_zero(peer->cdr->userfield)) {
1252                 char tmp[256];
1253                 if (!ast_strlen_zero(chan->cdr->userfield)) {
1254                         snprintf(tmp, sizeof(tmp), "%s;%s", chan->cdr->userfield, peer->cdr->userfield);
1255                         ast_cdr_appenduserfield(chan, tmp);
1256                 } else
1257                         ast_cdr_setuserfield(chan, peer->cdr->userfield);
1258                 /* free the peer's cdr without ast_cdr_free complaining */
1259                 free(peer->cdr);
1260                 peer->cdr = NULL;
1261         }
1262         for (;;) {
1263                 struct ast_channel *other;      /* used later */
1264                 if (config->feature_timer)
1265                         start = ast_tvnow();
1266
1267                 res = ast_channel_bridge(chan, peer, config, &f, &who);
1268
1269                 if (config->feature_timer) {
1270                         /* Update time limit for next pass */
1271                         diff = ast_tvdiff_ms(ast_tvnow(), start);
1272                         config->feature_timer -= diff;
1273                         if (hasfeatures) {
1274                                 /* Running on backup config, meaning a feature might be being
1275                                    activated, but that's no excuse to keep things going 
1276                                    indefinitely! */
1277                                 if (backup_config.feature_timer && ((backup_config.feature_timer -= diff) <= 0)) {
1278                                         ast_log(LOG_DEBUG, "Timed out, realtime this time!\n");
1279                                         config->feature_timer = 0;
1280                                         who = chan;
1281                                         if (f)
1282                                                 ast_frfree(f);
1283                                         f = NULL;
1284                                         res = 0;
1285                                 } else if (config->feature_timer <= 0) {
1286                                         /* Not *really* out of time, just out of time for
1287                                            digits to come in for features. */
1288                                         ast_log(LOG_DEBUG, "Timed out for feature!\n");
1289                                         if (!ast_strlen_zero(peer_featurecode)) {
1290                                                 ast_dtmf_stream(chan, peer, peer_featurecode, 0);
1291                                                 memset(peer_featurecode, 0, sizeof(peer_featurecode));
1292                                         }
1293                                         if (!ast_strlen_zero(chan_featurecode)) {
1294                                                 ast_dtmf_stream(peer, chan, chan_featurecode, 0);
1295                                                 memset(chan_featurecode, 0, sizeof(chan_featurecode));
1296                                         }
1297                                         if (f)
1298                                                 ast_frfree(f);
1299                                         hasfeatures = !ast_strlen_zero(chan_featurecode) || !ast_strlen_zero(peer_featurecode);
1300                                         if (!hasfeatures) {
1301                                                 /* Restore original (possibly time modified) bridge config */
1302                                                 memcpy(config, &backup_config, sizeof(struct ast_bridge_config));
1303                                                 memset(&backup_config, 0, sizeof(backup_config));
1304                                         }
1305                                         hadfeatures = hasfeatures;
1306                                         /* Continue as we were */
1307                                         continue;
1308                                 }
1309                         } else {
1310                                 if (config->feature_timer <=0) {
1311                                         /* We ran out of time */
1312                                         config->feature_timer = 0;
1313                                         who = chan;
1314                                         if (f)
1315                                                 ast_frfree(f);
1316                                         f = NULL;
1317                                         res = 0;
1318                                 }
1319                         }
1320                 }
1321                 if (res < 0) {
1322                         ast_log(LOG_WARNING, "Bridge failed on channels %s and %s\n", chan->name, peer->name);
1323                         return -1;
1324                 }
1325                 
1326                 if (!f || (f->frametype == AST_FRAME_CONTROL &&
1327                                 (f->subclass == AST_CONTROL_HANGUP || f->subclass == AST_CONTROL_BUSY || 
1328                                         f->subclass == AST_CONTROL_CONGESTION ) ) ) {
1329                         res = -1;
1330                         break;
1331                 }
1332                 /* many things should be sent to the 'other' channel */
1333                 other = (who == chan) ? peer : chan;
1334                 if (f->frametype == AST_FRAME_CONTROL) {
1335                         if (f->subclass == AST_CONTROL_RINGING)
1336                                 ast_indicate(other, AST_CONTROL_RINGING);
1337                         else if (f->subclass == -1)
1338                                 ast_indicate(other, -1);
1339                         else if (f->subclass == AST_CONTROL_FLASH)
1340                                 ast_indicate(other, AST_CONTROL_FLASH);
1341                         else if (f->subclass == AST_CONTROL_OPTION) {
1342                                 aoh = f->data;
1343                                 /* Forward option Requests */
1344                                 if (aoh && aoh->flag == AST_OPTION_FLAG_REQUEST)
1345                                         ast_channel_setoption(other, ntohs(aoh->option), aoh->data, f->datalen - sizeof(struct ast_option_header), 0);
1346                         }
1347                 }
1348                 /* check for '*', if we find it it's time to disconnect */
1349                 if (f->frametype == AST_FRAME_DTMF) {
1350                         char *featurecode;
1351                         int sense;
1352
1353                         hadfeatures = hasfeatures;
1354                         /* This cannot overrun because the longest feature is one shorter than our buffer */
1355                         if (who == chan) {
1356                                 sense = FEATURE_SENSE_CHAN;
1357                                 featurecode = chan_featurecode;
1358                         } else  {
1359                                 sense = FEATURE_SENSE_PEER;
1360                                 featurecode = peer_featurecode;
1361                         }
1362                         /* append the event to featurecode. we rely on the string being zero-filled, and
1363                          * not overflowing it. XXX how do we guarantee the latter ?
1364                          */
1365                         featurecode[strlen(featurecode)] = f->subclass;
1366                         config->feature_timer = backup_config.feature_timer;
1367                         res = ast_feature_interpret(chan, peer, config, featurecode, sense);
1368                         switch(res) {
1369                         case FEATURE_RETURN_PASSDIGITS:
1370                                 ast_dtmf_stream(other, who, featurecode, 0);
1371                                 /* Fall through */
1372                         case FEATURE_RETURN_SUCCESS:
1373                                 memset(featurecode, 0, sizeof(chan_featurecode));
1374                                 break;
1375                         }
1376                         if (res >= FEATURE_RETURN_PASSDIGITS) {
1377                                 res = 0;
1378                         } else {
1379                                 ast_frfree(f);
1380                                 break;
1381                         }
1382                         hasfeatures = !ast_strlen_zero(chan_featurecode) || !ast_strlen_zero(peer_featurecode);
1383                         if (hadfeatures && !hasfeatures) {
1384                                 /* Restore backup */
1385                                 memcpy(config, &backup_config, sizeof(struct ast_bridge_config));
1386                                 memset(&backup_config, 0, sizeof(struct ast_bridge_config));
1387                         } else if (hasfeatures) {
1388                                 if (!hadfeatures) {
1389                                         /* Backup configuration */
1390                                         memcpy(&backup_config, config, sizeof(struct ast_bridge_config));
1391                                         /* Setup temporary config options */
1392                                         config->play_warning = 0;
1393                                         ast_clear_flag(&(config->features_caller), AST_FEATURE_PLAY_WARNING);
1394                                         ast_clear_flag(&(config->features_callee), AST_FEATURE_PLAY_WARNING);
1395                                         config->warning_freq = 0;
1396                                         config->warning_sound = NULL;
1397                                         config->end_sound = NULL;
1398                                         config->start_sound = NULL;
1399                                         config->firstpass = 0;
1400                                 }
1401                                 config->feature_timer = featuredigittimeout;
1402                                 ast_log(LOG_DEBUG, "Set time limit to %ld\n", config->feature_timer);
1403                         }
1404                 }
1405                 if (f)
1406                         ast_frfree(f);
1407         }
1408         return res;
1409 }
1410
1411 /*! \brief Take care of parked calls and unpark them if needed */
1412 static void *do_parking_thread(void *ignore)
1413 {
1414         fd_set rfds, efds;      /* results from previous select, to be preserved across loops. */
1415         FD_ZERO(&rfds);
1416         FD_ZERO(&efds);
1417
1418         for (;;) {
1419                 struct parkeduser *pu, *pl, *pt = NULL;
1420                 int ms = -1;    /* select timeout, uninitialized */
1421                 int max = -1;   /* max fd, none there yet */
1422                 fd_set nrfds, nefds;    /* args for the next select */
1423                 FD_ZERO(&nrfds);
1424                 FD_ZERO(&nefds);
1425
1426                 ast_mutex_lock(&parking_lock);
1427                 pl = NULL;
1428                 pu = parkinglot;
1429                 /* navigate the list with prev-cur pointers to support removals */
1430                 while(pu) {
1431                         struct ast_channel *chan = pu->chan;    /* shorthand */
1432                         int tms;        /* timeout for this item */
1433                         int x;          /* fd index in channel */
1434                         struct ast_context *con;
1435
1436                         if (pu->notquiteyet) { /* Pretend this one isn't here yet */
1437                                 pl = pu;
1438                                 pu = pu->next;
1439                                 continue;
1440                         }
1441                         tms = ast_tvdiff_ms(ast_tvnow(), pu->start);
1442                         if (tms > pu->parkingtime) {
1443                                 /* Stop music on hold */
1444                                 ast_moh_stop(chan);
1445                                 ast_indicate(chan, AST_CONTROL_UNHOLD);
1446                                 /* Get chan, exten from derived kludge */
1447                                 if (pu->peername[0]) {
1448                                         char *peername = ast_strdupa(pu->peername);
1449                                         char *cp = strrchr(peername, '-');
1450                                         if (cp) 
1451                                                 *cp = 0;
1452                                         con = ast_context_find(parking_con_dial);
1453                                         if (!con) {
1454                                                 con = ast_context_create(NULL, parking_con_dial, registrar);
1455                                                 if (!con) {
1456                                                         ast_log(LOG_ERROR, "Parking dial context '%s' does not exist and unable to create\n", parking_con_dial);
1457                                                 }
1458                                         }
1459                                         if (con) {
1460                                                 char returnexten[AST_MAX_EXTENSION];
1461                                                 snprintf(returnexten, sizeof(returnexten), "%s||t", peername);
1462                                                 ast_add_extension2(con, 1, peername, 1, NULL, NULL, "Dial", strdup(returnexten), FREE, registrar);
1463                                         }
1464                                         set_c_e_p(chan, parking_con_dial, peername, 1);
1465                                 } else {
1466                                         /* They've been waiting too long, send them back to where they came.  Theoretically they
1467                                            should have their original extensions and such, but we copy to be on the safe side */
1468                                         set_c_e_p(chan, pu->context, pu->exten, pu->priority);
1469                                 }
1470
1471                                 manager_event(EVENT_FLAG_CALL, "ParkedCallTimeOut",
1472                                         "Exten: %d\r\n"
1473                                         "Channel: %s\r\n"
1474                                         "CallerID: %s\r\n"
1475                                         "CallerIDName: %s\r\n"
1476                                         ,pu->parkingnum, chan->name
1477                                         ,(chan->cid.cid_num ? chan->cid.cid_num : "<unknown>")
1478                                         ,(chan->cid.cid_name ? chan->cid.cid_name : "<unknown>")
1479                                         );
1480
1481                                 if (option_verbose > 1) 
1482                                         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);
1483                                 /* Start up the PBX, or hang them up */
1484                                 if (ast_pbx_start(chan))  {
1485                                         ast_log(LOG_WARNING, "Unable to restart the PBX for user on '%s', hanging them up...\n", chan->name);
1486                                         ast_hangup(chan);
1487                                 }
1488                                 /* And take them out of the parking lot */
1489                                 if (pl) 
1490                                         pl->next = pu->next;
1491                                 else
1492                                         parkinglot = pu->next;
1493                                 pt = pu;
1494                                 pu = pu->next;
1495                                 con = ast_context_find(parking_con);
1496                                 if (con) {
1497                                         char exten[AST_MAX_EXTENSION];
1498                                         snprintf(exten, sizeof(exten), "%d", pt->parkingnum);
1499                                         if (ast_context_remove_extension2(con, exten, 1, NULL))
1500                                                 ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
1501                                 } else
1502                                         ast_log(LOG_WARNING, "Whoa, no parking context?\n");
1503                                 free(pt);
1504                         } else {        /* still within parking time, process descriptors */
1505                                 for (x = 0; x < AST_MAX_FDS; x++) {
1506                                         struct ast_frame *f;
1507
1508                                         if (chan->fds[x] == -1 || (!FD_ISSET(chan->fds[x], &rfds) && !FD_ISSET(chan->fds[x], &efds)))
1509                                                 continue;       /* nothing on this descriptor */
1510
1511                                         if (FD_ISSET(chan->fds[x], &efds))
1512                                                 ast_set_flag(chan, AST_FLAG_EXCEPTION);
1513                                         else
1514                                                 ast_clear_flag(chan, AST_FLAG_EXCEPTION);
1515                                         chan->fdno = x;
1516                                         /* See if they need servicing */
1517                                         f = ast_read(chan);
1518                                         if (!f || (f->frametype == AST_FRAME_CONTROL && f->subclass ==  AST_CONTROL_HANGUP)) {
1519                                                 if (f)
1520                                                         ast_frfree(f);
1521                                                 manager_event(EVENT_FLAG_CALL, "ParkedCallGiveUp",
1522                                                         "Exten: %d\r\n"
1523                                                         "Channel: %s\r\n"
1524                                                         "CallerID: %s\r\n"
1525                                                         "CallerIDName: %s\r\n"
1526                                                         ,pu->parkingnum, chan->name
1527                                                         ,(chan->cid.cid_num ? chan->cid.cid_num : "<unknown>")
1528                                                         ,(chan->cid.cid_name ? chan->cid.cid_name : "<unknown>")
1529                                                         );
1530
1531                                                 /* There's a problem, hang them up*/
1532                                                 if (option_verbose > 1) 
1533                                                         ast_verbose(VERBOSE_PREFIX_2 "%s got tired of being parked\n", chan->name);
1534                                                 ast_hangup(chan);
1535                                                 /* And take them out of the parking lot */
1536                                                 if (pl) 
1537                                                         pl->next = pu->next;
1538                                                 else
1539                                                         parkinglot = pu->next;
1540                                                 pt = pu;
1541                                                 pu = pu->next;
1542                                                 con = ast_context_find(parking_con);
1543                                                 if (con) {
1544                                                         char exten[AST_MAX_EXTENSION];
1545                                                         snprintf(exten, sizeof(exten), "%d", pt->parkingnum);
1546                                                         if (ast_context_remove_extension2(con, exten, 1, NULL))
1547                                                                 ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
1548                                                 } else
1549                                                         ast_log(LOG_WARNING, "Whoa, no parking context?\n");
1550                                                 free(pt);
1551                                                 break;
1552                                         } else {
1553                                                 /* XXX Maybe we could do something with packets, like dial "0" for operator or something XXX */
1554                                                 ast_frfree(f);
1555                                                 if (pu->moh_trys < 3 && !chan->generatordata) {
1556                                                         ast_log(LOG_DEBUG, "MOH on parked call stopped by outside source.  Restarting.\n");
1557                                                         ast_moh_start(chan, NULL);
1558                                                         pu->moh_trys++;
1559                                                 }
1560                                                 goto std;       /* XXX Ick: jumping into an else statement??? XXX */
1561                                         }
1562
1563                                 } /* end for */
1564                                 if (x >= AST_MAX_FDS) {
1565 std:                                    for (x=0; x<AST_MAX_FDS; x++) { /* mark fds for next round */
1566                                                 if (chan->fds[x] > -1) {
1567                                                         FD_SET(chan->fds[x], &nrfds);
1568                                                         FD_SET(chan->fds[x], &nefds);
1569                                                         if (chan->fds[x] > max)
1570                                                                 max = chan->fds[x];
1571                                                 }
1572                                         }
1573                                         /* Keep track of our shortest wait */
1574                                         if (tms < ms || ms < 0)
1575                                                 ms = tms;
1576                                         pl = pu;
1577                                         pu = pu->next;
1578                                 }
1579                         }
1580                 } /* end while */
1581                 ast_mutex_unlock(&parking_lock);
1582                 rfds = nrfds;
1583                 efds = nefds;
1584                 {
1585                         struct timeval tv = ast_samp2tv(ms, 1000);
1586                         /* Wait for something to happen */
1587                         ast_select(max + 1, &rfds, NULL, &efds, (ms > -1) ? &tv : NULL);
1588                 }
1589                 pthread_testcancel();
1590         }
1591         return NULL;    /* Never reached */
1592 }
1593
1594 static int park_call_exec(struct ast_channel *chan, void *data)
1595 {
1596         /* Data is unused at the moment but could contain a parking
1597            lot context eventually */
1598         int res=0;
1599         struct localuser *u;
1600         LOCAL_USER_ADD(u);
1601         /* Setup the exten/priority to be s/1 since we don't know
1602            where this call should return */
1603         strcpy(chan->exten, "s");
1604         chan->priority = 1;
1605         if (chan->_state != AST_STATE_UP)
1606                 res = ast_answer(chan);
1607         if (!res)
1608                 res = ast_safe_sleep(chan, 1000);
1609         if (!res)
1610                 res = ast_park_call(chan, chan, 0, NULL);
1611         LOCAL_USER_REMOVE(u);
1612         if (!res)
1613                 res = AST_PBX_KEEPALIVE;
1614         return res;
1615 }
1616
1617 static int park_exec(struct ast_channel *chan, void *data)
1618 {
1619         int res=0;
1620         struct localuser *u;
1621         struct ast_channel *peer=NULL;
1622         struct parkeduser *pu, *pl=NULL;
1623         struct ast_context *con;
1624         int park;
1625         int dres;
1626         struct ast_bridge_config config;
1627
1628         if (!data) {
1629                 ast_log(LOG_WARNING, "Park requires an argument (extension number)\n");
1630                 return -1;
1631         }
1632         LOCAL_USER_ADD(u);
1633         park = atoi((char *)data);
1634         ast_mutex_lock(&parking_lock);
1635         pu = parkinglot;
1636         while(pu) {
1637                 if (pu->parkingnum == park) {
1638                         if (pl)
1639                                 pl->next = pu->next;
1640                         else
1641                                 parkinglot = pu->next;
1642                         break;
1643                 }
1644                 pl = pu;
1645                 pu = pu->next;
1646         }
1647         ast_mutex_unlock(&parking_lock);
1648         if (pu) {
1649                 peer = pu->chan;
1650                 con = ast_context_find(parking_con);
1651                 if (con) {
1652                         char exten[AST_MAX_EXTENSION];
1653                         snprintf(exten, sizeof(exten), "%d", pu->parkingnum);
1654                         if (ast_context_remove_extension2(con, exten, 1, NULL))
1655                                 ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
1656                 } else
1657                         ast_log(LOG_WARNING, "Whoa, no parking context?\n");
1658
1659                 manager_event(EVENT_FLAG_CALL, "UnParkedCall",
1660                         "Exten: %d\r\n"
1661                         "Channel: %s\r\n"
1662                         "From: %s\r\n"
1663                         "CallerID: %s\r\n"
1664                         "CallerIDName: %s\r\n"
1665                         ,pu->parkingnum, pu->chan->name, chan->name
1666                         ,(pu->chan->cid.cid_num ? pu->chan->cid.cid_num : "<unknown>")
1667                         ,(pu->chan->cid.cid_name ? pu->chan->cid.cid_name : "<unknown>")
1668                         );
1669
1670                 free(pu);
1671         }
1672         /* JK02: it helps to answer the channel if not already up */
1673         if (chan->_state != AST_STATE_UP)
1674                 ast_answer(chan);
1675
1676         if (peer) {
1677                 /* Play a courtesy to the source(s) configured to prefix the bridge connecting */
1678                 
1679                 if (!ast_strlen_zero(courtesytone)) {
1680                         int error = 0;
1681                         ast_moh_stop(peer);
1682                         ast_indicate(peer, AST_CONTROL_UNHOLD);
1683                         if (parkedplay == 0) {
1684                                 error = stream_and_wait(chan, courtesytone, chan->language, "");
1685                                         error = 1;
1686                         } else if (parkedplay == 1) {
1687                                 error = stream_and_wait(peer, courtesytone, chan->language, "");
1688                         } else if (parkedplay == 2) {
1689                                 if (!ast_streamfile(chan, courtesytone, chan->language) &&
1690                                                 !ast_streamfile(peer, courtesytone, chan->language)) {
1691                                         /* XXX we would like to wait on both! */
1692                                         res = ast_waitstream(chan, "");
1693                                         if (res >= 0)
1694                                                 res = ast_waitstream(peer, "");
1695                                         if (res < 0)
1696                                                 error = 1;
1697                                 }
1698                         }
1699                         if (error) {
1700                                 ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
1701                                 ast_hangup(peer);
1702                                 return -1;
1703                         }
1704                 }
1705  
1706                 res = ast_channel_make_compatible(chan, peer);
1707                 if (res < 0) {
1708                         ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for bridge\n", chan->name, peer->name);
1709                         ast_hangup(peer);
1710                         return -1;
1711                 }
1712                 /* This runs sorta backwards, since we give the incoming channel control, as if it
1713                    were the person called. */
1714                 if (option_verbose > 2) 
1715                         ast_verbose(VERBOSE_PREFIX_3 "Channel %s connected to parked call %d\n", chan->name, park);
1716
1717                 memset(&config, 0, sizeof(struct ast_bridge_config));
1718                 ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
1719                 ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
1720                 config.timelimit = 0;
1721                 config.play_warning = 0;
1722                 config.warning_freq = 0;
1723                 config.warning_sound=NULL;
1724                 res = ast_bridge_call(chan, peer, &config);
1725
1726                 /* Simulate the PBX hanging up */
1727                 if (res != AST_PBX_NO_HANGUP_PEER)
1728                         ast_hangup(peer);
1729                 return res;
1730         } else {
1731                 /* XXX Play a message XXX */
1732                 dres = ast_streamfile(chan, "pbx-invalidpark", chan->language);
1733                 if (!dres)
1734                         dres = ast_waitstream(chan, "");
1735                 else {
1736                         ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", "pbx-invalidpark", chan->name);
1737                         dres = 0;
1738                 }
1739                 if (option_verbose > 2) 
1740                         ast_verbose(VERBOSE_PREFIX_3 "Channel %s tried to talk to nonexistent parked call %d\n", chan->name, park);
1741                 res = -1;
1742         }
1743         LOCAL_USER_REMOVE(u);
1744         return res;
1745 }
1746
1747 static int handle_showfeatures(int fd, int argc, char *argv[])
1748 {
1749         int i;
1750         int fcount;
1751         struct ast_call_feature *feature;
1752         char format[] = "%-25s %-7s %-7s\n";
1753
1754         ast_cli(fd, format, "Builtin Feature", "Default", "Current");
1755         ast_cli(fd, format, "---------------", "-------", "-------");
1756
1757         ast_cli(fd, format, "Pickup", "*8", ast_pickup_ext());          /* default hardcoded above, so we'll hardcode it here */
1758
1759         fcount = sizeof(builtin_features) / sizeof(builtin_features[0]);
1760
1761         for (i = 0; i < fcount; i++)
1762         {
1763                 ast_cli(fd, format, builtin_features[i].fname, builtin_features[i].default_exten, builtin_features[i].exten);
1764         }
1765         ast_cli(fd, "\n");
1766         ast_cli(fd, format, "Dynamic Feature", "Default", "Current");
1767         ast_cli(fd, format, "---------------", "-------", "-------");
1768         if (AST_LIST_EMPTY(&feature_list)) {
1769                 ast_cli(fd, "(none)\n");
1770         }
1771         else {
1772                 AST_LIST_LOCK(&feature_list);
1773                 AST_LIST_TRAVERSE(&feature_list, feature, feature_entry) {
1774                         ast_cli(fd, format, feature->sname, "no def", feature->exten);  
1775                 }
1776                 AST_LIST_UNLOCK(&feature_list);
1777         }
1778         ast_cli(fd, "\nCall parking\n");
1779         ast_cli(fd, "------------\n");
1780         ast_cli(fd,"%-20s:      %s\n", "Parking extension", parking_ext);
1781         ast_cli(fd,"%-20s:      %s\n", "Parking context", parking_con);
1782         ast_cli(fd,"%-20s:      %d-%d\n", "Parked call extensions", parking_start, parking_stop);
1783         ast_cli(fd,"\n");
1784         
1785         return RESULT_SUCCESS;
1786 }
1787
1788 static char showfeatures_help[] =
1789 "Usage: show features\n"
1790 "       Lists currently configured features.\n";
1791
1792 static struct ast_cli_entry showfeatures =
1793 { { "show", "features", NULL }, handle_showfeatures, "Lists configured features", showfeatures_help };
1794
1795 static int handle_parkedcalls(int fd, int argc, char *argv[])
1796 {
1797         struct parkeduser *cur;
1798         int numparked = 0;
1799
1800         ast_cli(fd, "%4s %25s (%-15s %-12s %-4s) %-6s \n", "Num", "Channel"
1801                 , "Context", "Extension", "Pri", "Timeout");
1802
1803         ast_mutex_lock(&parking_lock);
1804
1805         for (cur = parkinglot; cur; cur = cur->next) {
1806                 ast_cli(fd, "%4d %25s (%-15s %-12s %-4d) %6lds\n"
1807                         ,cur->parkingnum, cur->chan->name, cur->context, cur->exten
1808                         ,cur->priority, cur->start.tv_sec + (cur->parkingtime/1000) - time(NULL));
1809
1810                 numparked++;
1811         }
1812         ast_cli(fd, "%d parked call%s.\n", numparked, (numparked != 1) ? "s" : "");
1813
1814         ast_mutex_unlock(&parking_lock);
1815
1816         return RESULT_SUCCESS;
1817 }
1818
1819 static char showparked_help[] =
1820 "Usage: show parkedcalls\n"
1821 "       Lists currently parked calls.\n";
1822
1823 static struct ast_cli_entry showparked =
1824 { { "show", "parkedcalls", NULL }, handle_parkedcalls, "Lists parked calls", showparked_help };
1825
1826 /*! \brief Dump lot status */
1827 static int manager_parking_status( struct mansession *s, struct message *m )
1828 {
1829         struct parkeduser *cur;
1830         char *id = astman_get_header(m,"ActionID");
1831         char idText[256] = "";
1832
1833         if (!ast_strlen_zero(id))
1834                 snprintf(idText,256,"ActionID: %s\r\n",id);
1835
1836         astman_send_ack(s, m, "Parked calls will follow");
1837
1838         ast_mutex_lock(&parking_lock);
1839
1840         for (cur=parkinglot; cur; cur = cur->next) {
1841                 astman_append(s, "Event: ParkedCall\r\n"
1842                         "Exten: %d\r\n"
1843                         "Channel: %s\r\n"
1844                         "From: %s\r\n"
1845                         "Timeout: %ld\r\n"
1846                         "CallerID: %s\r\n"
1847                         "CallerIDName: %s\r\n"
1848                         "%s"
1849                         "\r\n"
1850                         ,cur->parkingnum, cur->chan->name, cur->peername
1851                         ,(long)cur->start.tv_sec + (long)(cur->parkingtime/1000) - (long)time(NULL)
1852                         ,(cur->chan->cid.cid_num ? cur->chan->cid.cid_num : "")
1853                         ,(cur->chan->cid.cid_name ? cur->chan->cid.cid_name : "")
1854                         ,idText);
1855         }
1856
1857         astman_append(s,
1858                 "Event: ParkedCallsComplete\r\n"
1859                 "%s"
1860                 "\r\n",idText);
1861
1862         ast_mutex_unlock(&parking_lock);
1863
1864         return RESULT_SUCCESS;
1865 }
1866
1867 static char mandescr_park[] =
1868 "Description: Park a channel.\n"
1869 "Variables: (Names marked with * are required)\n"
1870 "       *Channel: Channel name to park\n"
1871 "       *Channel2: Channel to announce park info to (and return to if timeout)\n"
1872 "       Timeout: Number of milliseconds to wait before callback.\n";  
1873
1874 static int manager_park(struct mansession *s, struct message *m)
1875 {
1876         char *channel = astman_get_header(m, "Channel");
1877         char *channel2 = astman_get_header(m, "Channel2");
1878         char *timeout = astman_get_header(m, "Timeout");
1879         char buf[BUFSIZ];
1880         int to = 0;
1881         int res = 0;
1882         int parkExt = 0;
1883         struct ast_channel *ch1, *ch2;
1884
1885         if (ast_strlen_zero(channel)) {
1886                 astman_send_error(s, m, "Channel not specified");
1887                 return 0;
1888         }
1889
1890         if (ast_strlen_zero(channel2)) {
1891                 astman_send_error(s, m, "Channel2 not specified");
1892                 return 0;
1893         }
1894
1895         ch1 = ast_get_channel_by_name_locked(channel);
1896         if (!ch1) {
1897                 snprintf(buf, sizeof(buf), "Channel does not exist: %s", channel);
1898                 astman_send_error(s, m, buf);
1899                 return 0;
1900         }
1901
1902         ch2 = ast_get_channel_by_name_locked(channel2);
1903         if (!ch2) {
1904                 snprintf(buf, sizeof(buf), "Channel does not exist: %s", channel2);
1905                 astman_send_error(s, m, buf);
1906                 ast_mutex_unlock(&ch1->lock);
1907                 return 0;
1908         }
1909
1910         if (!ast_strlen_zero(timeout)) {
1911                 sscanf(timeout, "%d", &to);
1912         }
1913
1914         res = ast_masq_park_call(ch1, ch2, to, &parkExt);
1915         if (!res) {
1916                 ast_softhangup(ch2, AST_SOFTHANGUP_EXPLICIT);
1917                 astman_send_ack(s, m, "Park successful");
1918         } else {
1919                 astman_send_error(s, m, "Park failure");
1920         }
1921
1922         ast_mutex_unlock(&ch1->lock);
1923         ast_mutex_unlock(&ch2->lock);
1924
1925         return 0;
1926 }
1927
1928
1929 int ast_pickup_call(struct ast_channel *chan)
1930 {
1931         struct ast_channel *cur = NULL;
1932         int res = -1;
1933
1934         while ( (cur = ast_channel_walk_locked(cur)) != NULL) {
1935                 if (!cur->pbx && 
1936                         (cur != chan) &&
1937                         (chan->pickupgroup & cur->callgroup) &&
1938                         ((cur->_state == AST_STATE_RINGING) ||
1939                          (cur->_state == AST_STATE_RING))) {
1940                                 break;
1941                 }
1942                 ast_mutex_unlock(&cur->lock);
1943         }
1944         if (cur) {
1945                 if (option_debug)
1946                         ast_log(LOG_DEBUG, "Call pickup on chan '%s' by '%s'\n",cur->name, chan->name);
1947                 res = ast_answer(chan);
1948                 if (res)
1949                         ast_log(LOG_WARNING, "Unable to answer '%s'\n", chan->name);
1950                 res = ast_queue_control(chan, AST_CONTROL_ANSWER);
1951                 if (res)
1952                         ast_log(LOG_WARNING, "Unable to queue answer on '%s'\n", chan->name);
1953                 res = ast_channel_masquerade(cur, chan);
1954                 if (res)
1955                         ast_log(LOG_WARNING, "Unable to masquerade '%s' into '%s'\n", chan->name, cur->name);           /* Done */
1956                 ast_mutex_unlock(&cur->lock);
1957         } else  {
1958                 if (option_debug)
1959                         ast_log(LOG_DEBUG, "No call pickup possible...\n");
1960         }
1961         return res;
1962 }
1963
1964 static int load_config(void) 
1965 {
1966         int start = 0, end = 0;
1967         struct ast_context *con = NULL;
1968         struct ast_config *cfg = NULL;
1969         struct ast_variable *var = NULL;
1970         char old_parking_ext[AST_MAX_EXTENSION];
1971         char old_parking_con[AST_MAX_EXTENSION] = "";
1972
1973         if (!ast_strlen_zero(parking_con)) {
1974                 strcpy(old_parking_ext, parking_ext);
1975                 strcpy(old_parking_con, parking_con);
1976         } 
1977
1978         /* Reset to defaults */
1979         strcpy(parking_con, "parkedcalls");
1980         strcpy(parking_con_dial, "park-dial");
1981         strcpy(parking_ext, "700");
1982         strcpy(pickup_ext, "*8");
1983         courtesytone[0] = '\0';
1984         strcpy(xfersound, "beep");
1985         strcpy(xferfailsound, "pbx-invalid");
1986         parking_start = 701;
1987         parking_stop = 750;
1988         parkfindnext = 0;
1989         adsipark = 0;
1990
1991         transferdigittimeout = DEFAULT_TRANSFER_DIGIT_TIMEOUT;
1992         featuredigittimeout = DEFAULT_FEATURE_DIGIT_TIMEOUT;
1993
1994         cfg = ast_config_load("features.conf");
1995         if (cfg) {
1996                 for (var = ast_variable_browse(cfg, "general"); var; var = var->next) {
1997                         if (!strcasecmp(var->name, "parkext")) {
1998                                 ast_copy_string(parking_ext, var->value, sizeof(parking_ext));
1999                         } else if (!strcasecmp(var->name, "context")) {
2000                                 ast_copy_string(parking_con, var->value, sizeof(parking_con));
2001                         } else if (!strcasecmp(var->name, "parkingtime")) {
2002                                 if ((sscanf(var->value, "%d", &parkingtime) != 1) || (parkingtime < 1)) {
2003                                         ast_log(LOG_WARNING, "%s is not a valid parkingtime\n", var->value);
2004                                         parkingtime = DEFAULT_PARK_TIME;
2005                                 } else
2006                                         parkingtime = parkingtime * 1000;
2007                         } else if (!strcasecmp(var->name, "parkpos")) {
2008                                 if (sscanf(var->value, "%d-%d", &start, &end) != 2) {
2009                                         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);
2010                                 } else {
2011                                         parking_start = start;
2012                                         parking_stop = end;
2013                                 }
2014                         } else if (!strcasecmp(var->name, "findslot")) {
2015                                 parkfindnext = (!strcasecmp(var->value, "next"));
2016                         } else if (!strcasecmp(var->name, "adsipark")) {
2017                                 adsipark = ast_true(var->value);
2018                         } else if (!strcasecmp(var->name, "transferdigittimeout")) {
2019                                 if ((sscanf(var->value, "%d", &transferdigittimeout) != 1) || (transferdigittimeout < 1)) {
2020                                         ast_log(LOG_WARNING, "%s is not a valid transferdigittimeout\n", var->value);
2021                                         transferdigittimeout = DEFAULT_TRANSFER_DIGIT_TIMEOUT;
2022                                 } else
2023                                         transferdigittimeout = transferdigittimeout * 1000;
2024                         } else if (!strcasecmp(var->name, "featuredigittimeout")) {
2025                                 if ((sscanf(var->value, "%d", &featuredigittimeout) != 1) || (featuredigittimeout < 1)) {
2026                                         ast_log(LOG_WARNING, "%s is not a valid featuredigittimeout\n", var->value);
2027                                         featuredigittimeout = DEFAULT_FEATURE_DIGIT_TIMEOUT;
2028                                 }
2029                         } else if (!strcasecmp(var->name, "courtesytone")) {
2030                                 ast_copy_string(courtesytone, var->value, sizeof(courtesytone));
2031                         }  else if (!strcasecmp(var->name, "parkedplay")) {
2032                                 if (!strcasecmp(var->value, "both"))
2033                                         parkedplay = 2;
2034                                 else if (!strcasecmp(var->value, "parked"))
2035                                         parkedplay = 1;
2036                                 else
2037                                         parkedplay = 0;
2038                         } else if (!strcasecmp(var->name, "xfersound")) {
2039                                 ast_copy_string(xfersound, var->value, sizeof(xfersound));
2040                         } else if (!strcasecmp(var->name, "xferfailsound")) {
2041                                 ast_copy_string(xferfailsound, var->value, sizeof(xferfailsound));
2042                         } else if (!strcasecmp(var->name, "pickupexten")) {
2043                                 ast_copy_string(pickup_ext, var->value, sizeof(pickup_ext));
2044                         }
2045                 }
2046
2047                 unmap_features();
2048                 for (var = ast_variable_browse(cfg, "featuremap"); var; var = var->next) {
2049                         if (remap_feature(var->name, var->value))
2050                                 ast_log(LOG_NOTICE, "Unknown feature '%s'\n", var->name);
2051                 }
2052
2053                 /* Map a key combination to an application*/
2054                 ast_unregister_features();
2055                 for (var = ast_variable_browse(cfg, "applicationmap"); var; var = var->next) {
2056                         char *tmp_val = ast_strdup(var->value);
2057                         char *exten, *party=NULL, *app=NULL, *app_args=NULL; 
2058
2059                         if (!tmp_val) { 
2060                                 /* XXX No memory. We should probably break, but at least we do not
2061                                  * insist on this entry or we could be stuck in an
2062                                  * infinite loop.
2063                                  */
2064                                 continue;
2065                         }
2066
2067                         /* strsep() sets the argument to NULL if match not found, and it
2068                          * is safe to use it with a NULL argument, so we don't check
2069                          * between calls.
2070                          */
2071                         exten = strsep(&tmp_val,",");
2072                         party = strsep(&tmp_val,",");
2073                         app = strsep(&tmp_val,",");
2074                         app_args = strsep(&tmp_val,",");
2075
2076                         /* XXX var_name or app_args ? */
2077                         if (ast_strlen_zero(app) || ast_strlen_zero(exten) || ast_strlen_zero(party) || ast_strlen_zero(var->name)) {
2078                                 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);
2079                                 free(tmp_val);
2080                                 continue;
2081                         }
2082
2083                         {
2084                                 struct ast_call_feature *feature;
2085                                 int mallocd = 0;
2086                                 
2087                                 if (!(feature = find_feature(var->name))) {
2088                                         mallocd = 1;
2089                                         
2090                                         if (!(feature = ast_calloc(1, sizeof(*feature)))) {
2091                                                 free(tmp_val);
2092                                                 continue;                                       
2093                                         }
2094                                 }
2095
2096                                 ast_copy_string(feature->sname,var->name,FEATURE_SNAME_LEN);
2097                                 ast_copy_string(feature->app,app,FEATURE_APP_LEN);
2098                                 ast_copy_string(feature->exten, exten,FEATURE_EXTEN_LEN);
2099                                 free(tmp_val);
2100                                 
2101                                 if (app_args) 
2102                                         ast_copy_string(feature->app_args,app_args,FEATURE_APP_ARGS_LEN);
2103                                 
2104                                 ast_copy_string(feature->exten, exten,sizeof(feature->exten));
2105                                 feature->operation=feature_exec_app;
2106                                 ast_set_flag(feature,AST_FEATURE_FLAG_NEEDSDTMF);
2107                                 
2108                                 if (!strcasecmp(party,"caller"))
2109                                         ast_set_flag(feature,AST_FEATURE_FLAG_CALLER);
2110                                 else if (!strcasecmp(party, "callee"))
2111                                         ast_set_flag(feature,AST_FEATURE_FLAG_CALLEE);
2112                                 else {
2113                                         ast_log(LOG_NOTICE, "Invalid party specification for feature '%s', must be caller, or callee\n", var->name);
2114                                         continue;
2115                                 }
2116
2117                                 ast_register_feature(feature);
2118                                 
2119                                 if (option_verbose >=1)
2120                                         ast_verbose(VERBOSE_PREFIX_2 "Mapping Feature '%s' to app '%s' with code '%s'\n", var->name, app, exten);  
2121                         }
2122                 }        
2123         }
2124         ast_config_destroy(cfg);
2125
2126         /* Remove the old parking extension */
2127         if (!ast_strlen_zero(old_parking_con) && (con = ast_context_find(old_parking_con)))     {
2128                 ast_context_remove_extension2(con, old_parking_ext, 1, registrar);
2129                 ast_log(LOG_DEBUG, "Removed old parking extension %s@%s\n", old_parking_ext, old_parking_con);
2130         }
2131         
2132         if (!(con = ast_context_find(parking_con)) && !(con = ast_context_create(NULL, parking_con, registrar))) {
2133                 ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", parking_con);
2134                 return -1;
2135         }
2136         return ast_add_extension2(con, 1, ast_parking_ext(), 1, NULL, NULL, parkcall, strdup(""), FREE, registrar);
2137 }
2138
2139 static int reload(void *mod)
2140 {
2141         return load_config();
2142 }
2143
2144 static int load_module(void *mod)
2145 {
2146         int res;
2147         
2148         __mod_desc = mod;
2149         AST_LIST_HEAD_INIT(&feature_list);
2150         memset(parking_ext, 0, sizeof(parking_ext));
2151         memset(parking_con, 0, sizeof(parking_con));
2152
2153         if ((res = load_config()))
2154                 return res;
2155         ast_cli_register(&showparked);
2156         ast_cli_register(&showfeatures);
2157         ast_pthread_create(&parking_thread, NULL, do_parking_thread, NULL);
2158         res = ast_register_application(parkedcall, park_exec, synopsis, descrip);
2159         if (!res)
2160                 res = ast_register_application(parkcall, park_call_exec, synopsis2, descrip2);
2161         if (!res) {
2162                 ast_manager_register("ParkedCalls", 0, manager_parking_status, "List parked calls" );
2163                 ast_manager_register2("Park", EVENT_FLAG_CALL, manager_park,
2164                         "Park a channel", mandescr_park); 
2165         }
2166         return res;
2167 }
2168
2169
2170 static int unload_module(void *mod)
2171 {
2172         STANDARD_HANGUP_LOCALUSERS;
2173
2174         ast_manager_unregister("ParkedCalls");
2175         ast_manager_unregister("Park");
2176         ast_cli_unregister(&showfeatures);
2177         ast_cli_unregister(&showparked);
2178         ast_unregister_application(parkcall);
2179         return ast_unregister_application(parkedcall);
2180 }
2181
2182 static const char *description(void)
2183 {
2184         return "Call Features Resource";
2185 }
2186
2187 static const char *key(void)
2188 {
2189         return ASTERISK_GPL_KEY;
2190 }
2191
2192 STD_MOD(MOD_0 | NO_UNLOAD, reload, NULL, NULL);