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