d789d7657fdb97f64aa09b0f7c6fa1030fd5de1a
[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         int ms, tms, max;
1427         struct parkeduser *pu, *pl, *pt = NULL;
1428         struct timeval tv;
1429         struct ast_frame *f;
1430         char exten[AST_MAX_EXTENSION];
1431         char *peername,*cp;
1432         char returnexten[AST_MAX_EXTENSION];
1433         struct ast_context *con;
1434         int x;
1435         fd_set rfds, efds;
1436         fd_set nrfds, nefds;
1437         FD_ZERO(&rfds);
1438         FD_ZERO(&efds);
1439
1440         for (;;) {
1441                 ms = -1;
1442                 max = -1;
1443                 ast_mutex_lock(&parking_lock);
1444                 pl = NULL;
1445                 pu = parkinglot;
1446                 FD_ZERO(&nrfds);
1447                 FD_ZERO(&nefds);
1448                 while(pu) {
1449                         if (pu->notquiteyet) {
1450                                 /* Pretend this one isn't here yet */
1451                                 pl = pu;
1452                                 pu = pu->next;
1453                                 continue;
1454                         }
1455                         tms = ast_tvdiff_ms(ast_tvnow(), pu->start);
1456                         if (tms > pu->parkingtime) {
1457                                 /* Stop music on hold */
1458                                 ast_moh_stop(pu->chan);
1459                                 ast_indicate(pu->chan, AST_CONTROL_UNHOLD);
1460                                 /* Get chan, exten from derived kludge */
1461                                 if (pu->peername[0]) {
1462                                         peername = ast_strdupa(pu->peername);
1463                                         cp = strrchr(peername, '-');
1464                                         if (cp) 
1465                                                 *cp = 0;
1466                                         con = ast_context_find(parking_con_dial);
1467                                         if (!con) {
1468                                                 con = ast_context_create(NULL, parking_con_dial, registrar);
1469                                                 if (!con) {
1470                                                         ast_log(LOG_ERROR, "Parking dial context '%s' does not exist and unable to create\n", parking_con_dial);
1471                                                 }
1472                                         }
1473                                         if (con) {
1474                                                 snprintf(returnexten, sizeof(returnexten), "%s||t", peername);
1475                                                 ast_add_extension2(con, 1, peername, 1, NULL, NULL, "Dial", strdup(returnexten), FREE, registrar);
1476                                         }
1477                                         ast_copy_string(pu->chan->exten, peername, sizeof(pu->chan->exten));
1478                                         ast_copy_string(pu->chan->context, parking_con_dial, sizeof(pu->chan->context));
1479                                         pu->chan->priority = 1;
1480
1481                                 } else {
1482                                         /* They've been waiting too long, send them back to where they came.  Theoretically they
1483                                            should have their original extensions and such, but we copy to be on the safe side */
1484                                         ast_copy_string(pu->chan->exten, pu->exten, sizeof(pu->chan->exten));
1485                                         ast_copy_string(pu->chan->context, pu->context, sizeof(pu->chan->context));
1486                                         pu->chan->priority = pu->priority;
1487                                 }
1488
1489                                 manager_event(EVENT_FLAG_CALL, "ParkedCallTimeOut",
1490                                         "Exten: %d\r\n"
1491                                         "Channel: %s\r\n"
1492                                         "CallerID: %s\r\n"
1493                                         "CallerIDName: %s\r\n"
1494                                         ,pu->parkingnum, pu->chan->name
1495                                         ,(pu->chan->cid.cid_num ? pu->chan->cid.cid_num : "<unknown>")
1496                                         ,(pu->chan->cid.cid_name ? pu->chan->cid.cid_name : "<unknown>")
1497                                         );
1498
1499                                 if (option_verbose > 1) 
1500                                         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);
1501                                 /* Start up the PBX, or hang them up */
1502                                 if (ast_pbx_start(pu->chan))  {
1503                                         ast_log(LOG_WARNING, "Unable to restart the PBX for user on '%s', hanging them up...\n", pu->chan->name);
1504                                         ast_hangup(pu->chan);
1505                                 }
1506                                 /* And take them out of the parking lot */
1507                                 if (pl) 
1508                                         pl->next = pu->next;
1509                                 else
1510                                         parkinglot = pu->next;
1511                                 pt = pu;
1512                                 pu = pu->next;
1513                                 con = ast_context_find(parking_con);
1514                                 if (con) {
1515                                         snprintf(exten, sizeof(exten), "%d", pt->parkingnum);
1516                                         if (ast_context_remove_extension2(con, exten, 1, NULL))
1517                                                 ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
1518                                 } else
1519                                         ast_log(LOG_WARNING, "Whoa, no parking context?\n");
1520                                 free(pt);
1521                         } else {
1522                                 for (x = 0; x < AST_MAX_FDS; x++) {
1523                                         if ((pu->chan->fds[x] > -1) && (FD_ISSET(pu->chan->fds[x], &rfds) || FD_ISSET(pu->chan->fds[x], &efds))) {
1524                                                 if (FD_ISSET(pu->chan->fds[x], &efds))
1525                                                         ast_set_flag(pu->chan, AST_FLAG_EXCEPTION);
1526                                                 else
1527                                                         ast_clear_flag(pu->chan, AST_FLAG_EXCEPTION);
1528                                                 pu->chan->fdno = x;
1529                                                 /* See if they need servicing */
1530                                                 f = ast_read(pu->chan);
1531                                                 if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass ==  AST_CONTROL_HANGUP))) {
1532                                                         if (f)
1533                                                                 ast_frfree(f);
1534                                                         manager_event(EVENT_FLAG_CALL, "ParkedCallGiveUp",
1535                                                                 "Exten: %d\r\n"
1536                                                                 "Channel: %s\r\n"
1537                                                                 "CallerID: %s\r\n"
1538                                                                 "CallerIDName: %s\r\n"
1539                                                                 ,pu->parkingnum, pu->chan->name
1540                                                                 ,(pu->chan->cid.cid_num ? pu->chan->cid.cid_num : "<unknown>")
1541                                                                 ,(pu->chan->cid.cid_name ? pu->chan->cid.cid_name : "<unknown>")
1542                                                                 );
1543
1544                                                         /* There's a problem, hang them up*/
1545                                                         if (option_verbose > 1) 
1546                                                                 ast_verbose(VERBOSE_PREFIX_2 "%s got tired of being parked\n", pu->chan->name);
1547                                                         ast_hangup(pu->chan);
1548                                                         /* And take them out of the parking lot */
1549                                                         if (pl) 
1550                                                                 pl->next = pu->next;
1551                                                         else
1552                                                                 parkinglot = pu->next;
1553                                                         pt = pu;
1554                                                         pu = pu->next;
1555                                                         con = ast_context_find(parking_con);
1556                                                         if (con) {
1557                                                                 snprintf(exten, sizeof(exten), "%d", pt->parkingnum);
1558                                                                 if (ast_context_remove_extension2(con, exten, 1, NULL))
1559                                                                         ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
1560                                                         } else
1561                                                                 ast_log(LOG_WARNING, "Whoa, no parking context?\n");
1562                                                         free(pt);
1563                                                         break;
1564                                                 } else {
1565                                                         /* XXX Maybe we could do something with packets, like dial "0" for operator or something XXX */
1566                                                         ast_frfree(f);
1567                                                         if (pu->moh_trys < 3 && !pu->chan->generatordata) {
1568                                                                 ast_log(LOG_DEBUG, "MOH on parked call stopped by outside source.  Restarting.\n");
1569                                                                 ast_moh_start(pu->chan, NULL);
1570                                                                 pu->moh_trys++;
1571                                                         }
1572                                                         goto std;       /* XXX Ick: jumping into an else statement??? XXX */
1573                                                 }
1574                                         }
1575                                 } /* end for */
1576                                 if (x >= AST_MAX_FDS) {
1577 std:                                    for (x=0; x<AST_MAX_FDS; x++) {
1578                                                 /* Keep this one for next one */
1579                                                 if (pu->chan->fds[x] > -1) {
1580                                                         FD_SET(pu->chan->fds[x], &nrfds);
1581                                                         FD_SET(pu->chan->fds[x], &nefds);
1582                                                         if (pu->chan->fds[x] > max)
1583                                                                 max = pu->chan->fds[x];
1584                                                 }
1585                                         }
1586                                         /* Keep track of our longest wait */
1587                                         if ((tms < ms) || (ms < 0))
1588                                                 ms = tms;
1589                                         pl = pu;
1590                                         pu = pu->next;
1591                                 }
1592                         }
1593                 } /* end while */
1594                 ast_mutex_unlock(&parking_lock);
1595                 rfds = nrfds;
1596                 efds = nefds;
1597                 tv = ast_samp2tv(ms, 1000);
1598                 /* Wait for something to happen */
1599                 ast_select(max + 1, &rfds, NULL, &efds, (ms > -1) ? &tv : NULL);
1600                 pthread_testcancel();
1601         }
1602         return NULL;    /* Never reached */
1603 }
1604
1605 static int park_call_exec(struct ast_channel *chan, void *data)
1606 {
1607         /* Data is unused at the moment but could contain a parking
1608            lot context eventually */
1609         int res=0;
1610         struct localuser *u;
1611         LOCAL_USER_ADD(u);
1612         /* Setup the exten/priority to be s/1 since we don't know
1613            where this call should return */
1614         strcpy(chan->exten, "s");
1615         chan->priority = 1;
1616         if (chan->_state != AST_STATE_UP)
1617                 res = ast_answer(chan);
1618         if (!res)
1619                 res = ast_safe_sleep(chan, 1000);
1620         if (!res)
1621                 res = ast_park_call(chan, chan, 0, NULL);
1622         LOCAL_USER_REMOVE(u);
1623         if (!res)
1624                 res = AST_PBX_KEEPALIVE;
1625         return res;
1626 }
1627
1628 static int park_exec(struct ast_channel *chan, void *data)
1629 {
1630         int res=0;
1631         struct localuser *u;
1632         struct ast_channel *peer=NULL;
1633         struct parkeduser *pu, *pl=NULL;
1634         char exten[AST_MAX_EXTENSION];
1635         struct ast_context *con;
1636         int park;
1637         int dres;
1638         struct ast_bridge_config config;
1639
1640         if (!data) {
1641                 ast_log(LOG_WARNING, "Park requires an argument (extension number)\n");
1642                 return -1;
1643         }
1644         LOCAL_USER_ADD(u);
1645         park = atoi((char *)data);
1646         ast_mutex_lock(&parking_lock);
1647         pu = parkinglot;
1648         while(pu) {
1649                 if (pu->parkingnum == park) {
1650                         if (pl)
1651                                 pl->next = pu->next;
1652                         else
1653                                 parkinglot = pu->next;
1654                         break;
1655                 }
1656                 pl = pu;
1657                 pu = pu->next;
1658         }
1659         ast_mutex_unlock(&parking_lock);
1660         if (pu) {
1661                 peer = pu->chan;
1662                 con = ast_context_find(parking_con);
1663                 if (con) {
1664                         snprintf(exten, sizeof(exten), "%d", pu->parkingnum);
1665                         if (ast_context_remove_extension2(con, exten, 1, NULL))
1666                                 ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
1667                 } else
1668                         ast_log(LOG_WARNING, "Whoa, no parking context?\n");
1669
1670                 manager_event(EVENT_FLAG_CALL, "UnParkedCall",
1671                         "Exten: %d\r\n"
1672                         "Channel: %s\r\n"
1673                         "From: %s\r\n"
1674                         "CallerID: %s\r\n"
1675                         "CallerIDName: %s\r\n"
1676                         ,pu->parkingnum, pu->chan->name, chan->name
1677                         ,(pu->chan->cid.cid_num ? pu->chan->cid.cid_num : "<unknown>")
1678                         ,(pu->chan->cid.cid_name ? pu->chan->cid.cid_name : "<unknown>")
1679                         );
1680
1681                 free(pu);
1682         }
1683         /* JK02: it helps to answer the channel if not already up */
1684         if (chan->_state != AST_STATE_UP) {
1685                 ast_answer(chan);
1686         }
1687
1688         if (peer) {
1689                 /* Play a courtesy to the source(s) configured to prefix the bridge connecting */
1690                 
1691                 if (!ast_strlen_zero(courtesytone)) {
1692                         if (parkedplay == 0) {
1693                                 if (!ast_streamfile(chan, courtesytone, chan->language)) {
1694                                         if (ast_waitstream(chan, "") < 0) {
1695                                                 ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
1696                                                 ast_hangup(peer);
1697                                                 return -1;
1698                                         }
1699                                 }
1700                                 ast_moh_stop(peer);
1701                                 ast_indicate(peer, AST_CONTROL_UNHOLD);
1702                         } else {
1703                                 ast_moh_stop(peer);
1704                                 ast_indicate(peer, AST_CONTROL_UNHOLD);
1705                                 if (parkedplay == 2) {
1706                                         if (!ast_streamfile(chan, courtesytone, chan->language) && !ast_streamfile(peer, courtesytone, chan->language)) {
1707                                                 res = ast_waitstream(chan, "");
1708                                                 if (res >= 0)
1709                                                         res = ast_waitstream(peer, "");
1710                                                 if (res < 0) {
1711                                                         ast_log(LOG_WARNING, "Failed to play courtesy tones!\n");
1712                                                         ast_hangup(peer);
1713                                                         return -1;
1714                                                 }
1715                                         }
1716                                 } else if (parkedplay == 1) {
1717                                         if (!ast_streamfile(peer, courtesytone, chan->language)) {
1718                                                 if (ast_waitstream(peer, "") < 0) {
1719                                                         ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
1720                                                         ast_hangup(peer);
1721                                                         return -1;
1722                                                 }
1723                                         }
1724                                 }
1725                         }
1726                 }
1727  
1728                 res = ast_channel_make_compatible(chan, peer);
1729                 if (res < 0) {
1730                         ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for bridge\n", chan->name, peer->name);
1731                         ast_hangup(peer);
1732                         return -1;
1733                 }
1734                 /* This runs sorta backwards, since we give the incoming channel control, as if it
1735                    were the person called. */
1736                 if (option_verbose > 2) 
1737                         ast_verbose(VERBOSE_PREFIX_3 "Channel %s connected to parked call %d\n", chan->name, park);
1738
1739                 memset(&config, 0, sizeof(struct ast_bridge_config));
1740                 ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
1741                 ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
1742                 config.timelimit = 0;
1743                 config.play_warning = 0;
1744                 config.warning_freq = 0;
1745                 config.warning_sound=NULL;
1746                 res = ast_bridge_call(chan, peer, &config);
1747
1748                 /* Simulate the PBX hanging up */
1749                 if (res != AST_PBX_NO_HANGUP_PEER)
1750                         ast_hangup(peer);
1751                 return res;
1752         } else {
1753                 /* XXX Play a message XXX */
1754                 dres = ast_streamfile(chan, "pbx-invalidpark", chan->language);
1755                 if (!dres)
1756                         dres = ast_waitstream(chan, "");
1757                 else {
1758                         ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", "pbx-invalidpark", chan->name);
1759                         dres = 0;
1760                 }
1761                 if (option_verbose > 2) 
1762                         ast_verbose(VERBOSE_PREFIX_3 "Channel %s tried to talk to nonexistent parked call %d\n", chan->name, park);
1763                 res = -1;
1764         }
1765         LOCAL_USER_REMOVE(u);
1766         return res;
1767 }
1768
1769 static int handle_showfeatures(int fd, int argc, char *argv[])
1770 {
1771         int i;
1772         int fcount;
1773         struct ast_call_feature *feature;
1774         char format[] = "%-25s %-7s %-7s\n";
1775
1776         ast_cli(fd, format, "Builtin Feature", "Default", "Current");
1777         ast_cli(fd, format, "---------------", "-------", "-------");
1778
1779         ast_cli(fd, format, "Pickup", "*8", ast_pickup_ext());          /* default hardcoded above, so we'll hardcode it here */
1780
1781         fcount = sizeof(builtin_features) / sizeof(builtin_features[0]);
1782
1783         for (i = 0; i < fcount; i++)
1784         {
1785                 ast_cli(fd, format, builtin_features[i].fname, builtin_features[i].default_exten, builtin_features[i].exten);
1786         }
1787         ast_cli(fd, "\n");
1788         ast_cli(fd, format, "Dynamic Feature", "Default", "Current");
1789         ast_cli(fd, format, "---------------", "-------", "-------");
1790         if (AST_LIST_EMPTY(&feature_list)) {
1791                 ast_cli(fd, "(none)\n");
1792         }
1793         else {
1794                 AST_LIST_LOCK(&feature_list);
1795                 AST_LIST_TRAVERSE(&feature_list, feature, feature_entry) {
1796                         ast_cli(fd, format, feature->sname, "no def", feature->exten);  
1797                 }
1798                 AST_LIST_UNLOCK(&feature_list);
1799         }
1800         ast_cli(fd, "\nCall parking\n");
1801         ast_cli(fd, "------------\n");
1802         ast_cli(fd,"%-20s:      %s\n", "Parking extension", parking_ext);
1803         ast_cli(fd,"%-20s:      %s\n", "Parking context", parking_con);
1804         ast_cli(fd,"%-20s:      %d-%d\n", "Parked call extensions", parking_start, parking_stop);
1805         ast_cli(fd,"\n");
1806         
1807         return RESULT_SUCCESS;
1808 }
1809
1810 static char showfeatures_help[] =
1811 "Usage: show features\n"
1812 "       Lists currently configured features.\n";
1813
1814 static struct ast_cli_entry showfeatures =
1815 { { "show", "features", NULL }, handle_showfeatures, "Lists configured features", showfeatures_help };
1816
1817 static int handle_parkedcalls(int fd, int argc, char *argv[])
1818 {
1819         struct parkeduser *cur;
1820         int numparked = 0;
1821
1822         ast_cli(fd, "%4s %25s (%-15s %-12s %-4s) %-6s \n", "Num", "Channel"
1823                 , "Context", "Extension", "Pri", "Timeout");
1824
1825         ast_mutex_lock(&parking_lock);
1826
1827         cur = parkinglot;
1828         while(cur) {
1829                 ast_cli(fd, "%4d %25s (%-15s %-12s %-4d) %6lds\n"
1830                         ,cur->parkingnum, cur->chan->name, cur->context, cur->exten
1831                         ,cur->priority, cur->start.tv_sec + (cur->parkingtime/1000) - time(NULL));
1832
1833                 cur = cur->next;
1834                 numparked++;
1835         }
1836         ast_cli(fd, "%d parked call%s.\n", numparked, (numparked != 1) ? "s" : "");
1837
1838         ast_mutex_unlock(&parking_lock);
1839
1840         return RESULT_SUCCESS;
1841 }
1842
1843 static char showparked_help[] =
1844 "Usage: show parkedcalls\n"
1845 "       Lists currently parked calls.\n";
1846
1847 static struct ast_cli_entry showparked =
1848 { { "show", "parkedcalls", NULL }, handle_parkedcalls, "Lists parked calls", showparked_help };
1849
1850 /*! \brief Dump lot status */
1851 static int manager_parking_status( struct mansession *s, struct message *m )
1852 {
1853         struct parkeduser *cur;
1854         char *id = astman_get_header(m,"ActionID");
1855         char idText[256] = "";
1856
1857         if (!ast_strlen_zero(id))
1858                 snprintf(idText,256,"ActionID: %s\r\n",id);
1859
1860         astman_send_ack(s, m, "Parked calls will follow");
1861
1862         ast_mutex_lock(&parking_lock);
1863
1864         cur=parkinglot;
1865         while(cur) {
1866                         astman_append(s, "Event: ParkedCall\r\n"
1867                         "Exten: %d\r\n"
1868                         "Channel: %s\r\n"
1869                         "From: %s\r\n"
1870                         "Timeout: %ld\r\n"
1871                         "CallerID: %s\r\n"
1872                         "CallerIDName: %s\r\n"
1873                         "%s"
1874                         "\r\n"
1875                         ,cur->parkingnum, cur->chan->name, cur->peername
1876                         ,(long)cur->start.tv_sec + (long)(cur->parkingtime/1000) - (long)time(NULL)
1877                         ,(cur->chan->cid.cid_num ? cur->chan->cid.cid_num : "")
1878                         ,(cur->chan->cid.cid_name ? cur->chan->cid.cid_name : "")
1879                         ,idText);
1880
1881             cur = cur->next;
1882         }
1883
1884         astman_append(s,
1885         "Event: ParkedCallsComplete\r\n"
1886         "%s"
1887         "\r\n",idText);
1888
1889         ast_mutex_unlock(&parking_lock);
1890
1891         return RESULT_SUCCESS;
1892 }
1893
1894 static char mandescr_park[] =
1895 "Description: Park a channel.\n"
1896 "Variables: (Names marked with * are required)\n"
1897 "       *Channel: Channel name to park\n"
1898 "       *Channel2: Channel to announce park info to (and return to if timeout)\n"
1899 "       Timeout: Number of milliseconds to wait before callback.\n";  
1900
1901 static int manager_park(struct mansession *s, struct message *m)
1902 {
1903         char *channel = astman_get_header(m, "Channel");
1904         char *channel2 = astman_get_header(m, "Channel2");
1905         char *timeout = astman_get_header(m, "Timeout");
1906         char buf[BUFSIZ];
1907         int to = 0;
1908         int res = 0;
1909         int parkExt = 0;
1910         struct ast_channel *ch1, *ch2;
1911
1912         if (ast_strlen_zero(channel)) {
1913                 astman_send_error(s, m, "Channel not specified");
1914                 return 0;
1915         }
1916
1917         if (ast_strlen_zero(channel2)) {
1918                 astman_send_error(s, m, "Channel2 not specified");
1919                 return 0;
1920         }
1921
1922         ch1 = ast_get_channel_by_name_locked(channel);
1923         if (!ch1) {
1924                 snprintf(buf, sizeof(buf), "Channel does not exist: %s", channel);
1925                 astman_send_error(s, m, buf);
1926                 return 0;
1927         }
1928
1929         ch2 = ast_get_channel_by_name_locked(channel2);
1930         if (!ch2) {
1931                 snprintf(buf, sizeof(buf), "Channel does not exist: %s", channel2);
1932                 astman_send_error(s, m, buf);
1933                 ast_mutex_unlock(&ch1->lock);
1934                 return 0;
1935         }
1936
1937         if (!ast_strlen_zero(timeout)) {
1938                 sscanf(timeout, "%d", &to);
1939         }
1940
1941         res = ast_masq_park_call(ch1, ch2, to, &parkExt);
1942         if (!res) {
1943                 ast_softhangup(ch2, AST_SOFTHANGUP_EXPLICIT);
1944                 astman_send_ack(s, m, "Park successful");
1945         } else {
1946                 astman_send_error(s, m, "Park failure");
1947         }
1948
1949         ast_mutex_unlock(&ch1->lock);
1950         ast_mutex_unlock(&ch2->lock);
1951
1952         return 0;
1953 }
1954
1955
1956 int ast_pickup_call(struct ast_channel *chan)
1957 {
1958         struct ast_channel *cur = NULL;
1959         int res = -1;
1960
1961         while ( (cur = ast_channel_walk_locked(cur)) != NULL) {
1962                 if (!cur->pbx && 
1963                         (cur != chan) &&
1964                         (chan->pickupgroup & cur->callgroup) &&
1965                         ((cur->_state == AST_STATE_RINGING) ||
1966                          (cur->_state == AST_STATE_RING))) {
1967                                 break;
1968                 }
1969                 ast_mutex_unlock(&cur->lock);
1970         }
1971         if (cur) {
1972                 if (option_debug)
1973                         ast_log(LOG_DEBUG, "Call pickup on chan '%s' by '%s'\n",cur->name, chan->name);
1974                 res = ast_answer(chan);
1975                 if (res)
1976                         ast_log(LOG_WARNING, "Unable to answer '%s'\n", chan->name);
1977                 res = ast_queue_control(chan, AST_CONTROL_ANSWER);
1978                 if (res)
1979                         ast_log(LOG_WARNING, "Unable to queue answer on '%s'\n", chan->name);
1980                 res = ast_channel_masquerade(cur, chan);
1981                 if (res)
1982                         ast_log(LOG_WARNING, "Unable to masquerade '%s' into '%s'\n", chan->name, cur->name);           /* Done */
1983                 ast_mutex_unlock(&cur->lock);
1984         } else  {
1985                 if (option_debug)
1986                         ast_log(LOG_DEBUG, "No call pickup possible...\n");
1987         }
1988         return res;
1989 }
1990
1991 static int load_config(void) 
1992 {
1993         int start = 0, end = 0;
1994         struct ast_context *con = NULL;
1995         struct ast_config *cfg = NULL;
1996         struct ast_variable *var = NULL;
1997         char old_parking_ext[AST_MAX_EXTENSION];
1998         char old_parking_con[AST_MAX_EXTENSION] = "";
1999
2000         if (!ast_strlen_zero(parking_con)) {
2001                 strcpy(old_parking_ext, parking_ext);
2002                 strcpy(old_parking_con, parking_con);
2003         } 
2004
2005         /* Reset to defaults */
2006         strcpy(parking_con, "parkedcalls");
2007         strcpy(parking_con_dial, "park-dial");
2008         strcpy(parking_ext, "700");
2009         strcpy(pickup_ext, "*8");
2010         courtesytone[0] = '\0';
2011         strcpy(xfersound, "beep");
2012         strcpy(xferfailsound, "pbx-invalid");
2013         parking_start = 701;
2014         parking_stop = 750;
2015         parkfindnext = 0;
2016         adsipark = 0;
2017
2018         transferdigittimeout = DEFAULT_TRANSFER_DIGIT_TIMEOUT;
2019         featuredigittimeout = DEFAULT_FEATURE_DIGIT_TIMEOUT;
2020
2021         cfg = ast_config_load("features.conf");
2022         if (cfg) {
2023                 for (var = ast_variable_browse(cfg, "general"); var; var = var->next) {
2024                         if (!strcasecmp(var->name, "parkext")) {
2025                                 ast_copy_string(parking_ext, var->value, sizeof(parking_ext));
2026                         } else if (!strcasecmp(var->name, "context")) {
2027                                 ast_copy_string(parking_con, var->value, sizeof(parking_con));
2028                         } else if (!strcasecmp(var->name, "parkingtime")) {
2029                                 if ((sscanf(var->value, "%d", &parkingtime) != 1) || (parkingtime < 1)) {
2030                                         ast_log(LOG_WARNING, "%s is not a valid parkingtime\n", var->value);
2031                                         parkingtime = DEFAULT_PARK_TIME;
2032                                 } else
2033                                         parkingtime = parkingtime * 1000;
2034                         } else if (!strcasecmp(var->name, "parkpos")) {
2035                                 if (sscanf(var->value, "%d-%d", &start, &end) != 2) {
2036                                         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);
2037                                 } else {
2038                                         parking_start = start;
2039                                         parking_stop = end;
2040                                 }
2041                         } else if (!strcasecmp(var->name, "findslot")) {
2042                                 parkfindnext = (!strcasecmp(var->value, "next"));
2043                         } else if (!strcasecmp(var->name, "adsipark")) {
2044                                 adsipark = ast_true(var->value);
2045                         } else if (!strcasecmp(var->name, "transferdigittimeout")) {
2046                                 if ((sscanf(var->value, "%d", &transferdigittimeout) != 1) || (transferdigittimeout < 1)) {
2047                                         ast_log(LOG_WARNING, "%s is not a valid transferdigittimeout\n", var->value);
2048                                         transferdigittimeout = DEFAULT_TRANSFER_DIGIT_TIMEOUT;
2049                                 } else
2050                                         transferdigittimeout = transferdigittimeout * 1000;
2051                         } else if (!strcasecmp(var->name, "featuredigittimeout")) {
2052                                 if ((sscanf(var->value, "%d", &featuredigittimeout) != 1) || (featuredigittimeout < 1)) {
2053                                         ast_log(LOG_WARNING, "%s is not a valid featuredigittimeout\n", var->value);
2054                                         featuredigittimeout = DEFAULT_FEATURE_DIGIT_TIMEOUT;
2055                                 }
2056                         } else if (!strcasecmp(var->name, "courtesytone")) {
2057                                 ast_copy_string(courtesytone, var->value, sizeof(courtesytone));
2058                         }  else if (!strcasecmp(var->name, "parkedplay")) {
2059                                 if (!strcasecmp(var->value, "both"))
2060                                         parkedplay = 2;
2061                                 else if (!strcasecmp(var->value, "parked"))
2062                                         parkedplay = 1;
2063                                 else
2064                                         parkedplay = 0;
2065                         } else if (!strcasecmp(var->name, "xfersound")) {
2066                                 ast_copy_string(xfersound, var->value, sizeof(xfersound));
2067                         } else if (!strcasecmp(var->name, "xferfailsound")) {
2068                                 ast_copy_string(xferfailsound, var->value, sizeof(xferfailsound));
2069                         } else if (!strcasecmp(var->name, "pickupexten")) {
2070                                 ast_copy_string(pickup_ext, var->value, sizeof(pickup_ext));
2071                         }
2072                 }
2073
2074                 unmap_features();
2075                 for (var = ast_variable_browse(cfg, "featuremap"); var; var = var->next) {
2076                         if (remap_feature(var->name, var->value))
2077                                 ast_log(LOG_NOTICE, "Unknown feature '%s'\n", var->name);
2078                 }
2079
2080                 /* Map a key combination to an application*/
2081                 ast_unregister_features();
2082                 for (var = ast_variable_browse(cfg, "applicationmap"); var; var = var->next) {
2083                         char *tmp_val = ast_strdup(var->value);
2084                         char *exten, *party=NULL, *app=NULL, *app_args=NULL; 
2085
2086                         if (!tmp_val) { 
2087                                 /* XXX No memory. We should probably break, but at least we do not
2088                                  * insist on this entry or we could be stuck in an
2089                                  * infinite loop.
2090                                  */
2091                                 continue;
2092                         }
2093
2094                         /* strsep() sets the argument to NULL if match not found, and it
2095                          * is safe to use it with a NULL argument, so we don't check
2096                          * between calls.
2097                          */
2098                         exten = strsep(&tmp_val,",");
2099                         party = strsep(&tmp_val,",");
2100                         app = strsep(&tmp_val,",");
2101                         app_args = strsep(&tmp_val,",");
2102
2103                         /* XXX var_name or app_args ? */
2104                         if (ast_strlen_zero(app) || ast_strlen_zero(exten) || ast_strlen_zero(party) || ast_strlen_zero(var->name)) {
2105                                 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);
2106                                 free(tmp_val);
2107                                 continue;
2108                         }
2109
2110                         {
2111                                 struct ast_call_feature *feature;
2112                                 int mallocd = 0;
2113                                 
2114                                 if (!(feature = find_feature(var->name))) {
2115                                         mallocd = 1;
2116                                         
2117                                         if (!(feature = ast_calloc(1, sizeof(*feature)))) {
2118                                                 free(tmp_val);
2119                                                 continue;                                       
2120                                         }
2121                                 }
2122
2123                                 ast_copy_string(feature->sname,var->name,FEATURE_SNAME_LEN);
2124                                 ast_copy_string(feature->app,app,FEATURE_APP_LEN);
2125                                 ast_copy_string(feature->exten, exten,FEATURE_EXTEN_LEN);
2126                                 free(tmp_val);
2127                                 
2128                                 if (app_args) 
2129                                         ast_copy_string(feature->app_args,app_args,FEATURE_APP_ARGS_LEN);
2130                                 
2131                                 ast_copy_string(feature->exten, exten,sizeof(feature->exten));
2132                                 feature->operation=feature_exec_app;
2133                                 ast_set_flag(feature,AST_FEATURE_FLAG_NEEDSDTMF);
2134                                 
2135                                 if (!strcasecmp(party,"caller"))
2136                                         ast_set_flag(feature,AST_FEATURE_FLAG_CALLER);
2137                                 else if (!strcasecmp(party, "callee"))
2138                                         ast_set_flag(feature,AST_FEATURE_FLAG_CALLEE);
2139                                 else {
2140                                         ast_log(LOG_NOTICE, "Invalid party specification for feature '%s', must be caller, or callee\n", var->name);
2141                                         continue;
2142                                 }
2143
2144                                 ast_register_feature(feature);
2145                                 
2146                                 if (option_verbose >=1)
2147                                         ast_verbose(VERBOSE_PREFIX_2 "Mapping Feature '%s' to app '%s' with code '%s'\n", var->name, app, exten);  
2148                         }
2149                 }        
2150         }
2151         ast_config_destroy(cfg);
2152
2153         /* Remove the old parking extension */
2154         if (!ast_strlen_zero(old_parking_con) && (con = ast_context_find(old_parking_con)))     {
2155                 ast_context_remove_extension2(con, old_parking_ext, 1, registrar);
2156                 ast_log(LOG_DEBUG, "Removed old parking extension %s@%s\n", old_parking_ext, old_parking_con);
2157         }
2158         
2159         if (!(con = ast_context_find(parking_con)) && !(con = ast_context_create(NULL, parking_con, registrar))) {
2160                 ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", parking_con);
2161                 return -1;
2162         }
2163         return ast_add_extension2(con, 1, ast_parking_ext(), 1, NULL, NULL, parkcall, strdup(""), FREE, registrar);
2164 }
2165
2166 static int reload(void *mod)
2167 {
2168         return load_config();
2169 }
2170
2171 static int load_module(void *mod)
2172 {
2173         int res;
2174         
2175         __mod_desc = mod;
2176         AST_LIST_HEAD_INIT(&feature_list);
2177         memset(parking_ext, 0, sizeof(parking_ext));
2178         memset(parking_con, 0, sizeof(parking_con));
2179
2180         if ((res = load_config()))
2181                 return res;
2182         ast_cli_register(&showparked);
2183         ast_cli_register(&showfeatures);
2184         ast_pthread_create(&parking_thread, NULL, do_parking_thread, NULL);
2185         res = ast_register_application(parkedcall, park_exec, synopsis, descrip);
2186         if (!res)
2187                 res = ast_register_application(parkcall, park_call_exec, synopsis2, descrip2);
2188         if (!res) {
2189                 ast_manager_register("ParkedCalls", 0, manager_parking_status, "List parked calls" );
2190                 ast_manager_register2("Park", EVENT_FLAG_CALL, manager_park,
2191                         "Park a channel", mandescr_park); 
2192         }
2193         return res;
2194 }
2195
2196
2197 static int unload_module(void *mod)
2198 {
2199         STANDARD_HANGUP_LOCALUSERS;
2200
2201         ast_manager_unregister("ParkedCalls");
2202         ast_manager_unregister("Park");
2203         ast_cli_unregister(&showfeatures);
2204         ast_cli_unregister(&showparked);
2205         ast_unregister_application(parkcall);
2206         return ast_unregister_application(parkedcall);
2207 }
2208
2209 static const char *description(void)
2210 {
2211         return "Call Features Resource";
2212 }
2213
2214 static const char *key(void)
2215 {
2216         return ASTERISK_GPL_KEY;
2217 }
2218
2219 STD_MOD(MOD_0 | NO_UNLOAD, reload, NULL, NULL);