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