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