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