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