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