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