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