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