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