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