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