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