a8333728e4a1745402d0c6c992ed7cef70fe6328
[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                         /* Something bad happened, or a hangup has been requested. */
2387                         ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", chan->context, chan->exten, chan->priority, chan->name);
2388                         ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", chan->context, chan->exten, chan->priority, chan->name);
2389                 } else if (!found && res) {
2390                         res = 0;
2391                 }
2392                 /* swap it back */
2393                 ast_channel_lock(chan);
2394                 ast_copy_string(chan->exten, save_exten, sizeof(chan->exten));
2395                 chan->priority = save_prio;
2396                 chan->cdr = swapper;
2397                 ast_set_flag(chan, AST_FLAG_BRIDGE_HANGUP_RUN);
2398                 ast_channel_unlock(chan);
2399                 /* protect the lastapp/lastdata against the effects of the hangup/dialplan code */
2400                 ast_copy_string(bridge_cdr->lastapp, savelastapp, sizeof(bridge_cdr->lastapp));
2401                 ast_copy_string(bridge_cdr->lastdata, savelastdata, sizeof(bridge_cdr->lastdata));
2402         }
2403
2404         /* obey the NoCDR() wishes. */
2405         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))
2406                 ast_set_flag(new_peer_cdr, AST_CDR_FLAG_POST_DISABLED); /* DISABLED is viral-- it will propagate across a bridge */
2407         if (!new_chan_cdr || (new_chan_cdr && !ast_test_flag(new_chan_cdr, AST_CDR_FLAG_POST_DISABLED))) {
2408                 struct ast_channel *chan_ptr = NULL;
2409                 
2410                 ast_cdr_end(bridge_cdr);
2411                 
2412                 ast_cdr_detach(bridge_cdr);
2413                 
2414                 /* do a specialized reset on the beginning channel
2415                    CDR's, if they still exist, so as not to mess up
2416                    issues in future bridges;
2417   
2418                    Here are the rules of the game:
2419                    1. The chan and peer channel pointers will not change
2420                       during the life of the bridge.
2421                    2. But, in transfers, the channel names will change.
2422                       between the time the bridge is started, and the
2423                       time the channel ends. 
2424                       Usually, when a channel changes names, it will
2425                       also change CDR pointers.
2426                    3. Usually, only one of the two channels (chan or peer)
2427                       will change names.
2428                    4. Usually, if a channel changes names during a bridge,
2429                       it is because of a transfer. Usually, in these situations,
2430                       it is normal to see 2 bridges running simultaneously, and
2431                       it is not unusual to see the two channels that change
2432                       swapped between bridges.
2433                    5. After a bridge occurs, we have 2 or 3 channels' CDRs
2434                       to attend to; if the chan or peer changed names,
2435                       we have the before and after attached CDR's.
2436                 */
2437  
2438                 if (strcasecmp(orig_channame, chan->name) != 0) { 
2439                         /* old channel */
2440                         chan_ptr = ast_get_channel_by_name_locked(orig_channame);
2441                         if (chan_ptr) {
2442                                 if (!ast_bridged_channel(chan_ptr)) {
2443                                         struct ast_cdr *cur;
2444                                         for (cur = chan_ptr->cdr; cur; cur = cur->next) {
2445                                                 if (cur == chan_cdr) {
2446                                                         break;
2447                                                 }
2448                                         }
2449                                         if (cur)
2450                                                 ast_cdr_specialized_reset(chan_cdr,0);
2451                                 }
2452                                 ast_channel_unlock(chan_ptr);
2453                         }
2454                         /* new channel */
2455                         ast_cdr_specialized_reset(new_chan_cdr,0);
2456                 } else {
2457                         ast_cdr_specialized_reset(chan_cdr,0); /* nothing changed, reset the chan_cdr  */
2458                 }
2459                 if (strcasecmp(orig_peername, peer->name) != 0) { 
2460                         /* old channel */
2461                         chan_ptr = ast_get_channel_by_name_locked(orig_peername);
2462                         if (chan_ptr) {
2463                                 if (!ast_bridged_channel(chan_ptr)) {
2464                                         struct ast_cdr *cur;
2465                                         for (cur = chan_ptr->cdr; cur; cur = cur->next) {
2466                                                 if (cur == peer_cdr) {
2467                                                         break;
2468                                                 }
2469                                         }
2470                                         if (cur)
2471                                                 ast_cdr_specialized_reset(peer_cdr,0);
2472                                 }
2473                                 ast_channel_unlock(chan_ptr);
2474                         }
2475                         /* new channel */
2476                         ast_cdr_specialized_reset(new_peer_cdr,0);
2477                 } else {
2478                         ast_cdr_specialized_reset(peer_cdr,0); /* nothing changed, reset the peer_cdr  */
2479                 }
2480         }
2481         return res;
2482 }
2483
2484 /*! \brief Output parking event to manager */
2485 static void post_manager_event(const char *s, struct parkeduser *pu)
2486 {
2487         manager_event(EVENT_FLAG_CALL, s,
2488                 "Exten: %s\r\n"
2489                 "Channel: %s\r\n"
2490                 "Parkinglot: %s\r\n"
2491                 "CallerIDNum: %s\r\n"
2492                 "CallerIDName: %s\r\n"
2493                 "UniqueID: %s\r\n\r\n",
2494                 pu->parkingexten, 
2495                 pu->chan->name,
2496                 pu->parkinglot->name,
2497                 S_OR(pu->chan->cid.cid_num, "<unknown>"),
2498                 S_OR(pu->chan->cid.cid_name, "<unknown>"),
2499                 pu->chan->uniqueid
2500                 );
2501 }
2502
2503 /*! \brief Run management on parkinglots, collad once per parkinglot */
2504 int manage_parkinglot(struct ast_parkinglot *curlot, fd_set *rfds, fd_set *efds, fd_set *nrfds, fd_set *nefds, int *ms, int *max)
2505 {
2506
2507         struct parkeduser *pu;
2508         int res = 0;
2509         char parkingslot[AST_MAX_EXTENSION];
2510
2511         /* TODO: I believe this reference increase is not necessary since the iterator in the calling function already did so */
2512         //parkinglot_addref(curlot);
2513         /* Lock parking list */
2514         AST_LIST_LOCK(&curlot->parkings);
2515         AST_LIST_TRAVERSE_SAFE_BEGIN(&curlot->parkings, pu, list) {
2516                 struct ast_channel *chan = pu->chan;    /* shorthand */
2517                 int tms;        /* timeout for this item */
2518                 int x;          /* fd index in channel */
2519                 struct ast_context *con;
2520
2521                 if (pu->notquiteyet) { /* Pretend this one isn't here yet */
2522                         continue;
2523                 }
2524                 tms = ast_tvdiff_ms(ast_tvnow(), pu->start);
2525                 if (tms > pu->parkingtime) {
2526                         /* Stop music on hold */
2527                         ast_indicate(pu->chan, AST_CONTROL_UNHOLD);
2528                         /* Get chan, exten from derived kludge */
2529                         if (pu->peername[0]) {
2530                                 char *peername = ast_strdupa(pu->peername);
2531                                 char *cp = strrchr(peername, '-');
2532                                 char peername_flat[AST_MAX_EXTENSION]; /* using something like DAHDI/52 for an extension name is NOT a good idea */
2533                                 int i;
2534
2535                                 if (cp) 
2536                                         *cp = 0;
2537                                 ast_copy_string(peername_flat,peername,sizeof(peername_flat));
2538                                 for(i=0; peername_flat[i] && i < AST_MAX_EXTENSION; i++) {
2539                                         if (peername_flat[i] == '/') 
2540                                                 peername_flat[i]= '0';
2541                                 }
2542                                 con = ast_context_find_or_create(NULL, NULL, pu->parkinglot->parking_con_dial, registrar);
2543                                 if (!con) {
2544                                         ast_log(LOG_ERROR, "Parking dial context '%s' does not exist and unable to create\n", pu->parkinglot->parking_con_dial);
2545                                 }
2546                                 if (con) {
2547                                         char returnexten[AST_MAX_EXTENSION];
2548                                         struct ast_datastore *features_datastore;
2549                                         struct ast_dial_features *dialfeatures = NULL;
2550
2551                                         ast_channel_lock(chan);
2552
2553                                         if ((features_datastore = ast_channel_datastore_find(chan, &dial_features_info, NULL)))
2554                                                 dialfeatures = features_datastore->data;
2555
2556                                         ast_channel_unlock(chan);
2557
2558                                         if (dialfeatures)
2559                                                 snprintf(returnexten, sizeof(returnexten), "%s,,%s", peername, dialfeatures->options);
2560                                         else /* Existing default */
2561                                                 snprintf(returnexten, sizeof(returnexten), "%s,,t", peername);
2562
2563                                         ast_add_extension2(con, 1, peername_flat, 1, NULL, NULL, "Dial", ast_strdup(returnexten), ast_free_ptr, registrar);
2564                                 }
2565                                 if (comebacktoorigin) {
2566                                         set_c_e_p(chan, pu->parkinglot->parking_con_dial, peername_flat, 1);
2567                                 } else {
2568                                         ast_log(LOG_WARNING, "now going to parkedcallstimeout,s,1 | ps is %d\n",pu->parkingnum);
2569                                         snprintf(parkingslot, sizeof(parkingslot), "%d", pu->parkingnum);
2570                                         pbx_builtin_setvar_helper(chan, "PARKINGSLOT", parkingslot);
2571                                         set_c_e_p(chan, "parkedcallstimeout", peername_flat, 1);
2572                                 }
2573                         } else {
2574                                 /* They've been waiting too long, send them back to where they came.  Theoretically they
2575                                    should have their original extensions and such, but we copy to be on the safe side */
2576                                 set_c_e_p(chan, pu->context, pu->exten, pu->priority);
2577                         }
2578                         post_manager_event("ParkedCallTimeOut", pu);
2579
2580                         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);
2581                         /* Start up the PBX, or hang them up */
2582                         if (ast_pbx_start(chan))  {
2583                                 ast_log(LOG_WARNING, "Unable to restart the PBX for user on '%s', hanging them up...\n", pu->chan->name);
2584                                 ast_hangup(chan);
2585                         }
2586                         /* And take them out of the parking lot */
2587                         con = ast_context_find(pu->parkinglot->parking_con);
2588                         if (con) {
2589                                 if (ast_context_remove_extension2(con, pu->parkingexten, 1, NULL, 0))
2590                                         ast_log(LOG_WARNING, "Whoa, failed to remove the parking extension!\n");
2591                                 else
2592                                         notify_metermaids(pu->parkingexten, curlot->parking_con, AST_DEVICE_NOT_INUSE);
2593                         } else
2594                                 ast_log(LOG_WARNING, "Whoa, no parking context?\n");
2595                         AST_LIST_REMOVE_CURRENT(list);
2596                         parkinglot_unref(curlot);
2597                 } else {        /* still within parking time, process descriptors */
2598                         for (x = 0; x < AST_MAX_FDS; x++) {
2599                                 struct ast_frame *f;
2600
2601                                 if ((chan->fds[x] == -1) || (!FD_ISSET(chan->fds[x], rfds) && !FD_ISSET(pu->chan->fds[x], efds))) 
2602                                         continue;
2603                                 
2604                                 if (FD_ISSET(chan->fds[x], efds))
2605                                         ast_set_flag(chan, AST_FLAG_EXCEPTION);
2606                                 else
2607                                         ast_clear_flag(chan, AST_FLAG_EXCEPTION);
2608                                 chan->fdno = x;
2609
2610                                 /* See if they need servicing */
2611                                 f = ast_read(pu->chan);
2612                                 /* Hangup? */
2613                                 if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass ==  AST_CONTROL_HANGUP))) {
2614                                         if (f)
2615                                                 ast_frfree(f);
2616                                         post_manager_event("ParkedCallGiveUp", pu);
2617
2618                                         /* There's a problem, hang them up*/
2619                                         ast_verb(2, "%s got tired of being parked\n", chan->name);
2620                                         ast_hangup(chan);
2621                                         /* And take them out of the parking lot */
2622                                         con = ast_context_find(curlot->parking_con);
2623                                         if (con) {
2624                                                 if (ast_context_remove_extension2(con, pu->parkingexten, 1, NULL, 0))
2625                                                         ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
2626                                                 else
2627                                                         notify_metermaids(pu->parkingexten, curlot->parking_con, AST_DEVICE_NOT_INUSE);
2628                                         } else
2629                                                 ast_log(LOG_WARNING, "Whoa, no parking context for parking lot %s?\n", curlot->name);
2630                                         AST_LIST_REMOVE_CURRENT(list);
2631                                         parkinglot_unref(curlot);
2632                                         break;
2633                                 } else {
2634                                         /* XXX Maybe we could do something with packets, like dial "0" for operator or something XXX */
2635                                         ast_frfree(f);
2636                                         if (pu->moh_trys < 3 && !chan->generatordata) {
2637                                                 ast_debug(1, "MOH on parked call stopped by outside source.  Restarting on channel %s.\n", chan->name);
2638                                                 ast_indicate_data(chan, AST_CONTROL_HOLD, 
2639                                                         S_OR(curlot->mohclass, NULL),
2640                                                         (!ast_strlen_zero(curlot->mohclass) ? strlen(curlot->mohclass) + 1 : 0));
2641                                                 pu->moh_trys++;
2642                                         }
2643                                         goto std;       /* XXX Ick: jumping into an else statement??? XXX */
2644                                 }
2645                         } /* End for */
2646                         if (x >= AST_MAX_FDS) {
2647 std:                            for (x=0; x<AST_MAX_FDS; x++) { /* mark fds for next round */
2648                                         if (chan->fds[x] > -1) {
2649                                                 FD_SET(chan->fds[x], nrfds);
2650                                                 FD_SET(chan->fds[x], nefds);
2651                                                 if (chan->fds[x] > *max)
2652                                                         *max = chan->fds[x];
2653                                         }
2654                                 }
2655                                 /* Keep track of our shortest wait */
2656                                 if (tms < *ms || *ms < 0)
2657                                         *ms = tms;
2658                         }
2659                 }
2660         }
2661         AST_LIST_TRAVERSE_SAFE_END;
2662         AST_LIST_UNLOCK(&curlot->parkings);
2663         return res;
2664 }
2665
2666 /*! 
2667  * \brief Take care of parked calls and unpark them if needed 
2668  * \param ignore unused var.
2669  * 
2670  * Start inf loop, lock parking lot, check if any parked channels have gone above timeout
2671  * if so, remove channel from parking lot and return it to the extension that parked it.
2672  * Check if parked channel decided to hangup, wait until next FD via select().
2673 */
2674 static void *do_parking_thread(void *ignore)
2675 {
2676         fd_set rfds, efds;      /* results from previous select, to be preserved across loops. */
2677         fd_set nrfds, nefds;    /* args for the next select */
2678         FD_ZERO(&rfds);
2679         FD_ZERO(&efds);
2680
2681         for (;;) {
2682                 int res = 0;
2683                 int ms = -1;    /* select timeout, uninitialized */
2684                 int max = -1;   /* max fd, none there yet */
2685                 struct ao2_iterator iter;
2686                 struct ast_parkinglot *curlot;
2687                 FD_ZERO(&nrfds);
2688                 FD_ZERO(&nefds);
2689                 iter = ao2_iterator_init(parkinglots, 0);
2690
2691                 while ((curlot = ao2_iterator_next(&iter))) {
2692                         res = manage_parkinglot(curlot, &rfds, &efds, &nrfds, &nefds, &ms, &max);
2693                         ao2_ref(curlot, -1);
2694                 }
2695
2696                 rfds = nrfds;
2697                 efds = nefds;
2698                 {
2699                         struct timeval wait = ast_samp2tv(ms, 1000);
2700                         /* Wait for something to happen */
2701                         ast_select(max + 1, &rfds, NULL, &efds, (ms > -1) ? &wait : NULL);
2702                 }
2703                 pthread_testcancel();
2704         }
2705         return NULL;    /* Never reached */
2706 }
2707
2708 /*! \brief Find parkinglot by name */
2709 struct ast_parkinglot *find_parkinglot(const char *name)
2710 {
2711         struct ast_parkinglot *parkinglot = NULL;
2712         struct ast_parkinglot tmp_parkinglot;
2713         
2714         if (ast_strlen_zero(name))
2715                 return NULL;
2716
2717         ast_copy_string(tmp_parkinglot.name, name, sizeof(tmp_parkinglot.name));
2718
2719         parkinglot = ao2_find(parkinglots, &tmp_parkinglot, OBJ_POINTER);
2720
2721         if (parkinglot && option_debug)
2722                 ast_log(LOG_DEBUG, "Found Parkinglot: %s\n", parkinglot->name);
2723
2724         return parkinglot;
2725 }
2726
2727 AST_APP_OPTIONS(park_call_options, BEGIN_OPTIONS
2728         AST_APP_OPTION('r', AST_PARK_OPT_RINGING),
2729         AST_APP_OPTION('R', AST_PARK_OPT_RANDOMIZE),
2730         AST_APP_OPTION('s', AST_PARK_OPT_SILENCE),
2731 END_OPTIONS );
2732
2733 /*! \brief Park a call */
2734 static int park_call_exec(struct ast_channel *chan, void *data)
2735 {
2736         /* Cache the original channel name in case we get masqueraded in the middle
2737          * of a park--it is still theoretically possible for a transfer to happen before
2738          * we get here, but it is _really_ unlikely */
2739         char *orig_chan_name = ast_strdupa(chan->name);
2740         char orig_exten[AST_MAX_EXTENSION];
2741         int orig_priority = chan->priority;
2742
2743         /* Data is unused at the moment but could contain a parking
2744            lot context eventually */
2745         int res = 0;
2746
2747         char *parse = NULL;
2748         AST_DECLARE_APP_ARGS(app_args,
2749                 AST_APP_ARG(timeout);
2750                 AST_APP_ARG(return_con);
2751                 AST_APP_ARG(return_ext);
2752                 AST_APP_ARG(return_pri);
2753                 AST_APP_ARG(options);
2754         );
2755
2756         if (!ast_strlen_zero(data)) {
2757                 parse = ast_strdupa(data);
2758                 AST_STANDARD_APP_ARGS(app_args, parse);
2759         }
2760
2761         ast_copy_string(orig_exten, chan->exten, sizeof(orig_exten));
2762
2763         /* Setup the exten/priority to be s/1 since we don't know
2764            where this call should return */
2765         strcpy(chan->exten, "s");
2766         chan->priority = 1;
2767
2768         /* Answer if call is not up */
2769         if (chan->_state != AST_STATE_UP)
2770                 res = ast_answer(chan);
2771
2772         /* Sleep to allow VoIP streams to settle down */
2773         if (!res)
2774                 res = ast_safe_sleep(chan, 1000);
2775
2776         /* Park the call */
2777         if (!res) {
2778                 struct ast_park_call_args args = {
2779                         .orig_chan_name = orig_chan_name,
2780                 };
2781                 struct ast_flags flags = { 0 };
2782
2783                 if (parse && !ast_strlen_zero(app_args.timeout)) {
2784                         if (sscanf(app_args.timeout, "%d", &args.timeout) != 1) {
2785                                 ast_log(LOG_WARNING, "Invalid timeout '%s' provided\n", app_args.timeout);
2786                                 args.timeout = 0;
2787                         }
2788                 }
2789
2790                 args.return_con = app_args.return_con;
2791                 args.return_ext = app_args.return_ext;
2792                 if (parse && !ast_strlen_zero(app_args.return_pri)) {
2793                         if (sscanf(app_args.return_pri, "%d", &args.return_pri) != 1) {
2794                                 ast_log(LOG_WARNING, "Invalid priority '%s' specified\n", app_args.return_pri);
2795                                 args.return_pri = 0;
2796                         }
2797                 }
2798
2799                 ast_app_parse_options(park_call_options, &flags, NULL, app_args.options);
2800                 args.flags = flags.flags;
2801
2802                 res = ast_park_call_full(chan, chan, &args);
2803                 /* Continue on in the dialplan */
2804                 if (res == 1) {
2805                         ast_copy_string(chan->exten, orig_exten, sizeof(chan->exten));
2806                         chan->priority = orig_priority;
2807                         res = 0;
2808                 } else if (!res)
2809                         res = AST_PBX_KEEPALIVE;
2810         }
2811
2812         return res;
2813 }
2814
2815 /*! \brief Pickup parked call */
2816 static int park_exec_full(struct ast_channel *chan, void *data, struct ast_parkinglot *parkinglot)
2817 {
2818         int res = 0;
2819         struct ast_channel *peer=NULL;
2820         struct parkeduser *pu;
2821         struct ast_context *con;
2822         int park = 0;
2823         struct ast_bridge_config config;
2824
2825         if (data)
2826                 park = atoi((char *)data);
2827
2828         parkinglot = find_parkinglot(findparkinglotname(chan));         
2829         if (!parkinglot)
2830                 parkinglot = default_parkinglot;
2831
2832         AST_LIST_LOCK(&parkinglot->parkings);
2833         AST_LIST_TRAVERSE_SAFE_BEGIN(&parkinglot->parkings, pu, list) {
2834                 if (!data || pu->parkingnum == park) {
2835                         AST_LIST_REMOVE_CURRENT(list);
2836                         break;
2837                 }
2838         }
2839         AST_LIST_TRAVERSE_SAFE_END
2840         AST_LIST_UNLOCK(&parkinglot->parkings);
2841
2842         if (pu) {
2843                 peer = pu->chan;
2844                 con = ast_context_find(parkinglot->parking_con);
2845                 if (con) {
2846                         if (ast_context_remove_extension2(con, pu->parkingexten, 1, NULL, 0))
2847                                 ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
2848                         else
2849                                 notify_metermaids(pu->parkingexten, parkinglot->parking_con, AST_DEVICE_NOT_INUSE);
2850                 } else
2851                         ast_log(LOG_WARNING, "Whoa, no parking context?\n");
2852
2853                 manager_event(EVENT_FLAG_CALL, "UnParkedCall",
2854                         "Exten: %s\r\n"
2855                         "Channel: %s\r\n"
2856                         "From: %s\r\n"
2857                         "CallerIDNum: %s\r\n"
2858                         "CallerIDName: %s\r\n",
2859                         pu->parkingexten, pu->chan->name, chan->name,
2860                         S_OR(pu->chan->cid.cid_num, "<unknown>"),
2861                         S_OR(pu->chan->cid.cid_name, "<unknown>")
2862                         );
2863
2864                 ast_free(pu);
2865         }
2866         /* JK02: it helps to answer the channel if not already up */
2867         if (chan->_state != AST_STATE_UP)
2868                 ast_answer(chan);
2869
2870         //XXX Why do we unlock here ?
2871         // uncomment it for now, till my setup with debug_threads and detect_deadlocks starts to complain
2872         //ASTOBJ_UNLOCK(parkinglot);
2873
2874         if (peer) {
2875                 /* Play a courtesy to the source(s) configured to prefix the bridge connecting */
2876                 
2877                 if (!ast_strlen_zero(courtesytone)) {
2878                         int error = 0;
2879                         ast_indicate(peer, AST_CONTROL_UNHOLD);
2880                         if (parkedplay == 0) {
2881                                 error = ast_stream_and_wait(chan, courtesytone, "");
2882                         } else if (parkedplay == 1) {
2883                                 error = ast_stream_and_wait(peer, courtesytone, "");
2884                         } else if (parkedplay == 2) {
2885                                 if (!ast_streamfile(chan, courtesytone, chan->language) &&
2886                                                 !ast_streamfile(peer, courtesytone, chan->language)) {
2887                                         /*! \todo XXX we would like to wait on both! */
2888                                         res = ast_waitstream(chan, "");
2889                                         if (res >= 0)
2890                                                 res = ast_waitstream(peer, "");
2891                                         if (res < 0)
2892                                                 error = 1;
2893                                 }
2894                         }
2895                         if (error) {
2896                                 ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
2897                                 ast_hangup(peer);
2898                                 return -1;
2899                         }
2900                 } else
2901                         ast_indicate(peer, AST_CONTROL_UNHOLD); 
2902
2903                 res = ast_channel_make_compatible(chan, peer);
2904                 if (res < 0) {
2905                         ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for bridge\n", chan->name, peer->name);
2906                         ast_hangup(peer);
2907                         return -1;
2908                 }
2909                 /* This runs sorta backwards, since we give the incoming channel control, as if it
2910                    were the person called. */
2911                 ast_verb(3, "Channel %s connected to parked call %d\n", chan->name, park);
2912
2913                 pbx_builtin_setvar_helper(chan, "PARKEDCHANNEL", peer->name);
2914                 ast_cdr_setdestchan(chan->cdr, peer->name);
2915                 memset(&config, 0, sizeof(struct ast_bridge_config));
2916                 if ((parkinglot->parkedcalltransfers == AST_FEATURE_FLAG_BYCALLEE) || (parkinglot->parkedcalltransfers == AST_FEATURE_FLAG_BYBOTH))
2917                         ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
2918                 if ((parkinglot->parkedcalltransfers == AST_FEATURE_FLAG_BYCALLER) || (parkinglot->parkedcalltransfers == AST_FEATURE_FLAG_BYBOTH))
2919                         ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
2920                 if ((parkinglot->parkedcallreparking == AST_FEATURE_FLAG_BYCALLEE) || (parkinglot->parkedcallreparking == AST_FEATURE_FLAG_BYBOTH))
2921                         ast_set_flag(&(config.features_callee), AST_FEATURE_PARKCALL);
2922                 if ((parkinglot->parkedcallreparking == AST_FEATURE_FLAG_BYCALLER) || (parkinglot->parkedcallreparking == AST_FEATURE_FLAG_BYBOTH))
2923                         ast_set_flag(&(config.features_caller), AST_FEATURE_PARKCALL);
2924                 res = ast_bridge_call(chan, peer, &config);
2925
2926                 pbx_builtin_setvar_helper(chan, "PARKEDCHANNEL", peer->name);
2927                 ast_cdr_setdestchan(chan->cdr, peer->name);
2928
2929                 /* Simulate the PBX hanging up */
2930                 if (res != AST_PBX_NO_HANGUP_PEER)
2931                         ast_hangup(peer);
2932                 return res;
2933         } else {
2934                 /*! \todo XXX Play a message XXX */
2935                 if (ast_stream_and_wait(chan, "pbx-invalidpark", ""))
2936                         ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", "pbx-invalidpark", chan->name);
2937                 ast_verb(3, "Channel %s tried to talk to nonexistent parked call %d\n", chan->name, park);
2938                 res = -1;
2939         }
2940
2941         return res;
2942 }
2943
2944 static int park_exec(struct ast_channel *chan, void *data) 
2945 {
2946         return park_exec_full(chan, data, default_parkinglot);
2947 }
2948
2949 /*! \brief Unreference parkinglot object. If no more references,
2950         then go ahead and delete it */
2951 static void parkinglot_unref(struct ast_parkinglot *parkinglot) 
2952 {
2953         int refcount = ao2_ref(parkinglot, -1);
2954         if (option_debug > 2)
2955                 ast_log(LOG_DEBUG, "Multiparking: %s refcount now %d\n", parkinglot->name, refcount - 1);
2956 }
2957
2958 static struct ast_parkinglot *parkinglot_addref(struct ast_parkinglot *parkinglot)
2959 {
2960         int refcount = ao2_ref(parkinglot, +1);
2961         if (option_debug > 2)
2962                 ast_log(LOG_DEBUG, "Multiparking: %s refcount now %d\n", parkinglot->name, refcount + 1);
2963         return parkinglot;
2964 }
2965
2966 /*! \brief Allocate parking lot structure */
2967 static struct ast_parkinglot *create_parkinglot(char *name)
2968 {
2969         struct ast_parkinglot *newlot = (struct ast_parkinglot *) NULL;
2970
2971         if (!name)
2972                 return NULL;
2973
2974         newlot = ao2_alloc(sizeof(*newlot), parkinglot_destroy);
2975         if (!newlot)
2976                 return NULL;
2977         
2978         ast_copy_string(newlot->name, name, sizeof(newlot->name));
2979
2980         return newlot;
2981 }
2982
2983 /*! \brief Destroy a parking lot */
2984 static void parkinglot_destroy(void *obj)
2985 {
2986         struct ast_parkinglot *ruin = obj;
2987         struct ast_context *con;
2988         con = ast_context_find(ruin->parking_con);
2989         if (con)
2990                 ast_context_destroy(con, registrar);
2991         ao2_unlink(parkinglots, ruin);
2992 }
2993
2994 /*! \brief Build parkinglot from configuration and chain it in */
2995 static struct ast_parkinglot *build_parkinglot(char *name, struct ast_variable *var)
2996 {
2997         struct ast_parkinglot *parkinglot;
2998         struct ast_context *con = NULL;
2999
3000         struct ast_variable *confvar = var;
3001         int error = 0;
3002         int start = 0, end = 0;
3003         int oldparkinglot = 0;
3004
3005         parkinglot = find_parkinglot(name);
3006         if (parkinglot)
3007                 oldparkinglot = 1;
3008         else
3009                 parkinglot = create_parkinglot(name);
3010
3011         if (!parkinglot)
3012                 return NULL;
3013
3014         ao2_lock(parkinglot);
3015
3016         if (option_debug)
3017                 ast_log(LOG_DEBUG, "Building parking lot %s\n", name);
3018         
3019         /* Do some config stuff */
3020         while(confvar) {
3021                 if (!strcasecmp(confvar->name, "context")) {
3022                         ast_copy_string(parkinglot->parking_con, confvar->value, sizeof(parkinglot->parking_con));
3023                 } else if (!strcasecmp(confvar->name, "parkingtime")) {
3024                         if ((sscanf(confvar->value, "%d", &parkinglot->parkingtime) != 1) || (parkinglot->parkingtime < 1)) {
3025                                 ast_log(LOG_WARNING, "%s is not a valid parkingtime\n", confvar->value);
3026                                 parkinglot->parkingtime = DEFAULT_PARK_TIME;
3027                         } else
3028                                 parkinglot->parkingtime = parkinglot->parkingtime * 1000;
3029                 } else if (!strcasecmp(confvar->name, "parkpos")) {
3030                         if (sscanf(confvar->value, "%d-%d", &start, &end) != 2) {
3031                                 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);
3032                                 error = 1;
3033                         } else {
3034                                 parkinglot->parking_start = start;
3035                                 parkinglot->parking_stop = end;
3036                         }
3037                 } else if (!strcasecmp(confvar->name, "findslot")) {
3038                         parkinglot->parkfindnext = (!strcasecmp(confvar->value, "next"));
3039                 }
3040                 confvar = confvar->next;
3041         }
3042         /* make sure parkingtime is set if not specified */
3043         if (parkinglot->parkingtime == 0) {
3044                 parkinglot->parkingtime = DEFAULT_PARK_TIME;
3045         }
3046
3047         if (!var) {     /* Default parking lot */
3048                 ast_copy_string(parkinglot->parking_con, "parkedcalls", sizeof(parkinglot->parking_con));
3049                 ast_copy_string(parkinglot->parking_con_dial, "park-dial", sizeof(parkinglot->parking_con_dial));
3050                 ast_copy_string(parkinglot->mohclass, "default", sizeof(parkinglot->mohclass));
3051         }
3052
3053         /* Check for errors */
3054         if (ast_strlen_zero(parkinglot->parking_con)) {
3055                 ast_log(LOG_WARNING, "Parking lot %s lacks context\n", name);
3056                 error = 1;
3057         }
3058
3059         /* Create context */
3060         if (!error && !(con = ast_context_find_or_create(NULL, NULL, parkinglot->parking_con, registrar))) {
3061                 ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", parkinglot->parking_con);
3062                 error = 1;
3063         }
3064
3065         /* Add a parking extension into the context */
3066         if (!oldparkinglot) {
3067                 if (!ast_strlen_zero(ast_parking_ext())) {
3068                         if (ast_add_extension2(con, 1, ast_parking_ext(), 1, NULL, NULL, parkcall, strdup(""), ast_free, registrar) == -1)
3069                                 error = 1;
3070                 }
3071         }
3072
3073         ao2_unlock(parkinglot);
3074
3075         if (error) {
3076                 ast_log(LOG_WARNING, "Parking %s not open for business. Configuration error.\n", name);
3077                 parkinglot_destroy(parkinglot);
3078                 return NULL;
3079         }
3080         if (option_debug)
3081                 ast_log(LOG_DEBUG, "Parking %s now open for business. (start exten %d end %d)\n", name, start, end);
3082
3083
3084         /* Move it into the list, if it wasn't already there */
3085         if (!oldparkinglot) {
3086                 ao2_link(parkinglots, parkinglot);
3087         }
3088         parkinglot_unref(parkinglot);
3089
3090         return parkinglot;
3091 }
3092
3093
3094 /*! 
3095  * \brief Add parking hints for all defined parking lots 
3096  * \param context
3097  * \param start starting parkinglot number
3098  * \param stop ending parkinglot number
3099 */
3100 static void park_add_hints(char *context, int start, int stop)
3101 {
3102         int numext;
3103         char device[AST_MAX_EXTENSION];
3104         char exten[10];
3105
3106         for (numext = start; numext <= stop; numext++) {
3107                 snprintf(exten, sizeof(exten), "%d", numext);
3108                 snprintf(device, sizeof(device), "park:%s@%s", exten, context);
3109                 ast_add_extension(context, 1, exten, PRIORITY_HINT, NULL, NULL, device, NULL, NULL, registrar);
3110         }
3111 }
3112
3113 static int load_config(void) 
3114 {
3115         int start = 0, end = 0;
3116         int res;
3117         int i;
3118         struct ast_context *con = NULL;
3119         struct ast_config *cfg = NULL;
3120         struct ast_variable *var = NULL;
3121         struct feature_group *fg = NULL;
3122         struct ast_flags config_flags = { 0 };
3123         char old_parking_ext[AST_MAX_EXTENSION];
3124         char old_parking_con[AST_MAX_EXTENSION] = "";
3125         char *ctg; 
3126         static const char *categories[] = { 
3127                 /* Categories in features.conf that are not
3128                  * to be parsed as group categories
3129                  */
3130                 "general",
3131                 "featuremap",
3132                 "applicationmap"
3133         };
3134
3135         if (default_parkinglot) {
3136                 strcpy(old_parking_con, default_parkinglot->parking_con);
3137                 strcpy(old_parking_ext, parking_ext);
3138         } else {
3139                 default_parkinglot = build_parkinglot(DEFAULT_PARKINGLOT, NULL);
3140                 if (default_parkinglot) {
3141                         ao2_lock(default_parkinglot);
3142                         default_parkinglot->parking_start = 701;
3143                         default_parkinglot->parking_stop = 750;
3144                         default_parkinglot->parking_offset = 0;
3145                         default_parkinglot->parkfindnext = 0;
3146                         default_parkinglot->parkingtime = DEFAULT_PARK_TIME;
3147                         ao2_unlock(default_parkinglot);
3148                 }
3149         }
3150         if (default_parkinglot) {
3151                 if (option_debug)
3152                         ast_log(LOG_DEBUG, "Configuration of default parkinglot done.\n");
3153         } else {
3154                 ast_log(LOG_ERROR, "Configuration of default parkinglot failed.\n");
3155                 return -1;
3156         }
3157         
3158
3159         /* Reset to defaults */
3160         strcpy(parking_ext, "700");
3161         strcpy(pickup_ext, "*8");
3162         courtesytone[0] = '\0';
3163         strcpy(xfersound, "beep");
3164         strcpy(xferfailsound, "pbx-invalid");
3165         adsipark = 0;
3166         comebacktoorigin = 1;
3167
3168         default_parkinglot->parkaddhints = 0;
3169         default_parkinglot->parkedcalltransfers = 0;
3170         default_parkinglot->parkedcallreparking = 0;
3171
3172         transferdigittimeout = DEFAULT_TRANSFER_DIGIT_TIMEOUT;
3173         featuredigittimeout = DEFAULT_FEATURE_DIGIT_TIMEOUT;
3174         atxfernoanswertimeout = DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER;
3175         atxferloopdelay = DEFAULT_ATXFER_LOOP_DELAY;
3176         atxferdropcall = DEFAULT_ATXFER_DROP_CALL;
3177         atxfercallbackretries = DEFAULT_ATXFER_CALLBACK_RETRIES;
3178
3179         cfg = ast_config_load2("features.conf", "features", config_flags);
3180         if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
3181                 ast_log(LOG_WARNING,"Could not load features.conf\n");
3182                 return 0;
3183         }
3184         for (var = ast_variable_browse(cfg, "general"); var; var = var->next) {
3185                 if (!strcasecmp(var->name, "parkext")) {
3186                         ast_copy_string(parking_ext, var->value, sizeof(parking_ext));
3187                 } else if (!strcasecmp(var->name, "context")) {
3188                         ast_copy_string(default_parkinglot->parking_con, var->value, sizeof(default_parkinglot->parking_con));
3189                 } else if (!strcasecmp(var->name, "parkingtime")) {
3190                         if ((sscanf(var->value, "%d", &default_parkinglot->parkingtime) != 1) || (default_parkinglot->parkingtime < 1)) {
3191                                 ast_log(LOG_WARNING, "%s is not a valid parkingtime\n", var->value);
3192                                 default_parkinglot->parkingtime = DEFAULT_PARK_TIME;
3193                         } else
3194                                 default_parkinglot->parkingtime = default_parkinglot->parkingtime * 1000;
3195                 } else if (!strcasecmp(var->name, "parkpos")) {
3196                         if (sscanf(var->value, "%d-%d", &start, &end) != 2) {
3197                                 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);
3198                         } else if (default_parkinglot) {
3199                                 default_parkinglot->parking_start = start;
3200                                 default_parkinglot->parking_stop = end;
3201                         } else {
3202                                 ast_log(LOG_WARNING, "No default parking lot!\n");
3203                         }
3204                 } else if (!strcasecmp(var->name, "findslot")) {
3205                         default_parkinglot->parkfindnext = (!strcasecmp(var->value, "next"));
3206                 } else if (!strcasecmp(var->name, "parkinghints")) {
3207                         default_parkinglot->parkaddhints = ast_true(var->value);
3208                 } else if (!strcasecmp(var->name, "parkedcalltransfers")) {
3209                         if (!strcasecmp(var->value, "both"))
3210                                 default_parkinglot->parkedcalltransfers = AST_FEATURE_FLAG_BYBOTH;
3211                         else if (!strcasecmp(var->value, "caller"))
3212                                 default_parkinglot->parkedcalltransfers = AST_FEATURE_FLAG_BYCALLER;
3213                         else if (!strcasecmp(var->value, "callee"))
3214                                 default_parkinglot->parkedcalltransfers = AST_FEATURE_FLAG_BYCALLEE;
3215                 } else if (!strcasecmp(var->name, "parkedcallreparking")) {
3216                         if (!strcasecmp(var->value, "both"))
3217                                 default_parkinglot->parkedcallreparking = AST_FEATURE_FLAG_BYBOTH;
3218                         else if (!strcasecmp(var->value, "caller"))
3219                                 default_parkinglot->parkedcallreparking = AST_FEATURE_FLAG_BYCALLER;
3220                         else if (!strcasecmp(var->value, "callee"))
3221                                 default_parkinglot->parkedcallreparking = AST_FEATURE_FLAG_BYCALLEE;
3222                 } else if (!strcasecmp(var->name, "adsipark")) {
3223                         adsipark = ast_true(var->value);
3224                 } else if (!strcasecmp(var->name, "transferdigittimeout")) {
3225                         if ((sscanf(var->value, "%d", &transferdigittimeout) != 1) || (transferdigittimeout < 1)) {
3226                                 ast_log(LOG_WARNING, "%s is not a valid transferdigittimeout\n", var->value);
3227                                 transferdigittimeout = DEFAULT_TRANSFER_DIGIT_TIMEOUT;
3228                         } else
3229                                 transferdigittimeout = transferdigittimeout * 1000;
3230                 } else if (!strcasecmp(var->name, "featuredigittimeout")) {
3231                         if ((sscanf(var->value, "%d", &featuredigittimeout) != 1) || (featuredigittimeout < 1)) {
3232                                 ast_log(LOG_WARNING, "%s is not a valid featuredigittimeout\n", var->value);
3233                                 featuredigittimeout = DEFAULT_FEATURE_DIGIT_TIMEOUT;
3234                         }
3235                 } else if (!strcasecmp(var->name, "atxfernoanswertimeout")) {
3236                         if ((sscanf(var->value, "%d", &atxfernoanswertimeout) != 1) || (atxfernoanswertimeout < 1)) {
3237                                 ast_log(LOG_WARNING, "%s is not a valid atxfernoanswertimeout\n", var->value);
3238                                 atxfernoanswertimeout = DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER;
3239                         } else
3240                                 atxfernoanswertimeout = atxfernoanswertimeout * 1000;
3241                 } else if (!strcasecmp(var->name, "atxferloopdelay")) {
3242                         if ((sscanf(var->value, "%u", &atxferloopdelay) != 1)) {
3243                                 ast_log(LOG_WARNING, "%s is not a valid atxferloopdelay\n", var->value);
3244                                 atxferloopdelay = DEFAULT_ATXFER_LOOP_DELAY;
3245                         } else 
3246                                 atxferloopdelay *= 1000;
3247                 } else if (!strcasecmp(var->name, "atxferdropcall")) {
3248                         atxferdropcall = ast_true(var->value);
3249                 } else if (!strcasecmp(var->name, "atxfercallbackretries")) {
3250                         if ((sscanf(var->value, "%u", &atxferloopdelay) != 1)) {
3251                                 ast_log(LOG_WARNING, "%s is not a valid atxfercallbackretries\n", var->value);
3252                                 atxfercallbackretries = DEFAULT_ATXFER_CALLBACK_RETRIES;
3253                         }
3254                 } else if (!strcasecmp(var->name, "courtesytone")) {
3255                         ast_copy_string(courtesytone, var->value, sizeof(courtesytone));
3256                 }  else if (!strcasecmp(var->name, "parkedplay")) {
3257                         if (!strcasecmp(var->value, "both"))
3258                                 parkedplay = 2;
3259                         else if (!strcasecmp(var->value, "parked"))
3260                                 parkedplay = 1;
3261                         else
3262                                 parkedplay = 0;
3263                 } else if (!strcasecmp(var->name, "xfersound")) {
3264                         ast_copy_string(xfersound, var->value, sizeof(xfersound));
3265                 } else if (!strcasecmp(var->name, "xferfailsound")) {
3266                         ast_copy_string(xferfailsound, var->value, sizeof(xferfailsound));
3267                 } else if (!strcasecmp(var->name, "pickupexten")) {
3268                         ast_copy_string(pickup_ext, var->value, sizeof(pickup_ext));
3269                 } else if (!strcasecmp(var->name, "comebacktoorigin")) {
3270                         comebacktoorigin = ast_true(var->value);
3271                 } else if (!strcasecmp(var->name, "parkedmusicclass")) {
3272                         ast_copy_string(default_parkinglot->mohclass, var->value, sizeof(default_parkinglot->mohclass));
3273                 }
3274         }
3275
3276         unmap_features();
3277         for (var = ast_variable_browse(cfg, "featuremap"); var; var = var->next) {
3278                 if (remap_feature(var->name, var->value))
3279                         ast_log(LOG_NOTICE, "Unknown feature '%s'\n", var->name);
3280         }
3281
3282         /* Map a key combination to an application*/
3283         ast_unregister_features();
3284         for (var = ast_variable_browse(cfg, "applicationmap"); var; var = var->next) {
3285                 char *tmp_val = ast_strdupa(var->value);
3286                 char *exten, *activateon, *activatedby, *app, *app_args, *moh_class; 
3287                 struct ast_call_feature *feature;
3288
3289                 /* strsep() sets the argument to NULL if match not found, and it
3290                  * is safe to use it with a NULL argument, so we don't check
3291                  * between calls.
3292                  */
3293                 exten = strsep(&tmp_val,",");
3294                 activatedby = strsep(&tmp_val,",");
3295                 app = strsep(&tmp_val,",");
3296                 app_args = strsep(&tmp_val,",");
3297                 moh_class = strsep(&tmp_val,",");
3298
3299                 activateon = strsep(&activatedby, "/"); 
3300
3301                 /*! \todo XXX var_name or app_args ? */
3302                 if (ast_strlen_zero(app) || ast_strlen_zero(exten) || ast_strlen_zero(activateon) || ast_strlen_zero(var->name)) {
3303                         ast_log(LOG_NOTICE, "Please check the feature Mapping Syntax, either extension, name, or app aren't provided %s %s %s %s\n",
3304                                 app, exten, activateon, var->name);
3305                         continue;
3306                 }
3307
3308                 AST_LIST_LOCK(&feature_list);
3309                 if ((feature = find_dynamic_feature(var->name))) {
3310                         AST_LIST_UNLOCK(&feature_list);
3311                         ast_log(LOG_WARNING, "Dynamic Feature '%s' specified more than once!\n", var->name);
3312                         continue;
3313                 }
3314                 AST_LIST_UNLOCK(&feature_list);
3315                                 
3316                 if (!(feature = ast_calloc(1, sizeof(*feature))))
3317                         continue;                                       
3318
3319                 ast_copy_string(feature->sname, var->name, FEATURE_SNAME_LEN);
3320                 ast_copy_string(feature->app, app, FEATURE_APP_LEN);
3321                 ast_copy_string(feature->exten, exten, FEATURE_EXTEN_LEN);
3322                 
3323                 if (app_args) 
3324                         ast_copy_string(feature->app_args, app_args, FEATURE_APP_ARGS_LEN);
3325
3326                 if (moh_class)
3327                         ast_copy_string(feature->moh_class, moh_class, FEATURE_MOH_LEN);
3328                         
3329                 ast_copy_string(feature->exten, exten, sizeof(feature->exten));
3330                 feature->operation = feature_exec_app;
3331                 ast_set_flag(feature, AST_FEATURE_FLAG_NEEDSDTMF);
3332
3333                 /* Allow caller and calle to be specified for backwards compatability */
3334                 if (!strcasecmp(activateon, "self") || !strcasecmp(activateon, "caller"))
3335                         ast_set_flag(feature, AST_FEATURE_FLAG_ONSELF);
3336                 else if (!strcasecmp(activateon, "peer") || !strcasecmp(activateon, "callee"))
3337                         ast_set_flag(feature, AST_FEATURE_FLAG_ONPEER);
3338                 else {
3339                         ast_log(LOG_NOTICE, "Invalid 'ActivateOn' specification for feature '%s',"
3340                                 " must be 'self', or 'peer'\n", var->name);
3341                         continue;
3342                 }
3343
3344                 if (ast_strlen_zero(activatedby))
3345                         ast_set_flag(feature, AST_FEATURE_FLAG_BYBOTH);
3346                 else if (!strcasecmp(activatedby, "caller"))
3347                         ast_set_flag(feature, AST_FEATURE_FLAG_BYCALLER);
3348                 else if (!strcasecmp(activatedby, "callee"))
3349                         ast_set_flag(feature, AST_FEATURE_FLAG_BYCALLEE);
3350                 else if (!strcasecmp(activatedby, "both"))
3351                         ast_set_flag(feature, AST_FEATURE_FLAG_BYBOTH);
3352                 else {
3353                         ast_log(LOG_NOTICE, "Invalid 'ActivatedBy' specification for feature '%s',"
3354                                 " must be 'caller', or 'callee', or 'both'\n", var->name);
3355                         continue;
3356                 }
3357
3358                 ast_register_feature(feature);
3359                         
3360                 ast_verb(2, "Mapping Feature '%s' to app '%s(%s)' with code '%s'\n", var->name, app, app_args, exten);
3361         }
3362
3363         ast_unregister_groups();
3364         AST_RWLIST_WRLOCK(&feature_groups);
3365
3366         ctg = NULL;
3367         while ((ctg = ast_category_browse(cfg, ctg))) {
3368                 /* Is this a parkinglot definition ? */
3369                 if (!strncasecmp(ctg, "parkinglot_", strlen("parkinglot_"))) {
3370                         ast_debug(2, "Found configuration section %s, assume parking context\n", ctg);
3371                         if(!build_parkinglot(ctg, ast_variable_browse(cfg, ctg)))
3372                                 ast_log(LOG_ERROR, "Could not build parking lot %s. Configuration error.\n", ctg);
3373                         else
3374                                 ast_debug(1, "Configured parking context %s\n", ctg);
3375                         continue;       
3376                 }
3377                 /* No, check if it's a group */
3378                 for (i = 0; i < ARRAY_LEN(categories); i++) {
3379                         if (!strcasecmp(categories[i], ctg))
3380                                 break;
3381                 }
3382
3383                 if (i < ARRAY_LEN(categories)) 
3384                         continue;
3385
3386                 if (!(fg = register_group(ctg)))
3387                         continue;
3388
3389                 for (var = ast_variable_browse(cfg, ctg); var; var = var->next) {