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