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