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