Update to current coding standards, also changing the argument delimiter to ',' ...
[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 #define DEFAULT_ATXFER_DROP_CALL 0
67 #define DEFAULT_ATXFER_LOOP_DELAY 10000
68 #define DEFAULT_ATXFER_CALLBACK_RETRIES 2
69
70 #define AST_MAX_WATCHERS 256
71
72 enum {
73         AST_FEATURE_FLAG_NEEDSDTMF = (1 << 0),
74         AST_FEATURE_FLAG_ONPEER =    (1 << 1),
75         AST_FEATURE_FLAG_ONSELF =    (1 << 2),
76         AST_FEATURE_FLAG_BYCALLEE =  (1 << 3),
77         AST_FEATURE_FLAG_BYCALLER =  (1 << 4),
78         AST_FEATURE_FLAG_BYBOTH  =   (3 << 3),
79 };
80
81 struct feature_group_exten {
82         AST_LIST_ENTRY(feature_group_exten) entry;
83         AST_DECLARE_STRING_FIELDS(
84                 AST_STRING_FIELD(exten);
85         );
86         struct ast_call_feature *feature;
87 };
88
89 struct feature_group {
90         AST_LIST_ENTRY(feature_group) entry;
91         AST_DECLARE_STRING_FIELDS(
92                 AST_STRING_FIELD(gname);
93         );
94         AST_LIST_HEAD_NOLOCK(, feature_group_exten) features;
95 };
96
97 static AST_RWLIST_HEAD_STATIC(feature_groups, feature_group);
98
99 static char *parkedcall = "ParkedCall";
100
101 static int parkaddhints = 0;                               /*!< Add parking hints automatically */
102 static int parkedcalltransfers = 0;                        /*!< Enable DTMF based transfers on bridge when picking up parked calls */
103 static int parkedcallreparking = 0;                        /*!< Enable DTMF based parking on bridge when picking up parked calls */
104 static int parkingtime = DEFAULT_PARK_TIME;                /*!< No more than 45 seconds parked before you do something with them */
105 static char parking_con[AST_MAX_EXTENSION];                /*!< Context for which parking is made accessible */
106 static char parking_con_dial[AST_MAX_EXTENSION];           /*!< Context for dialback for parking (KLUDGE) */
107 static char parking_ext[AST_MAX_EXTENSION];                /*!< Extension you type to park the call */
108 static char pickup_ext[AST_MAX_EXTENSION];                 /*!< Call pickup extension */
109 static char parkmohclass[MAX_MUSICCLASS];                  /*!< Music class used for parking */
110 static int parking_start;                                  /*!< First available extension for parking */
111 static int parking_stop;                                   /*!< Last available extension for parking */
112
113 static char courtesytone[256];                             /*!< Courtesy tone */
114 static int parkedplay = 0;                                 /*!< Who to play the courtesy tone to */
115 static char xfersound[256];                                /*!< Call transfer sound */
116 static char xferfailsound[256];                            /*!< Call transfer failure sound */
117
118 static int parking_offset;
119 static int parkfindnext;
120
121 static int adsipark;
122
123 static int transferdigittimeout;
124 static int featuredigittimeout;
125 static int comebacktoorigin = 1;
126
127 static int atxfernoanswertimeout;
128 static unsigned int atxferdropcall;
129 static unsigned int atxferloopdelay;
130 static unsigned int atxfercallbackretries;
131
132 static char *registrar = "res_features";                   /*!< Registrar for operations */
133
134 /* module and CLI command definitions */
135 static char *synopsis = "Answer a parked call";
136
137 static char *descrip = "ParkedCall(exten):"
138 "Used to connect to a parked call.  This application is always\n"
139 "registered internally and does not need to be explicitly added\n"
140 "into the dialplan, although you should include the 'parkedcalls'\n"
141 "context.\n";
142
143 static char *parkcall = "Park";
144
145 static char *synopsis2 = "Park yourself";
146
147 static char *descrip2 = "Park():"
148 "Used to park yourself (typically in combination with a supervised\n"
149 "transfer to know the parking space). This application is always\n"
150 "registered internally and does not need to be explicitly added\n"
151 "into the dialplan, although you should include the 'parkedcalls'\n"
152 "context (or the context specified in features.conf).\n\n"
153 "If you set the PARKINGEXTEN variable to an extension in your\n"
154 "parking context, park() will park the call on that extension, unless\n"
155 "it already exists. In that case, execution will continue at next\n"
156 "priority.\n" ;
157
158 static struct ast_app *monitor_app = NULL;
159 static int monitor_ok = 1;
160
161 struct parkeduser {
162         struct ast_channel *chan;                   /*!< Parking channel */
163         struct timeval start;                       /*!< Time the parking started */
164         int parkingnum;                             /*!< Parking lot */
165         char parkingexten[AST_MAX_EXTENSION];       /*!< If set beforehand, parking extension used for this call */
166         char context[AST_MAX_CONTEXT];              /*!< Where to go if our parking time expires */
167         char exten[AST_MAX_EXTENSION];
168         int priority;
169         int parkingtime;                            /*!< Maximum length in parking lot before return */
170         int notquiteyet;
171         char peername[1024];
172         unsigned char moh_trys;
173         AST_LIST_ENTRY(parkeduser) list;
174 };
175
176 static AST_LIST_HEAD_STATIC(parkinglot, parkeduser);
177
178 static pthread_t parking_thread;
179
180 const char *ast_parking_ext(void)
181 {
182         return parking_ext;
183 }
184
185 const char *ast_pickup_ext(void)
186 {
187         return pickup_ext;
188 }
189
190 struct ast_bridge_thread_obj 
191 {
192         struct ast_bridge_config bconfig;
193         struct ast_channel *chan;
194         struct ast_channel *peer;
195         unsigned int return_to_pbx:1;
196 };
197
198
199
200 /*!
201  * \brief store context, extension and priority 
202  * \param chan, context, ext, pri
203 */
204 static void set_c_e_p(struct ast_channel *chan, const char *context, const char *ext, int pri)
205 {
206         ast_copy_string(chan->context, context, sizeof(chan->context));
207         ast_copy_string(chan->exten, ext, sizeof(chan->exten));
208         chan->priority = pri;
209 }
210
211 /*!
212  * \brief Check goto on transfer
213  * \param chan
214  *
215  * Check if channel has 'GOTO_ON_BLINDXFR' set, if not exit.
216  * When found make sure the types are compatible. Check if channel is valid
217  * if so start the new channel else hangup the call. 
218 */
219 static void check_goto_on_transfer(struct ast_channel *chan) 
220 {
221         struct ast_channel *xferchan;
222         const char *val = pbx_builtin_getvar_helper(chan, "GOTO_ON_BLINDXFR");
223         char *x, *goto_on_transfer;
224         struct ast_frame *f;
225
226         if (ast_strlen_zero(val))
227                 return;
228
229         goto_on_transfer = ast_strdupa(val);
230
231         if (!(xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, chan->name)))
232                 return;
233
234         for (x = goto_on_transfer; x && *x; x++) {
235                 if (*x == '^')
236                         *x = '|';
237         }
238         /* Make formats okay */
239         xferchan->readformat = chan->readformat;
240         xferchan->writeformat = chan->writeformat;
241         ast_channel_masquerade(xferchan, chan);
242         ast_parseable_goto(xferchan, goto_on_transfer);
243         xferchan->_state = AST_STATE_UP;
244         ast_clear_flag(xferchan, AST_FLAGS_ALL);        
245         xferchan->_softhangup = 0;
246         if ((f = ast_read(xferchan))) {
247                 ast_frfree(f);
248                 f = NULL;
249                 ast_pbx_start(xferchan);
250         } else {
251                 ast_hangup(xferchan);
252         }
253 }
254
255 static struct ast_channel *ast_feature_request_and_dial(struct ast_channel *caller, struct ast_channel *transferee, const char *type, int format, void *data, int timeout, int *outstate, const char *cid_num, const char *cid_name, int igncallerstate);
256
257 /*!
258  * \brief bridge the call 
259  * \param data thread bridge.
260  *
261  * Set Last Data for respective channels, reset cdr for channels
262  * bridge call, check if we're going back to dialplan
263  * if not hangup both legs of the call
264 */
265 static void *ast_bridge_call_thread(void *data) 
266 {
267         struct ast_bridge_thread_obj *tobj = data;
268         int res;
269
270         tobj->chan->appl = !tobj->return_to_pbx ? "Transferred Call" : "ManagerBridge";
271         tobj->chan->data = tobj->peer->name;
272         tobj->peer->appl = !tobj->return_to_pbx ? "Transferred Call" : "ManagerBridge";
273         tobj->peer->data = tobj->chan->name;
274
275         if (tobj->chan->cdr) {
276                 ast_cdr_reset(tobj->chan->cdr, NULL);
277                 ast_cdr_setdestchan(tobj->chan->cdr, tobj->peer->name);
278         }
279         if (tobj->peer->cdr) {
280                 ast_cdr_reset(tobj->peer->cdr, NULL);
281                 ast_cdr_setdestchan(tobj->peer->cdr, tobj->chan->name);
282         }
283
284         ast_bridge_call(tobj->peer, tobj->chan, &tobj->bconfig);
285
286         if (tobj->return_to_pbx) {
287                 if (!ast_check_hangup(tobj->peer)) {
288                         ast_log(LOG_VERBOSE, "putting peer %s into PBX again\n", tobj->peer->name);
289                         res = ast_pbx_start(tobj->peer);
290                         if (res != AST_PBX_SUCCESS)
291                                 ast_log(LOG_WARNING, "FAILED continuing PBX on peer %s\n", tobj->peer->name);
292                 } else
293                         ast_hangup(tobj->peer);
294                 if (!ast_check_hangup(tobj->chan)) {
295                         ast_log(LOG_VERBOSE, "putting chan %s into PBX again\n", tobj->chan->name);
296                         res = ast_pbx_start(tobj->chan);
297                         if (res != AST_PBX_SUCCESS)
298                                 ast_log(LOG_WARNING, "FAILED continuing PBX on chan %s\n", tobj->chan->name);
299                 } else
300                         ast_hangup(tobj->chan);
301         } else {
302                 ast_hangup(tobj->chan);
303                 ast_hangup(tobj->peer);
304         }
305
306         ast_free(tobj);
307
308         return NULL;
309 }
310
311 /*!
312  * \brief create thread for the parked call
313  * \param data
314  *
315  * Create thread and attributes, call ast_bridge_call_thread
316 */
317 static void ast_bridge_call_thread_launch(void *data) 
318 {
319         pthread_t thread;
320         pthread_attr_t attr;
321         struct sched_param sched;
322
323         pthread_attr_init(&attr);
324         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
325         ast_pthread_create(&thread, &attr,ast_bridge_call_thread, data);
326         pthread_attr_destroy(&attr);
327         memset(&sched, 0, sizeof(sched));
328         pthread_setschedparam(thread, SCHED_RR, &sched);
329 }
330
331 /*!
332  * \brief Announce call parking by ADSI
333  * \param chan .
334  * \param parkingexten .
335  * Create message to show for ADSI, display message.
336  * \retval 0 on success.
337  * \retval -1 on failure.
338 */
339 static int adsi_announce_park(struct ast_channel *chan, char *parkingexten)
340 {
341         int res;
342         int justify[5] = {ADSI_JUST_CENT, ADSI_JUST_CENT, ADSI_JUST_CENT, ADSI_JUST_CENT};
343         char tmp[256];
344         char *message[5] = {NULL, NULL, NULL, NULL, NULL};
345
346         snprintf(tmp, sizeof(tmp), "Parked on %s", parkingexten);
347         message[0] = tmp;
348         res = ast_adsi_load_session(chan, NULL, 0, 1);
349         if (res == -1)
350                 return res;
351         return ast_adsi_print(chan, message, justify, 1);
352 }
353
354 /*! \brief Notify metermaids that we've changed an extension */
355 static void notify_metermaids(const char *exten, char *context, enum ast_device_state state)
356 {
357         ast_debug(4, "Notification of state change to metermaids %s@%s\n to state '%s'", 
358                 exten, context, devstate2str(state));
359
360         ast_devstate_changed(state, "park:%s@%s", exten, context);
361 }
362
363 /*! \brief metermaids callback from devicestate.c */
364 static enum ast_device_state metermaidstate(const char *data)
365 {
366         char *context;
367         char *exten;
368
369         context = ast_strdupa(data);
370
371         exten = strsep(&context, "@");
372         if (!context)
373                 return AST_DEVICE_INVALID;
374         
375         ast_debug(4, "Checking state of exten %s in context %s\n", exten, context);
376
377         if (!ast_exists_extension(NULL, context, exten, 1, NULL))
378                 return AST_DEVICE_NOT_INUSE;
379
380         return AST_DEVICE_INUSE;
381 }
382
383 /* Park a call */
384 int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeout, int *extout)
385 {
386         struct parkeduser *pu, *cur;
387         int i, x = -1, parking_range;
388         struct ast_context *con;
389         const char *parkingexten;
390         
391         /* Allocate memory for parking data */
392         if (!(pu = ast_calloc(1, sizeof(*pu)))) 
393                 return -1;
394
395         /* Lock parking lot */
396         AST_LIST_LOCK(&parkinglot);
397         /* Check for channel variable PARKINGEXTEN */
398         parkingexten = pbx_builtin_getvar_helper(chan, "PARKINGEXTEN");
399         if (!ast_strlen_zero(parkingexten)) {
400                 if (ast_exists_extension(NULL, parking_con, parkingexten, 1, NULL)) {
401                         AST_LIST_UNLOCK(&parkinglot);
402                         ast_free(pu);
403                         ast_log(LOG_WARNING, "Requested parking extension already exists: %s@%s\n", parkingexten, parking_con);
404                         return -1; /* We failed to park this call, plain and simple so we need to error out */
405                 }
406                 ast_copy_string(pu->parkingexten, parkingexten, sizeof(pu->parkingexten));
407                 x = atoi(parkingexten);
408         } else {
409                 /* Select parking space within range */
410                 parking_range = parking_stop - parking_start+1;
411                 for (i = 0; i < parking_range; i++) {
412                         x = (i + parking_offset) % parking_range + parking_start;
413                         AST_LIST_TRAVERSE(&parkinglot, cur, list) {
414                                 if (cur->parkingnum == x)
415                                         break;
416                         }
417                         if (!cur)
418                                 break;
419                 }
420
421                 if (!(i < parking_range)) {
422                         ast_log(LOG_WARNING, "No more parking spaces\n");
423                         ast_free(pu);
424                         AST_LIST_UNLOCK(&parkinglot);
425                         return -1;
426                 }
427                 /* Set pointer for next parking */
428                 if (parkfindnext) 
429                         parking_offset = x - parking_start + 1;
430         }
431         
432         chan->appl = "Parked Call";
433         chan->data = NULL; 
434
435         pu->chan = chan;
436         
437         /* Put the parked channel on hold if we have two different channels */
438         if (chan != peer) {
439                 ast_indicate_data(pu->chan, AST_CONTROL_HOLD, 
440                         S_OR(parkmohclass, NULL),
441                         !ast_strlen_zero(parkmohclass) ? strlen(parkmohclass) + 1 : 0);
442         }
443         
444         pu->start = ast_tvnow();
445         pu->parkingnum = x;
446         pu->parkingtime = (timeout > 0) ? timeout : parkingtime;
447         if (extout)
448                 *extout = x;
449
450         if (peer) 
451                 ast_copy_string(pu->peername, peer->name, sizeof(pu->peername));
452
453         /* Remember what had been dialed, so that if the parking
454            expires, we try to come back to the same place */
455         ast_copy_string(pu->context, S_OR(chan->macrocontext, chan->context), sizeof(pu->context));
456         ast_copy_string(pu->exten, S_OR(chan->macroexten, chan->exten), sizeof(pu->exten));
457         pu->priority = chan->macropriority ? chan->macropriority : chan->priority;
458         AST_LIST_INSERT_TAIL(&parkinglot, pu, list);
459
460         /* If parking a channel directly, don't quiet yet get parking running on it */
461         if (peer == chan) 
462                 pu->notquiteyet = 1;
463         AST_LIST_UNLOCK(&parkinglot);
464         /* Wake up the (presumably select()ing) thread */
465         pthread_kill(parking_thread, SIGURG);
466         ast_verb(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));
467
468         if (pu->parkingnum != -1)
469                 snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", x);
470         manager_event(EVENT_FLAG_CALL, "ParkedCall",
471                 "Exten: %s\r\n"
472                 "Channel: %s\r\n"
473                 "From: %s\r\n"
474                 "Timeout: %ld\r\n"
475                 "CallerIDNum: %s\r\n"
476                 "CallerIDName: %s\r\n",
477                 pu->parkingexten, pu->chan->name, peer ? peer->name : "",
478                 (long)pu->start.tv_sec + (long)(pu->parkingtime/1000) - (long)time(NULL),
479                 S_OR(pu->chan->cid.cid_num, "<unknown>"),
480                 S_OR(pu->chan->cid.cid_name, "<unknown>")
481                 );
482
483         if (peer && adsipark && ast_adsi_available(peer)) {
484                 adsi_announce_park(peer, pu->parkingexten);     /* Only supports parking numbers */
485                 ast_adsi_unload_session(peer);
486         }
487
488         con = ast_context_find(parking_con);
489         if (!con) 
490                 con = ast_context_create(NULL, parking_con, registrar);
491         if (!con)       /* Still no context? Bad */
492                 ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", parking_con);
493         /* Tell the peer channel the number of the parking space */
494         if (peer && pu->parkingnum != -1) { /* Only say number if it's a number */
495                 /* Make sure we don't start saying digits to the channel being parked */
496                 ast_set_flag(peer, AST_FLAG_MASQ_NOSTREAM);
497                 ast_say_digits(peer, pu->parkingnum, "", peer->language);
498                 ast_clear_flag(peer, AST_FLAG_MASQ_NOSTREAM);
499         }
500         if (con) {
501                 if (!ast_add_extension2(con, 1, pu->parkingexten, 1, NULL, NULL, parkedcall, ast_strdup(pu->parkingexten), ast_free_ptr, registrar))
502                         notify_metermaids(pu->parkingexten, parking_con, AST_DEVICE_INUSE);
503         }
504         if (pu->notquiteyet) {
505                 /* Wake up parking thread if we're really done */
506                 ast_indicate_data(pu->chan, AST_CONTROL_HOLD, 
507                         S_OR(parkmohclass, NULL),
508                         !ast_strlen_zero(parkmohclass) ? strlen(parkmohclass) + 1 : 0);
509                 pu->notquiteyet = 0;
510                 pthread_kill(parking_thread, SIGURG);
511         }
512         return 0;
513 }
514
515 /* Park call via masquraded channel */
516 int ast_masq_park_call(struct ast_channel *rchan, struct ast_channel *peer, int timeout, int *extout)
517 {
518         struct ast_channel *chan;
519         struct ast_frame *f;
520
521         /* Make a new, fake channel that we'll use to masquerade in the real one */
522         if (!(chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, rchan->accountcode, rchan->exten, rchan->context, rchan->amaflags, "Parked/%s",rchan->name))) {
523                 ast_log(LOG_WARNING, "Unable to create parked channel\n");
524                 return -1;
525         }
526
527         /* Make formats okay */
528         chan->readformat = rchan->readformat;
529         chan->writeformat = rchan->writeformat;
530         ast_channel_masquerade(chan, rchan);
531
532         /* Setup the extensions and such */
533         set_c_e_p(chan, rchan->context, rchan->exten, rchan->priority);
534
535         /* Make the masq execute */
536         f = ast_read(chan);
537         if (f)
538                 ast_frfree(f);
539
540         ast_park_call(chan, peer, timeout, extout);
541         return 0;
542 }
543
544
545 #define FEATURE_RETURN_HANGUP           -1
546 #define FEATURE_RETURN_SUCCESSBREAK      0
547 #define FEATURE_RETURN_PBX_KEEPALIVE    AST_PBX_KEEPALIVE
548 #define FEATURE_RETURN_NO_HANGUP_PEER   AST_PBX_NO_HANGUP_PEER
549 #define FEATURE_RETURN_PASSDIGITS        21
550 #define FEATURE_RETURN_STOREDIGITS       22
551 #define FEATURE_RETURN_SUCCESS           23
552 #define FEATURE_RETURN_KEEPTRYING    24
553
554 #define FEATURE_SENSE_CHAN      (1 << 0)
555 #define FEATURE_SENSE_PEER      (1 << 1)
556
557 /*! 
558  * \brief set caller and callee according to the direction 
559  * \param caller, callee, peer, chan, sense
560  *
561  * Detect who triggered feature and set callee/caller variables accordingly
562 */
563 static void set_peers(struct ast_channel **caller, struct ast_channel **callee,
564         struct ast_channel *peer, struct ast_channel *chan, int sense)
565 {
566         if (sense == FEATURE_SENSE_PEER) {
567                 *caller = peer;
568                 *callee = chan;
569         } else {
570                 *callee = peer;
571                 *caller = chan;
572         }
573 }
574
575 /*! 
576  * \brief support routing for one touch call parking
577  * \param chan channel parking call
578  * \param peer channel to be parked
579  * \param config unsed
580  * \param code unused
581  * \param sense feature options
582  *
583  * \param data
584  * Setup channel, set return exten,priority to 's,1'
585  * answer chan, sleep chan, park call
586 */
587 static int builtin_parkcall(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
588 {
589         struct ast_channel *parker;
590         struct ast_channel *parkee;
591         int res = 0;
592         struct ast_module_user *u;
593
594         u = ast_module_user_add(chan);
595
596         set_peers(&parker, &parkee, peer, chan, sense);
597         /* Setup the exten/priority to be s/1 since we don't know
598            where this call should return */
599         strcpy(chan->exten, "s");
600         chan->priority = 1;
601         if (chan->_state != AST_STATE_UP)
602                 res = ast_answer(chan);
603         if (!res)
604                 res = ast_safe_sleep(chan, 1000);
605         if (!res)
606                 res = ast_park_call(parkee, parker, 0, NULL);
607
608         ast_module_user_remove(u);
609
610         if (!res) {
611                 if (sense == FEATURE_SENSE_CHAN)
612                         res = AST_PBX_NO_HANGUP_PEER;
613                 else
614                         res = AST_PBX_KEEPALIVE;
615         }
616         return res;
617
618 }
619
620 /*!
621  * \brief Monitor a channel by DTMF
622  * \param chan channel requesting monitor
623  * \param peer channel to be monitored
624  * \param config
625  * \param code
626  * \param sense feature options
627  *
628  * \param data
629  * Check monitor app enabled, setup channels, both caller/callee chans not null
630  * get TOUCH_MONITOR variable for filename if exists, exec monitor app.
631  * \retval FEATURE_RETURN_SUCCESS on success.
632  * \retval -1 on error.
633 */
634 static int builtin_automonitor(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
635 {
636         char *caller_chan_id = NULL, *callee_chan_id = NULL, *args = NULL, *touch_filename = NULL;
637         int x = 0;
638         size_t len;
639         struct ast_channel *caller_chan, *callee_chan;
640
641         if (!monitor_ok) {
642                 ast_log(LOG_ERROR,"Cannot record the call. The monitor application is disabled.\n");
643                 return -1;
644         }
645
646         if (!monitor_app && !(monitor_app = pbx_findapp("Monitor"))) {
647                 monitor_ok = 0;
648                 ast_log(LOG_ERROR,"Cannot record the call. The monitor application is disabled.\n");
649                 return -1;
650         }
651
652         set_peers(&caller_chan, &callee_chan, peer, chan, sense);
653
654         if (!ast_strlen_zero(courtesytone)) {
655                 if (ast_autoservice_start(callee_chan))
656                         return -1;
657                 if (ast_stream_and_wait(caller_chan, courtesytone, "")) {
658                         ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
659                         ast_autoservice_stop(callee_chan);
660                         return -1;
661                 }
662                 if (ast_autoservice_stop(callee_chan))
663                         return -1;
664         }
665         
666         if (callee_chan->monitor) {
667                 ast_verb(4, "User hit '%s' to stop recording call.\n", code);
668                 ast_monitor_stop(callee_chan, 1);
669                 return FEATURE_RETURN_SUCCESS;
670         }
671
672         if (caller_chan && callee_chan) {
673                 const char *touch_format = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_FORMAT");
674                 const char *touch_monitor = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR");
675
676                 if (!touch_format)
677                         touch_format = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR_FORMAT");
678
679                 if (!touch_monitor)
680                         touch_monitor = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR");
681         
682                 if (touch_monitor) {
683                         len = strlen(touch_monitor) + 50;
684                         args = alloca(len);
685                         touch_filename = alloca(len);
686                         snprintf(touch_filename, len, "auto-%ld-%s", (long)time(NULL), touch_monitor);
687                         snprintf(args, len, "%s|%s|m", (touch_format) ? touch_format : "wav", touch_filename);
688                 } else {
689                         caller_chan_id = ast_strdupa(S_OR(caller_chan->cid.cid_num, caller_chan->name));
690                         callee_chan_id = ast_strdupa(S_OR(callee_chan->cid.cid_num, callee_chan->name));
691                         len = strlen(caller_chan_id) + strlen(callee_chan_id) + 50;
692                         args = alloca(len);
693                         touch_filename = alloca(len);
694                         snprintf(touch_filename, len, "auto-%ld-%s-%s", (long)time(NULL), caller_chan_id, callee_chan_id);
695                         snprintf(args, len, "%s|%s|m", S_OR(touch_format, "wav"), touch_filename);
696                 }
697
698                 for(x = 0; x < strlen(args); x++) {
699                         if (args[x] == '/')
700                                 args[x] = '-';
701                 }
702                 
703                 ast_verb(4, "User hit '%s' to record call. filename: %s\n", code, args);
704
705                 pbx_exec(callee_chan, monitor_app, args);
706                 pbx_builtin_setvar_helper(callee_chan, "TOUCH_MONITOR_OUTPUT", touch_filename);
707                 pbx_builtin_setvar_helper(caller_chan, "TOUCH_MONITOR_OUTPUT", touch_filename);
708         
709                 return FEATURE_RETURN_SUCCESS;
710         }
711         
712         ast_log(LOG_NOTICE,"Cannot record the call. One or both channels have gone away.\n");   
713         return -1;
714 }
715
716 static int builtin_disconnect(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
717 {
718         ast_verb(4, "User hit '%s' to disconnect call.\n", code);
719         return FEATURE_RETURN_HANGUP;
720 }
721
722 static int finishup(struct ast_channel *chan)
723 {
724         ast_indicate(chan, AST_CONTROL_UNHOLD);
725   
726         return ast_autoservice_stop(chan);
727 }
728
729 /*!
730  * \brief Find the context for the transfer
731  * \param transferer
732  * \param transferee
733  * 
734  * Grab the TRANSFER_CONTEXT, if fails try grabbing macrocontext.
735  * \return a context string
736 */
737 static const char *real_ctx(struct ast_channel *transferer, struct ast_channel *transferee)
738 {
739         const char *s = pbx_builtin_getvar_helper(transferer, "TRANSFER_CONTEXT");
740         if (ast_strlen_zero(s))
741                 s = pbx_builtin_getvar_helper(transferee, "TRANSFER_CONTEXT");
742         if (ast_strlen_zero(s)) /* Use the non-macro context to transfer the call XXX ? */
743                 s = transferer->macrocontext;
744         if (ast_strlen_zero(s))
745                 s = transferer->context;
746         return s;  
747 }
748
749 /*!
750  * \brief Blind transfer user to another extension
751  * \param chan channel to be transfered
752  * \param peer channel initiated blind transfer
753  * \param config
754  * \param code
755  * \param data
756  * \param sense  feature options
757  * 
758  * Place chan on hold, check if transferred to parkinglot extension,
759  * otherwise check extension exists and transfer caller.
760  * \retval FEATURE_RETURN_SUCCESS.
761  * \retval -1 on failure.
762 */
763 static int builtin_blindtransfer(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
764 {
765         struct ast_channel *transferer;
766         struct ast_channel *transferee;
767         const char *transferer_real_context;
768         char xferto[256];
769         int res;
770
771         set_peers(&transferer, &transferee, peer, chan, sense);
772         transferer_real_context = real_ctx(transferer, transferee);
773         /* Start autoservice on chan while we talk to the originator */
774         ast_autoservice_start(transferee);
775         ast_indicate(transferee, AST_CONTROL_HOLD);
776
777         memset(xferto, 0, sizeof(xferto));
778         
779         /* Transfer */
780         res = ast_stream_and_wait(transferer, "pbx-transfer", AST_DIGIT_ANY);
781         if (res < 0) {
782                 finishup(transferee);
783                 return -1; /* error ? */
784         }
785         if (res > 0)    /* If they've typed a digit already, handle it */
786                 xferto[0] = (char) res;
787
788         ast_stopstream(transferer);
789         res = ast_app_dtget(transferer, transferer_real_context, xferto, sizeof(xferto), 100, transferdigittimeout);
790         if (res < 0) {  /* hangup, would be 0 for invalid and 1 for valid */
791                 finishup(transferee);
792                 return res;
793         }
794         if (!strcmp(xferto, ast_parking_ext())) {
795                 res = finishup(transferee);
796                 if (res)
797                         res = -1;
798                 else if (!ast_park_call(transferee, transferer, 0, NULL)) {     /* success */
799                         /* We return non-zero, but tell the PBX not to hang the channel when
800                            the thread dies -- We have to be careful now though.  We are responsible for 
801                            hanging up the channel, else it will never be hung up! */
802
803                         return (transferer == peer) ? AST_PBX_KEEPALIVE : AST_PBX_NO_HANGUP_PEER;
804                 } else {
805                         ast_log(LOG_WARNING, "Unable to park call %s\n", transferee->name);
806                 }
807                 /*! \todo XXX Maybe we should have another message here instead of invalid extension XXX */
808         } else if (ast_exists_extension(transferee, transferer_real_context, xferto, 1, transferer->cid.cid_num)) {
809                 pbx_builtin_setvar_helper(peer, "BLINDTRANSFER", transferee->name);
810                 pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", peer->name);
811                 res=finishup(transferee);
812                 if (!transferer->cdr) {
813                         transferer->cdr=ast_cdr_alloc();
814                         if (transferer) {
815                                 ast_cdr_init(transferer->cdr, transferer); /* initilize our channel's cdr */
816                                 ast_cdr_start(transferer->cdr);
817                         }
818                 }
819                 if (transferer->cdr) {
820                         ast_cdr_setdestchan(transferer->cdr, transferee->name);
821                         ast_cdr_setapp(transferer->cdr, "BLINDTRANSFER","");
822                 }
823                 if (!transferee->pbx) {
824                         /* Doh!  Use our handy async_goto functions */
825                         if (option_verbose > 2) 
826                                 ast_verbose(VERBOSE_PREFIX_3 "Transferring %s to '%s' (context %s) priority 1\n"
827                                                                 ,transferee->name, xferto, transferer_real_context);
828                         if (ast_async_goto(transferee, transferer_real_context, xferto, 1))
829                                 ast_log(LOG_WARNING, "Async goto failed :-(\n");
830                 } else {
831                         /* Set the channel's new extension, since it exists, using transferer context */
832                         set_c_e_p(transferee, transferer_real_context, xferto, 0);
833                 }
834                 check_goto_on_transfer(transferer);
835                 return res;
836         } else {
837                 ast_verb(3, "Unable to find extension '%s' in context '%s'\n", xferto, transferer_real_context);
838         }
839         if (ast_stream_and_wait(transferer, xferfailsound, AST_DIGIT_ANY) < 0) {
840                 finishup(transferee);
841                 return -1;
842         }
843         ast_stopstream(transferer);
844         res = finishup(transferee);
845         if (res) {
846                 ast_verb(2, "Hungup during autoservice stop on '%s'\n", transferee->name);
847                 return res;
848         }
849         return FEATURE_RETURN_SUCCESS;
850 }
851
852 /*!
853  * \brief make channels compatible
854  * \param c
855  * \param newchan
856  * \retval 0 on success.
857  * \retval -1 on failure.
858 */
859 static int check_compat(struct ast_channel *c, struct ast_channel *newchan)
860 {
861         if (ast_channel_make_compatible(c, newchan) < 0) {
862                 ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n",
863                         c->name, newchan->name);
864                 ast_hangup(newchan);
865                 return -1;
866         }
867         return 0;
868 }
869
870 /*!
871  * \brief Attended transfer
872  * \param chan transfered user
873  * \param peer person transfering call
874  * \param config
875  * \param code
876  * \param sense feature options
877  * 
878  * \param data
879  * Get extension to transfer to, if you cannot generate channel (or find extension) 
880  * return to host channel. After called channel answered wait for hangup of transferer,
881  * bridge call between transfer peer (taking them off hold) to attended transfer channel.
882  *
883  * \return -1 on failure
884 */
885 static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
886 {
887         struct ast_channel *transferer;
888         struct ast_channel *transferee;
889         const char *transferer_real_context;
890         char xferto[256] = "";
891         char callbackto[256] = "";
892         int res;
893         int outstate=0;
894         struct ast_channel *newchan;
895         struct ast_channel *xferchan;
896         struct ast_bridge_thread_obj *tobj;
897         struct ast_bridge_config bconfig;
898         struct ast_frame *f;
899         int l;
900
901         ast_debug(1, "Executing Attended Transfer %s, %s (sense=%d) \n", chan->name, peer->name, sense);
902         set_peers(&transferer, &transferee, peer, chan, sense);
903         transferer_real_context = real_ctx(transferer, transferee);
904         /* Start autoservice on chan while we talk to the originator */
905         ast_autoservice_start(transferee);
906         ast_indicate(transferee, AST_CONTROL_HOLD);
907         
908         /* Transfer */
909         res = ast_stream_and_wait(transferer, "pbx-transfer", AST_DIGIT_ANY);
910         if (res < 0) {
911                 finishup(transferee);
912                 return res;
913         }
914         if (res > 0) /* If they've typed a digit already, handle it */
915                 xferto[0] = (char) res;
916
917         /* this is specific of atxfer */
918         res = ast_app_dtget(transferer, transferer_real_context, xferto, sizeof(xferto), 100, transferdigittimeout);
919         if (res < 0) {  /* hangup, would be 0 for invalid and 1 for valid */
920                 finishup(transferee);
921                 return res;
922         }
923         if (res == 0) {
924                 ast_log(LOG_WARNING, "Did not read data.\n");
925                 finishup(transferee);
926                 if (ast_stream_and_wait(transferer, "beeperr", ""))
927                         return -1;
928                 return FEATURE_RETURN_SUCCESS;
929         }
930
931         /* valid extension, res == 1 */
932         if (!ast_exists_extension(transferer, transferer_real_context, xferto, 1, transferer->cid.cid_num)) {
933                 ast_log(LOG_WARNING, "Extension %s does not exist in context %s\n",xferto,transferer_real_context);
934                 finishup(transferee);
935                 if (ast_stream_and_wait(transferer, "beeperr", ""))
936                         return -1;
937                 return FEATURE_RETURN_SUCCESS;
938         }
939
940         l = strlen(xferto);
941         snprintf(xferto + l, sizeof(xferto) - l, "@%s/n", transferer_real_context);     /* append context */
942         newchan = ast_feature_request_and_dial(transferer, transferee, "Local", ast_best_codec(transferer->nativeformats),
943                 xferto, atxfernoanswertimeout, &outstate, transferer->cid.cid_num, transferer->cid.cid_name, 1);
944
945         if (!ast_check_hangup(transferer)) {
946                 /* Transferer is up - old behaviour */
947                 ast_indicate(transferer, -1);
948                 if (!newchan) {
949                         finishup(transferee);
950                         /* any reason besides user requested cancel and busy triggers the failed sound */
951                         if (outstate != AST_CONTROL_UNHOLD && outstate != AST_CONTROL_BUSY &&
952                                 ast_stream_and_wait(transferer, xferfailsound, ""))
953                                 return -1;
954                         if (ast_stream_and_wait(transferer, xfersound, ""))
955                                 ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
956                         return FEATURE_RETURN_SUCCESS;
957                 }
958
959                 if (check_compat(transferer, newchan)) {
960                         /* we do mean transferee here, NOT transferer */
961                         finishup(transferee);
962                         return -1;
963                 }
964                 memset(&bconfig,0,sizeof(struct ast_bridge_config));
965                 ast_set_flag(&(bconfig.features_caller), AST_FEATURE_DISCONNECT);
966                 ast_set_flag(&(bconfig.features_callee), AST_FEATURE_DISCONNECT);
967                 res = ast_bridge_call(transferer, newchan, &bconfig);
968                 if (ast_check_hangup(newchan) || !ast_check_hangup(transferer)) {
969                         ast_hangup(newchan);
970                         if (ast_stream_and_wait(transferer, xfersound, ""))
971                                 ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
972                         finishup(transferee);
973                         transferer->_softhangup = 0;
974                         return FEATURE_RETURN_SUCCESS;
975                 }
976                 if (check_compat(transferee, newchan)) {
977                         finishup(transferee);
978                         return -1;
979                 }
980                 ast_indicate(transferee, AST_CONTROL_UNHOLD);
981
982                 if ((ast_autoservice_stop(transferee) < 0)
983                  || (ast_waitfordigit(transferee, 100) < 0)
984                  || (ast_waitfordigit(newchan, 100) < 0)
985                  || ast_check_hangup(transferee)
986                  || ast_check_hangup(newchan)) {
987                         ast_hangup(newchan);
988                         return -1;
989                 }
990                 xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Transfered/%s", transferee->name);
991                 if (!xferchan) {
992                         ast_hangup(newchan);
993                         return -1;
994                 }
995                 /* Make formats okay */
996                 xferchan->readformat = transferee->readformat;
997                 xferchan->writeformat = transferee->writeformat;
998                 ast_channel_masquerade(xferchan, transferee);
999                 ast_explicit_goto(xferchan, transferee->context, transferee->exten, transferee->priority);
1000                 xferchan->_state = AST_STATE_UP;
1001                 ast_clear_flag(xferchan, AST_FLAGS_ALL);
1002                 xferchan->_softhangup = 0;
1003                 if ((f = ast_read(xferchan)))
1004                         ast_frfree(f);
1005                 newchan->_state = AST_STATE_UP;
1006                 ast_clear_flag(newchan, AST_FLAGS_ALL);
1007                 newchan->_softhangup = 0;
1008                 if (!(tobj = ast_calloc(1, sizeof(*tobj)))) {
1009                         ast_hangup(xferchan);
1010                         ast_hangup(newchan);
1011                         return -1;
1012                 }
1013                 tobj->chan = xferchan;
1014                 tobj->peer = newchan;
1015                 tobj->bconfig = *config;
1016
1017                 if (ast_stream_and_wait(newchan, xfersound, ""))
1018                         ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
1019                 ast_bridge_call_thread_launch(tobj);
1020                 return -1;      /* XXX meaning the channel is bridged ? */
1021         } else if (!ast_check_hangup(transferee)) {
1022                 /* act as blind transfer */
1023                 if (ast_autoservice_stop(transferee) < 0) {
1024                         ast_hangup(newchan);
1025                         return -1;
1026                 }
1027
1028                 if (!newchan) {
1029                         unsigned int tries = 0;
1030
1031                         /* newchan wasn't created - we should callback to transferer */
1032                         if (!ast_exists_extension(transferer, transferer_real_context, transferer->cid.cid_num, 1, transferee->cid.cid_num)) {
1033                                 ast_log(LOG_WARNING, "Extension %s does not exist in context %s - callback failed\n",transferer->cid.cid_num,transferer_real_context);
1034                                 if (ast_stream_and_wait(transferee, "beeperr", ""))
1035                                         return -1;
1036                                 return FEATURE_RETURN_SUCCESS;
1037                         }
1038                         snprintf(callbackto, sizeof(callbackto), "%s@%s/n", transferer->cid.cid_num, transferer_real_context);  /* append context */
1039
1040                         newchan = ast_feature_request_and_dial(transferee, NULL, "Local", ast_best_codec(transferee->nativeformats),
1041                                 callbackto, atxfernoanswertimeout, &outstate, transferee->cid.cid_num, transferee->cid.cid_name, 0);
1042                         while (!newchan && !atxferdropcall && tries < atxfercallbackretries) {
1043                                 /* Trying to transfer again */
1044                                 ast_autoservice_start(transferee);
1045                                 ast_indicate(transferee, AST_CONTROL_HOLD);
1046
1047                                 newchan = ast_feature_request_and_dial(transferer, transferee, "Local", ast_best_codec(transferer->nativeformats),
1048                                 xferto, atxfernoanswertimeout, &outstate, transferer->cid.cid_num, transferer->cid.cid_name, 1);
1049                                 if (ast_autoservice_stop(transferee) < 0) {
1050                                         if (newchan)
1051                                                 ast_hangup(newchan);
1052                                         return -1;
1053                                 }
1054                                 if (!newchan) {
1055                                         /* Transfer failed, sleeping */
1056                                         ast_debug(1, "Sleeping for %d ms before callback.\n", atxferloopdelay);
1057                                         ast_safe_sleep(transferee, atxferloopdelay);
1058                                         ast_debug(1, "Trying to callback...\n");
1059                                         newchan = ast_feature_request_and_dial(transferee, NULL, "Local", ast_best_codec(transferee->nativeformats),
1060                                                 callbackto, atxfernoanswertimeout, &outstate, transferee->cid.cid_num, transferee->cid.cid_name, 0);
1061                                 }
1062                                 tries++;
1063                         }
1064                 }
1065                 if (!newchan)
1066                         return -1;
1067
1068                 /* newchan is up, we should prepare transferee and bridge them */
1069                 if (check_compat(transferee, newchan)) {
1070                         finishup(transferee);
1071                         return -1;
1072                 }
1073                 ast_indicate(transferee, AST_CONTROL_UNHOLD);
1074
1075                 if ((ast_waitfordigit(transferee, 100) < 0)
1076                    || (ast_waitfordigit(newchan, 100) < 0)
1077                    || ast_check_hangup(transferee)
1078                    || ast_check_hangup(newchan)) {
1079                         ast_hangup(newchan);
1080                         return -1;
1081                 }
1082
1083                 xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Transfered/%s", transferee->name);
1084                 if (!xferchan) {
1085                         ast_hangup(newchan);
1086                         return -1;
1087                 }
1088                 /* Make formats okay */
1089                 xferchan->readformat = transferee->readformat;
1090                 xferchan->writeformat = transferee->writeformat;
1091                 ast_channel_masquerade(xferchan, transferee);
1092                 ast_explicit_goto(xferchan, transferee->context, transferee->exten, transferee->priority);
1093                 xferchan->_state = AST_STATE_UP;
1094                 ast_clear_flag(xferchan, AST_FLAGS_ALL);
1095                 xferchan->_softhangup = 0;
1096                 if ((f = ast_read(xferchan)))
1097                         ast_frfree(f);
1098                 newchan->_state = AST_STATE_UP;
1099                 ast_clear_flag(newchan, AST_FLAGS_ALL);
1100                 newchan->_softhangup = 0;
1101                 if (!(tobj = ast_calloc(1, sizeof(*tobj)))) {
1102                         ast_hangup(xferchan);
1103                         ast_hangup(newchan);
1104                         return -1;
1105                 }
1106                 tobj->chan = xferchan;
1107                 tobj->peer = newchan;
1108                 tobj->bconfig = *config;
1109
1110                 if (ast_stream_and_wait(newchan, xfersound, ""))
1111                         ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
1112                 ast_bridge_call_thread_launch(tobj);
1113                 return -1;      /* XXX meaning the channel is bridged ? */
1114         } else {
1115                 /* Transferee hung up */
1116                 finishup(transferee);
1117                 return -1;
1118         }
1119 }
1120
1121 /* add atxfer and automon as undefined so you can only use em if you configure them */
1122 #define FEATURES_COUNT ARRAY_LEN(builtin_features)
1123
1124 AST_RWLOCK_DEFINE_STATIC(features_lock);
1125
1126 static struct ast_call_feature builtin_features[] = 
1127 {
1128         { AST_FEATURE_REDIRECT, "Blind Transfer", "blindxfer", "#", "#", builtin_blindtransfer, AST_FEATURE_FLAG_NEEDSDTMF, "" },
1129         { AST_FEATURE_REDIRECT, "Attended Transfer", "atxfer", "", "", builtin_atxfer, AST_FEATURE_FLAG_NEEDSDTMF, "" },
1130         { AST_FEATURE_AUTOMON, "One Touch Monitor", "automon", "", "", builtin_automonitor, AST_FEATURE_FLAG_NEEDSDTMF, "" },
1131         { AST_FEATURE_DISCONNECT, "Disconnect Call", "disconnect", "*", "*", builtin_disconnect, AST_FEATURE_FLAG_NEEDSDTMF, "" },
1132         { AST_FEATURE_PARKCALL, "Park Call", "parkcall", "", "", builtin_parkcall, AST_FEATURE_FLAG_NEEDSDTMF, "" },
1133 };
1134
1135
1136 static AST_LIST_HEAD_STATIC(feature_list,ast_call_feature);
1137
1138 /*! \brief register new feature into feature_list*/
1139 void ast_register_feature(struct ast_call_feature *feature)
1140 {
1141         if (!feature) {
1142                 ast_log(LOG_NOTICE,"You didn't pass a feature!\n");
1143                 return;
1144         }
1145   
1146         AST_LIST_LOCK(&feature_list);
1147         AST_LIST_INSERT_HEAD(&feature_list,feature,feature_entry);
1148         AST_LIST_UNLOCK(&feature_list);
1149
1150         ast_verb(2, "Registered Feature '%s'\n",feature->sname);
1151 }
1152
1153 /*! 
1154  * \brief Add new feature group
1155  * \param fgname feature group name.
1156  *
1157  * Add new feature group to the feature group list insert at head of list.
1158  * \note This function MUST be called while feature_groups is locked.
1159 */
1160 static struct feature_group* register_group(const char *fgname)
1161 {
1162         struct feature_group *fg;
1163
1164         if (!fgname) {
1165                 ast_log(LOG_NOTICE, "You didn't pass a new group name!\n");
1166                 return NULL;
1167         }
1168
1169         if (!(fg = ast_calloc(1, sizeof(*fg))))
1170                 return NULL;
1171
1172         if (ast_string_field_init(fg, 128)) {
1173                 ast_free(fg);
1174                 return NULL;
1175         }
1176
1177         ast_string_field_set(fg, gname, fgname);
1178
1179         AST_LIST_INSERT_HEAD(&feature_groups, fg, entry);
1180
1181         ast_verb(2, "Registered group '%s'\n", fg->gname);
1182
1183         return fg;
1184 }
1185
1186 /*! 
1187  * \brief Add feature to group
1188  * \param fg feature group
1189  * \param exten
1190  * \param feature feature to add.
1191  *
1192  * Check fg and feature specified, add feature to list
1193  * \note This function MUST be called while feature_groups is locked. 
1194 */
1195 static void register_group_feature(struct feature_group *fg, const char *exten, struct ast_call_feature *feature) 
1196 {
1197         struct feature_group_exten *fge;
1198
1199         if (!(fge = ast_calloc(1, sizeof(*fge))))
1200                 return;
1201
1202         if (ast_string_field_init(fge, 128)) {
1203                 ast_free(fge);
1204                 return;
1205         }
1206
1207         if (!fg) {
1208                 ast_log(LOG_NOTICE, "You didn't pass a group!\n");
1209                 return;
1210         }
1211
1212         if (!feature) {
1213                 ast_log(LOG_NOTICE, "You didn't pass a feature!\n");
1214                 return;
1215         }
1216
1217         ast_string_field_set(fge, exten, (ast_strlen_zero(exten) ? feature->exten : exten));
1218
1219         fge->feature = feature;
1220
1221         AST_LIST_INSERT_HEAD(&fg->features, fge, entry);                
1222
1223         ast_verb(2, "Registered feature '%s' for group '%s' at exten '%s'\n",
1224                                         feature->sname, fg->gname, exten);
1225 }
1226
1227 void ast_unregister_feature(struct ast_call_feature *feature)
1228 {
1229         if (!feature)
1230                 return;
1231
1232         AST_LIST_LOCK(&feature_list);
1233         AST_LIST_REMOVE(&feature_list,feature,feature_entry);
1234         AST_LIST_UNLOCK(&feature_list);
1235         ast_free(feature);
1236 }
1237
1238 /*! \brief Remove all features in the list */
1239 static void ast_unregister_features(void)
1240 {
1241         struct ast_call_feature *feature;
1242
1243         AST_LIST_LOCK(&feature_list);
1244         while ((feature = AST_LIST_REMOVE_HEAD(&feature_list,feature_entry)))
1245                 ast_free(feature);
1246         AST_LIST_UNLOCK(&feature_list);
1247 }
1248
1249 /*! \brief find a call feature by name */
1250 static struct ast_call_feature *find_dynamic_feature(const char *name)
1251 {
1252         struct ast_call_feature *tmp;
1253
1254         AST_LIST_TRAVERSE(&feature_list, tmp, feature_entry) {
1255                 if (!strcasecmp(tmp->sname, name))
1256                         break;
1257         }
1258
1259         return tmp;
1260 }
1261
1262 /*! \brief Remove all feature groups in the list */
1263 static void ast_unregister_groups(void)
1264 {
1265         struct feature_group *fg;
1266         struct feature_group_exten *fge;
1267
1268         AST_RWLIST_WRLOCK(&feature_groups);
1269         while ((fg = AST_LIST_REMOVE_HEAD(&feature_groups, entry))) {
1270                 while ((fge = AST_LIST_REMOVE_HEAD(&fg->features, entry))) {
1271                         ast_string_field_free_all(fge);
1272                         ast_free(fge);
1273                 }
1274
1275                 ast_string_field_free_all(fg);
1276                 ast_free(fg);
1277         }
1278         AST_RWLIST_UNLOCK(&feature_groups);
1279 }
1280
1281 /*! 
1282  * \brief Find a group by name 
1283  * \param name feature name
1284  * \retval feature group on success.
1285  * \retval NULL on failure.
1286 */
1287 static struct feature_group *find_group(const char *name) {
1288         struct feature_group *fg = NULL;
1289
1290         AST_LIST_TRAVERSE(&feature_groups, fg, entry) {
1291                 if (!strcasecmp(fg->gname, name))
1292                         break;
1293         }
1294
1295         return fg;
1296 }
1297
1298 void ast_rdlock_call_features(void)
1299 {
1300         ast_rwlock_rdlock(&features_lock);
1301 }
1302
1303 void ast_unlock_call_features(void)
1304 {
1305         ast_rwlock_unlock(&features_lock);
1306 }
1307
1308 struct ast_call_feature *ast_find_call_feature(const char *name)
1309 {
1310         int x;
1311         for (x = 0; x < FEATURES_COUNT; x++) {
1312                 if (!strcasecmp(name, builtin_features[x].sname))
1313                         return &builtin_features[x];
1314         }
1315         return NULL;
1316 }
1317
1318 /*!
1319  * \brief exec an app by feature 
1320  * \param chan,peer,config,code,sense,data
1321  *
1322  * Find a feature, determine which channel activated
1323  * \retval FEATURE_RETURN_PBX_KEEPALIVE,FEATURE_RETURN_NO_HANGUP_PEER
1324  * \retval -1 error.
1325  * \retval -2 when an application cannot be found.
1326 */
1327 static int feature_exec_app(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
1328 {
1329         struct ast_app *app;
1330         struct ast_call_feature *feature = data;
1331         struct ast_channel *work, *idle;
1332         int res;
1333
1334         if (!feature) { /* shouldn't ever happen! */
1335                 ast_log(LOG_NOTICE, "Found feature before, but at execing we've lost it??\n");
1336                 return -1; 
1337         }
1338
1339         if (sense == FEATURE_SENSE_CHAN) {
1340                 if (!ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLER))
1341                         return FEATURE_RETURN_KEEPTRYING;
1342                 if (ast_test_flag(feature, AST_FEATURE_FLAG_ONSELF)) {
1343                         work = chan;
1344                         idle = peer;
1345                 } else {
1346                         work = peer;
1347                         idle = chan;
1348                 }
1349         } else {
1350                 if (!ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLEE))
1351                         return FEATURE_RETURN_KEEPTRYING;
1352                 if (ast_test_flag(feature, AST_FEATURE_FLAG_ONSELF)) {
1353                         work = peer;
1354                         idle = chan;
1355                 } else {
1356                         work = chan;
1357                         idle = peer;
1358                 }
1359         }
1360
1361         if (!(app = pbx_findapp(feature->app))) {
1362                 ast_log(LOG_WARNING, "Could not find application (%s)\n", feature->app);
1363                 return -2;
1364         }
1365
1366         ast_autoservice_start(idle);
1367         
1368         if (!ast_strlen_zero(feature->moh_class))
1369                 ast_moh_start(idle, feature->moh_class, NULL);
1370
1371         res = pbx_exec(work, app, feature->app_args);
1372
1373         if (!ast_strlen_zero(feature->moh_class))
1374                 ast_moh_stop(idle);
1375
1376         ast_autoservice_stop(idle);
1377
1378         if (res == AST_PBX_KEEPALIVE)
1379                 return FEATURE_RETURN_PBX_KEEPALIVE;
1380         else if (res == AST_PBX_NO_HANGUP_PEER)
1381                 return FEATURE_RETURN_NO_HANGUP_PEER;
1382         else if (res)
1383                 return FEATURE_RETURN_SUCCESSBREAK;
1384         
1385         return FEATURE_RETURN_SUCCESS;  /*! \todo XXX should probably return res */
1386 }
1387
1388 static void unmap_features(void)
1389 {
1390         int x;
1391
1392         ast_rwlock_wrlock(&features_lock);
1393         for (x = 0; x < FEATURES_COUNT; x++)
1394                 strcpy(builtin_features[x].exten, builtin_features[x].default_exten);
1395         ast_rwlock_unlock(&features_lock);
1396 }
1397
1398 static int remap_feature(const char *name, const char *value)
1399 {
1400         int x, res = -1;
1401
1402         ast_rwlock_wrlock(&features_lock);
1403         for (x = 0; x < FEATURES_COUNT; x++) {
1404                 if (strcasecmp(builtin_features[x].sname, name))
1405                         continue;
1406
1407                 ast_copy_string(builtin_features[x].exten, value, sizeof(builtin_features[x].exten));
1408                 res = 0;
1409                 break;
1410         }
1411         ast_rwlock_unlock(&features_lock);
1412
1413         return res;
1414 }
1415
1416 /*!
1417  * \brief Check the dynamic features
1418  * \param chan,peer,config,code,sense
1419  *
1420  * Lock features list, browse for code, unlock list
1421  * \retval res on success.
1422  * \retval -1 on failure.
1423 */
1424 static int ast_feature_interpret(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense)
1425 {
1426         int x;
1427         struct ast_flags features;
1428         int res = FEATURE_RETURN_PASSDIGITS;
1429         struct ast_call_feature *feature;
1430         struct feature_group *fg = NULL;
1431         struct feature_group_exten *fge;
1432         const char *dynamic_features=pbx_builtin_getvar_helper(chan,"DYNAMIC_FEATURES");
1433         char *tmp, *tok;
1434
1435         if (sense == FEATURE_SENSE_CHAN)
1436                 ast_copy_flags(&features, &(config->features_caller), AST_FLAGS_ALL);
1437         else
1438                 ast_copy_flags(&features, &(config->features_callee), AST_FLAGS_ALL);
1439         ast_debug(3, "Feature interpret: chan=%s, peer=%s, sense=%d, features=%d\n", chan->name, peer->name, sense, features.flags);
1440
1441         ast_rwlock_rdlock(&features_lock);
1442         for (x = 0; x < FEATURES_COUNT; x++) {
1443                 if ((ast_test_flag(&features, builtin_features[x].feature_mask)) &&
1444                     !ast_strlen_zero(builtin_features[x].exten)) {
1445                         /* Feature is up for consideration */
1446                         if (!strcmp(builtin_features[x].exten, code)) {
1447                                 res = builtin_features[x].operation(chan, peer, config, code, sense, NULL);
1448                                 break;
1449                         } else if (!strncmp(builtin_features[x].exten, code, strlen(code))) {
1450                                 if (res == FEATURE_RETURN_PASSDIGITS)
1451                                         res = FEATURE_RETURN_STOREDIGITS;
1452                         }
1453                 }
1454         }
1455         ast_rwlock_unlock(&features_lock);
1456
1457         if (ast_strlen_zero(dynamic_features))
1458                 return res;
1459
1460         tmp = ast_strdupa(dynamic_features);
1461
1462         while ((tok = strsep(&tmp, "#"))) {
1463                 AST_RWLIST_RDLOCK(&feature_groups);
1464
1465                 fg = find_group(tok);
1466
1467                 if (fg) {
1468                         AST_LIST_TRAVERSE(&fg->features, fge, entry) {
1469                                 if (strcasecmp(fge->exten, code))
1470                                         continue;
1471
1472                                 res = fge->feature->operation(chan, peer, config, code, sense, fge->feature);
1473                                 if (res != FEATURE_RETURN_KEEPTRYING) {
1474                                         AST_RWLIST_UNLOCK(&feature_groups);
1475                                         break;
1476                                 }
1477                                 res = FEATURE_RETURN_PASSDIGITS;
1478                         }
1479                         if (fge)
1480                                 break;
1481                 }
1482
1483                 AST_RWLIST_UNLOCK(&feature_groups);
1484                 AST_LIST_LOCK(&feature_list);
1485
1486                 if(!(feature = find_dynamic_feature(tok))) {
1487                         AST_LIST_UNLOCK(&feature_list);
1488                         continue;
1489                 }
1490                         
1491                 /* Feature is up for consideration */
1492                 if (!strcmp(feature->exten, code)) {
1493                         ast_verb(3, " Feature Found: %s exten: %s\n",feature->sname, tok);
1494                         res = feature->operation(chan, peer, config, code, sense, feature);
1495                         if (res != FEATURE_RETURN_KEEPTRYING) {
1496                                 AST_LIST_UNLOCK(&feature_list);
1497                                 break;
1498                         }
1499                         res = FEATURE_RETURN_PASSDIGITS;
1500                 } else if (!strncmp(feature->exten, code, strlen(code)))
1501                         res = FEATURE_RETURN_STOREDIGITS;
1502
1503                 AST_LIST_UNLOCK(&feature_list);
1504         }
1505         
1506         return res;
1507 }
1508
1509 static void set_config_flags(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config)
1510 {
1511         int x;
1512         
1513         ast_clear_flag(config, AST_FLAGS_ALL);
1514
1515         ast_rwlock_rdlock(&features_lock);
1516         for (x = 0; x < FEATURES_COUNT; x++) {
1517                 if (!ast_test_flag(builtin_features + x, AST_FEATURE_FLAG_NEEDSDTMF))
1518                         continue;
1519
1520                 if (ast_test_flag(&(config->features_caller), builtin_features[x].feature_mask))
1521                         ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
1522
1523                 if (ast_test_flag(&(config->features_callee), builtin_features[x].feature_mask))
1524                         ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
1525         }
1526         ast_rwlock_unlock(&features_lock);
1527         
1528         if (chan && peer && !(ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_0) && ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_1))) {
1529                 const char *dynamic_features = pbx_builtin_getvar_helper(chan, "DYNAMIC_FEATURES");
1530
1531                 if (dynamic_features) {
1532                         char *tmp = ast_strdupa(dynamic_features);
1533                         char *tok;
1534                         struct ast_call_feature *feature;
1535
1536                         /* while we have a feature */
1537                         while ((tok = strsep(&tmp, "#"))) {
1538                                 AST_LIST_LOCK(&feature_list);
1539                                 if ((feature = find_dynamic_feature(tok)) && ast_test_flag(feature, AST_FEATURE_FLAG_NEEDSDTMF)) {
1540                                         if (ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLER))
1541                                                 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
1542                                         if (ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLEE))
1543                                                 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
1544                                 }
1545                                 AST_LIST_UNLOCK(&feature_list);
1546                         }
1547                 }
1548         }
1549 }
1550
1551 /*! 
1552  * \brief Get feature and dial
1553  * \param caller,transferee,type,format,data,timeout,outstate,cid_num,cid_name,igncallerstate
1554  *
1555  * Request channel, set channel variables, initiate call,check if they want to disconnect
1556  * go into loop, check if timeout has elapsed, check if person to be transfered hung up,
1557  * check for answer break loop, set cdr return channel.
1558  *
1559  * \todo XXX Check - this is very similar to the code in channel.c 
1560  * \return always a channel
1561 */
1562 static struct ast_channel *ast_feature_request_and_dial(struct ast_channel *caller, struct ast_channel *transferee, const char *type, int format, void *data, int timeout, int *outstate, const char *cid_num, const char *cid_name, int igncallerstate)
1563 {
1564         int state = 0;
1565         int cause = 0;
1566         int to;
1567         struct ast_channel *chan;
1568         struct ast_channel *monitor_chans[2];
1569         struct ast_channel *active_channel;
1570         int res = 0, ready = 0;
1571         
1572         if ((chan = ast_request(type, format, data, &cause))) {
1573                 ast_set_callerid(chan, cid_num, cid_name, cid_num);
1574                 ast_channel_inherit_variables(caller, chan);    
1575                 pbx_builtin_setvar_helper(chan, "TRANSFERERNAME", caller->name);
1576                 if (!chan->cdr) {
1577                         chan->cdr=ast_cdr_alloc();
1578                         if (chan->cdr) {
1579                                 ast_cdr_init(chan->cdr, chan); /* initilize our channel's cdr */
1580                                 ast_cdr_start(chan->cdr);
1581                         }
1582                 }
1583                         
1584                 if (!ast_call(chan, data, timeout)) {
1585                         struct timeval started;
1586                         int x, len = 0;
1587                         char *disconnect_code = NULL, *dialed_code = NULL;
1588
1589                         ast_indicate(caller, AST_CONTROL_RINGING);
1590                         /* support dialing of the featuremap disconnect code while performing an attended tranfer */
1591                         ast_rwlock_rdlock(&features_lock);
1592                         for (x = 0; x < FEATURES_COUNT; x++) {
1593                                 if (strcasecmp(builtin_features[x].sname, "disconnect"))
1594                                         continue;
1595
1596                                 disconnect_code = builtin_features[x].exten;
1597                                 len = strlen(disconnect_code) + 1;
1598                                 dialed_code = alloca(len);
1599                                 memset(dialed_code, 0, len);
1600                                 break;
1601                         }
1602                         ast_rwlock_unlock(&features_lock);
1603                         x = 0;
1604                         started = ast_tvnow();
1605                         to = timeout;
1606
1607                         ast_poll_channel_add(caller, chan);
1608
1609                         while (!((transferee && ast_check_hangup(transferee)) && (!igncallerstate && ast_check_hangup(caller))) && timeout && (chan->_state != AST_STATE_UP)) {
1610                                 struct ast_frame *f = NULL;
1611
1612                                 monitor_chans[0] = caller;
1613                                 monitor_chans[1] = chan;
1614                                 active_channel = ast_waitfor_n(monitor_chans, 2, &to);
1615
1616                                 /* see if the timeout has been violated */
1617                                 if(ast_tvdiff_ms(ast_tvnow(), started) > timeout) {
1618                                         state = AST_CONTROL_UNHOLD;
1619                                         ast_log(LOG_NOTICE, "We exceeded our AT-timeout\n");
1620                                         break; /*doh! timeout*/
1621                                 }
1622
1623                                 if (!active_channel)
1624                                         continue;
1625
1626                                 if (chan && (chan == active_channel)){
1627                                         f = ast_read(chan);
1628                                         if (f == NULL) { /*doh! where'd he go?*/
1629                                                 state = AST_CONTROL_HANGUP;
1630                                                 res = 0;
1631                                                 break;
1632                                         }
1633                                         
1634                                         if (f->frametype == AST_FRAME_CONTROL || f->frametype == AST_FRAME_DTMF || f->frametype == AST_FRAME_TEXT) {
1635                                                 if (f->subclass == AST_CONTROL_RINGING) {
1636                                                         state = f->subclass;
1637                                                         ast_verb(3, "%s is ringing\n", chan->name);
1638                                                         ast_indicate(caller, AST_CONTROL_RINGING);
1639                                                 } else if ((f->subclass == AST_CONTROL_BUSY) || (f->subclass == AST_CONTROL_CONGESTION)) {
1640                                                         state = f->subclass;
1641                                                         ast_verb(3, "%s is busy\n", chan->name);
1642                                                         ast_indicate(caller, AST_CONTROL_BUSY);
1643                                                         ast_frfree(f);
1644                                                         f = NULL;
1645                                                         break;
1646                                                 } else if (f->subclass == AST_CONTROL_ANSWER) {
1647                                                         /* This is what we are hoping for */
1648                                                         state = f->subclass;
1649                                                         ast_frfree(f);
1650                                                         f = NULL;
1651                                                         ready=1;
1652                                                         break;
1653                                                 } else if (f->subclass != -1) {
1654                                                         ast_log(LOG_NOTICE, "Don't know what to do about control frame: %d\n", f->subclass);
1655                                                 }
1656                                                 /* else who cares */
1657                                         }
1658
1659                                 } else if (caller && (active_channel == caller)) {
1660                                         f = ast_read(caller);
1661                                         if (f == NULL) { /*doh! where'd he go?*/
1662                                                 if (!igncallerstate) {
1663                                                         if (ast_check_hangup(caller) && !ast_check_hangup(chan)) {
1664                                                                 /* make this a blind transfer */
1665                                                                 ready = 1;
1666                                                                 break;
1667                                                         }
1668                                                         state = AST_CONTROL_HANGUP;
1669                                                         res = 0;
1670                                                         break;
1671                                                 }
1672                                         } else {
1673                                         
1674                                                 if (f->frametype == AST_FRAME_DTMF) {
1675                                                         dialed_code[x++] = f->subclass;
1676                                                         dialed_code[x] = '\0';
1677                                                         if (strlen(dialed_code) == len) {
1678                                                                 x = 0;
1679                                                         } else if (x && strncmp(dialed_code, disconnect_code, x)) {
1680                                                                 x = 0;
1681                                                                 dialed_code[x] = '\0';
1682                                                         }
1683                                                         if (*dialed_code && !strcmp(dialed_code, disconnect_code)) {
1684                                                                 /* Caller Canceled the call */
1685                                                                 state = AST_CONTROL_UNHOLD;
1686                                                                 ast_frfree(f);
1687                                                                 f = NULL;
1688                                                                 break;
1689                                                         }
1690                                                 }
1691                                         }
1692                                 }
1693                                 if (f)
1694                                         ast_frfree(f);
1695                         } /* end while */
1696
1697                         ast_poll_channel_del(caller, chan);
1698
1699                 } else
1700                         ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
1701         } else {
1702                 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
1703                 switch(cause) {
1704                 case AST_CAUSE_BUSY:
1705                         state = AST_CONTROL_BUSY;
1706                         break;
1707                 case AST_CAUSE_CONGESTION:
1708                         state = AST_CONTROL_CONGESTION;
1709                         break;
1710                 }
1711         }
1712         
1713         ast_indicate(caller, -1);
1714         if (chan && ready) {
1715                 if (chan->_state == AST_STATE_UP) 
1716                         state = AST_CONTROL_ANSWER;
1717                 res = 0;
1718         } else if(chan) {
1719                 res = -1;
1720                 ast_hangup(chan);
1721                 chan = NULL;
1722         } else {
1723                 res = -1;
1724         }
1725         
1726         if (outstate)
1727                 *outstate = state;
1728
1729         if (chan && res <= 0) {
1730                 if (chan->cdr || (chan->cdr = ast_cdr_alloc())) {
1731                         char tmp[256];
1732                         ast_cdr_init(chan->cdr, chan);
1733                         snprintf(tmp, 256, "%s/%s", type, (char *)data);
1734                         ast_cdr_setapp(chan->cdr,"Dial",tmp);
1735                         ast_cdr_update(chan);
1736                         ast_cdr_start(chan->cdr);
1737                         ast_cdr_end(chan->cdr);
1738                         /* If the cause wasn't handled properly */
1739                         if (ast_cdr_disposition(chan->cdr,chan->hangupcause))
1740                                 ast_cdr_failed(chan->cdr);
1741                 } else {
1742                         ast_log(LOG_WARNING, "Unable to create Call Detail Record\n");
1743                 }
1744         }
1745         
1746         return chan;
1747 }
1748
1749 /*!
1750  * \brief bridge the call and set CDR
1751  * \param chan,peer,config
1752  * 
1753  * Set start time, check for two channels,check if monitor on
1754  * check for feature activation, create new CDR
1755  * \retval res on success.
1756  * \retval -1 on failure to bridge.
1757 */
1758 int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast_bridge_config *config)
1759 {
1760         /* Copy voice back and forth between the two channels.  Give the peer
1761            the ability to transfer calls with '#<extension' syntax. */
1762         struct ast_frame *f;
1763         struct ast_channel *who;
1764         char chan_featurecode[FEATURE_MAX_LEN + 1]="";
1765         char peer_featurecode[FEATURE_MAX_LEN + 1]="";
1766         int res;
1767         int diff;
1768         int hasfeatures=0;
1769         int hadfeatures=0;
1770         struct ast_option_header *aoh;
1771         struct ast_bridge_config backup_config;
1772         struct ast_cdr *bridge_cdr;
1773
1774         memset(&backup_config, 0, sizeof(backup_config));
1775
1776         config->start_time = ast_tvnow();
1777
1778         if (chan && peer) {
1779                 pbx_builtin_setvar_helper(chan, "BRIDGEPEER", peer->name);
1780                 pbx_builtin_setvar_helper(peer, "BRIDGEPEER", chan->name);
1781         } else if (chan)
1782                 pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", NULL);
1783
1784         if (monitor_ok) {
1785                 const char *monitor_exec;
1786                 struct ast_channel *src = NULL;
1787                 if (!monitor_app) { 
1788                         if (!(monitor_app = pbx_findapp("Monitor")))
1789                                 monitor_ok=0;
1790                 }
1791                 if ((monitor_exec = pbx_builtin_getvar_helper(chan, "AUTO_MONITOR"))) 
1792                         src = chan;
1793                 else if ((monitor_exec = pbx_builtin_getvar_helper(peer, "AUTO_MONITOR")))
1794                         src = peer;
1795                 if (monitor_app && src) {
1796                         char *tmp = ast_strdupa(monitor_exec);
1797                         pbx_exec(src, monitor_app, tmp);
1798                 }
1799         }
1800         
1801         set_config_flags(chan, peer, config);
1802         config->firstpass = 1;
1803
1804         /* Answer if need be */
1805         if (ast_answer(chan))
1806                 return -1;
1807         peer->appl = "Bridged Call";
1808         peer->data = chan->name;
1809
1810         /* copy the userfield from the B-leg to A-leg if applicable */
1811         if (chan->cdr && peer->cdr && !ast_strlen_zero(peer->cdr->userfield)) {
1812                 char tmp[256];
1813                 if (!ast_strlen_zero(chan->cdr->userfield)) {
1814                         snprintf(tmp, sizeof(tmp), "%s;%s", chan->cdr->userfield, peer->cdr->userfield);
1815                         ast_cdr_appenduserfield(chan, tmp);
1816                 } else
1817                         ast_cdr_setuserfield(chan, peer->cdr->userfield);
1818                 /* free the peer's cdr without ast_cdr_free complaining */
1819                 ast_free(peer->cdr);
1820                 peer->cdr = NULL;
1821         }
1822
1823         for (;;) {
1824                 struct ast_channel *other;      /* used later */
1825
1826                 res = ast_channel_bridge(chan, peer, config, &f, &who);
1827
1828                 if (config->feature_timer) {
1829                         /* Update time limit for next pass */
1830                         diff = ast_tvdiff_ms(ast_tvnow(), config->start_time);
1831                         config->feature_timer -= diff;
1832                         if (hasfeatures) {
1833                                 /* Running on backup config, meaning a feature might be being
1834                                    activated, but that's no excuse to keep things going 
1835                                    indefinitely! */
1836                                 if (backup_config.feature_timer && ((backup_config.feature_timer -= diff) <= 0)) {
1837                                         ast_debug(1, "Timed out, realtime this time!\n");
1838                                         config->feature_timer = 0;
1839                                         who = chan;
1840                                         if (f)
1841                                                 ast_frfree(f);
1842                                         f = NULL;
1843                                         res = 0;
1844                                 } else if (config->feature_timer <= 0) {
1845                                         /* Not *really* out of time, just out of time for
1846                                            digits to come in for features. */
1847                                         ast_debug(1, "Timed out for feature!\n");
1848                                         if (!ast_strlen_zero(peer_featurecode)) {
1849                                                 ast_dtmf_stream(chan, peer, peer_featurecode, 0, 0);
1850                                                 memset(peer_featurecode, 0, sizeof(peer_featurecode));
1851                                         }
1852                                         if (!ast_strlen_zero(chan_featurecode)) {
1853                                                 ast_dtmf_stream(peer, chan, chan_featurecode, 0, 0);
1854                                                 memset(chan_featurecode, 0, sizeof(chan_featurecode));
1855                                         }
1856                                         if (f)
1857                                                 ast_frfree(f);
1858                                         hasfeatures = !ast_strlen_zero(chan_featurecode) || !ast_strlen_zero(peer_featurecode);
1859                                         if (!hasfeatures) {
1860                                                 /* Restore original (possibly time modified) bridge config */
1861                                                 memcpy(config, &backup_config, sizeof(struct ast_bridge_config));
1862                                                 memset(&backup_config, 0, sizeof(backup_config));
1863                                         }
1864                                         hadfeatures = hasfeatures;
1865                                         /* Continue as we were */
1866                                         continue;
1867                                 } else if (!f) {
1868                                         /* The bridge returned without a frame and there is a feature in progress.
1869                                          * However, we don't think the feature has quite yet timed out, so just
1870                                          * go back into the bridge. */
1871                                         continue;
1872                                 }
1873                         } else {
1874                                 if (config->feature_timer <=0) {
1875                                         /* We ran out of time */
1876                                         config->feature_timer = 0;
1877                                         who = chan;
1878                                         if (f)
1879                                                 ast_frfree(f);
1880                                         f = NULL;
1881                                         res = 0;
1882                                 }
1883                         }
1884                 }
1885                 if (res < 0) {
1886                         if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_test_flag(peer, AST_FLAG_ZOMBIE))
1887                                 ast_log(LOG_WARNING, "Bridge failed on channels %s and %s, res = %d\n", chan->name, peer->name, res);
1888                         return -1;
1889                 }
1890                 
1891                 if (!f || (f->frametype == AST_FRAME_CONTROL &&
1892                                 (f->subclass == AST_CONTROL_HANGUP || f->subclass == AST_CONTROL_BUSY || 
1893                                         f->subclass == AST_CONTROL_CONGESTION))) {
1894                         res = -1;
1895                         break;
1896                 }
1897                 /* many things should be sent to the 'other' channel */
1898                 other = (who == chan) ? peer : chan;
1899                 if (f->frametype == AST_FRAME_CONTROL) {
1900                         switch (f->subclass) {
1901                         case AST_CONTROL_RINGING:
1902                         case AST_CONTROL_FLASH:
1903                         case -1:
1904                                 ast_indicate(other, f->subclass);
1905                                 break;
1906                         case AST_CONTROL_HOLD:
1907                         case AST_CONTROL_UNHOLD:
1908                                 ast_indicate_data(other, f->subclass, f->data, f->datalen);
1909                                 break;
1910                         case AST_CONTROL_OPTION:
1911                                 aoh = f->data;
1912                                 /* Forward option Requests */
1913                                 if (aoh && aoh->flag == AST_OPTION_FLAG_REQUEST) {
1914                                         ast_channel_setoption(other, ntohs(aoh->option), aoh->data, 
1915                                                 f->datalen - sizeof(struct ast_option_header), 0);
1916                                 }
1917                                 break;
1918                         }
1919                 } else if (f->frametype == AST_FRAME_DTMF_BEGIN) {
1920                         /* eat it */
1921                 } else if (f->frametype == AST_FRAME_DTMF) {
1922                         char *featurecode;
1923                         int sense;
1924
1925                         hadfeatures = hasfeatures;
1926                         /* This cannot overrun because the longest feature is one shorter than our buffer */
1927                         if (who == chan) {
1928                                 sense = FEATURE_SENSE_CHAN;
1929                                 featurecode = chan_featurecode;
1930                         } else  {
1931                                 sense = FEATURE_SENSE_PEER;
1932                                 featurecode = peer_featurecode;
1933                         }
1934                         /*! append the event to featurecode. we rely on the string being zero-filled, and
1935                          * not overflowing it. 
1936                          * \todo XXX how do we guarantee the latter ?
1937                          */
1938                         featurecode[strlen(featurecode)] = f->subclass;
1939                         /* Get rid of the frame before we start doing "stuff" with the channels */
1940                         ast_frfree(f);
1941                         f = NULL;
1942                         config->feature_timer = backup_config.feature_timer;
1943                         res = ast_feature_interpret(chan, peer, config, featurecode, sense);
1944                         switch(res) {
1945                         case FEATURE_RETURN_PASSDIGITS:
1946                                 ast_dtmf_stream(other, who, featurecode, 0, 0);
1947                                 /* Fall through */
1948                         case FEATURE_RETURN_SUCCESS:
1949                                 memset(featurecode, 0, sizeof(chan_featurecode));
1950                                 break;
1951                         }
1952                         if (res >= FEATURE_RETURN_PASSDIGITS) {
1953                                 res = 0;
1954                         } else 
1955                                 break;
1956                         hasfeatures = !ast_strlen_zero(chan_featurecode) || !ast_strlen_zero(peer_featurecode);
1957                         if (hadfeatures && !hasfeatures) {
1958                                 /* Restore backup */
1959                                 memcpy(config, &backup_config, sizeof(struct ast_bridge_config));
1960                                 memset(&backup_config, 0, sizeof(struct ast_bridge_config));
1961                         } else if (hasfeatures) {
1962                                 if (!hadfeatures) {
1963                                         /* Backup configuration */
1964                                         memcpy(&backup_config, config, sizeof(struct ast_bridge_config));
1965                                         /* Setup temporary config options */
1966                                         config->play_warning = 0;
1967                                         ast_clear_flag(&(config->features_caller), AST_FEATURE_PLAY_WARNING);
1968                                         ast_clear_flag(&(config->features_callee), AST_FEATURE_PLAY_WARNING);
1969                                         config->warning_freq = 0;
1970                                         config->warning_sound = NULL;
1971                                         config->end_sound = NULL;
1972                                         config->start_sound = NULL;
1973                                         config->firstpass = 0;
1974                                 }
1975                                 config->start_time = ast_tvnow();
1976                                 config->feature_timer = featuredigittimeout;
1977                                 ast_debug(1, "Set time limit to %ld\n", config->feature_timer);
1978                         }
1979                 }
1980                 if (f)
1981                         ast_frfree(f);
1982
1983         }
1984         /* arrange the cdrs */
1985         bridge_cdr = ast_cdr_alloc();
1986         if (bridge_cdr) {
1987                 if (chan->cdr && peer->cdr) { /* both of them? merge */
1988                         ast_cdr_init(bridge_cdr,chan); /* seems more logicaller to use the  destination as a base, but, really, it's random */
1989                         ast_cdr_start(bridge_cdr); /* now is the time to start */
1990                         
1991                         /* absorb the channel cdr */
1992                         ast_cdr_merge(bridge_cdr, chan->cdr);
1993                         if (!ast_test_flag(chan->cdr, AST_CDR_FLAG_LOCKED))
1994                                 ast_cdr_discard(chan->cdr); /* if locked cdrs are in chan, they are taken over in the merge */
1995                         
1996                         /* absorb the peer cdr */
1997                         ast_cdr_merge(bridge_cdr, peer->cdr);
1998                         if (!ast_test_flag(peer->cdr, AST_CDR_FLAG_LOCKED))
1999                                 ast_cdr_discard(peer->cdr); /* if locked cdrs are in peer, they are taken over in the merge */
2000                         
2001                         peer->cdr = NULL;
2002                         chan->cdr = bridge_cdr; /* make this available to the rest of the world via the chan while the call is in progress */
2003                 } else if (chan->cdr) {
2004                         /* take the cdr from the channel - literally */
2005                         ast_cdr_init(bridge_cdr,chan);
2006                         /* absorb this data */
2007                         ast_cdr_merge(bridge_cdr, chan->cdr);
2008                         if (!ast_test_flag(chan->cdr, AST_CDR_FLAG_LOCKED))
2009                                 ast_cdr_discard(chan->cdr); /* if locked cdrs are in chan, they are taken over in the merge */
2010                         chan->cdr = bridge_cdr; /* make this available to the rest of the world via the chan while the call is in progress */
2011                 } else if (peer->cdr) {
2012                         /* take the cdr from the peer - literally */
2013                         ast_cdr_init(bridge_cdr,peer);
2014                         /* absorb this data */
2015                         ast_cdr_merge(bridge_cdr, peer->cdr);
2016                         if (!ast_test_flag(peer->cdr, AST_CDR_FLAG_LOCKED))
2017                                 ast_cdr_discard(peer->cdr); /* if locked cdrs are in chan, they are taken over in the merge */
2018                         peer->cdr = NULL;
2019                         peer->cdr = bridge_cdr; /* make this available to the rest of the world via the chan while the call is in progress */
2020                 } else {
2021                         /* make up a new cdr */
2022                         ast_cdr_init(bridge_cdr,chan); /* eh, just pick one of them */
2023                         chan->cdr = bridge_cdr; /*  */
2024                 }
2025                 if (ast_strlen_zero(bridge_cdr->dstchannel)) {
2026                         if (strcmp(bridge_cdr->channel, peer->name) != 0)
2027                                 ast_cdr_setdestchan(bridge_cdr, peer->name);
2028                         else
2029                                 ast_cdr_setdestchan(bridge_cdr, chan->name);
2030                 }
2031         }
2032         return res;
2033 }
2034
2035 /*! \brief Output parking event to manager */
2036 static void post_manager_event(const char *s, struct parkeduser *pu)
2037 {
2038         manager_event(EVENT_FLAG_CALL, s,
2039                 "Exten: %s\r\n"
2040                 "Channel: %s\r\n"
2041                 "CallerIDNum: %s\r\n"
2042                 "CallerIDName: %s\r\n\r\n",
2043                 pu->parkingexten, 
2044                 pu->chan->name,
2045                 S_OR(pu->chan->cid.cid_num, "<unknown>"),
2046                 S_OR(pu->chan->cid.cid_name, "<unknown>")
2047                 );
2048 }
2049
2050 /*! 
2051  * \brief Take care of parked calls and unpark them if needed 
2052  * \param ignore unused var.
2053  * 
2054  * Start inf loop, lock parking lot, check if any parked channels have gone above timeout
2055  * if so, remove channel from parking lot and return it to the extension that parked it.
2056  * Check if parked channel decided to hangup, wait until next FD via select().
2057 */
2058 static void *do_parking_thread(void *ignore)
2059 {
2060         char parkingslot[AST_MAX_EXTENSION];
2061         fd_set rfds, efds;      /* results from previous select, to be preserved across loops. */
2062
2063         FD_ZERO(&rfds);
2064         FD_ZERO(&efds);
2065
2066         for (;;) {
2067                 struct parkeduser *pu;
2068                 int ms = -1;    /* select timeout, uninitialized */
2069                 int max = -1;   /* max fd, none there yet */
2070                 fd_set nrfds, nefds;    /* args for the next select */
2071                 FD_ZERO(&nrfds);
2072                 FD_ZERO(&nefds);
2073
2074                 AST_LIST_LOCK(&parkinglot);
2075                 AST_LIST_TRAVERSE_SAFE_BEGIN(&parkinglot, pu, list) {
2076                         struct ast_channel *chan = pu->chan;    /* shorthand */
2077                         int tms;        /* timeout for this item */
2078                         int x;          /* fd index in channel */
2079                         struct ast_context *con;
2080
2081                         if (pu->notquiteyet) /* Pretend this one isn't here yet */
2082                                 continue;
2083                         tms = ast_tvdiff_ms(ast_tvnow(), pu->start);
2084                         if (tms > pu->parkingtime) {
2085                                 ast_indicate(chan, AST_CONTROL_UNHOLD);
2086                                 /* Get chan, exten from derived kludge */
2087                                 if (pu->peername[0]) {
2088                                         char *peername = ast_strdupa(pu->peername);
2089                                         char *cp = strrchr(peername, '-');
2090                                         if (cp) 
2091                                                 *cp = 0;
2092                                         con = ast_context_find(parking_con_dial);
2093                                         if (!con) {
2094                                                 con = ast_context_create(NULL, parking_con_dial, registrar);
2095                                                 if (!con)
2096                                                         ast_log(LOG_ERROR, "Parking dial context '%s' does not exist and unable to create\n", parking_con_dial);
2097                                         }
2098                                         if (con) {
2099                                                 char returnexten[AST_MAX_EXTENSION];
2100                                                 snprintf(returnexten, sizeof(returnexten), "%s,,t", peername);
2101                                                 ast_add_extension2(con, 1, peername, 1, NULL, NULL, "Dial", ast_strdup(returnexten), ast_free_ptr, registrar);
2102                                         }
2103                                         if (comebacktoorigin) { 
2104                                                 set_c_e_p(chan, parking_con_dial, peername, 1);
2105                                         } else {
2106                                                 ast_log(LOG_WARNING, "now going to parkedcallstimeout,s,1 | ps is %d\n",pu->parkingnum);
2107                                                 snprintf(parkingslot, sizeof(parkingslot), "%d", pu->parkingnum);
2108                                                 pbx_builtin_setvar_helper(pu->chan, "PARKINGSLOT", parkingslot);
2109                                                 set_c_e_p(chan, "parkedcallstimeout", peername, 1);
2110                                         }
2111                                 } else {
2112                                         /* They've been waiting too long, send them back to where they came.  Theoretically they
2113                                            should have their original extensions and such, but we copy to be on the safe side */
2114                                         set_c_e_p(chan, pu->context, pu->exten, pu->priority);
2115                                 }
2116
2117                                 post_manager_event("ParkedCallTimeOut", pu);
2118
2119                                 ast_verb(2, "Timeout for %s parked on %d. Returning to %s,%s,%d\n", chan->name, pu->parkingnum, chan->context, chan->exten, chan->priority);
2120                                 /* Start up the PBX, or hang them up */
2121                                 if (ast_pbx_start(chan))  {
2122                                         ast_log(LOG_WARNING, "Unable to restart the PBX for user on '%s', hanging them up...\n", chan->name);
2123                                         ast_hangup(chan);
2124                                 }
2125                                 /* And take them out of the parking lot */
2126                                 AST_LIST_REMOVE_CURRENT(&parkinglot, list);
2127                                 con = ast_context_find(parking_con);
2128                                 if (con) {
2129                                         if (ast_context_remove_extension2(con, pu->parkingexten, 1, NULL))
2130                                                 ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
2131                                         else
2132                                                 notify_metermaids(pu->parkingexten, parking_con, AST_DEVICE_NOT_INUSE);
2133                                 } else
2134                                         ast_log(LOG_WARNING, "Whoa, no parking context?\n");
2135                                 ast_free(pu);
2136                         } else {        /* still within parking time, process descriptors */
2137                                 for (x = 0; x < AST_MAX_FDS; x++) {
2138                                         struct ast_frame *f;
2139
2140                                         if (chan->fds[x] == -1 || (!FD_ISSET(chan->fds[x], &rfds) && !FD_ISSET(chan->fds[x], &efds)))
2141                                                 continue;       /* nothing on this descriptor */
2142
2143                                         if (FD_ISSET(chan->fds[x], &efds))
2144                                                 ast_set_flag(chan, AST_FLAG_EXCEPTION);
2145                                         else
2146                                                 ast_clear_flag(chan, AST_FLAG_EXCEPTION);
2147                                         chan->fdno = x;
2148
2149                                         /* See if they need servicing */
2150                                         f = ast_read(chan);
2151                                         if (!f || (f->frametype == AST_FRAME_CONTROL && f->subclass ==  AST_CONTROL_HANGUP)) {
2152                                                 if (f)
2153                                                         ast_frfree(f);
2154                                                 post_manager_event("ParkedCallGiveUp", pu);
2155
2156                                                 /* There's a problem, hang them up*/
2157                                                 ast_verb(2, "%s got tired of being parked\n", chan->name);
2158                                                 ast_hangup(chan);
2159                                                 /* And take them out of the parking lot */
2160                                                 AST_LIST_REMOVE_CURRENT(&parkinglot, list);
2161                                                 con = ast_context_find(parking_con);
2162                                                 if (con) {
2163                                                         if (ast_context_remove_extension2(con, pu->parkingexten, 1, NULL))
2164                                                                 ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
2165                                                         else
2166                                                                 notify_metermaids(pu->parkingexten, parking_con, AST_DEVICE_NOT_INUSE);
2167                                                 } else
2168                                                         ast_log(LOG_WARNING, "Whoa, no parking context?\n");
2169                                                 ast_free(pu);
2170                                                 break;
2171                                         } else {
2172                                                 /*! \todo XXX Maybe we could do something with packets, like dial "0" for operator or something XXX */
2173                                                 ast_frfree(f);
2174                                                 if (pu->moh_trys < 3 && !chan->generatordata) {
2175                                                         ast_debug(1, "MOH on parked call stopped by outside source.  Restarting.\n");
2176                                                         ast_indicate_data(chan, AST_CONTROL_HOLD, 
2177                                                                 S_OR(parkmohclass, NULL),
2178                                                                 !ast_strlen_zero(parkmohclass) ? strlen(parkmohclass) + 1 : 0);
2179                                                         pu->moh_trys++;
2180                                                 }
2181                                                 goto std;       /*! \todo XXX Ick: jumping into an else statement??? XXX */
2182                                         }
2183
2184                                 } /* end for */
2185                                 if (x >= AST_MAX_FDS) {
2186 std:                                    for (x=0; x<AST_MAX_FDS; x++) { /* mark fds for next round */
2187                                                 if (chan->fds[x] > -1) {
2188                                                         FD_SET(chan->fds[x], &nrfds);
2189                                                         FD_SET(chan->fds[x], &nefds);
2190                                                         if (chan->fds[x] > max)
2191                                                                 max = chan->fds[x];
2192                                                 }
2193                                         }
2194                                         /* Keep track of our shortest wait */
2195                                         if (tms < ms || ms < 0)
2196                                                 ms = tms;
2197                                 }
2198                         }
2199                 } /* end while */
2200                 AST_LIST_TRAVERSE_SAFE_END
2201                 AST_LIST_UNLOCK(&parkinglot);
2202                 rfds = nrfds;
2203                 efds = nefds;
2204                 {
2205                         struct timeval tv = ast_samp2tv(ms, 1000);
2206                         /* Wait for something to happen */
2207                         ast_select(max + 1, &rfds, NULL, &efds, (ms > -1) ? &tv : NULL);
2208                 }
2209                 pthread_testcancel();
2210         }
2211         return NULL;    /* Never reached */
2212 }
2213
2214 /*! \brief Park a call */
2215 static int park_call_exec(struct ast_channel *chan, void *data)
2216 {
2217         /* Data is unused at the moment but could contain a parking
2218            lot context eventually */
2219         int res = 0;
2220         struct ast_module_user *u;
2221
2222         u = ast_module_user_add(chan);
2223
2224         /* Setup the exten/priority to be s/1 since we don't know
2225            where this call should return */
2226         strcpy(chan->exten, "s");
2227         chan->priority = 1;
2228         /* Answer if call is not up */
2229         if (chan->_state != AST_STATE_UP)
2230                 res = ast_answer(chan);
2231         /* Sleep to allow VoIP streams to settle down */
2232         if (!res)
2233                 res = ast_safe_sleep(chan, 1000);
2234         /* Park the call */
2235         if (!res)
2236                 res = ast_park_call(chan, chan, 0, NULL);
2237
2238         ast_module_user_remove(u);
2239
2240         return !res ? AST_PBX_KEEPALIVE : res;
2241 }
2242
2243 /*! \brief Pickup parked call */
2244 static int park_exec(struct ast_channel *chan, void *data)
2245 {
2246         int res = 0;
2247         struct ast_module_user *u;
2248         struct ast_channel *peer=NULL;
2249         struct parkeduser *pu;
2250         struct ast_context *con;
2251
2252         int park;
2253         struct ast_bridge_config config;
2254
2255         if (!data) {
2256                 ast_log(LOG_WARNING, "Parkedcall requires an argument (extension number)\n");
2257                 return -1;
2258         }
2259         
2260         u = ast_module_user_add(chan);
2261
2262         park = atoi((char *)data);
2263
2264         AST_LIST_LOCK(&parkinglot);
2265         AST_LIST_TRAVERSE_SAFE_BEGIN(&parkinglot, pu, list) {
2266                 if (pu->parkingnum == park) {
2267                         AST_LIST_REMOVE_CURRENT(&parkinglot, list);
2268                         break;
2269                 }
2270         }
2271         AST_LIST_TRAVERSE_SAFE_END
2272         AST_LIST_UNLOCK(&parkinglot);
2273
2274         if (pu) {
2275                 peer = pu->chan;
2276                 con = ast_context_find(parking_con);
2277                 if (con) {
2278                         if (ast_context_remove_extension2(con, pu->parkingexten, 1, NULL))
2279                                 ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
2280                         else
2281                                 notify_metermaids(pu->parkingexten, parking_con, AST_DEVICE_NOT_INUSE);
2282                 } else
2283                         ast_log(LOG_WARNING, "Whoa, no parking context?\n");
2284
2285                 manager_event(EVENT_FLAG_CALL, "UnParkedCall",
2286                         "Exten: %s\r\n"
2287                         "Channel: %s\r\n"
2288                         "From: %s\r\n"
2289                         "CallerIDNum: %s\r\n"
2290                         "CallerIDName: %s\r\n",
2291                         pu->parkingexten, pu->chan->name, chan->name,
2292                         S_OR(pu->chan->cid.cid_num, "<unknown>"),
2293                         S_OR(pu->chan->cid.cid_name, "<unknown>")
2294                         );
2295
2296                 ast_free(pu);
2297         }
2298         /* JK02: it helps to answer the channel if not already up */
2299         if (chan->_state != AST_STATE_UP)
2300                 ast_answer(chan);
2301
2302         if (peer) {
2303                 /* Play a courtesy to the source(s) configured to prefix the bridge connecting */
2304                 
2305                 if (!ast_strlen_zero(courtesytone)) {
2306                         int error = 0;
2307                         ast_indicate(peer, AST_CONTROL_UNHOLD);
2308                         if (parkedplay == 0) {
2309                                 error = ast_stream_and_wait(chan, courtesytone, "");
2310                         } else if (parkedplay == 1) {
2311                                 error = ast_stream_and_wait(peer, courtesytone, "");
2312                         } else if (parkedplay == 2) {
2313                                 if (!ast_streamfile(chan, courtesytone, chan->language) &&
2314                                                 !ast_streamfile(peer, courtesytone, chan->language)) {
2315                                         /*! \todo XXX we would like to wait on both! */
2316                                         res = ast_waitstream(chan, "");
2317                                         if (res >= 0)
2318                                                 res = ast_waitstream(peer, "");
2319                                         if (res < 0)
2320                                                 error = 1;
2321                                 }
2322                         }
2323                         if (error) {
2324                                 ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
2325                                 ast_hangup(peer);
2326                                 return -1;
2327                         }
2328                 } else
2329                         ast_indicate(peer, AST_CONTROL_UNHOLD); 
2330
2331                 res = ast_channel_make_compatible(chan, peer);
2332                 if (res < 0) {
2333                         ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for bridge\n", chan->name, peer->name);
2334                         ast_hangup(peer);
2335                         return -1;
2336                 }
2337                 /* This runs sorta backwards, since we give the incoming channel control, as if it
2338                    were the person called. */
2339                 ast_verb(3, "Channel %s connected to parked call %d\n", chan->name, park);
2340
2341                 pbx_builtin_setvar_helper(chan, "PARKEDCHANNEL", peer->name);
2342                 ast_cdr_setdestchan(chan->cdr, peer->name);
2343                 memset(&config, 0, sizeof(struct ast_bridge_config));
2344                 if ((parkedcalltransfers == AST_FEATURE_FLAG_BYCALLEE) || (parkedcalltransfers == AST_FEATURE_FLAG_BYBOTH))
2345                         ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
2346                 if ((parkedcalltransfers == AST_FEATURE_FLAG_BYCALLER) || (parkedcalltransfers == AST_FEATURE_FLAG_BYBOTH))
2347                         ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
2348                 if ((parkedcallreparking == AST_FEATURE_FLAG_BYCALLEE) || (parkedcallreparking == AST_FEATURE_FLAG_BYBOTH))
2349                         ast_set_flag(&(config.features_callee), AST_FEATURE_PARKCALL);
2350                 if ((parkedcallreparking == AST_FEATURE_FLAG_BYCALLER) || (parkedcallreparking == AST_FEATURE_FLAG_BYBOTH))
2351                         ast_set_flag(&(config.features_caller), AST_FEATURE_PARKCALL);
2352                 res = ast_bridge_call(chan, peer, &config);
2353
2354                 pbx_builtin_setvar_helper(chan, "PARKEDCHANNEL", peer->name);
2355                 ast_cdr_setdestchan(chan->cdr, peer->name);
2356
2357                 /* Simulate the PBX hanging up */
2358                 if (res != AST_PBX_NO_HANGUP_PEER)
2359                         ast_hangup(peer);
2360                 return res;
2361         } else {
2362                 /*! \todo XXX Play a message XXX */
2363                 if (ast_stream_and_wait(chan, "pbx-invalidpark", ""))
2364                         ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", "pbx-invalidpark", chan->name);
2365                 ast_verb(3, "Channel %s tried to talk to nonexistent parked call %d\n", chan->name, park);
2366                 res = -1;
2367         }
2368
2369         ast_module_user_remove(u);
2370
2371         return res;
2372 }
2373
2374 /*!
2375  * \brief CLI command to list configured features
2376  * \param e
2377  * \param cmd
2378  * \param a
2379  *
2380  * \retval CLI_SUCCESS on success.
2381  * \retval NULL when tab completion is used.
2382  */
2383 static char *handle_feature_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) {
2384         int i;
2385         struct ast_call_feature *feature;
2386         char format[] = "%-25s %-7s %-7s\n";
2387
2388         switch (cmd) {
2389         
2390         case CLI_INIT:
2391                 e->command = "features show";
2392                 e->usage =
2393                         "Usage: features show\n"
2394                         "       Lists configured features\n";
2395                 return NULL;
2396         case CLI_GENERATE:
2397                 return NULL;
2398         }
2399
2400         ast_cli(a->fd, format, "Builtin Feature", "Default", "Current");
2401         ast_cli(a->fd, format, "---------------", "-------", "-------");
2402
2403         ast_cli(a->fd, format, "Pickup", "*8", ast_pickup_ext());          /* default hardcoded above, so we'll hardcode it here */
2404
2405         ast_rwlock_rdlock(&features_lock);
2406         for (i = 0; i < FEATURES_COUNT; i++)
2407                 ast_cli(a->fd, format, builtin_features[i].fname, builtin_features[i].default_exten, builtin_features[i].exten);
2408         ast_rwlock_unlock(&features_lock);
2409
2410         ast_cli(a->fd, "\n");
2411         ast_cli(a->fd, format, "Dynamic Feature", "Default", "Current");
2412         ast_cli(a->fd, format, "---------------", "-------", "-------");
2413         if (AST_LIST_EMPTY(&feature_list))
2414                 ast_cli(a->fd, "(none)\n");
2415         else {
2416                 AST_LIST_LOCK(&feature_list);
2417                 AST_LIST_TRAVERSE(&feature_list, feature, feature_entry)
2418                         ast_cli(a->fd, format, feature->sname, "no def", feature->exten);
2419                 AST_LIST_UNLOCK(&feature_list);
2420         }
2421         ast_cli(a->fd, "\nCall parking\n");
2422         ast_cli(a->fd, "------------\n");
2423         ast_cli(a->fd,"%-20s:      %s\n", "Parking extension", parking_ext);
2424         ast_cli(a->fd,"%-20s:      %s\n", "Parking context", parking_con);
2425         ast_cli(a->fd,"%-20s:      %d-%d\n", "Parked call extensions", parking_start, parking_stop);
2426         ast_cli(a->fd,"\n");
2427
2428         return CLI_SUCCESS;
2429 }
2430
2431 static char mandescr_bridge[] =
2432 "Description: Bridge together two channels already in the PBX\n"
2433 "Variables: ( Headers marked with * are required )\n"
2434 "   *Channel1: Channel to Bridge to Channel2\n"
2435 "   *Channel2: Channel to Bridge to Channel1\n"
2436 "        Tone: (Yes|No) Play courtesy tone to Channel 2\n"
2437 "\n";
2438
2439 /*!
2440  * \brief Actual bridge
2441  * \param chan
2442  * \param tmpchan
2443  * 
2444  * Stop hold music, lock both channels, masq channels,
2445  * after bridge return channel to next priority.
2446 */
2447 static void do_bridge_masquerade(struct ast_channel *chan, struct ast_channel *tmpchan)
2448 {
2449         ast_moh_stop(chan);
2450         ast_mutex_lock(&chan->lock);
2451         ast_setstate(tmpchan, chan->_state);
2452         tmpchan->readformat = chan->readformat;
2453         tmpchan->writeformat = chan->writeformat;
2454         ast_channel_masquerade(tmpchan, chan);
2455         ast_mutex_lock(&tmpchan->lock);
2456         ast_do_masquerade(tmpchan);
2457         /* when returning from bridge, the channel will continue at the next priority */
2458         ast_explicit_goto(tmpchan, chan->context, chan->exten, chan->priority + 1);
2459         ast_mutex_unlock(&tmpchan->lock);
2460         ast_mutex_unlock(&chan->lock);
2461 }
2462
2463 /*!
2464  * \brief Bridge channels together
2465  * \param s
2466  * \param m
2467  * 
2468  * Make sure valid channels were specified, 
2469  * send errors if any of the channels could not be found/locked, answer channels if needed,
2470  * create the placeholder channels and grab the other channels 
2471  * make the channels compatible, send error if we fail doing so 
2472  * setup the bridge thread object and start the bridge.
2473  * 
2474  * \retval 0 on success or on incorrect use.
2475  * \retval 1 on failure to bridge channels.
2476 */
2477 static int action_bridge(struct mansession *s, const struct message *m)
2478 {
2479         const char *channela = astman_get_header(m, "Channel1");
2480         const char *channelb = astman_get_header(m, "Channel2");
2481         const char *playtone = astman_get_header(m, "Tone");
2482         struct ast_channel *chana = NULL, *chanb = NULL;
2483         struct ast_channel *tmpchana = NULL, *tmpchanb = NULL;
2484         struct ast_bridge_thread_obj *tobj = NULL;
2485
2486         /* make sure valid channels were specified */
2487         if (!ast_strlen_zero(channela) && !ast_strlen_zero(channelb)) {
2488                 chana = ast_get_channel_by_name_prefix_locked(channela, strlen(channela));
2489                 chanb = ast_get_channel_by_name_prefix_locked(channelb, strlen(channelb));
2490                 if (chana)
2491                         ast_mutex_unlock(&chana->lock);
2492                 if (chanb)
2493                         ast_mutex_unlock(&chanb->lock);
2494
2495                 /* send errors if any of the channels could not be found/locked */
2496                 if (!chana) {
2497                         char buf[256];
2498                         snprintf(buf, sizeof(buf), "Channel1 does not exists: %s", channela);
2499                         astman_send_error(s, m, buf);
2500                         return 0;
2501                 }
2502                 if (!chanb) {
2503                         char buf[256];
2504                         snprintf(buf, sizeof(buf), "Channel2 does not exists: %s", channelb);
2505                         astman_send_error(s, m, buf);
2506                         return 0;
2507                 }
2508         } else {
2509                 astman_send_error(s, m, "Missing channel parameter in request");
2510                 return 0;
2511         }
2512
2513         /* Answer the channels if needed */
2514         if (chana->_state != AST_STATE_UP)
2515                 ast_answer(chana);
2516         if (chanb->_state != AST_STATE_UP)
2517                 ast_answer(chanb);
2518
2519         /* create the placeholder channels and grab the other channels */
2520         if (!(tmpchana = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL, 
2521                 NULL, NULL, 0, "Bridge/%s", chana->name))) {
2522                 astman_send_error(s, m, "Unable to create temporary channel!");
2523                 return 1;
2524         }
2525
2526         if (!(tmpchanb = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL, 
2527                 NULL, NULL, 0, "Bridge/%s", chanb->name))) {
2528                 astman_send_error(s, m, "Unable to create temporary channels!");
2529                 ast_channel_free(tmpchana);
2530                 return 1;
2531         }
2532
2533         do_bridge_masquerade(chana, tmpchana);
2534         do_bridge_masquerade(chanb, tmpchanb);
2535         
2536         /* make the channels compatible, send error if we fail doing so */
2537         if (ast_channel_make_compatible(tmpchana, tmpchanb)) {
2538                 ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for manager bridge\n", tmpchana->name, tmpchanb->name);
2539                 astman_send_error(s, m, "Could not make channels compatible for manager bridge");
2540                 ast_hangup(tmpchana);
2541                 ast_hangup(tmpchanb);
2542                 return 1;
2543         }
2544
2545         /* setup the bridge thread object and start the bridge */
2546         if (!(tobj = ast_calloc(1, sizeof(*tobj)))) {
2547                 ast_log(LOG_WARNING, "Unable to spawn a new bridge thread on %s and %s: %s\n", tmpchana->name, tmpchanb->name, strerror(errno));
2548                 astman_send_error(s, m, "Unable to spawn a new bridge thread");
2549                 ast_hangup(tmpchana);
2550                 ast_hangup(tmpchanb);
2551                 return 1;
2552         }
2553
2554         tobj->chan = tmpchana;
2555         tobj->peer = tmpchanb;
2556         tobj->return_to_pbx = 1;
2557         
2558         if (ast_true(playtone)) {
2559                 if (!ast_strlen_zero(xfersound) && !ast_streamfile(tmpchanb, xfersound, tmpchanb->language)) {
2560                         if (ast_waitstream(tmpchanb, "") < 0)
2561                                 ast_log(LOG_WARNING, "Failed to play a courtesy tone on chan %s\n", tmpchanb->name);
2562                 }
2563         }
2564
2565         ast_bridge_call_thread_launch(tobj);
2566
2567         astman_send_ack(s, m, "Launched bridge thread with success");
2568
2569         return 0;
2570 }
2571
2572 /*!
2573  * \brief CLI command to list parked calls
2574  * \param e 
2575  * \param cmd
2576  * \param a
2577  *  
2578  * Check right usage, lock parking lot, display parked calls, unlock parking lot list.
2579  * \retval CLI_SUCCESS on success.
2580  * \retval CLI_SHOWUSAGE on incorrect number of arguements.
2581  * \retval NULL when tab completion is used.
2582 */
2583 static char *handle_parkedcalls(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2584 {
2585         struct parkeduser *cur;
2586         int numparked = 0;
2587
2588         switch (cmd) {
2589         case CLI_INIT:
2590                 e->command = "parkedcalls show";
2591                 e->usage =
2592                         "Usage: parkedcalls show\n"
2593                         "       List currently parked calls\n";
2594                 return NULL;
2595         case CLI_GENERATE:
2596                 return NULL;
2597         }
2598
2599         if (a->argc > e->args)
2600                 return CLI_SHOWUSAGE;
2601
2602         ast_cli(a->fd, "%4s %25s (%-15s %-12s %-4s) %-6s \n", "Num", "Channel"
2603                 , "Context", "Extension", "Pri", "Timeout");
2604
2605         AST_LIST_LOCK(&parkinglot);
2606         AST_LIST_TRAVERSE(&parkinglot, cur, list) {
2607                 ast_cli(a->fd, "%-10.10s %25s (%-15s %-12s %-4d) %6lds\n"
2608                         ,cur->parkingexten, cur->chan->name, cur->context, cur->exten
2609                         ,cur->priority, cur->start.tv_sec + (cur->parkingtime/1000) - time(NULL));
2610
2611                 numparked++;
2612         }
2613         AST_LIST_UNLOCK(&parkinglot);
2614         ast_cli(a->fd, "%d parked call%s.\n", numparked, ESS(numparked));
2615
2616
2617         return CLI_SUCCESS;
2618 }
2619
2620 static char *handle_parkedcalls_deprecated(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2621 {
2622         char *res = handle_parkedcalls(e, cmd, a);
2623         if (cmd == CLI_INIT)
2624                 e->command = "show parkedcalls";
2625         return res;
2626 }
2627
2628 static struct ast_cli_entry cli_show_parkedcalls_deprecated = NEW_CLI(handle_parkedcalls_deprecated, "List currently parked calls.");
2629
2630 static struct ast_cli_entry cli_features[] = {
2631         NEW_CLI(handle_feature_show, "Lists configured features"),
2632         NEW_CLI(handle_parkedcalls, "List currently parked calls", .deprecate_cmd = &cli_show_parkedcalls_deprecated),
2633 };
2634
2635 /*! 
2636  * \brief Dump parking lot status
2637  * \param s
2638  * \param m
2639  * 
2640  * Lock parking lot, iterate list and append parked calls status, unlock parking lot.
2641  * \return Always RESULT_SUCCESS 
2642 */
2643 static int manager_parking_status(struct mansession *s, const struct message *m)
2644 {
2645         struct parkeduser *cur;
2646         const char *id = astman_get_header(m, "ActionID");
2647         char idText[256] = "";
2648
2649         if (!ast_strlen_zero(id))
2650                 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
2651
2652         astman_send_ack(s, m, "Parked calls will follow");
2653
2654         AST_LIST_LOCK(&parkinglot);
2655
2656         AST_LIST_TRAVERSE(&parkinglot, cur, list) {
2657                 astman_append(s, "Event: ParkedCall\r\n"
2658                         "Exten: %d\r\n"
2659                         "Channel: %s\r\n"
2660                         "From: %s\r\n"
2661                         "Timeout: %ld\r\n"
2662                         "CallerIDNum: %s\r\n"
2663                         "CallerIDName: %s\r\n"
2664                         "%s"
2665                         "\r\n",
2666                         cur->parkingnum, cur->chan->name, cur->peername,
2667                         (long) cur->start.tv_sec + (long) (cur->parkingtime / 1000) - (long) time(NULL),
2668                         S_OR(cur->chan->cid.cid_num, ""),       /* XXX in other places it is <unknown> */
2669                         S_OR(cur->chan->cid.cid_name, ""),
2670                         idText);
2671         }
2672
2673         astman_append(s,
2674                 "Event: ParkedCallsComplete\r\n"
2675                 "%s"
2676                 "\r\n",idText);
2677
2678         AST_LIST_UNLOCK(&parkinglot);
2679
2680         return RESULT_SUCCESS;
2681 }
2682
2683 static char mandescr_park[] =
2684 "Description: Park a channel.\n"
2685 "Variables: (Names marked with * are required)\n"
2686 "       *Channel: Channel name to park\n"
2687 "       *Channel2: Channel to announce park info to (and return to if timeout)\n"
2688 "       Timeout: Number of milliseconds to wait before callback.\n";  
2689
2690 /*!
2691  * \brief Create manager event for parked calls
2692  * \param s
2693  * \param m
2694  *
2695  * Get channels involved in park, create event.
2696  * \return Always 0
2697 */
2698 static int manager_park(struct mansession *s, const struct message *m)
2699 {
2700         const char *channel = astman_get_header(m, "Channel");
2701         const char *channel2 = astman_get_header(m, "Channel2");
2702         const char *timeout = astman_get_header(m, "Timeout");
2703         char buf[BUFSIZ];
2704         int to = 0;
2705         int res = 0;
2706         int parkExt = 0;
2707         struct ast_channel *ch1, *ch2;
2708
2709         if (ast_strlen_zero(channel)) {
2710                 astman_send_error(s, m, "Channel not specified");
2711                 return 0;
2712         }
2713
2714         if (ast_strlen_zero(channel2)) {
2715                 astman_send_error(s, m, "Channel2 not specified");
2716                 return 0;
2717         }
2718
2719         ch1 = ast_get_channel_by_name_locked(channel);
2720         if (!ch1) {
2721                 snprintf(buf, sizeof(buf), "Channel does not exist: %s", channel);
2722                 astman_send_error(s, m, buf);
2723                 return 0;
2724         }
2725
2726         ch2 = ast_get_channel_by_name_locked(channel2);
2727         if (!ch2) {
2728                 snprintf(buf, sizeof(buf), "Channel does not exist: %s", channel2);
2729                 astman_send_error(s, m, buf);
2730                 ast_channel_unlock(ch1);
2731                 return 0;
2732         }
2733
2734         if (!ast_strlen_zero(timeout)) {
2735                 sscanf(timeout, "%d", &to);
2736         }
2737
2738         res = ast_masq_park_call(ch1, ch2, to, &parkExt);
2739         if (!res) {
2740                 ast_softhangup(ch2, AST_SOFTHANGUP_EXPLICIT);
2741                 astman_send_ack(s, m, "Park successful");
2742         } else {
2743                 astman_send_error(s, m, "Park failure");
2744         }
2745
2746         ast_channel_unlock(ch1);
2747         ast_channel_unlock(ch2);
2748
2749         return 0;
2750 }
2751
2752 /*!
2753  * \brief Pickup a call
2754  * \param chan channel that initiated pickup.
2755  *
2756  * Walk list of channels, checking it is not itself, channel is pbx one,
2757  * check that the callgroup for both channels are the same and the channel is ringing.
2758  * Answer calling channel, flag channel as answered on queue, masq channels together.
2759 */
2760 int ast_pickup_call(struct ast_channel *chan)
2761 {
2762         struct ast_channel *cur = NULL;
2763         int res = -1;
2764
2765         while ((cur = ast_channel_walk_locked(cur)) != NULL) {
2766                 if (!cur->pbx && 
2767                         (cur != chan) &&
2768                         (chan->pickupgroup & cur->callgroup) &&
2769                         ((cur->_state == AST_STATE_RINGING) ||
2770                          (cur->_state == AST_STATE_RING))) {
2771                                 break;
2772                 }
2773                 ast_channel_unlock(cur);
2774         }
2775         if (cur) {
2776                 ast_debug(1, "Call pickup on chan '%s' by '%s'\n",cur->name, chan->name);
2777                 res = ast_answer(chan);
2778                 if (res)
2779                         ast_log(LOG_WARNING, "Unable to answer '%s'\n", chan->name);
2780                 res = ast_queue_control(chan, AST_CONTROL_ANSWER);
2781                 if (res)
2782                         ast_log(LOG_WARNING, "Unable to queue answer on '%s'\n", chan->name);
2783                 res = ast_channel_masquerade(cur, chan);
2784                 if (res)
2785                         ast_log(LOG_WARNING, "Unable to masquerade '%s' into '%s'\n", chan->name, cur->name);           /* Done */
2786                 ast_channel_unlock(cur);
2787         } else  {
2788                 ast_debug(1, "No call pickup possible...\n");
2789         }
2790         return res;
2791 }
2792
2793 /*! 
2794  * \brief Add parking hints for all defined parking lots 
2795  * \param context
2796  * \param start starting parkinglot number
2797  * \param stop ending parkinglot number
2798 */
2799 static void park_add_hints(char *context, int start, int stop)
2800 {
2801         int numext;
2802         char device[AST_MAX_EXTENSION];
2803         char exten[10];
2804
2805         for (numext = start; numext <= stop; numext++) {
2806                 snprintf(exten, sizeof(exten), "%d", numext);
2807                 snprintf(device, sizeof(device), "park:%s@%s", exten, context);
2808                 ast_add_extension(context, 1, exten, PRIORITY_HINT, NULL, NULL, device, NULL, NULL, registrar);
2809         }
2810 }
2811
2812
2813 static int load_config(void) 
2814 {
2815         int start = 0, end = 0;
2816         int res;
2817         int i;
2818         struct ast_context *con = NULL;
2819         struct ast_config *cfg = NULL;
2820         struct ast_variable *var = NULL;
2821         struct feature_group *fg = NULL;
2822         struct ast_flags config_flags = { 0 };
2823         char old_parking_ext[AST_MAX_EXTENSION];
2824         char old_parking_con[AST_MAX_EXTENSION] = "";
2825         char *ctg; 
2826         static const char *categories[] = { 
2827                 /* Categories in features.conf that are not
2828                  * to be parsed as group categories
2829                  */
2830                 "general",
2831                 "featuremap",
2832                 "applicationmap"
2833         };
2834
2835         if (!ast_strlen_zero(parking_con)) {
2836                 strcpy(old_parking_ext, parking_ext);
2837                 strcpy(old_parking_con, parking_con);
2838         } 
2839
2840         /* Reset to defaults */
2841         strcpy(parking_con, "parkedcalls");
2842         strcpy(parking_con_dial, "park-dial");
2843         strcpy(parking_ext, "700");
2844         strcpy(pickup_ext, "*8");
2845         strcpy(parkmohclass, "default");
2846         courtesytone[0] = '\0';
2847         strcpy(xfersound, "beep");
2848         strcpy(xferfailsound, "pbx-invalid");
2849         parking_start = 701;
2850         parking_stop = 750;
2851         parkfindnext = 0;
2852         adsipark = 0;
2853         comebacktoorigin = 1;
2854         parkaddhints = 0;
2855         parkedcalltransfers = 0;
2856         parkedcallreparking = 0;
2857
2858         transferdigittimeout = DEFAULT_TRANSFER_DIGIT_TIMEOUT;
2859         featuredigittimeout = DEFAULT_FEATURE_DIGIT_TIMEOUT;
2860         atxfernoanswertimeout = DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER;
2861         atxferloopdelay = DEFAULT_ATXFER_LOOP_DELAY;
2862         atxferdropcall = DEFAULT_ATXFER_DROP_CALL;
2863         atxfercallbackretries = DEFAULT_ATXFER_CALLBACK_RETRIES;
2864
2865         cfg = ast_config_load("features.conf", config_flags);
2866         if (!cfg) {
2867                 ast_log(LOG_WARNING,"Could not load features.conf\n");
2868                 return AST_MODULE_LOAD_DECLINE;
2869         }
2870         for (var = ast_variable_browse(cfg, "general"); var; var = var->next) {
2871                 if (!strcasecmp(var->name, "parkext")) {
2872                         ast_copy_string(parking_ext, var->value, sizeof(parking_ext));
2873                 } else if (!strcasecmp(var->name, "context")) {
2874                         ast_copy_string(parking_con, var->value, sizeof(parking_con));
2875                 } else if (!strcasecmp(var->name, "parkingtime")) {
2876                         if ((sscanf(var->value, "%d", &parkingtime) != 1) || (parkingtime < 1)) {
2877                                 ast_log(LOG_WARNING, "%s is not a valid parkingtime\n", var->value);
2878                                 parkingtime = DEFAULT_PARK_TIME;
2879                         } else
2880                                 parkingtime = parkingtime * 1000;
2881                 } else if (!strcasecmp(var->name, "parkpos")) {
2882                         if (sscanf(var->value, "%d-%d", &start, &end) != 2) {
2883                                 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);
2884                         } else {
2885                                 parking_start = start;
2886                                 parking_stop = end;
2887                         }
2888                 } else if (!strcasecmp(var->name, "findslot")) {
2889                         parkfindnext = (!strcasecmp(var->value, "next"));
2890                 } else if (!strcasecmp(var->name, "parkinghints")) {
2891                         parkaddhints = ast_true(var->value);
2892                 } else if (!strcasecmp(var->name, "parkedcalltransfers")) {
2893                         if (!strcasecmp(var->value, "both"))
2894                                 parkedcalltransfers = AST_FEATURE_FLAG_BYBOTH;
2895                         else if (!strcasecmp(var->value, "caller"))
2896                                 parkedcalltransfers = AST_FEATURE_FLAG_BYCALLER;
2897                         else if (!strcasecmp(var->value, "callee"))
2898                                 parkedcalltransfers = AST_FEATURE_FLAG_BYCALLEE;
2899                 } else if (!strcasecmp(var->name, "parkedcallreparking")) {
2900                         if (!strcasecmp(var->value, "both"))
2901                                 parkedcalltransfers = AST_FEATURE_FLAG_BYBOTH;
2902                         else if (!strcasecmp(var->value, "caller"))
2903                                 parkedcalltransfers = AST_FEATURE_FLAG_BYCALLER;
2904                         else if (!strcasecmp(var->value, "callee"))
2905                                 parkedcalltransfers = AST_FEATURE_FLAG_BYCALLEE;
2906                 } else if (!strcasecmp(var->name, "adsipark")) {
2907                         adsipark = ast_true(var->value);
2908                 } else if (!strcasecmp(var->name, "transferdigittimeout")) {
2909                         if ((sscanf(var->value, "%d", &transferdigittimeout) != 1) || (transferdigittimeout < 1)) {
2910                                 ast_log(LOG_WARNING, "%s is not a valid transferdigittimeout\n", var->value);
2911                                 transferdigittimeout = DEFAULT_TRANSFER_DIGIT_TIMEOUT;
2912                         } else
2913                                 transferdigittimeout = transferdigittimeout * 1000;
2914                 } else if (!strcasecmp(var->name, "featuredigittimeout")) {
2915                         if ((sscanf(var->value, "%d", &featuredigittimeout) != 1) || (featuredigittimeout < 1)) {
2916                                 ast_log(LOG_WARNING, "%s is not a valid featuredigittimeout\n", var->value);
2917                                 featuredigittimeout = DEFAULT_FEATURE_DIGIT_TIMEOUT;
2918                         }
2919                 } else if (!strcasecmp(var->name, "atxfernoanswertimeout")) {
2920                         if ((sscanf(var->value, "%d", &atxfernoanswertimeout) != 1) || (atxfernoanswertimeout < 1)) {
2921                                 ast_log(LOG_WARNING, "%s is not a valid atxfernoanswertimeout\n", var->value);
2922                                 atxfernoanswertimeout = DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER;
2923                         } else
2924                                 atxfernoanswertimeout = atxfernoanswertimeout * 1000;
2925                 } else if (!strcasecmp(var->name, "atxferloopdelay")) {
2926                         if ((sscanf(var->value, "%u", &atxferloopdelay) != 1)) {
2927                                 ast_log(LOG_WARNING, "%s is not a valid atxferloopdelay\n", var->value);
2928                                 atxferloopdelay = DEFAULT_ATXFER_LOOP_DELAY;
2929                         } else 
2930                                 atxferloopdelay *= 1000;
2931                 } else if (!strcasecmp(var->name, "atxferdropcall")) {
2932                         atxferdropcall = ast_true(var->value);
2933                 } else if (!strcasecmp(var->name, "atxfercallbackretries")) {
2934                         if ((sscanf(var->value, "%u", &atxferloopdelay) != 1)) {
2935                                 ast_log(LOG_WARNING, "%s is not a valid atxfercallbackretries\n", var->value);
2936                                 atxfercallbackretries = DEFAULT_ATXFER_CALLBACK_RETRIES;
2937                         }
2938                 } else if (!strcasecmp(var->name, "courtesytone")) {
2939                         ast_copy_string(courtesytone, var->value, sizeof(courtesytone));
2940                 }  else if (!strcasecmp(var->name, "parkedplay")) {
2941                         if (!strcasecmp(var->value, "both"))
2942                                 parkedplay = 2;
2943                         else if (!strcasecmp(var->value, "parked"))
2944                                 parkedplay = 1;
2945                         else
2946                                 parkedplay = 0;
2947                 } else if (!strcasecmp(var->name, "xfersound")) {
2948                         ast_copy_string(xfersound, var->value, sizeof(xfersound));
2949                 } else if (!strcasecmp(var->name, "xferfailsound")) {
2950                         ast_copy_string(xferfailsound, var->value, sizeof(xferfailsound));
2951                 } else if (!strcasecmp(var->name, "pickupexten")) {
2952                         ast_copy_string(pickup_ext, var->value, sizeof(pickup_ext));
2953                 } else if (!strcasecmp(var->name, "comebacktoorigin")) {
2954                         comebacktoorigin = ast_true(var->value);
2955                 } else if (!strcasecmp(var->name, "parkedmusicclass")) {
2956                         ast_copy_string(parkmohclass, var->value, sizeof(parkmohclass));
2957                 }
2958         }
2959
2960         unmap_features();
2961         for (var = ast_variable_browse(cfg, "featuremap"); var; var = var->next) {
2962                 if (remap_feature(var->name, var->value))
2963                         ast_log(LOG_NOTICE, "Unknown feature '%s'\n", var->name);
2964         }
2965
2966         /* Map a key combination to an application*/
2967         ast_unregister_features();