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