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