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