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