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