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