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