merge new_loader_completion branch, including (at least):
[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 = adsi_load_session(chan, NULL, 0, 1);
269         if (res == -1)
270                 return res;
271         return 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                 "CallerID: %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 && adsi_available(peer)) {
411                 adsi_announce_park(peer, pu->parkingexten);     /* Only supports parking numbers */
412                 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;
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                 work = ast_test_flag(feature, AST_FEATURE_FLAG_ONSELF) ? chan : peer;
962         } else {
963                 if (!ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLEE))
964                         return FEATURE_RETURN_PASSDIGITS;
965                 work = ast_test_flag(feature, AST_FEATURE_FLAG_ONSELF) ? peer : chan;
966         }
967
968         if (!(app = pbx_findapp(feature->app))) {
969                 ast_log(LOG_WARNING, "Could not find application (%s)\n", feature->app);
970                 return -2;
971         }
972
973         /* XXX Should we service the other channel while this runs? */
974         res = pbx_exec(work, app, feature->app_args);
975
976         if (res == AST_PBX_KEEPALIVE)
977                 return FEATURE_RETURN_PBX_KEEPALIVE;
978         else if (res == AST_PBX_NO_HANGUP_PEER)
979                 return FEATURE_RETURN_NO_HANGUP_PEER;
980         else if (res)
981                 return FEATURE_RETURN_SUCCESSBREAK;
982         
983         return FEATURE_RETURN_SUCCESS;  /*! \todo XXX should probably return res */
984 }
985
986 static void unmap_features(void)
987 {
988         int x;
989         for (x = 0; x < FEATURES_COUNT; x++)
990                 strcpy(builtin_features[x].exten, builtin_features[x].default_exten);
991 }
992
993 static int remap_feature(const char *name, const char *value)
994 {
995         int x;
996         int res = -1;
997         for (x = 0; x < FEATURES_COUNT; x++) {
998                 if (!strcasecmp(name, builtin_features[x].sname)) {
999                         ast_copy_string(builtin_features[x].exten, value, sizeof(builtin_features[x].exten));
1000                         if (option_verbose > 1)
1001                                 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);
1002                         res = 0;
1003                 } else if (!strcmp(value, builtin_features[x].exten)) 
1004                         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);
1005         }
1006         return res;
1007 }
1008
1009 static int ast_feature_interpret(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense)
1010 {
1011         int x;
1012         struct ast_flags features;
1013         int res = FEATURE_RETURN_PASSDIGITS;
1014         struct ast_call_feature *feature;
1015         const char *dynamic_features=pbx_builtin_getvar_helper(chan,"DYNAMIC_FEATURES");
1016
1017         if (sense == FEATURE_SENSE_CHAN)
1018                 ast_copy_flags(&features, &(config->features_caller), AST_FLAGS_ALL);   
1019         else
1020                 ast_copy_flags(&features, &(config->features_callee), AST_FLAGS_ALL);   
1021         if (option_debug > 2)
1022                 ast_log(LOG_DEBUG, "Feature interpret: chan=%s, peer=%s, sense=%d, features=%d\n", chan->name, peer->name, sense, features.flags);
1023
1024         for (x=0; x < FEATURES_COUNT; x++) {
1025                 if ((ast_test_flag(&features, builtin_features[x].feature_mask)) &&
1026                     !ast_strlen_zero(builtin_features[x].exten)) {
1027                         /* Feature is up for consideration */
1028                         if (!strcmp(builtin_features[x].exten, code)) {
1029                                 res = builtin_features[x].operation(chan, peer, config, code, sense);
1030                                 break;
1031                         } else if (!strncmp(builtin_features[x].exten, code, strlen(code))) {
1032                                 if (res == FEATURE_RETURN_PASSDIGITS)
1033                                         res = FEATURE_RETURN_STOREDIGITS;
1034                         }
1035                 }
1036         }
1037
1038
1039         if (!ast_strlen_zero(dynamic_features)) {
1040                 char *tmp = ast_strdupa(dynamic_features);
1041                 char *tok;
1042
1043                 while ((tok = strsep(&tmp, "#")) != NULL) {
1044                         feature = find_feature(tok);
1045                         
1046                         if (feature) {
1047                                 /* Feature is up for consideration */
1048                                 if (!strcmp(feature->exten, code)) {
1049                                         if (option_verbose > 2)
1050                                                 ast_verbose(VERBOSE_PREFIX_3 " Feature Found: %s exten: %s\n",feature->sname, tok);
1051                                         res = feature->operation(chan, peer, config, code, sense);
1052                                         break;
1053                                 } else if (!strncmp(feature->exten, code, strlen(code))) {
1054                                         res = FEATURE_RETURN_STOREDIGITS;
1055                                 }
1056                         }
1057                 }
1058         }
1059         
1060         return res;
1061 }
1062
1063 static void set_config_flags(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config)
1064 {
1065         int x;
1066         
1067         ast_clear_flag(config, AST_FLAGS_ALL);  
1068         for (x = 0; x < FEATURES_COUNT; x++) {
1069                 if (ast_test_flag(builtin_features + x, AST_FEATURE_FLAG_NEEDSDTMF)) {
1070                         if (ast_test_flag(&(config->features_caller), builtin_features[x].feature_mask))
1071                                 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
1072
1073                         if (ast_test_flag(&(config->features_callee), builtin_features[x].feature_mask))
1074                                 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
1075                 }
1076         }
1077         
1078         if (chan && peer && !(ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_0) && ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_1))) {
1079                 const char *dynamic_features = pbx_builtin_getvar_helper(chan, "DYNAMIC_FEATURES");
1080
1081                 if (dynamic_features) {
1082                         char *tmp = ast_strdupa(dynamic_features);
1083                         char *tok;
1084                         struct ast_call_feature *feature;
1085
1086                         /* while we have a feature */
1087                         while ((tok = strsep(&tmp, "#"))) {
1088                                 if ((feature = find_feature(tok)) && ast_test_flag(feature, AST_FEATURE_FLAG_NEEDSDTMF)) {
1089                                         if (ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLER))
1090                                                 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
1091                                         if (ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLEE))
1092                                                 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
1093                                 }
1094                         }
1095                 }
1096         }
1097 }
1098
1099 /*! \todo XXX Check - this is very similar to the code in channel.c */
1100 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)
1101 {
1102         int state = 0;
1103         int cause = 0;
1104         int to;
1105         struct ast_channel *chan;
1106         struct ast_channel *monitor_chans[2];
1107         struct ast_channel *active_channel;
1108         int res = 0, ready = 0;
1109         
1110         if ((chan = ast_request(type, format, data, &cause))) {
1111                 ast_set_callerid(chan, cid_num, cid_name, cid_num);
1112                 ast_channel_inherit_variables(caller, chan);    
1113                 pbx_builtin_setvar_helper(chan, "TRANSFERERNAME", caller->name);
1114                 if (!ast_call(chan, data, timeout)) {
1115                         struct timeval started;
1116                         int x, len = 0;
1117                         char *disconnect_code = NULL, *dialed_code = NULL;
1118
1119                         ast_indicate(caller, AST_CONTROL_RINGING);
1120                         /* support dialing of the featuremap disconnect code while performing an attended tranfer */
1121                         for (x=0; x < FEATURES_COUNT; x++) {
1122                                 if (strcasecmp(builtin_features[x].sname, "disconnect"))
1123                                         continue;
1124
1125                                 disconnect_code = builtin_features[x].exten;
1126                                 len = strlen(disconnect_code) + 1;
1127                                 dialed_code = alloca(len);
1128                                 memset(dialed_code, 0, len);
1129                                 break;
1130                         }
1131                         x = 0;
1132                         started = ast_tvnow();
1133                         to = timeout;
1134                         while (!ast_check_hangup(caller) && timeout && (chan->_state != AST_STATE_UP)) {
1135                                 struct ast_frame *f = NULL;
1136
1137                                 monitor_chans[0] = caller;
1138                                 monitor_chans[1] = chan;
1139                                 active_channel = ast_waitfor_n(monitor_chans, 2, &to);
1140
1141                                 /* see if the timeout has been violated */
1142                                 if(ast_tvdiff_ms(ast_tvnow(), started) > timeout) {
1143                                         state = AST_CONTROL_UNHOLD;
1144                                         ast_log(LOG_NOTICE, "We exceeded our AT-timeout\n");
1145                                         break; /*doh! timeout*/
1146                                 }
1147
1148                                 if (!active_channel)
1149                                         continue;
1150
1151                                 if (chan && (chan == active_channel)){
1152                                         f = ast_read(chan);
1153                                         if (f == NULL) { /*doh! where'd he go?*/
1154                                                 state = AST_CONTROL_HANGUP;
1155                                                 res = 0;
1156                                                 break;
1157                                         }
1158                                         
1159                                         if (f->frametype == AST_FRAME_CONTROL || f->frametype == AST_FRAME_DTMF || f->frametype == AST_FRAME_TEXT) {
1160                                                 if (f->subclass == AST_CONTROL_RINGING) {
1161                                                         state = f->subclass;
1162                                                         if (option_verbose > 2)
1163                                                                 ast_verbose( VERBOSE_PREFIX_3 "%s is ringing\n", chan->name);
1164                                                         ast_indicate(caller, AST_CONTROL_RINGING);
1165                                                 } else if ((f->subclass == AST_CONTROL_BUSY) || (f->subclass == AST_CONTROL_CONGESTION)) {
1166                                                         state = f->subclass;
1167                                                         if (option_verbose > 2)
1168                                                                 ast_verbose( VERBOSE_PREFIX_3 "%s is busy\n", chan->name);
1169                                                         ast_indicate(caller, AST_CONTROL_BUSY);
1170                                                         ast_frfree(f);
1171                                                         f = NULL;
1172                                                         break;
1173                                                 } else if (f->subclass == AST_CONTROL_ANSWER) {
1174                                                         /* This is what we are hoping for */
1175                                                         state = f->subclass;
1176                                                         ast_frfree(f);
1177                                                         f = NULL;
1178                                                         ready=1;
1179                                                         break;
1180                                                 } else {
1181                                                         ast_log(LOG_NOTICE, "Don't know what to do about control frame: %d\n", f->subclass);
1182                                                 }
1183                                                 /* else who cares */
1184                                         }
1185
1186                                 } else if (caller && (active_channel == caller)) {
1187                                         f = ast_read(caller);
1188                                         if (f == NULL) { /*doh! where'd he go?*/
1189                                                 if (caller->_softhangup && !chan->_softhangup) {
1190                                                         /* make this a blind transfer */
1191                                                         ready = 1;
1192                                                         break;
1193                                                 }
1194                                                 state = AST_CONTROL_HANGUP;
1195                                                 res = 0;
1196                                                 break;
1197                                         }
1198                                         
1199                                         if (f->frametype == AST_FRAME_DTMF) {
1200                                                 dialed_code[x++] = f->subclass;
1201                                                 dialed_code[x] = '\0';
1202                                                 if (strlen(dialed_code) == len) {
1203                                                         x = 0;
1204                                                 } else if (x && strncmp(dialed_code, disconnect_code, x)) {
1205                                                         x = 0;
1206                                                         dialed_code[x] = '\0';
1207                                                 }
1208                                                 if (*dialed_code && !strcmp(dialed_code, disconnect_code)) {
1209                                                         /* Caller Canceled the call */
1210                                                         state = AST_CONTROL_UNHOLD;
1211                                                         ast_frfree(f);
1212                                                         f = NULL;
1213                                                         break;
1214                                                 }
1215                                         }
1216                                 }
1217                                 if (f)
1218                                         ast_frfree(f);
1219                         } /* end while */
1220                 } else
1221                         ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
1222         } else {
1223                 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
1224                 switch(cause) {
1225                 case AST_CAUSE_BUSY:
1226                         state = AST_CONTROL_BUSY;
1227                         break;
1228                 case AST_CAUSE_CONGESTION:
1229                         state = AST_CONTROL_CONGESTION;
1230                         break;
1231                 }
1232         }
1233         
1234         ast_indicate(caller, -1);
1235         if (chan && ready) {
1236                 if (chan->_state == AST_STATE_UP) 
1237                         state = AST_CONTROL_ANSWER;
1238                 res = 0;
1239         } else if(chan) {
1240                 res = -1;
1241                 ast_hangup(chan);
1242                 chan = NULL;
1243         } else {
1244                 res = -1;
1245         }
1246         
1247         if (outstate)
1248                 *outstate = state;
1249
1250         if (chan && res <= 0) {
1251                 if (chan->cdr || (chan->cdr = ast_cdr_alloc())) {
1252                         char tmp[256];
1253                         ast_cdr_init(chan->cdr, chan);
1254                         snprintf(tmp, 256, "%s/%s", type, (char *)data);
1255                         ast_cdr_setapp(chan->cdr,"Dial",tmp);
1256                         ast_cdr_update(chan);
1257                         ast_cdr_start(chan->cdr);
1258                         ast_cdr_end(chan->cdr);
1259                         /* If the cause wasn't handled properly */
1260                         if (ast_cdr_disposition(chan->cdr,chan->hangupcause))
1261                                 ast_cdr_failed(chan->cdr);
1262                 } else {
1263                         ast_log(LOG_WARNING, "Unable to create Call Detail Record\n");
1264                 }
1265         }
1266         
1267         return chan;
1268 }
1269
1270 int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast_bridge_config *config)
1271 {
1272         /* Copy voice back and forth between the two channels.  Give the peer
1273            the ability to transfer calls with '#<extension' syntax. */
1274         struct ast_frame *f;
1275         struct ast_channel *who;
1276         char chan_featurecode[FEATURE_MAX_LEN + 1]="";
1277         char peer_featurecode[FEATURE_MAX_LEN + 1]="";
1278         int res;
1279         int diff;
1280         int hasfeatures=0;
1281         int hadfeatures=0;
1282         struct ast_option_header *aoh;
1283         struct timeval start = { 0 , 0 };
1284         struct ast_bridge_config backup_config;
1285
1286         memset(&backup_config, 0, sizeof(backup_config));
1287
1288         config->start_time = ast_tvnow();
1289
1290         if (chan && peer) {
1291                 pbx_builtin_setvar_helper(chan, "BRIDGEPEER", peer->name);
1292                 pbx_builtin_setvar_helper(peer, "BRIDGEPEER", chan->name);
1293         } else if (chan)
1294                 pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", NULL);
1295
1296         if (monitor_ok) {
1297                 const char *monitor_exec;
1298                 struct ast_channel *src = NULL;
1299                 if (!monitor_app) { 
1300                         if (!(monitor_app = pbx_findapp("Monitor")))
1301                                 monitor_ok=0;
1302                 }
1303                 if ((monitor_exec = pbx_builtin_getvar_helper(chan, "AUTO_MONITOR"))) 
1304                         src = chan;
1305                 else if ((monitor_exec = pbx_builtin_getvar_helper(peer, "AUTO_MONITOR")))
1306                         src = peer;
1307                 if (monitor_app && src) {
1308                         char *tmp = ast_strdupa(monitor_exec);
1309                         pbx_exec(src, monitor_app, tmp);
1310                 }
1311         }
1312         
1313         set_config_flags(chan, peer, config);
1314         config->firstpass = 1;
1315
1316         /* Answer if need be */
1317         if (ast_answer(chan))
1318                 return -1;
1319         peer->appl = "Bridged Call";
1320         peer->data = chan->name;
1321
1322         /* copy the userfield from the B-leg to A-leg if applicable */
1323         if (chan->cdr && peer->cdr && !ast_strlen_zero(peer->cdr->userfield)) {
1324                 char tmp[256];
1325                 if (!ast_strlen_zero(chan->cdr->userfield)) {
1326                         snprintf(tmp, sizeof(tmp), "%s;%s", chan->cdr->userfield, peer->cdr->userfield);
1327                         ast_cdr_appenduserfield(chan, tmp);
1328                 } else
1329                         ast_cdr_setuserfield(chan, peer->cdr->userfield);
1330                 /* free the peer's cdr without ast_cdr_free complaining */
1331                 free(peer->cdr);
1332                 peer->cdr = NULL;
1333         }
1334         for (;;) {
1335                 struct ast_channel *other;      /* used later */
1336                 if (config->feature_timer)
1337                         start = ast_tvnow();
1338
1339                 res = ast_channel_bridge(chan, peer, config, &f, &who);
1340
1341                 if (config->feature_timer) {
1342                         /* Update time limit for next pass */
1343                         diff = ast_tvdiff_ms(ast_tvnow(), start);
1344                         config->feature_timer -= diff;
1345                         if (hasfeatures) {
1346                                 /* Running on backup config, meaning a feature might be being
1347                                    activated, but that's no excuse to keep things going 
1348                                    indefinitely! */
1349                                 if (backup_config.feature_timer && ((backup_config.feature_timer -= diff) <= 0)) {
1350                                         if (option_debug)
1351                                                 ast_log(LOG_DEBUG, "Timed out, realtime this time!\n");
1352                                         config->feature_timer = 0;
1353                                         who = chan;
1354                                         if (f)
1355                                                 ast_frfree(f);
1356                                         f = NULL;
1357                                         res = 0;
1358                                 } else if (config->feature_timer <= 0) {
1359                                         /* Not *really* out of time, just out of time for
1360                                            digits to come in for features. */
1361                                         if (option_debug)
1362                                                 ast_log(LOG_DEBUG, "Timed out for feature!\n");
1363                                         if (!ast_strlen_zero(peer_featurecode)) {
1364                                                 ast_dtmf_stream(chan, peer, peer_featurecode, 0);
1365                                                 memset(peer_featurecode, 0, sizeof(peer_featurecode));
1366                                         }
1367                                         if (!ast_strlen_zero(chan_featurecode)) {
1368                                                 ast_dtmf_stream(peer, chan, chan_featurecode, 0);
1369                                                 memset(chan_featurecode, 0, sizeof(chan_featurecode));
1370                                         }
1371                                         if (f)
1372                                                 ast_frfree(f);
1373                                         hasfeatures = !ast_strlen_zero(chan_featurecode) || !ast_strlen_zero(peer_featurecode);
1374                                         if (!hasfeatures) {
1375                                                 /* Restore original (possibly time modified) bridge config */
1376                                                 memcpy(config, &backup_config, sizeof(struct ast_bridge_config));
1377                                                 memset(&backup_config, 0, sizeof(backup_config));
1378                                         }
1379                                         hadfeatures = hasfeatures;
1380                                         /* Continue as we were */
1381                                         continue;
1382                                 }
1383                         } else {
1384                                 if (config->feature_timer <=0) {
1385                                         /* We ran out of time */
1386                                         config->feature_timer = 0;
1387                                         who = chan;
1388                                         if (f)
1389                                                 ast_frfree(f);
1390                                         f = NULL;
1391                                         res = 0;
1392                                 }
1393                         }
1394                 }
1395                 if (res < 0) {
1396                         ast_log(LOG_WARNING, "Bridge failed on channels %s and %s\n", chan->name, peer->name);
1397                         return -1;
1398                 }
1399                 
1400                 if (!f || (f->frametype == AST_FRAME_CONTROL &&
1401                                 (f->subclass == AST_CONTROL_HANGUP || f->subclass == AST_CONTROL_BUSY || 
1402                                         f->subclass == AST_CONTROL_CONGESTION ) ) ) {
1403                         res = -1;
1404                         break;
1405                 }
1406                 /* many things should be sent to the 'other' channel */
1407                 other = (who == chan) ? peer : chan;
1408                 if (f->frametype == AST_FRAME_CONTROL) {
1409                         if (f->subclass == AST_CONTROL_RINGING)
1410                                 ast_indicate(other, AST_CONTROL_RINGING);
1411                         else if (f->subclass == -1)
1412                                 ast_indicate(other, -1);
1413                         else if (f->subclass == AST_CONTROL_FLASH)
1414                                 ast_indicate(other, AST_CONTROL_FLASH);
1415                         else if (f->subclass == AST_CONTROL_OPTION) {
1416                                 aoh = f->data;
1417                                 /* Forward option Requests */
1418                                 if (aoh && aoh->flag == AST_OPTION_FLAG_REQUEST)
1419                                         ast_channel_setoption(other, ntohs(aoh->option), aoh->data, f->datalen - sizeof(struct ast_option_header), 0);
1420                         }
1421                 }
1422                 /* check for '*', if we find it it's time to disconnect */
1423                 if (f->frametype == AST_FRAME_DTMF) {
1424                         char *featurecode;
1425                         int sense;
1426
1427                         hadfeatures = hasfeatures;
1428                         /* This cannot overrun because the longest feature is one shorter than our buffer */
1429                         if (who == chan) {
1430                                 sense = FEATURE_SENSE_CHAN;
1431                                 featurecode = chan_featurecode;
1432                         } else  {
1433                                 sense = FEATURE_SENSE_PEER;
1434                                 featurecode = peer_featurecode;
1435                         }
1436                         /*! append the event to featurecode. we rely on the string being zero-filled, and
1437                          * not overflowing it. 
1438                          * \todo XXX how do we guarantee the latter ?
1439                          */
1440                         featurecode[strlen(featurecode)] = f->subclass;
1441                         /* Get rid of the frame before we start doing "stuff" with the channels */
1442                         ast_frfree(f);
1443                         f = NULL;
1444                         config->feature_timer = backup_config.feature_timer;
1445                         res = ast_feature_interpret(chan, peer, config, featurecode, sense);
1446                         switch(res) {
1447                         case FEATURE_RETURN_PASSDIGITS:
1448                                 ast_dtmf_stream(other, who, featurecode, 0);
1449                                 /* Fall through */
1450                         case FEATURE_RETURN_SUCCESS:
1451                                 memset(featurecode, 0, sizeof(chan_featurecode));
1452                                 break;
1453                         }
1454                         if (res >= FEATURE_RETURN_PASSDIGITS) {
1455                                 res = 0;
1456                         } else 
1457                                 break;
1458                         hasfeatures = !ast_strlen_zero(chan_featurecode) || !ast_strlen_zero(peer_featurecode);
1459                         if (hadfeatures && !hasfeatures) {
1460                                 /* Restore backup */
1461                                 memcpy(config, &backup_config, sizeof(struct ast_bridge_config));
1462                                 memset(&backup_config, 0, sizeof(struct ast_bridge_config));
1463                         } else if (hasfeatures) {
1464                                 if (!hadfeatures) {
1465                                         /* Backup configuration */
1466                                         memcpy(&backup_config, config, sizeof(struct ast_bridge_config));
1467                                         /* Setup temporary config options */
1468                                         config->play_warning = 0;
1469                                         ast_clear_flag(&(config->features_caller), AST_FEATURE_PLAY_WARNING);
1470                                         ast_clear_flag(&(config->features_callee), AST_FEATURE_PLAY_WARNING);
1471                                         config->warning_freq = 0;
1472                                         config->warning_sound = NULL;
1473                                         config->end_sound = NULL;
1474                                         config->start_sound = NULL;
1475                                         config->firstpass = 0;
1476                                 }
1477                                 config->start_time = ast_tvnow();
1478                                 config->feature_timer = featuredigittimeout;
1479                                 if (option_debug)
1480                                         ast_log(LOG_DEBUG, "Set time limit to %ld\n", config->feature_timer);
1481                         }
1482                 }
1483                 if (f)
1484                         ast_frfree(f);
1485         }
1486         return res;
1487 }
1488
1489 static void post_manager_event(const char *s, char *parkingexten, struct ast_channel *chan)
1490 {
1491         manager_event(EVENT_FLAG_CALL, s,
1492                 "Exten: %s\r\n"
1493                 "Channel: %s\r\n"
1494                 "CallerID: %s\r\n"
1495                 "CallerIDName: %s\r\n\r\n",
1496                 parkingexten, 
1497                 chan->name,
1498                 S_OR(chan->cid.cid_num, "<unknown>"),
1499                 S_OR(chan->cid.cid_name, "<unknown>")
1500                 );
1501 }
1502
1503 /*! \brief Take care of parked calls and unpark them if needed */
1504 static void *do_parking_thread(void *ignore)
1505 {
1506         fd_set rfds, efds;      /* results from previous select, to be preserved across loops. */
1507         FD_ZERO(&rfds);
1508         FD_ZERO(&efds);
1509
1510         for (;;) {
1511                 struct parkeduser *pu, *pl, *pt = NULL;
1512                 int ms = -1;    /* select timeout, uninitialized */
1513                 int max = -1;   /* max fd, none there yet */
1514                 fd_set nrfds, nefds;    /* args for the next select */
1515                 FD_ZERO(&nrfds);
1516                 FD_ZERO(&nefds);
1517
1518                 ast_mutex_lock(&parking_lock);
1519                 pl = NULL;
1520                 pu = parkinglot;
1521                 /* navigate the list with prev-cur pointers to support removals */
1522                 while (pu) {
1523                         struct ast_channel *chan = pu->chan;    /* shorthand */
1524                         int tms;        /* timeout for this item */
1525                         int x;          /* fd index in channel */
1526                         struct ast_context *con;
1527
1528                         if (pu->notquiteyet) { /* Pretend this one isn't here yet */
1529                                 pl = pu;
1530                                 pu = pu->next;
1531                                 continue;
1532                         }
1533                         tms = ast_tvdiff_ms(ast_tvnow(), pu->start);
1534                         if (tms > pu->parkingtime) {
1535                                 ast_indicate(chan, AST_CONTROL_UNHOLD);
1536                                 /* Get chan, exten from derived kludge */
1537                                 if (pu->peername[0]) {
1538                                         char *peername = ast_strdupa(pu->peername);
1539                                         char *cp = strrchr(peername, '-');
1540                                         if (cp) 
1541                                                 *cp = 0;
1542                                         con = ast_context_find(parking_con_dial);
1543                                         if (!con) {
1544                                                 con = ast_context_create(NULL, parking_con_dial, registrar);
1545                                                 if (!con)
1546                                                         ast_log(LOG_ERROR, "Parking dial context '%s' does not exist and unable to create\n", parking_con_dial);
1547                                         }
1548                                         if (con) {
1549                                                 char returnexten[AST_MAX_EXTENSION];
1550                                                 snprintf(returnexten, sizeof(returnexten), "%s||t", peername);
1551                                                 ast_add_extension2(con, 1, peername, 1, NULL, NULL, "Dial", strdup(returnexten), ast_free, registrar);
1552                                         }
1553                                         set_c_e_p(chan, parking_con_dial, peername, 1);
1554                                 } else {
1555                                         /* They've been waiting too long, send them back to where they came.  Theoretically they
1556                                            should have their original extensions and such, but we copy to be on the safe side */
1557                                         set_c_e_p(chan, pu->context, pu->exten, pu->priority);
1558                                 }
1559
1560                                 post_manager_event("ParkedCallTimeOut", pu->parkingexten, chan);
1561
1562                                 if (option_verbose > 1) 
1563                                         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);
1564                                 /* Start up the PBX, or hang them up */
1565                                 if (ast_pbx_start(chan))  {
1566                                         ast_log(LOG_WARNING, "Unable to restart the PBX for user on '%s', hanging them up...\n", chan->name);
1567                                         ast_hangup(chan);
1568                                 }
1569                                 /* And take them out of the parking lot */
1570                                 if (pl) 
1571                                         pl->next = pu->next;
1572                                 else
1573                                         parkinglot = pu->next;
1574                                 pt = pu;
1575                                 pu = pu->next;
1576                                 con = ast_context_find(parking_con);
1577                                 if (con) {
1578                                         if (ast_context_remove_extension2(con, pt->parkingexten, 1, NULL))
1579                                                 ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
1580                                         else
1581                                                 notify_metermaids(pt->parkingexten, parking_con);
1582                                 } else
1583                                         ast_log(LOG_WARNING, "Whoa, no parking context?\n");
1584                                 free(pt);
1585                         } else {        /* still within parking time, process descriptors */
1586                                 for (x = 0; x < AST_MAX_FDS; x++) {
1587                                         struct ast_frame *f;
1588
1589                                         if (chan->fds[x] == -1 || (!FD_ISSET(chan->fds[x], &rfds) && !FD_ISSET(chan->fds[x], &efds)))
1590                                                 continue;       /* nothing on this descriptor */
1591
1592                                         if (FD_ISSET(chan->fds[x], &efds))
1593                                                 ast_set_flag(chan, AST_FLAG_EXCEPTION);
1594                                         else
1595                                                 ast_clear_flag(chan, AST_FLAG_EXCEPTION);
1596                                         chan->fdno = x;
1597
1598                                         /* See if they need servicing */
1599                                         f = ast_read(chan);
1600                                         if (!f || (f->frametype == AST_FRAME_CONTROL && f->subclass ==  AST_CONTROL_HANGUP)) {
1601                                                 if (f)
1602                                                         ast_frfree(f);
1603                                                 post_manager_event("ParkedCallGiveUp", pu->parkingexten, chan);
1604
1605                                                 /* There's a problem, hang them up*/
1606                                                 if (option_verbose > 1) 
1607                                                         ast_verbose(VERBOSE_PREFIX_2 "%s got tired of being parked\n", chan->name);
1608                                                 ast_hangup(chan);
1609                                                 /* And take them out of the parking lot */
1610                                                 if (pl) 
1611                                                         pl->next = pu->next;
1612                                                 else
1613                                                         parkinglot = pu->next;
1614                                                 pt = pu;
1615                                                 pu = pu->next;
1616                                                 con = ast_context_find(parking_con);
1617                                                 if (con) {
1618                                                         if (ast_context_remove_extension2(con, pt->parkingexten, 1, NULL))
1619                                                                 ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
1620                                                 else
1621                                                         notify_metermaids(pt->parkingexten, parking_con);
1622                                                 } else
1623                                                         ast_log(LOG_WARNING, "Whoa, no parking context?\n");
1624                                                 free(pt);
1625                                                 break;
1626                                         } else {
1627                                                 /*! \todo XXX Maybe we could do something with packets, like dial "0" for operator or something XXX */
1628                                                 ast_frfree(f);
1629                                                 if (pu->moh_trys < 3 && !chan->generatordata) {
1630                                                         if (option_debug)
1631                                                                 ast_log(LOG_DEBUG, "MOH on parked call stopped by outside source.  Restarting.\n");
1632                                                         ast_indicate_data(pu->chan, AST_CONTROL_HOLD, 
1633                                                                 S_OR(parkmohclass, NULL),
1634                                                                 !ast_strlen_zero(parkmohclass) ? strlen(parkmohclass) + 1 : 0);
1635                                                         pu->moh_trys++;
1636                                                 }
1637                                                 goto std;       /*! \todo XXX Ick: jumping into an else statement??? XXX */
1638                                         }
1639
1640                                 } /* end for */
1641                                 if (x >= AST_MAX_FDS) {
1642 std:                                    for (x=0; x<AST_MAX_FDS; x++) { /* mark fds for next round */
1643                                                 if (chan->fds[x] > -1) {
1644                                                         FD_SET(chan->fds[x], &nrfds);
1645                                                         FD_SET(chan->fds[x], &nefds);
1646                                                         if (chan->fds[x] > max)
1647                                                                 max = chan->fds[x];
1648                                                 }
1649                                         }
1650                                         /* Keep track of our shortest wait */
1651                                         if (tms < ms || ms < 0)
1652                                                 ms = tms;
1653                                         pl = pu;
1654                                         pu = pu->next;
1655                                 }
1656                         }
1657                 } /* end while */
1658                 ast_mutex_unlock(&parking_lock);
1659                 rfds = nrfds;
1660                 efds = nefds;
1661                 {
1662                         struct timeval tv = ast_samp2tv(ms, 1000);
1663                         /* Wait for something to happen */
1664                         ast_select(max + 1, &rfds, NULL, &efds, (ms > -1) ? &tv : NULL);
1665                 }
1666                 pthread_testcancel();
1667         }
1668         return NULL;    /* Never reached */
1669 }
1670
1671 /*! \brief Park a call */
1672 static int park_call_exec(struct ast_channel *chan, void *data)
1673 {
1674         /* Data is unused at the moment but could contain a parking
1675            lot context eventually */
1676         int res = 0;
1677         struct ast_module_user *u;
1678
1679         u = ast_module_user_add(chan);
1680
1681         /* Setup the exten/priority to be s/1 since we don't know
1682            where this call should return */
1683         strcpy(chan->exten, "s");
1684         chan->priority = 1;
1685         /* Answer if call is not up */
1686         if (chan->_state != AST_STATE_UP)
1687                 res = ast_answer(chan);
1688         /* Sleep to allow VoIP streams to settle down */
1689         if (!res)
1690                 res = ast_safe_sleep(chan, 1000);
1691         /* Park the call */
1692         if (!res)
1693                 res = ast_park_call(chan, chan, 0, NULL);
1694
1695         ast_module_user_remove(u);
1696
1697         return !res ? AST_PBX_KEEPALIVE : res;
1698 }
1699
1700 /*! \brief Pickup parked call */
1701 static int park_exec(struct ast_channel *chan, void *data)
1702 {
1703         int res = 0;
1704         struct ast_module_user *u;
1705         struct ast_channel *peer=NULL;
1706         struct parkeduser *pu, *pl=NULL;
1707         struct ast_context *con;
1708         int park;
1709         struct ast_bridge_config config;
1710
1711         if (!data) {
1712                 ast_log(LOG_WARNING, "Parkedcall requires an argument (extension number)\n");
1713                 return -1;
1714         }
1715         
1716         u = ast_module_user_add(chan);
1717
1718         park = atoi((char *)data);
1719         ast_mutex_lock(&parking_lock);
1720         pu = parkinglot;
1721         while(pu) {
1722                 if (pu->parkingnum == park) {
1723                         if (pl)
1724                                 pl->next = pu->next;
1725                         else
1726                                 parkinglot = pu->next;
1727                         break;
1728                 }
1729                 pl = pu;
1730                 pu = pu->next;
1731         }
1732         ast_mutex_unlock(&parking_lock);
1733         if (pu) {
1734                 peer = pu->chan;
1735                 con = ast_context_find(parking_con);
1736                 if (con) {
1737                         if (ast_context_remove_extension2(con, pu->parkingexten, 1, NULL))
1738                                 ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
1739                         else
1740                                 notify_metermaids(pu->parkingexten, parking_con);
1741                 } else
1742                         ast_log(LOG_WARNING, "Whoa, no parking context?\n");
1743
1744                 manager_event(EVENT_FLAG_CALL, "UnParkedCall",
1745                         "Exten: %s\r\n"
1746                         "Channel: %s\r\n"
1747                         "From: %s\r\n"
1748                         "CallerID: %s\r\n"
1749                         "CallerIDName: %s\r\n",
1750                         pu->parkingexten, pu->chan->name, chan->name,
1751                         S_OR(pu->chan->cid.cid_num, "<unknown>"),
1752                         S_OR(pu->chan->cid.cid_name, "<unknown>")
1753                         );
1754
1755                 free(pu);
1756         }
1757         /* JK02: it helps to answer the channel if not already up */
1758         if (chan->_state != AST_STATE_UP)
1759                 ast_answer(chan);
1760
1761         if (peer) {
1762                 /* Play a courtesy to the source(s) configured to prefix the bridge connecting */
1763                 
1764                 if (!ast_strlen_zero(courtesytone)) {
1765                         int error = 0;
1766                         ast_indicate(peer, AST_CONTROL_UNHOLD);
1767                         if (parkedplay == 0) {
1768                                 error = ast_stream_and_wait(chan, courtesytone, chan->language, "");
1769                         } else if (parkedplay == 1) {
1770                                 error = ast_stream_and_wait(peer, courtesytone, chan->language, "");
1771                         } else if (parkedplay == 2) {
1772                                 if (!ast_streamfile(chan, courtesytone, chan->language) &&
1773                                                 !ast_streamfile(peer, courtesytone, chan->language)) {
1774                                         /*! \todo XXX we would like to wait on both! */
1775                                         res = ast_waitstream(chan, "");
1776                                         if (res >= 0)
1777                                                 res = ast_waitstream(peer, "");
1778                                         if (res < 0)
1779                                                 error = 1;
1780                                 }
1781                         }
1782                         if (error) {
1783                                 ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
1784                                 ast_hangup(peer);
1785                                 return -1;
1786                         }
1787                 } else
1788                         ast_indicate(peer, AST_CONTROL_UNHOLD); 
1789
1790                 res = ast_channel_make_compatible(chan, peer);
1791                 if (res < 0) {
1792                         ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for bridge\n", chan->name, peer->name);
1793                         ast_hangup(peer);
1794                         return -1;
1795                 }
1796                 /* This runs sorta backwards, since we give the incoming channel control, as if it
1797                    were the person called. */
1798                 if (option_verbose > 2) 
1799                         ast_verbose(VERBOSE_PREFIX_3 "Channel %s connected to parked call %d\n", chan->name, park);
1800
1801                 memset(&config, 0, sizeof(struct ast_bridge_config));
1802                 ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
1803                 ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
1804                 config.timelimit = 0;
1805                 config.play_warning = 0;
1806                 config.warning_freq = 0;
1807                 config.warning_sound=NULL;
1808                 res = ast_bridge_call(chan, peer, &config);
1809
1810                 /* Simulate the PBX hanging up */
1811                 if (res != AST_PBX_NO_HANGUP_PEER)
1812                         ast_hangup(peer);
1813                 return res;
1814         } else {
1815                 /*! \todo XXX Play a message XXX */
1816                 if (ast_stream_and_wait(chan, "pbx-invalidpark", chan->language, ""))
1817                         ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", "pbx-invalidpark", chan->name);
1818                 if (option_verbose > 2) 
1819                         ast_verbose(VERBOSE_PREFIX_3 "Channel %s tried to talk to nonexistent parked call %d\n", chan->name, park);
1820                 res = -1;
1821         }
1822
1823         ast_module_user_remove(u);
1824
1825         return res;
1826 }
1827
1828 static int handle_showfeatures(int fd, int argc, char *argv[])
1829 {
1830         int i;
1831         int fcount;
1832         struct ast_call_feature *feature;
1833         char format[] = "%-25s %-7s %-7s\n";
1834
1835         ast_cli(fd, format, "Builtin Feature", "Default", "Current");
1836         ast_cli(fd, format, "---------------", "-------", "-------");
1837
1838         ast_cli(fd, format, "Pickup", "*8", ast_pickup_ext());          /* default hardcoded above, so we'll hardcode it here */
1839
1840         fcount = sizeof(builtin_features) / sizeof(builtin_features[0]);
1841
1842         for (i = 0; i < fcount; i++)
1843         {
1844                 ast_cli(fd, format, builtin_features[i].fname, builtin_features[i].default_exten, builtin_features[i].exten);
1845         }
1846         ast_cli(fd, "\n");
1847         ast_cli(fd, format, "Dynamic Feature", "Default", "Current");
1848         ast_cli(fd, format, "---------------", "-------", "-------");
1849         if (AST_LIST_EMPTY(&feature_list)) {
1850                 ast_cli(fd, "(none)\n");
1851         }
1852         else {
1853                 AST_LIST_LOCK(&feature_list);
1854                 AST_LIST_TRAVERSE(&feature_list, feature, feature_entry) {
1855                         ast_cli(fd, format, feature->sname, "no def", feature->exten);  
1856                 }
1857                 AST_LIST_UNLOCK(&feature_list);
1858         }
1859         ast_cli(fd, "\nCall parking\n");
1860         ast_cli(fd, "------------\n");
1861         ast_cli(fd,"%-20s:      %s\n", "Parking extension", parking_ext);
1862         ast_cli(fd,"%-20s:      %s\n", "Parking context", parking_con);
1863         ast_cli(fd,"%-20s:      %d-%d\n", "Parked call extensions", parking_start, parking_stop);
1864         ast_cli(fd,"\n");
1865         
1866         return RESULT_SUCCESS;
1867 }
1868
1869 static char showfeatures_help[] =
1870 "Usage: show features\n"
1871 "       Lists currently configured features.\n";
1872
1873 static struct ast_cli_entry showfeatures =
1874 { { "show", "features", NULL }, handle_showfeatures, "Lists configured features", showfeatures_help };
1875
1876 static int handle_parkedcalls(int fd, int argc, char *argv[])
1877 {
1878         struct parkeduser *cur;
1879         int numparked = 0;
1880
1881         ast_cli(fd, "%4s %25s (%-15s %-12s %-4s) %-6s \n", "Num", "Channel"
1882                 , "Context", "Extension", "Pri", "Timeout");
1883
1884         ast_mutex_lock(&parking_lock);
1885
1886         for (cur = parkinglot; cur; cur = cur->next) {
1887                 ast_cli(fd, "%-10.10s %25s (%-15s %-12s %-4d) %6lds\n"
1888                         ,cur->parkingexten, cur->chan->name, cur->context, cur->exten
1889                         ,cur->priority, cur->start.tv_sec + (cur->parkingtime/1000) - time(NULL));
1890
1891                 numparked++;
1892         }
1893         ast_mutex_unlock(&parking_lock);
1894         ast_cli(fd, "%d parked call%s.\n", numparked, (numparked != 1) ? "s" : "");
1895
1896
1897         return RESULT_SUCCESS;
1898 }
1899
1900 static char showparked_help[] =
1901 "Usage: show parkedcalls\n"
1902 "       Lists currently parked calls.\n";
1903
1904 static struct ast_cli_entry showparked =
1905 { { "show", "parkedcalls", NULL }, handle_parkedcalls, "Lists parked calls", showparked_help };
1906
1907 /*! \brief Dump lot status */
1908 static int manager_parking_status( struct mansession *s, struct message *m )
1909 {
1910         struct parkeduser *cur;
1911         char *id = astman_get_header(m,"ActionID");
1912         char idText[256] = "";
1913
1914         if (!ast_strlen_zero(id))
1915                 snprintf(idText, 256, "ActionID: %s\r\n", id);
1916
1917         astman_send_ack(s, m, "Parked calls will follow");
1918
1919         ast_mutex_lock(&parking_lock);
1920
1921         for (cur=parkinglot; cur; cur = cur->next) {
1922                 astman_append(s, "Event: ParkedCall\r\n"
1923                         "Exten: %d\r\n"
1924                         "Channel: %s\r\n"
1925                         "From: %s\r\n"
1926                         "Timeout: %ld\r\n"
1927                         "CallerID: %s\r\n"
1928                         "CallerIDName: %s\r\n"
1929                         "%s"
1930                         "\r\n",
1931                         cur->parkingnum, cur->chan->name, cur->peername,
1932                         (long)cur->start.tv_sec + (long)(cur->parkingtime/1000) - (long)time(NULL),
1933                         S_OR(cur->chan->cid.cid_num, ""),       /* XXX in other places it is <unknown> */
1934                         S_OR(cur->chan->cid.cid_name, ""),
1935                         idText);
1936         }
1937
1938         astman_append(s,
1939                 "Event: ParkedCallsComplete\r\n"
1940                 "%s"
1941                 "\r\n",idText);
1942
1943         ast_mutex_unlock(&parking_lock);
1944
1945         return RESULT_SUCCESS;
1946 }
1947
1948 static char mandescr_park[] =
1949 "Description: Park a channel.\n"
1950 "Variables: (Names marked with * are required)\n"
1951 "       *Channel: Channel name to park\n"
1952 "       *Channel2: Channel to announce park info to (and return to if timeout)\n"
1953 "       Timeout: Number of milliseconds to wait before callback.\n";  
1954
1955 static int manager_park(struct mansession *s, struct message *m)
1956 {
1957         char *channel = astman_get_header(m, "Channel");
1958         char *channel2 = astman_get_header(m, "Channel2");
1959         char *timeout = astman_get_header(m, "Timeout");
1960         char buf[BUFSIZ];
1961         int to = 0;
1962         int res = 0;
1963         int parkExt = 0;
1964         struct ast_channel *ch1, *ch2;
1965
1966         if (ast_strlen_zero(channel)) {
1967                 astman_send_error(s, m, "Channel not specified");
1968                 return 0;
1969         }
1970
1971         if (ast_strlen_zero(channel2)) {
1972                 astman_send_error(s, m, "Channel2 not specified");
1973                 return 0;
1974         }
1975
1976         ch1 = ast_get_channel_by_name_locked(channel);
1977         if (!ch1) {
1978                 snprintf(buf, sizeof(buf), "Channel does not exist: %s", channel);
1979                 astman_send_error(s, m, buf);
1980                 return 0;
1981         }
1982
1983         ch2 = ast_get_channel_by_name_locked(channel2);
1984         if (!ch2) {
1985                 snprintf(buf, sizeof(buf), "Channel does not exist: %s", channel2);
1986                 astman_send_error(s, m, buf);
1987                 ast_channel_unlock(ch1);
1988                 return 0;
1989         }
1990
1991         if (!ast_strlen_zero(timeout)) {
1992                 sscanf(timeout, "%d", &to);
1993         }
1994
1995         res = ast_masq_park_call(ch1, ch2, to, &parkExt);
1996         if (!res) {
1997                 ast_softhangup(ch2, AST_SOFTHANGUP_EXPLICIT);
1998                 astman_send_ack(s, m, "Park successful");
1999         } else {
2000                 astman_send_error(s, m, "Park failure");
2001         }
2002
2003         ast_channel_unlock(ch1);
2004         ast_channel_unlock(ch2);
2005
2006         return 0;
2007 }
2008
2009
2010 int ast_pickup_call(struct ast_channel *chan)
2011 {
2012         struct ast_channel *cur = NULL;
2013         int res = -1;
2014
2015         while ( (cur = ast_channel_walk_locked(cur)) != NULL) {
2016                 if (!cur->pbx && 
2017                         (cur != chan) &&
2018                         (chan->pickupgroup & cur->callgroup) &&
2019                         ((cur->_state == AST_STATE_RINGING) ||
2020                          (cur->_state == AST_STATE_RING))) {
2021                                 break;
2022                 }
2023                 ast_channel_unlock(cur);
2024         }
2025         if (cur) {
2026                 if (option_debug)
2027                         ast_log(LOG_DEBUG, "Call pickup on chan '%s' by '%s'\n",cur->name, chan->name);
2028                 res = ast_answer(chan);
2029                 if (res)
2030                         ast_log(LOG_WARNING, "Unable to answer '%s'\n", chan->name);
2031                 res = ast_queue_control(chan, AST_CONTROL_ANSWER);
2032                 if (res)
2033                         ast_log(LOG_WARNING, "Unable to queue answer on '%s'\n", chan->name);
2034                 res = ast_channel_masquerade(cur, chan);
2035                 if (res)
2036                         ast_log(LOG_WARNING, "Unable to masquerade '%s' into '%s'\n", chan->name, cur->name);           /* Done */
2037                 ast_channel_unlock(cur);
2038         } else  {
2039                 if (option_debug)
2040                         ast_log(LOG_DEBUG, "No call pickup possible...\n");
2041         }
2042         return res;
2043 }
2044
2045 /*! \brief Add parking hints for all defined parking lots */
2046 static void park_add_hints(char *context, int start, int stop)
2047 {
2048         int numext;
2049         char device[AST_MAX_EXTENSION];
2050         char exten[10];
2051
2052         for (numext = start; numext <= stop; numext++) {
2053                 snprintf(exten, sizeof(exten), "%d", numext);
2054                 snprintf(device, sizeof(device), "park:%s@%s", exten, context);
2055                 ast_add_extension(context, 1, exten, PRIORITY_HINT, NULL, NULL, device, NULL, NULL, registrar);
2056         }
2057 }
2058
2059
2060 static int load_config(void) 
2061 {
2062         int start = 0, end = 0;
2063         int res;
2064         struct ast_context *con = NULL;
2065         struct ast_config *cfg = NULL;
2066         struct ast_variable *var = NULL;
2067         char old_parking_ext[AST_MAX_EXTENSION];
2068         char old_parking_con[AST_MAX_EXTENSION] = "";
2069
2070         if (!ast_strlen_zero(parking_con)) {
2071                 strcpy(old_parking_ext, parking_ext);
2072                 strcpy(old_parking_con, parking_con);
2073         } 
2074
2075         /* Reset to defaults */
2076         strcpy(parking_con, "parkedcalls");
2077         strcpy(parking_con_dial, "park-dial");
2078         strcpy(parking_ext, "700");
2079         strcpy(pickup_ext, "*8");
2080         strcpy(parkmohclass, "default");
2081         courtesytone[0] = '\0';
2082         strcpy(xfersound, "beep");
2083         strcpy(xferfailsound, "pbx-invalid");
2084         parking_start = 701;
2085         parking_stop = 750;
2086         parkfindnext = 0;
2087         adsipark = 0;
2088         parkaddhints = 0;
2089
2090         transferdigittimeout = DEFAULT_TRANSFER_DIGIT_TIMEOUT;
2091         featuredigittimeout = DEFAULT_FEATURE_DIGIT_TIMEOUT;
2092         atxfernoanswertimeout = DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER;
2093
2094         cfg = ast_config_load("features.conf");
2095         if (cfg) {
2096                 for (var = ast_variable_browse(cfg, "general"); var; var = var->next) {
2097                         if (!strcasecmp(var->name, "parkext")) {
2098                                 ast_copy_string(parking_ext, var->value, sizeof(parking_ext));
2099                         } else if (!strcasecmp(var->name, "context")) {
2100                                 ast_copy_string(parking_con, var->value, sizeof(parking_con));
2101                         } else if (!strcasecmp(var->name, "parkingtime")) {
2102                                 if ((sscanf(var->value, "%d", &parkingtime) != 1) || (parkingtime < 1)) {
2103                                         ast_log(LOG_WARNING, "%s is not a valid parkingtime\n", var->value);
2104                                         parkingtime = DEFAULT_PARK_TIME;
2105                                 } else
2106                                         parkingtime = parkingtime * 1000;
2107                         } else if (!strcasecmp(var->name, "parkpos")) {
2108                                 if (sscanf(var->value, "%d-%d", &start, &end) != 2) {
2109                                         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);
2110                                 } else {
2111                                         parking_start = start;
2112                                         parking_stop = end;
2113                                 }
2114                         } else if (!strcasecmp(var->name, "findslot")) {
2115                                 parkfindnext = (!strcasecmp(var->value, "next"));
2116                         } else if (!strcasecmp(var->name, "parkinghints")) {
2117                                 parkaddhints = ast_true(var->value);
2118                         } else if (!strcasecmp(var->name, "adsipark")) {
2119                                 adsipark = ast_true(var->value);
2120                         } else if (!strcasecmp(var->name, "transferdigittimeout")) {
2121                                 if ((sscanf(var->value, "%d", &transferdigittimeout) != 1) || (transferdigittimeout < 1)) {
2122                                         ast_log(LOG_WARNING, "%s is not a valid transferdigittimeout\n", var->value);
2123                                         transferdigittimeout = DEFAULT_TRANSFER_DIGIT_TIMEOUT;
2124                                 } else
2125                                         transferdigittimeout = transferdigittimeout * 1000;
2126                         } else if (!strcasecmp(var->name, "featuredigittimeout")) {
2127                                 if ((sscanf(var->value, "%d", &featuredigittimeout) != 1) || (featuredigittimeout < 1)) {
2128                                         ast_log(LOG_WARNING, "%s is not a valid featuredigittimeout\n", var->value);
2129                                         featuredigittimeout = DEFAULT_FEATURE_DIGIT_TIMEOUT;
2130                                 }
2131                         } else if (!strcasecmp(var->name, "atxfernoanswertimeout")) {
2132                                 if ((sscanf(var->value, "%d", &atxfernoanswertimeout) != 1) || (atxfernoanswertimeout < 1)) {
2133                                         ast_log(LOG_WARNING, "%s is not a valid atxfernoanswertimeout\n", var->value);
2134                                         atxfernoanswertimeout = DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER;
2135                                 } else
2136                                         atxfernoanswertimeout = atxfernoanswertimeout * 1000;
2137                         } else if (!strcasecmp(var->name, "courtesytone")) {
2138                                 ast_copy_string(courtesytone, var->value, sizeof(courtesytone));
2139                         }  else if (!strcasecmp(var->name, "parkedplay")) {
2140                                 if (!strcasecmp(var->value, "both"))
2141                                         parkedplay = 2;
2142                                 else if (!strcasecmp(var->value, "parked"))
2143                                         parkedplay = 1;
2144                                 else
2145                                         parkedplay = 0;
2146                         } else if (!strcasecmp(var->name, "xfersound")) {
2147                                 ast_copy_string(xfersound, var->value, sizeof(xfersound));
2148                         } else if (!strcasecmp(var->name, "xferfailsound")) {
2149                                 ast_copy_string(xferfailsound, var->value, sizeof(xferfailsound));
2150                         } else if (!strcasecmp(var->name, "pickupexten")) {
2151                                 ast_copy_string(pickup_ext, var->value, sizeof(pickup_ext));
2152                         } else if (!strcasecmp(var->name, "parkedmusicclass")) {
2153                                 ast_copy_string(parkmohclass, var->value, sizeof(parkmohclass));
2154                         }
2155                 }
2156
2157                 unmap_features();
2158                 for (var = ast_variable_browse(cfg, "featuremap"); var; var = var->next) {
2159                         if (remap_feature(var->name, var->value))
2160                                 ast_log(LOG_NOTICE, "Unknown feature '%s'\n", var->name);
2161                 }
2162
2163                 /* Map a key combination to an application*/
2164                 ast_unregister_features();
2165                 for (var = ast_variable_browse(cfg, "applicationmap"); var; var = var->next) {
2166                         char *tmp_val = ast_strdupa(var->value);
2167                         char *exten, *activateon, *activatedby, *app, *app_args; 
2168                         struct ast_call_feature *feature;
2169
2170                         /* strsep() sets the argument to NULL if match not found, and it
2171                          * is safe to use it with a NULL argument, so we don't check
2172                          * between calls.
2173                          */
2174                         exten = strsep(&tmp_val,",");
2175                         activatedby = strsep(&tmp_val,",");
2176                         app = strsep(&tmp_val,",");
2177                         app_args = strsep(&tmp_val,",");
2178
2179                         activateon = strsep(&activatedby, "/"); 
2180
2181                         /*! \todo XXX var_name or app_args ? */
2182                         if (ast_strlen_zero(app) || ast_strlen_zero(exten) || ast_strlen_zero(activateon) || ast_strlen_zero(var->name)) {
2183                                 ast_log(LOG_NOTICE, "Please check the feature Mapping Syntax, either extension, name, or app aren't provided %s %s %s %s\n",
2184                                         app, exten, activateon, var->name);
2185                                 continue;
2186                         }
2187
2188                         if ((feature = find_feature(var->name))) {
2189                                 ast_log(LOG_WARNING, "Dynamic Feature '%s' specified more than once!\n", var->name);
2190                                 continue;
2191                         }
2192                                         
2193                         if (!(feature = ast_calloc(1, sizeof(*feature))))
2194                                 continue;                                       
2195
2196                         ast_copy_string(feature->sname, var->name, FEATURE_SNAME_LEN);
2197                         ast_copy_string(feature->app, app, FEATURE_APP_LEN);
2198                         ast_copy_string(feature->exten, exten, FEATURE_EXTEN_LEN);
2199                         
2200                         if (app_args) 
2201                                 ast_copy_string(feature->app_args, app_args, FEATURE_APP_ARGS_LEN);
2202                                 
2203                         ast_copy_string(feature->exten, exten, sizeof(feature->exten));
2204                         feature->operation = feature_exec_app;
2205                         ast_set_flag(feature, AST_FEATURE_FLAG_NEEDSDTMF);
2206
2207                         /* Allow caller and calle to be specified for backwards compatability */
2208                         if (!strcasecmp(activateon, "self") || !strcasecmp(activateon, "caller"))
2209                                 ast_set_flag(feature, AST_FEATURE_FLAG_ONSELF);
2210                         else if (!strcasecmp(activateon, "peer") || !strcasecmp(activateon, "callee"))
2211                                 ast_set_flag(feature, AST_FEATURE_FLAG_ONPEER);
2212                         else {
2213                                 ast_log(LOG_NOTICE, "Invalid 'ActivateOn' specification for feature '%s',"
2214                                         " must be 'self', or 'peer'\n", var->name);
2215                                 continue;
2216                         }
2217
2218                         if (ast_strlen_zero(activatedby))
2219                                 ast_set_flag(feature, AST_FEATURE_FLAG_BYBOTH);
2220                         else if (!strcasecmp(activatedby, "caller"))
2221                                 ast_set_flag(feature, AST_FEATURE_FLAG_BYCALLER);
2222                         else if (!strcasecmp(activatedby, "callee"))
2223                                 ast_set_flag(feature, AST_FEATURE_FLAG_BYCALLEE);
2224                         else if (!strcasecmp(activatedby, "both"))
2225                                 ast_set_flag(feature, AST_FEATURE_FLAG_BYBOTH);
2226                         else {
2227                                 ast_log(LOG_NOTICE, "Invalid 'ActivatedBy' specification for feature '%s',"
2228                                         " must be 'caller', or 'callee', or 'both'\n", var->name);
2229                                 continue;
2230                         }
2231
2232                         ast_register_feature(feature);
2233                                 
2234                         if (option_verbose >= 1)
2235                                 ast_verbose(VERBOSE_PREFIX_2 "Mapping Feature '%s' to app '%s(%s)' with code '%s'\n", var->name, app, app_args, exten);  
2236                 }        
2237         }
2238         ast_config_destroy(cfg);
2239
2240         /* Remove the old parking extension */
2241         if (!ast_strlen_zero(old_parking_con) && (con = ast_context_find(old_parking_con)))     {
2242                 if(ast_context_remove_extension2(con, old_parking_ext, 1, registrar))
2243                                 notify_metermaids(old_parking_ext, old_parking_con);
2244                 if (option_debug)
2245                         ast_log(LOG_DEBUG, "Removed old parking extension %s@%s\n", old_parking_ext, old_parking_con);
2246         }
2247         
2248         if (!(con = ast_context_find(parking_con)) && !(con = ast_context_create(NULL, parking_con, registrar))) {
2249                 ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", parking_con);
2250                 return -1;
2251         }
2252         res = ast_add_extension2(con, 1, ast_parking_ext(), 1, NULL, NULL, parkcall, strdup(""), ast_free, registrar);
2253         if (parkaddhints)
2254                 park_add_hints(parking_con, parking_start, parking_stop);
2255         if (!res)
2256                 notify_metermaids(ast_parking_ext(), parking_con);
2257         return res;
2258
2259 }
2260
2261 static int reload(void)
2262 {
2263         return load_config();
2264 }
2265
2266 static int load_module(void)
2267 {
2268         int res;
2269         
2270         memset(parking_ext, 0, sizeof(parking_ext));
2271         memset(parking_con, 0, sizeof(parking_con));
2272
2273         if ((res = load_config()))
2274                 return res;
2275         ast_cli_register(&showparked);
2276         ast_cli_register(&showfeatures);
2277         ast_pthread_create(&parking_thread, NULL, do_parking_thread, NULL);
2278         res = ast_register_application(parkedcall, park_exec, synopsis, descrip);
2279         if (!res)
2280                 res = ast_register_application(parkcall, park_call_exec, synopsis2, descrip2);
2281         if (!res) {
2282                 ast_manager_register("ParkedCalls", 0, manager_parking_status, "List parked calls" );
2283                 ast_manager_register2("Park", EVENT_FLAG_CALL, manager_park,
2284                         "Park a channel", mandescr_park); 
2285         }
2286
2287         res |= ast_devstate_prov_add("Park", metermaidstate);
2288
2289         return res;
2290 }
2291
2292
2293 static int unload_module(void)
2294 {
2295         ast_module_user_hangup_all();
2296
2297         ast_manager_unregister("ParkedCalls");
2298         ast_manager_unregister("Park");
2299         ast_cli_unregister(&showfeatures);
2300         ast_cli_unregister(&showparked);
2301         ast_unregister_application(parkcall);
2302         ast_devstate_prov_del("Park");
2303         return ast_unregister_application(parkedcall);
2304 }
2305
2306 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "Call Features Resource",
2307                 .load = load_module,
2308                 .unload = unload_module,
2309                 .reload = reload,
2310                );