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