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