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