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