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