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