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