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