2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 1999 - 2008, Digium, Inc.
6 * Mark Spencer <markster@digium.com>
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.
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.
21 * \brief Routines implementing call features as call pickup, parking and transfer
23 * \author Mark Spencer <markster@digium.com>
28 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
30 #include "asterisk/_private.h"
34 #include <sys/signal.h>
35 #include <netinet/in.h>
37 #include "asterisk/lock.h"
38 #include "asterisk/file.h"
39 #include "asterisk/channel.h"
40 #include "asterisk/pbx.h"
41 #include "asterisk/causes.h"
42 #include "asterisk/module.h"
43 #include "asterisk/translate.h"
44 #include "asterisk/app.h"
45 #include "asterisk/say.h"
46 #include "asterisk/features.h"
47 #include "asterisk/musiconhold.h"
48 #include "asterisk/config.h"
49 #include "asterisk/cli.h"
50 #include "asterisk/manager.h"
51 #include "asterisk/utils.h"
52 #include "asterisk/adsi.h"
53 #include "asterisk/devicestate.h"
54 #include "asterisk/monitor.h"
55 #include "asterisk/audiohook.h"
56 #include "asterisk/global_datastores.h"
57 #include "asterisk/astobj2.h"
60 <application name="Bridge" language="en_US">
65 <parameter name="channel" required="true">
66 <para>The current channel is bridged to the specified <replaceable>channel</replaceable>.</para>
68 <parameter name="options">
71 <para>Play a courtesy tone to <replaceable>channel</replaceable>.</para>
77 <para>Allows the ability to bridge two channels via the dialplan.</para>
78 <para>This application sets the following channel variable upon completion:</para>
80 <variable name="BRIDGERESULT">
81 <para>The result of the bridge attempt as a text string.</para>
82 <value name="SUCCESS" />
83 <value name="FAILURE" />
85 <value name="NONEXISTENT" />
86 <value name="INCOMPATIBLE" />
91 <application name="ParkedCall" language="en_US">
96 <parameter name="exten" required="true" />
99 <para>Used to connect to a parked call. This application is always
100 registered internally and does not need to be explicitly added
101 into the dialplan, although you should include the <literal>parkedcalls</literal>
102 context. If no extension is provided, then the first available
103 parked call will be acquired.</para>
106 <ref type="application">Park</ref>
107 <ref type="application">ParkAndAnnounce</ref>
110 <application name="Park" language="en_US">
115 <parameter name="timeout">
116 <para>A custom parking timeout for this parked call.</para>
118 <parameter name="return_context">
119 <para>The context to return the call to after it times out.</para>
121 <parameter name="return_exten">
122 <para>The extension to return the call to after it times out.</para>
124 <parameter name="return_priority">
125 <para>The priority to return the call to after it times out.</para>
127 <parameter name="options">
128 <para>A list of options for this parked call.</para>
131 <para>Send ringing instead of MOH to the parked call.</para>
134 <para>Randomize the selection of a parking space.</para>
137 <para>Silence announcement of the parking space number.</para>
143 <para>Used to park yourself (typically in combination with a supervised
144 transfer to know the parking space). This application is always
145 registered internally and does not need to be explicitly added
146 into the dialplan, although you should include the <literal>parkedcalls</literal>
147 context (or the context specified in <filename>features.conf</filename>).</para>
148 <para>If you set the <variable>PARKINGEXTEN</variable> variable to an extension in your
149 parking context, Park() will park the call on that extension, unless
150 it already exists. In that case, execution will continue at next priority.</para>
153 <ref type="application">ParkAndAnnounce</ref>
154 <ref type="application">ParkedCall</ref>
159 #define DEFAULT_PARK_TIME 45000
160 #define DEFAULT_TRANSFER_DIGIT_TIMEOUT 3000
161 #define DEFAULT_FEATURE_DIGIT_TIMEOUT 2000
162 #define DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER 15000
163 #define DEFAULT_PARKINGLOT "default" /*!< Default parking lot */
164 #define DEFAULT_ATXFER_DROP_CALL 0
165 #define DEFAULT_ATXFER_LOOP_DELAY 10000
166 #define DEFAULT_ATXFER_CALLBACK_RETRIES 2
168 #define AST_MAX_WATCHERS 256
169 #define MAX_DIAL_FEATURE_OPTIONS 30
171 struct feature_group_exten {
172 AST_LIST_ENTRY(feature_group_exten) entry;
173 AST_DECLARE_STRING_FIELDS(
174 AST_STRING_FIELD(exten);
176 struct ast_call_feature *feature;
179 struct feature_group {
180 AST_LIST_ENTRY(feature_group) entry;
181 AST_DECLARE_STRING_FIELDS(
182 AST_STRING_FIELD(gname);
184 AST_LIST_HEAD_NOLOCK(, feature_group_exten) features;
187 static AST_RWLIST_HEAD_STATIC(feature_groups, feature_group);
189 static char *parkedcall = "ParkedCall";
191 static char pickup_ext[AST_MAX_EXTENSION]; /*!< Call pickup extension */
193 /*! \brief Description of one parked call, added to a list while active, then removed.
194 The list belongs to a parkinglot
197 struct ast_channel *chan; /*!< Parking channel */
198 struct timeval start; /*!< Time the parking started */
199 int parkingnum; /*!< Parking lot */
200 char parkingexten[AST_MAX_EXTENSION]; /*!< If set beforehand, parking extension used for this call */
201 char context[AST_MAX_CONTEXT]; /*!< Where to go if our parking time expires */
202 char exten[AST_MAX_EXTENSION];
204 int parkingtime; /*!< Maximum length in parking lot before return */
207 unsigned char moh_trys;
208 struct ast_parkinglot *parkinglot;
209 AST_LIST_ENTRY(parkeduser) list;
212 /*! \brief Structure for parking lots which are put in a container. */
213 struct ast_parkinglot {
214 char name[AST_MAX_CONTEXT];
215 char parking_con[AST_MAX_EXTENSION]; /*!< Context for which parking is made accessible */
216 char parking_con_dial[AST_MAX_EXTENSION]; /*!< Context for dialback for parking (KLUDGE) */
217 int parking_start; /*!< First available extension for parking */
218 int parking_stop; /*!< Last available extension for parking */
221 int parkingtime; /*!< Default parking time */
222 char mohclass[MAX_MUSICCLASS]; /*!< Music class used for parking */
223 int parkaddhints; /*!< Add parking hints automatically */
224 int parkedcalltransfers; /*!< Enable DTMF based transfers on bridge when picking up parked calls */
225 int parkedcallreparking; /*!< Enable DTMF based parking on bridge when picking up parked calls */
226 int parkedcallhangup; /*!< Enable DTMF based hangup on a bridge when pickup up parked calls */
227 int parkedcallrecording; /*!< Enable DTMF based recording on a bridge when picking up parked calls */
228 AST_LIST_HEAD(parkinglot_parklist, parkeduser) parkings; /*!< List of active parkings in this parkinglot */
231 /*! \brief The list of parking lots configured. Always at least one - the default parking lot */
232 static struct ao2_container *parkinglots;
234 struct ast_parkinglot *default_parkinglot;
235 char parking_ext[AST_MAX_EXTENSION]; /*!< Extension you type to park the call */
237 static char courtesytone[256]; /*!< Courtesy tone */
238 static int parkedplay = 0; /*!< Who to play the courtesy tone to */
239 static char xfersound[256]; /*!< Call transfer sound */
240 static char xferfailsound[256]; /*!< Call transfer failure sound */
244 static int transferdigittimeout;
245 static int featuredigittimeout;
246 static int comebacktoorigin = 1;
248 static int atxfernoanswertimeout;
249 static unsigned int atxferdropcall;
250 static unsigned int atxferloopdelay;
251 static unsigned int atxfercallbackretries;
253 static char *registrar = "features"; /*!< Registrar for operations */
255 /* module and CLI command definitions */
256 static char *parkcall = PARK_APP_NAME;
258 static struct ast_app *monitor_app = NULL;
259 static int monitor_ok = 1;
261 static struct ast_app *mixmonitor_app = NULL;
262 static int mixmonitor_ok = 1;
264 static struct ast_app *stopmixmonitor_app = NULL;
265 static int stopmixmonitor_ok = 1;
267 static pthread_t parking_thread;
268 struct ast_dial_features {
269 struct ast_flags features_caller;
270 struct ast_flags features_callee;
274 static void *dial_features_duplicate(void *data)
276 struct ast_dial_features *df = data, *df_copy;
278 if (!(df_copy = ast_calloc(1, sizeof(*df)))) {
282 memcpy(df_copy, df, sizeof(*df));
287 static void dial_features_destroy(void *data)
289 struct ast_dial_features *df = data;
295 const struct ast_datastore_info dial_features_info = {
296 .type = "dial-features",
297 .destroy = dial_features_destroy,
298 .duplicate = dial_features_duplicate,
301 /* Forward declarations */
302 static struct ast_parkinglot *parkinglot_addref(struct ast_parkinglot *parkinglot);
303 static void parkinglot_unref(struct ast_parkinglot *parkinglot);
304 static void parkinglot_destroy(void *obj);
305 int manage_parkinglot(struct ast_parkinglot *curlot, fd_set *rfds, fd_set *efds, fd_set *nrfds, fd_set *nefds, int *fs, int *max);
306 struct ast_parkinglot *find_parkinglot(const char *name);
309 const char *ast_parking_ext(void)
314 const char *ast_pickup_ext(void)
319 struct ast_bridge_thread_obj
321 struct ast_bridge_config bconfig;
322 struct ast_channel *chan;
323 struct ast_channel *peer;
324 unsigned int return_to_pbx:1;
327 static int parkinglot_hash_cb(const void *obj, const int flags)
329 const struct ast_parkinglot *parkinglot = obj;
331 return ast_str_case_hash(parkinglot->name);
334 static int parkinglot_cmp_cb(void *obj, void *arg, int flags)
336 struct ast_parkinglot *parkinglot = obj, *parkinglot2 = arg;
338 return !strcasecmp(parkinglot->name, parkinglot2->name) ? CMP_MATCH | CMP_STOP : 0;
342 * \brief store context, extension and priority
343 * \param chan, context, ext, pri
345 static void set_c_e_p(struct ast_channel *chan, const char *context, const char *ext, int pri)
347 ast_copy_string(chan->context, context, sizeof(chan->context));
348 ast_copy_string(chan->exten, ext, sizeof(chan->exten));
349 chan->priority = pri;
353 * \brief Check goto on transfer
356 * Check if channel has 'GOTO_ON_BLINDXFR' set, if not exit.
357 * When found make sure the types are compatible. Check if channel is valid
358 * if so start the new channel else hangup the call.
360 static void check_goto_on_transfer(struct ast_channel *chan)
362 struct ast_channel *xferchan;
363 const char *val = pbx_builtin_getvar_helper(chan, "GOTO_ON_BLINDXFR");
364 char *x, *goto_on_transfer;
367 if (ast_strlen_zero(val))
370 goto_on_transfer = ast_strdupa(val);
372 if (!(xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "%s", chan->name)))
375 for (x = goto_on_transfer; x && *x; x++) {
379 /* Make formats okay */
380 xferchan->readformat = chan->readformat;
381 xferchan->writeformat = chan->writeformat;
382 ast_channel_masquerade(xferchan, chan);
383 ast_parseable_goto(xferchan, goto_on_transfer);
384 xferchan->_state = AST_STATE_UP;
385 ast_clear_flag(xferchan, AST_FLAGS_ALL);
386 xferchan->_softhangup = 0;
387 if ((f = ast_read(xferchan))) {
390 ast_pbx_start(xferchan);
392 ast_hangup(xferchan);
396 static struct ast_channel *ast_feature_request_and_dial(struct ast_channel *caller, struct ast_channel *transferee, const char *type, int format, void *data, int timeout, int *outstate, const char *cid_num, const char *cid_name, int igncallerstate, const char *language);
399 * \brief bridge the call
400 * \param data thread bridge.
402 * Set Last Data for respective channels, reset cdr for channels
403 * bridge call, check if we're going back to dialplan
404 * if not hangup both legs of the call
406 static void *ast_bridge_call_thread(void *data)
408 struct ast_bridge_thread_obj *tobj = data;
411 tobj->chan->appl = !tobj->return_to_pbx ? "Transferred Call" : "ManagerBridge";
412 tobj->chan->data = tobj->peer->name;
413 tobj->peer->appl = !tobj->return_to_pbx ? "Transferred Call" : "ManagerBridge";
414 tobj->peer->data = tobj->chan->name;
416 ast_bridge_call(tobj->peer, tobj->chan, &tobj->bconfig);
418 if (tobj->return_to_pbx) {
419 if (!ast_check_hangup(tobj->peer)) {
420 ast_log(LOG_VERBOSE, "putting peer %s into PBX again\n", tobj->peer->name);
421 res = ast_pbx_start(tobj->peer);
422 if (res != AST_PBX_SUCCESS)
423 ast_log(LOG_WARNING, "FAILED continuing PBX on peer %s\n", tobj->peer->name);
425 ast_hangup(tobj->peer);
426 if (!ast_check_hangup(tobj->chan)) {
427 ast_log(LOG_VERBOSE, "putting chan %s into PBX again\n", tobj->chan->name);
428 res = ast_pbx_start(tobj->chan);
429 if (res != AST_PBX_SUCCESS)
430 ast_log(LOG_WARNING, "FAILED continuing PBX on chan %s\n", tobj->chan->name);
432 ast_hangup(tobj->chan);
434 ast_hangup(tobj->chan);
435 ast_hangup(tobj->peer);
444 * \brief create thread for the parked call
447 * Create thread and attributes, call ast_bridge_call_thread
449 static void ast_bridge_call_thread_launch(void *data)
453 struct sched_param sched;
455 pthread_attr_init(&attr);
456 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
457 ast_pthread_create(&thread, &attr,ast_bridge_call_thread, data);
458 pthread_attr_destroy(&attr);
459 memset(&sched, 0, sizeof(sched));
460 pthread_setschedparam(thread, SCHED_RR, &sched);
464 * \brief Announce call parking by ADSI
466 * \param parkingexten .
467 * Create message to show for ADSI, display message.
468 * \retval 0 on success.
469 * \retval -1 on failure.
471 static int adsi_announce_park(struct ast_channel *chan, char *parkingexten)
474 int justify[5] = {ADSI_JUST_CENT, ADSI_JUST_CENT, ADSI_JUST_CENT, ADSI_JUST_CENT};
476 char *message[5] = {NULL, NULL, NULL, NULL, NULL};
478 snprintf(tmp, sizeof(tmp), "Parked on %s", parkingexten);
480 res = ast_adsi_load_session(chan, NULL, 0, 1);
483 return ast_adsi_print(chan, message, justify, 1);
486 /*! \brief Find parking lot name from channel */
487 static const char *findparkinglotname(struct ast_channel *chan)
489 const char *temp, *parkinglot = NULL;
491 /* Check if the channel has a parking lot */
492 if (!ast_strlen_zero(chan->parkinglot))
493 parkinglot = chan->parkinglot;
495 /* Channel variables override everything */
497 if ((temp = pbx_builtin_getvar_helper(chan, "PARKINGLOT")))
503 /*! \brief Notify metermaids that we've changed an extension */
504 static void notify_metermaids(const char *exten, char *context, enum ast_device_state state)
506 ast_debug(4, "Notification of state change to metermaids %s@%s\n to state '%s'",
507 exten, context, ast_devstate2str(state));
509 ast_devstate_changed(state, "park:%s@%s", exten, context);
512 /*! \brief metermaids callback from devicestate.c */
513 static enum ast_device_state metermaidstate(const char *data)
518 context = ast_strdupa(data);
520 exten = strsep(&context, "@");
522 return AST_DEVICE_INVALID;
524 ast_debug(4, "Checking state of exten %s in context %s\n", exten, context);
526 if (!ast_exists_extension(NULL, context, exten, 1, NULL))
527 return AST_DEVICE_NOT_INUSE;
529 return AST_DEVICE_INUSE;
532 /*! Options to pass to ast_park_call_full */
533 enum ast_park_call_options {
534 /*! Provide ringing to the parked caller instead of music on hold */
535 AST_PARK_OPT_RINGING = (1 << 0),
536 /*! Randomly choose a parking spot for the caller instead of choosing
537 * the first one that is available. */
538 AST_PARK_OPT_RANDOMIZE = (1 << 1),
539 /*! Do not announce the parking number */
540 AST_PARK_OPT_SILENCE = (1 << 2),
543 struct ast_park_call_args {
544 /*! How long to wait in the parking lot before the call gets sent back
545 * to the specified return extension (or a best guess at where it came
546 * from if not explicitly specified). */
548 /*! An output parameter to store the parking space where the parked caller
551 const char *orig_chan_name;
552 const char *return_con;
553 const char *return_ext;
556 /*! Parked user that has already obtained a parking space */
557 struct parkeduser *pu;
560 static struct parkeduser *park_space_reserve(struct ast_channel *chan,
561 struct ast_channel *peer, struct ast_park_call_args *args)
563 struct parkeduser *pu;
564 int i, parking_space = -1, parking_range;
565 const char *parkinglotname = NULL;
566 const char *parkingexten;
567 struct ast_parkinglot *parkinglot = NULL;
570 parkinglotname = findparkinglotname(peer);
572 if (parkinglotname) {
574 ast_log(LOG_DEBUG, "Found chanvar Parkinglot: %s\n", parkinglotname);
575 parkinglot = find_parkinglot(parkinglotname);
578 parkinglot = default_parkinglot;
580 parkinglot_addref(parkinglot);
582 ast_log(LOG_DEBUG, "Parkinglot: %s\n", parkinglot->name);
584 /* Allocate memory for parking data */
585 if (!(pu = ast_calloc(1, sizeof(*pu)))) {
586 parkinglot_unref(parkinglot);
590 /* Lock parking list */
591 AST_LIST_LOCK(&parkinglot->parkings);
592 /* Check for channel variable PARKINGEXTEN */
593 parkingexten = pbx_builtin_getvar_helper(chan, "PARKINGEXTEN");
594 if (!ast_strlen_zero(parkingexten)) {
595 /*!\note The API forces us to specify a numeric parking slot, even
596 * though the architecture would tend to support non-numeric extensions
597 * (as are possible with SIP, for example). Hence, we enforce that
598 * limitation here. If extout was not numeric, we could permit
599 * arbitrary non-numeric extensions.
601 if (sscanf(parkingexten, "%d", &parking_space) != 1 || parking_space < 0) {
602 AST_LIST_UNLOCK(&parkinglot->parkings);
603 parkinglot_unref(parkinglot);
605 ast_log(LOG_WARNING, "PARKINGEXTEN does not indicate a valid parking slot: '%s'.\n", parkingexten);
608 snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", parking_space);
610 if (ast_exists_extension(NULL, parkinglot->parking_con, pu->parkingexten, 1, NULL)) {
611 AST_LIST_UNLOCK(&parkinglot->parkings);
612 parkinglot_unref(parkinglot);
614 ast_log(LOG_WARNING, "Requested parking extension already exists: %s@%s\n", parkingexten, parkinglot->parking_con);
619 struct parkeduser *cur = NULL;
621 /* Select parking space within range */
622 parking_range = parkinglot->parking_stop - parkinglot->parking_start + 1;
624 if (ast_test_flag(args, AST_PARK_OPT_RANDOMIZE)) {
625 start = ast_random() % (parkinglot->parking_stop - parkinglot->parking_start + 1);
627 start = parkinglot->parking_start;
630 for (i = start; 1; i++) {
631 if (i == parkinglot->parking_stop + 1) {
632 i = parkinglot->parking_start - 1;
636 AST_LIST_TRAVERSE(&parkinglot->parkings, cur, list) {
637 if (cur->parkingnum == i) {
642 if (!cur || i == start - 1) {
648 if (i == start - 1 && cur) {
649 ast_log(LOG_WARNING, "No more parking spaces\n");
651 AST_LIST_UNLOCK(&parkinglot->parkings);
652 parkinglot_unref(parkinglot);
655 /* Set pointer for next parking */
656 if (parkinglot->parkfindnext)
657 parkinglot->parking_offset = parking_space - parkinglot->parking_start + 1;
658 snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", parking_space);
662 pu->parkingnum = parking_space;
663 pu->parkinglot = parkinglot;
664 AST_LIST_INSERT_TAIL(&parkinglot->parkings, pu, list);
665 parkinglot_unref(parkinglot);
671 static int ast_park_call_full(struct ast_channel *chan, struct ast_channel *peer, struct ast_park_call_args *args)
673 struct ast_context *con;
675 struct parkeduser *pu = args->pu;
678 pu = park_space_reserve(chan, peer, args);
680 return 1; /* Continue execution if possible */
682 snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", pu->parkingnum);
684 chan->appl = "Parked Call";
689 /* Put the parked channel on hold if we have two different channels */
691 if (ast_test_flag(args, AST_PARK_OPT_RINGING)) {
692 ast_indicate(pu->chan, AST_CONTROL_RINGING);
694 ast_indicate_data(pu->chan, AST_CONTROL_HOLD,
695 S_OR(pu->parkinglot->mohclass, NULL),
696 !ast_strlen_zero(pu->parkinglot->mohclass) ? strlen(pu->parkinglot->mohclass) + 1 : 0);
700 pu->start = ast_tvnow();
701 pu->parkingtime = (args->timeout > 0) ? args->timeout : pu->parkinglot->parkingtime;
702 parkingnum_copy = pu->parkingnum;
704 *(args->extout) = pu->parkingnum;
707 /* This is so ugly that it hurts, but implementing get_base_channel() on local channels
708 could have ugly side effects. We could have transferer<->local,1<->local,2<->parking
709 and we need the callback name to be that of transferer. Since local,1/2 have the same
710 name we can be tricky and just grab the bridged channel from the other side of the local
712 if (!strcasecmp(peer->tech->type, "Local")) {
713 struct ast_channel *tmpchan, *base_peer;
714 char other_side[AST_CHANNEL_NAME];
716 ast_copy_string(other_side, S_OR(args->orig_chan_name, peer->name), sizeof(other_side));
717 if ((c = strrchr(other_side, ';'))) {
720 if ((tmpchan = ast_get_channel_by_name_locked(other_side))) {
721 if ((base_peer = ast_bridged_channel(tmpchan))) {
722 ast_copy_string(pu->peername, base_peer->name, sizeof(pu->peername));
724 ast_channel_unlock(tmpchan);
727 ast_copy_string(pu->peername, S_OR(args->orig_chan_name, peer->name), sizeof(pu->peername));
731 /* Remember what had been dialed, so that if the parking
732 expires, we try to come back to the same place */
733 ast_copy_string(pu->context,
734 S_OR(args->return_con, S_OR(chan->macrocontext, chan->context)),
735 sizeof(pu->context));
736 ast_copy_string(pu->exten,
737 S_OR(args->return_ext, S_OR(chan->macroexten, chan->exten)),
739 pu->priority = pu->priority ? pu->priority :
740 (chan->macropriority ? chan->macropriority : chan->priority);
742 /* If parking a channel directly, don't quiet yet get parking running on it.
743 * All parking lot entries are put into the parking lot with notquiteyet on. */
747 /* Wake up the (presumably select()ing) thread */
748 pthread_kill(parking_thread, SIGURG);
749 ast_verb(2, "Parked %s on %d (lot %s). Will timeout back to extension [%s] %s, %d in %d seconds\n", pu->chan->name, pu->parkingnum, pu->parkinglot->name, pu->context, pu->exten, pu->priority, (pu->parkingtime/1000));
751 manager_event(EVENT_FLAG_CALL, "ParkedCall",
757 "CallerIDNum: %s\r\n"
758 "CallerIDName: %s\r\n"
760 pu->parkingexten, pu->chan->name, pu->parkinglot->name, peer ? peer->name : "",
761 (long)pu->start.tv_sec + (long)(pu->parkingtime/1000) - (long)time(NULL),
762 S_OR(pu->chan->cid.cid_num, "<unknown>"),
763 S_OR(pu->chan->cid.cid_name, "<unknown>"),
767 if (peer && adsipark && ast_adsi_available(peer)) {
768 adsi_announce_park(peer, pu->parkingexten); /* Only supports parking numbers */
769 ast_adsi_unload_session(peer);
772 con = ast_context_find_or_create(NULL, NULL, pu->parkinglot->parking_con, registrar);
773 if (!con) /* Still no context? Bad */
774 ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", pu->parkinglot->parking_con);
776 if (!ast_add_extension2(con, 1, pu->parkingexten, 1, NULL, NULL, parkedcall, ast_strdup(pu->parkingexten), ast_free_ptr, registrar))
777 notify_metermaids(pu->parkingexten, pu->parkinglot->parking_con, AST_DEVICE_INUSE);
780 AST_LIST_UNLOCK(&pu->parkinglot->parkings);
782 /* Only say number if it's a number and the channel hasn't been masqueraded away */
783 if (peer && !ast_test_flag(args, AST_PARK_OPT_SILENCE) && (ast_strlen_zero(args->orig_chan_name) || !strcasecmp(peer->name, args->orig_chan_name))) {
784 /* If a channel is masqueraded into peer while playing back the parking slot number do not continue playing it back. This is the case if an attended transfer occurs. */
785 ast_set_flag(peer, AST_FLAG_MASQ_NOSTREAM);
786 /* Tell the peer channel the number of the parking space */
787 ast_say_digits(peer, pu->parkingnum, "", peer->language);
788 ast_clear_flag(peer, AST_FLAG_MASQ_NOSTREAM);
790 if (peer == chan) { /* pu->notquiteyet = 1 */
791 /* Wake up parking thread if we're really done */
792 ast_indicate_data(pu->chan, AST_CONTROL_HOLD,
793 S_OR(pu->parkinglot->mohclass, NULL),
794 !ast_strlen_zero(pu->parkinglot->mohclass) ? strlen(pu->parkinglot->mohclass) + 1 : 0);
796 pthread_kill(parking_thread, SIGURG);
801 /*! \brief Park a call */
802 int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeout, int *extout)
804 struct ast_park_call_args args = {
809 return ast_park_call_full(chan, peer, &args);
812 static int masq_park_call(struct ast_channel *rchan, struct ast_channel *peer, int timeout, int *extout, int play_announcement, struct ast_park_call_args *args)
814 struct ast_channel *chan;
817 struct ast_park_call_args park_args = {0,};
821 args->timeout = timeout;
822 args->extout = extout;
825 if ((args->pu = park_space_reserve(rchan, peer, args)) == NULL) {
827 ast_stream_and_wait(peer, "beeperr", "");
828 return AST_FEATURE_RETURN_PARKFAILED;
831 /* Make a new, fake channel that we'll use to masquerade in the real one */
832 if (!(chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, rchan->accountcode, rchan->exten, rchan->context, rchan->amaflags, "Parked/%s",rchan->name))) {
833 ast_log(LOG_WARNING, "Unable to create parked channel\n");
837 /* Make formats okay */
838 chan->readformat = rchan->readformat;
839 chan->writeformat = rchan->writeformat;
840 ast_channel_masquerade(chan, rchan);
842 /* Setup the extensions and such */
843 set_c_e_p(chan, rchan->context, rchan->exten, rchan->priority);
845 /* Make the masq execute */
846 if ((f = ast_read(chan)))
853 if (!play_announcement && args == &park_args) {
854 args->orig_chan_name = ast_strdupa(chan->name);
857 park_status = ast_park_call_full(chan, peer, args);
858 if (park_status == 1) {
859 /* would be nice to play "invalid parking extension" */
867 /* Park call via masquraded channel */
868 int ast_masq_park_call(struct ast_channel *rchan, struct ast_channel *peer, int timeout, int *extout)
870 return masq_park_call(rchan, peer, timeout, extout, 0, NULL);
873 static int masq_park_call_announce_args(struct ast_channel *rchan, struct ast_channel *peer, struct ast_park_call_args *args)
875 return masq_park_call(rchan, peer, 0, NULL, 1, args);
878 static int masq_park_call_announce(struct ast_channel *rchan, struct ast_channel *peer, int timeout, int *extout)
880 return masq_park_call(rchan, peer, timeout, extout, 1, NULL);
883 #define FEATURE_SENSE_CHAN (1 << 0)
884 #define FEATURE_SENSE_PEER (1 << 1)
887 * \brief set caller and callee according to the direction
888 * \param caller, callee, peer, chan, sense
890 * Detect who triggered feature and set callee/caller variables accordingly
892 static void set_peers(struct ast_channel **caller, struct ast_channel **callee,
893 struct ast_channel *peer, struct ast_channel *chan, int sense)
895 if (sense == FEATURE_SENSE_PEER) {
905 * \brief support routing for one touch call parking
906 * \param chan channel parking call
907 * \param peer channel to be parked
908 * \param config unsed
910 * \param sense feature options
913 * Setup channel, set return exten,priority to 's,1'
914 * answer chan, sleep chan, park call
916 static int builtin_parkcall(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
918 struct ast_channel *parker;
919 struct ast_channel *parkee;
922 set_peers(&parker, &parkee, peer, chan, sense);
923 /* we used to set chan's exten and priority to "s" and 1
924 here, but this generates (in some cases) an invalid
925 extension, and if "s" exists, could errantly
926 cause execution of extensions you don't expect. It
927 makes more sense to let nature take its course
928 when chan finishes, and let the pbx do its thing
929 and hang up when the park is over.
931 if (chan->_state != AST_STATE_UP)
932 res = ast_answer(chan);
934 res = ast_safe_sleep(chan, 1000);
936 if (!res) { /* one direction used to call park_call.... */
937 res = masq_park_call_announce(parkee, parker, 0, NULL);
938 /* PBX should hangup zombie channel if a masquerade actually occurred (res=0) */
944 /*! \brief Play message to both caller and callee in bridged call, plays synchronously, autoservicing the
945 other channel during the message, so please don't use this for very long messages
947 static int play_message_in_bridged_call(struct ast_channel *caller_chan, struct ast_channel *callee_chan, const char *audiofile)
949 /* First play for caller, put other channel on auto service */
950 if (ast_autoservice_start(callee_chan))
952 if (ast_stream_and_wait(caller_chan, audiofile, "")) {
953 ast_log(LOG_WARNING, "Failed to play automon message!\n");
954 ast_autoservice_stop(callee_chan);
957 if (ast_autoservice_stop(callee_chan))
959 /* Then play for callee, put other channel on auto service */
960 if (ast_autoservice_start(caller_chan))
962 if (ast_stream_and_wait(callee_chan, audiofile, "")) {
963 ast_log(LOG_WARNING, "Failed to play automon message !\n");
964 ast_autoservice_stop(caller_chan);
967 if (ast_autoservice_stop(caller_chan))
973 * \brief Monitor a channel by DTMF
974 * \param chan channel requesting monitor
975 * \param peer channel to be monitored
978 * \param sense feature options
981 * Check monitor app enabled, setup channels, both caller/callee chans not null
982 * get TOUCH_MONITOR variable for filename if exists, exec monitor app.
983 * \retval AST_FEATURE_RETURN_SUCCESS on success.
984 * \retval -1 on error.
986 static int builtin_automonitor(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
988 char *caller_chan_id = NULL, *callee_chan_id = NULL, *args = NULL, *touch_filename = NULL;
991 struct ast_channel *caller_chan, *callee_chan;
992 const char *automon_message_start = NULL;
993 const char *automon_message_stop = NULL;
996 ast_log(LOG_ERROR,"Cannot record the call. The monitor application is disabled.\n");
1000 if (!monitor_app && !(monitor_app = pbx_findapp("Monitor"))) {
1002 ast_log(LOG_ERROR,"Cannot record the call. The monitor application is disabled.\n");
1006 set_peers(&caller_chan, &callee_chan, peer, chan, sense);
1007 if (caller_chan) { /* Find extra messages */
1008 automon_message_start = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_MESSAGE_START");
1009 automon_message_stop = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_MESSAGE_STOP");
1012 if (!ast_strlen_zero(courtesytone)) { /* Play courtesy tone if configured */
1013 if(play_message_in_bridged_call(caller_chan, callee_chan, courtesytone) == -1) {
1018 if (callee_chan->monitor) {
1019 ast_verb(4, "User hit '%s' to stop recording call.\n", code);
1020 if (!ast_strlen_zero(automon_message_stop)) {
1021 play_message_in_bridged_call(caller_chan, callee_chan, automon_message_stop);
1023 callee_chan->monitor->stop(callee_chan, 1);
1024 return AST_FEATURE_RETURN_SUCCESS;
1027 if (caller_chan && callee_chan) {
1028 const char *touch_format = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_FORMAT");
1029 const char *touch_monitor = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR");
1030 const char *touch_monitor_prefix = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_PREFIX");
1033 touch_format = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR_FORMAT");
1036 touch_monitor = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR");
1038 if (!touch_monitor_prefix)
1039 touch_monitor_prefix = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR_PREFIX");
1041 if (touch_monitor) {
1042 len = strlen(touch_monitor) + 50;
1044 touch_filename = alloca(len);
1045 snprintf(touch_filename, len, "%s-%ld-%s", S_OR(touch_monitor_prefix, "auto"), (long)time(NULL), touch_monitor);
1046 snprintf(args, len, "%s,%s,m", S_OR(touch_format, "wav"), touch_filename);
1048 caller_chan_id = ast_strdupa(S_OR(caller_chan->cid.cid_num, caller_chan->name));
1049 callee_chan_id = ast_strdupa(S_OR(callee_chan->cid.cid_num, callee_chan->name));
1050 len = strlen(caller_chan_id) + strlen(callee_chan_id) + 50;
1052 touch_filename = alloca(len);
1053 snprintf(touch_filename, len, "%s-%ld-%s-%s", S_OR(touch_monitor_prefix, "auto"), (long)time(NULL), caller_chan_id, callee_chan_id);
1054 snprintf(args, len, "%s,%s,m", S_OR(touch_format, "wav"), touch_filename);
1057 for(x = 0; x < strlen(args); x++) {
1062 ast_verb(4, "User hit '%s' to record call. filename: %s\n", code, args);
1064 pbx_exec(callee_chan, monitor_app, args);
1065 pbx_builtin_setvar_helper(callee_chan, "TOUCH_MONITOR_OUTPUT", touch_filename);
1066 pbx_builtin_setvar_helper(caller_chan, "TOUCH_MONITOR_OUTPUT", touch_filename);
1068 if (!ast_strlen_zero(automon_message_start)) { /* Play start message for both channels */
1069 play_message_in_bridged_call(caller_chan, callee_chan, automon_message_start);
1072 return AST_FEATURE_RETURN_SUCCESS;
1075 ast_log(LOG_NOTICE,"Cannot record the call. One or both channels have gone away.\n");
1079 static int builtin_automixmonitor(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
1081 char *caller_chan_id = NULL, *callee_chan_id = NULL, *args = NULL, *touch_filename = NULL;
1084 struct ast_channel *caller_chan, *callee_chan;
1085 const char *mixmonitor_spy_type = "MixMonitor";
1088 if (!mixmonitor_ok) {
1089 ast_log(LOG_ERROR,"Cannot record the call. The mixmonitor application is disabled.\n");
1093 if (!(mixmonitor_app = pbx_findapp("MixMonitor"))) {
1095 ast_log(LOG_ERROR,"Cannot record the call. The mixmonitor application is disabled.\n");
1099 set_peers(&caller_chan, &callee_chan, peer, chan, sense);
1101 if (!ast_strlen_zero(courtesytone)) {
1102 if (ast_autoservice_start(callee_chan))
1104 if (ast_stream_and_wait(caller_chan, courtesytone, "")) {
1105 ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
1106 ast_autoservice_stop(callee_chan);
1109 if (ast_autoservice_stop(callee_chan))
1113 ast_channel_lock(callee_chan);
1114 count = ast_channel_audiohook_count_by_source(callee_chan, mixmonitor_spy_type, AST_AUDIOHOOK_TYPE_SPY);
1115 ast_channel_unlock(callee_chan);
1117 /* This means a mixmonitor is attached to the channel, running or not is unknown. */
1120 ast_verb(3, "User hit '%s' to stop recording call.\n", code);
1122 /* Make sure they are running */
1123 ast_channel_lock(callee_chan);
1124 count = ast_channel_audiohook_count_by_source_running(callee_chan, mixmonitor_spy_type, AST_AUDIOHOOK_TYPE_SPY);
1125 ast_channel_unlock(callee_chan);
1127 if (!stopmixmonitor_ok) {
1128 ast_log(LOG_ERROR,"Cannot stop recording the call. The stopmixmonitor application is disabled.\n");
1131 if (!(stopmixmonitor_app = pbx_findapp("StopMixMonitor"))) {
1132 stopmixmonitor_ok = 0;
1133 ast_log(LOG_ERROR,"Cannot stop recording the call. The stopmixmonitor application is disabled.\n");
1136 pbx_exec(callee_chan, stopmixmonitor_app, "");
1137 return AST_FEATURE_RETURN_SUCCESS;
1141 ast_log(LOG_WARNING,"Stopped MixMonitors are attached to the channel.\n");
1144 if (caller_chan && callee_chan) {
1145 const char *touch_format = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MIXMONITOR_FORMAT");
1146 const char *touch_monitor = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MIXMONITOR");
1149 touch_format = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MIXMONITOR_FORMAT");
1152 touch_monitor = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MIXMONITOR");
1154 if (touch_monitor) {
1155 len = strlen(touch_monitor) + 50;
1157 touch_filename = alloca(len);
1158 snprintf(touch_filename, len, "auto-%ld-%s", (long)time(NULL), touch_monitor);
1159 snprintf(args, len, "%s.%s,b", touch_filename, (touch_format) ? touch_format : "wav");
1161 caller_chan_id = ast_strdupa(S_OR(caller_chan->cid.cid_num, caller_chan->name));
1162 callee_chan_id = ast_strdupa(S_OR(callee_chan->cid.cid_num, callee_chan->name));
1163 len = strlen(caller_chan_id) + strlen(callee_chan_id) + 50;
1165 touch_filename = alloca(len);
1166 snprintf(touch_filename, len, "auto-%ld-%s-%s", (long)time(NULL), caller_chan_id, callee_chan_id);
1167 snprintf(args, len, "%s.%s,b", touch_filename, S_OR(touch_format, "wav"));
1170 for( x = 0; x < strlen(args); x++) {
1175 ast_verb(3, "User hit '%s' to record call. filename: %s\n", code, touch_filename);
1177 pbx_exec(callee_chan, mixmonitor_app, args);
1178 pbx_builtin_setvar_helper(callee_chan, "TOUCH_MIXMONITOR_OUTPUT", touch_filename);
1179 pbx_builtin_setvar_helper(caller_chan, "TOUCH_MIXMONITOR_OUTPUT", touch_filename);
1180 return AST_FEATURE_RETURN_SUCCESS;
1184 ast_log(LOG_NOTICE,"Cannot record the call. One or both channels have gone away.\n");
1189 static int builtin_disconnect(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
1191 ast_verb(4, "User hit '%s' to disconnect call.\n", code);
1192 return AST_FEATURE_RETURN_HANGUP;
1195 static int finishup(struct ast_channel *chan)
1197 ast_indicate(chan, AST_CONTROL_UNHOLD);
1199 return ast_autoservice_stop(chan);
1203 * \brief Find the context for the transfer
1207 * Grab the TRANSFER_CONTEXT, if fails try grabbing macrocontext.
1208 * \return a context string
1210 static const char *real_ctx(struct ast_channel *transferer, struct ast_channel *transferee)
1212 const char *s = pbx_builtin_getvar_helper(transferer, "TRANSFER_CONTEXT");
1213 if (ast_strlen_zero(s)) {
1214 s = pbx_builtin_getvar_helper(transferee, "TRANSFER_CONTEXT");
1216 if (ast_strlen_zero(s)) { /* Use the non-macro context to transfer the call XXX ? */
1217 s = transferer->macrocontext;
1219 if (ast_strlen_zero(s)) {
1220 s = transferer->context;
1226 * \brief Blind transfer user to another extension
1227 * \param chan channel to be transfered
1228 * \param peer channel initiated blind transfer
1232 * \param sense feature options
1234 * Place chan on hold, check if transferred to parkinglot extension,
1235 * otherwise check extension exists and transfer caller.
1236 * \retval AST_FEATURE_RETURN_SUCCESS.
1237 * \retval -1 on failure.
1239 static int builtin_blindtransfer(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
1241 struct ast_channel *transferer;
1242 struct ast_channel *transferee;
1243 const char *transferer_real_context;
1245 int res, parkstatus = 0;
1247 set_peers(&transferer, &transferee, peer, chan, sense);
1248 transferer_real_context = real_ctx(transferer, transferee);
1249 /* Start autoservice on chan while we talk to the originator */
1250 ast_autoservice_start(transferee);
1251 ast_indicate(transferee, AST_CONTROL_HOLD);
1253 memset(xferto, 0, sizeof(xferto));
1256 res = ast_stream_and_wait(transferer, "pbx-transfer", AST_DIGIT_ANY);
1258 finishup(transferee);
1259 return -1; /* error ? */
1261 if (res > 0) /* If they've typed a digit already, handle it */
1262 xferto[0] = (char) res;
1264 ast_stopstream(transferer);
1265 res = ast_app_dtget(transferer, transferer_real_context, xferto, sizeof(xferto), 100, transferdigittimeout);
1266 if (res < 0) { /* hangup, would be 0 for invalid and 1 for valid */
1267 finishup(transferee);
1270 if (!strcmp(xferto, ast_parking_ext())) {
1271 res = finishup(transferee);
1274 else if (!(parkstatus = masq_park_call_announce(transferee, transferer, 0, NULL))) { /* success */
1275 /* We return non-zero, but tell the PBX not to hang the channel when
1276 the thread dies -- We have to be careful now though. We are responsible for
1277 hanging up the channel, else it will never be hung up! */
1281 ast_log(LOG_WARNING, "Unable to park call %s, parkstatus = %d\n", transferee->name, parkstatus);
1283 /*! \todo XXX Maybe we should have another message here instead of invalid extension XXX */
1284 } else if (ast_exists_extension(transferee, transferer_real_context, xferto, 1, transferer->cid.cid_num)) {
1285 pbx_builtin_setvar_helper(transferer, "BLINDTRANSFER", transferee->name);
1286 pbx_builtin_setvar_helper(transferee, "BLINDTRANSFER", transferer->name);
1287 res=finishup(transferee);
1288 if (!transferer->cdr) { /* this code should never get called (in a perfect world) */
1289 transferer->cdr=ast_cdr_alloc();
1290 if (transferer->cdr) {
1291 ast_cdr_init(transferer->cdr, transferer); /* initilize our channel's cdr */
1292 ast_cdr_start(transferer->cdr);
1295 if (transferer->cdr) {
1296 struct ast_cdr *swap = transferer->cdr;
1297 ast_log(LOG_DEBUG,"transferer=%s; transferee=%s; lastapp=%s; lastdata=%s; chan=%s; dstchan=%s\n",
1298 transferer->name, transferee->name, transferer->cdr->lastapp, transferer->cdr->lastdata,
1299 transferer->cdr->channel, transferer->cdr->dstchannel);
1300 ast_log(LOG_DEBUG,"TRANSFEREE; lastapp=%s; lastdata=%s, chan=%s; dstchan=%s\n",
1301 transferee->cdr->lastapp, transferee->cdr->lastdata, transferee->cdr->channel, transferee->cdr->dstchannel);
1302 ast_log(LOG_DEBUG,"transferer_real_context=%s; xferto=%s\n", transferer_real_context, xferto);
1303 /* swap cdrs-- it will save us some time & work */
1304 transferer->cdr = transferee->cdr;
1305 transferee->cdr = swap;
1307 if (!transferee->pbx) {
1308 /* Doh! Use our handy async_goto functions */
1309 ast_verb(3, "Transferring %s to '%s' (context %s) priority 1\n"
1310 ,transferee->name, xferto, transferer_real_context);
1311 if (ast_async_goto(transferee, transferer_real_context, xferto, 1))
1312 ast_log(LOG_WARNING, "Async goto failed :-(\n");
1314 /* Set the channel's new extension, since it exists, using transferer context */
1315 ast_set_flag(transferee, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */
1316 ast_log(LOG_DEBUG,"ABOUT TO AST_ASYNC_GOTO, have a pbx... set HANGUP_DONT on chan=%s\n", transferee->name);
1317 set_c_e_p(transferee, transferer_real_context, xferto, 0);
1319 check_goto_on_transfer(transferer);
1322 ast_verb(3, "Unable to find extension '%s' in context '%s'\n", xferto, transferer_real_context);
1324 if (parkstatus != AST_FEATURE_RETURN_PARKFAILED && ast_stream_and_wait(transferer, xferfailsound, AST_DIGIT_ANY) < 0) {
1325 finishup(transferee);
1328 ast_stopstream(transferer);
1329 res = finishup(transferee);
1331 ast_verb(2, "Hungup during autoservice stop on '%s'\n", transferee->name);
1334 return AST_FEATURE_RETURN_SUCCESS;
1338 * \brief make channels compatible
1341 * \retval 0 on success.
1342 * \retval -1 on failure.
1344 static int check_compat(struct ast_channel *c, struct ast_channel *newchan)
1346 if (ast_channel_make_compatible(c, newchan) < 0) {
1347 ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n",
1348 c->name, newchan->name);
1349 ast_hangup(newchan);
1356 * \brief Attended transfer
1357 * \param chan transfered user
1358 * \param peer person transfering call
1361 * \param sense feature options
1364 * Get extension to transfer to, if you cannot generate channel (or find extension)
1365 * return to host channel. After called channel answered wait for hangup of transferer,
1366 * bridge call between transfer peer (taking them off hold) to attended transfer channel.
1368 * \return -1 on failure
1370 static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
1372 struct ast_channel *transferer;
1373 struct ast_channel *transferee;
1374 const char *transferer_real_context;
1375 char xferto[256] = "";
1378 struct ast_channel *newchan;
1379 struct ast_channel *xferchan;
1380 struct ast_bridge_thread_obj *tobj;
1381 struct ast_bridge_config bconfig;
1382 struct ast_frame *f;
1384 struct ast_datastore *features_datastore;
1385 struct ast_dial_features *dialfeatures = NULL;
1387 ast_debug(1, "Executing Attended Transfer %s, %s (sense=%d) \n", chan->name, peer->name, sense);
1388 set_peers(&transferer, &transferee, peer, chan, sense);
1389 transferer_real_context = real_ctx(transferer, transferee);
1390 /* Start autoservice on chan while we talk to the originator */
1391 ast_autoservice_start(transferee);
1392 ast_indicate(transferee, AST_CONTROL_HOLD);
1395 res = ast_stream_and_wait(transferer, "pbx-transfer", AST_DIGIT_ANY);
1397 finishup(transferee);
1400 if (res > 0) /* If they've typed a digit already, handle it */
1401 xferto[0] = (char) res;
1403 /* this is specific of atxfer */
1404 res = ast_app_dtget(transferer, transferer_real_context, xferto, sizeof(xferto), 100, transferdigittimeout);
1405 if (res < 0) { /* hangup, would be 0 for invalid and 1 for valid */
1406 finishup(transferee);
1410 ast_log(LOG_WARNING, "Did not read data.\n");
1411 finishup(transferee);
1412 if (ast_stream_and_wait(transferer, "beeperr", ""))
1414 return AST_FEATURE_RETURN_SUCCESS;
1417 /* valid extension, res == 1 */
1418 if (!ast_exists_extension(transferer, transferer_real_context, xferto, 1, transferer->cid.cid_num)) {
1419 ast_log(LOG_WARNING, "Extension %s does not exist in context %s\n",xferto,transferer_real_context);
1420 finishup(transferee);
1421 if (ast_stream_and_wait(transferer, "beeperr", ""))
1423 return AST_FEATURE_RETURN_SUCCESS;
1426 /* If we are attended transfering to parking, just use builtin_parkcall instead of trying to track all of
1427 * the different variables for handling this properly with a builtin_atxfer */
1428 if (!strcmp(xferto, ast_parking_ext())) {
1429 finishup(transferee);
1430 return builtin_parkcall(chan, peer, config, code, sense, data);
1434 snprintf(xferto + l, sizeof(xferto) - l, "@%s/n", transferer_real_context); /* append context */
1436 /* If we are performing an attended transfer and we have two channels involved then
1437 copy sound file information to play upon attended transfer completion */
1439 const char *chan1_attended_sound = pbx_builtin_getvar_helper(transferer, "ATTENDED_TRANSFER_COMPLETE_SOUND");
1440 const char *chan2_attended_sound = pbx_builtin_getvar_helper(transferee, "ATTENDED_TRANSFER_COMPLETE_SOUND");
1442 if (!ast_strlen_zero(chan1_attended_sound)) {
1443 pbx_builtin_setvar_helper(transferer, "BRIDGE_PLAY_SOUND", chan1_attended_sound);
1445 if (!ast_strlen_zero(chan2_attended_sound)) {
1446 pbx_builtin_setvar_helper(transferee, "BRIDGE_PLAY_SOUND", chan2_attended_sound);
1450 newchan = ast_feature_request_and_dial(transferer, transferee, "Local", ast_best_codec(transferer->nativeformats),
1451 xferto, atxfernoanswertimeout, &outstate, transferer->cid.cid_num, transferer->cid.cid_name, 1, transferer->language);
1453 if (!ast_check_hangup(transferer)) {
1454 /* Transferer is up - old behaviour */
1455 ast_indicate(transferer, -1);
1457 finishup(transferee);
1458 /* any reason besides user requested cancel and busy triggers the failed sound */
1459 if (outstate != AST_CONTROL_UNHOLD && outstate != AST_CONTROL_BUSY &&
1460 ast_stream_and_wait(transferer, xferfailsound, ""))
1462 if (ast_stream_and_wait(transferer, xfersound, ""))
1463 ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
1464 return AST_FEATURE_RETURN_SUCCESS;
1467 if (check_compat(transferer, newchan)) {
1468 /* we do mean transferee here, NOT transferer */
1469 finishup(transferee);
1472 memset(&bconfig,0,sizeof(struct ast_bridge_config));
1473 ast_set_flag(&(bconfig.features_caller), AST_FEATURE_DISCONNECT);
1474 ast_set_flag(&(bconfig.features_callee), AST_FEATURE_DISCONNECT);
1475 res = ast_bridge_call(transferer, newchan, &bconfig);
1476 if (ast_check_hangup(newchan) || !ast_check_hangup(transferer)) {
1477 ast_hangup(newchan);
1478 if (ast_stream_and_wait(transferer, xfersound, ""))
1479 ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
1480 finishup(transferee);
1481 transferer->_softhangup = 0;
1482 return AST_FEATURE_RETURN_SUCCESS;
1484 if (check_compat(transferee, newchan)) {
1485 finishup(transferee);
1488 ast_indicate(transferee, AST_CONTROL_UNHOLD);
1490 if ((ast_autoservice_stop(transferee) < 0)
1491 || (ast_waitfordigit(transferee, 100) < 0)
1492 || (ast_waitfordigit(newchan, 100) < 0)
1493 || ast_check_hangup(transferee)
1494 || ast_check_hangup(newchan)) {
1495 ast_hangup(newchan);
1498 xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Transfered/%s", transferee->name);
1500 ast_hangup(newchan);
1503 /* Make formats okay */
1504 xferchan->visible_indication = transferer->visible_indication;
1505 xferchan->readformat = transferee->readformat;
1506 xferchan->writeformat = transferee->writeformat;
1507 ast_channel_masquerade(xferchan, transferee);
1508 ast_explicit_goto(xferchan, transferee->context, transferee->exten, transferee->priority);
1509 xferchan->_state = AST_STATE_UP;
1510 ast_clear_flag(xferchan, AST_FLAGS_ALL);
1511 xferchan->_softhangup = 0;
1512 if ((f = ast_read(xferchan)))
1514 newchan->_state = AST_STATE_UP;
1515 ast_clear_flag(newchan, AST_FLAGS_ALL);
1516 newchan->_softhangup = 0;
1517 if (!(tobj = ast_calloc(1, sizeof(*tobj)))) {
1518 ast_hangup(xferchan);
1519 ast_hangup(newchan);
1523 ast_channel_lock(newchan);
1524 if ((features_datastore = ast_channel_datastore_find(newchan, &dial_features_info, NULL))) {
1525 dialfeatures = features_datastore->data;
1527 ast_channel_unlock(newchan);
1530 /* newchan should always be the callee and shows up as callee in dialfeatures, but for some reason
1531 I don't currently understand, the abilities of newchan seem to be stored on the caller side */
1532 ast_copy_flags(&(config->features_callee), &(dialfeatures->features_caller), AST_FLAGS_ALL);
1533 dialfeatures = NULL;
1536 ast_channel_lock(xferchan);
1537 if ((features_datastore = ast_channel_datastore_find(xferchan, &dial_features_info, NULL))) {
1538 dialfeatures = features_datastore->data;
1540 ast_channel_unlock(xferchan);
1543 ast_copy_flags(&(config->features_caller), &(dialfeatures->features_caller), AST_FLAGS_ALL);
1546 tobj->chan = newchan;
1547 tobj->peer = xferchan;
1548 tobj->bconfig = *config;
1550 if (tobj->bconfig.end_bridge_callback_data_fixup) {
1551 tobj->bconfig.end_bridge_callback_data_fixup(&tobj->bconfig, tobj->peer, tobj->chan);
1554 if (ast_stream_and_wait(newchan, xfersound, ""))
1555 ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
1556 ast_bridge_call_thread_launch(tobj);
1557 return -1; /* XXX meaning the channel is bridged ? */
1558 } else if (!ast_check_hangup(transferee)) {
1559 /* act as blind transfer */
1560 if (ast_autoservice_stop(transferee) < 0) {
1561 ast_hangup(newchan);
1566 unsigned int tries = 0;
1567 char *transferer_tech, *transferer_name = ast_strdupa(transferer->name);
1569 transferer_tech = strsep(&transferer_name, "/");
1570 transferer_name = strsep(&transferer_name, "-");
1572 if (ast_strlen_zero(transferer_name) || ast_strlen_zero(transferer_tech)) {
1573 ast_log(LOG_WARNING, "Transferer has invalid channel name: '%s'\n", transferer->name);
1574 if (ast_stream_and_wait(transferee, "beeperr", ""))
1576 return AST_FEATURE_RETURN_SUCCESS;
1579 ast_log(LOG_NOTICE, "We're trying to call %s/%s\n", transferer_tech, transferer_name);
1580 newchan = ast_feature_request_and_dial(transferee, NULL, transferer_tech, ast_best_codec(transferee->nativeformats),
1581 transferer_name, atxfernoanswertimeout, &outstate, transferee->cid.cid_num, transferee->cid.cid_name, 0, transferer->language);
1582 while (!newchan && !atxferdropcall && tries < atxfercallbackretries) {
1583 /* Trying to transfer again */
1584 ast_autoservice_start(transferee);
1585 ast_indicate(transferee, AST_CONTROL_HOLD);
1587 newchan = ast_feature_request_and_dial(transferer, transferee, "Local", ast_best_codec(transferer->nativeformats),
1588 xferto, atxfernoanswertimeout, &outstate, transferer->cid.cid_num, transferer->cid.cid_name, 1, transferer->language);
1589 if (ast_autoservice_stop(transferee) < 0) {
1591 ast_hangup(newchan);
1595 /* Transfer failed, sleeping */
1596 ast_debug(1, "Sleeping for %d ms before callback.\n", atxferloopdelay);
1597 ast_safe_sleep(transferee, atxferloopdelay);
1598 ast_debug(1, "Trying to callback...\n");
1599 newchan = ast_feature_request_and_dial(transferee, NULL, transferer_tech, ast_best_codec(transferee->nativeformats),
1600 transferer_name, atxfernoanswertimeout, &outstate, transferee->cid.cid_num, transferee->cid.cid_name, 0, transferer->language);
1608 /* newchan is up, we should prepare transferee and bridge them */
1609 if (check_compat(transferee, newchan)) {
1610 finishup(transferee);
1613 ast_indicate(transferee, AST_CONTROL_UNHOLD);
1615 if ((ast_waitfordigit(transferee, 100) < 0)
1616 || (ast_waitfordigit(newchan, 100) < 0)
1617 || ast_check_hangup(transferee)
1618 || ast_check_hangup(newchan)) {
1619 ast_hangup(newchan);
1623 xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Transfered/%s", transferee->name);
1625 ast_hangup(newchan);
1628 /* Make formats okay */
1629 xferchan->visible_indication = transferer->visible_indication;
1630 xferchan->readformat = transferee->readformat;
1631 xferchan->writeformat = transferee->writeformat;
1632 ast_channel_masquerade(xferchan, transferee);
1633 ast_explicit_goto(xferchan, transferee->context, transferee->exten, transferee->priority);
1634 xferchan->_state = AST_STATE_UP;
1635 ast_clear_flag(xferchan, AST_FLAGS_ALL);
1636 xferchan->_softhangup = 0;
1637 if ((f = ast_read(xferchan)))
1639 newchan->_state = AST_STATE_UP;
1640 ast_clear_flag(newchan, AST_FLAGS_ALL);
1641 newchan->_softhangup = 0;
1642 if (!(tobj = ast_calloc(1, sizeof(*tobj)))) {
1643 ast_hangup(xferchan);
1644 ast_hangup(newchan);
1647 tobj->chan = newchan;
1648 tobj->peer = xferchan;
1649 tobj->bconfig = *config;
1651 if (tobj->bconfig.end_bridge_callback_data_fixup) {
1652 tobj->bconfig.end_bridge_callback_data_fixup(&tobj->bconfig, tobj->peer, tobj->chan);
1655 if (ast_stream_and_wait(newchan, xfersound, ""))
1656 ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
1657 ast_bridge_call_thread_launch(tobj);
1658 return -1; /* XXX meaning the channel is bridged ? */
1660 /* Transferee hung up */
1661 finishup(transferee);
1666 /* add atxfer and automon as undefined so you can only use em if you configure them */
1667 #define FEATURES_COUNT ARRAY_LEN(builtin_features)
1669 AST_RWLOCK_DEFINE_STATIC(features_lock);
1671 static struct ast_call_feature builtin_features[] =
1673 { AST_FEATURE_REDIRECT, "Blind Transfer", "blindxfer", "#", "#", builtin_blindtransfer, AST_FEATURE_FLAG_NEEDSDTMF, "" },
1674 { AST_FEATURE_REDIRECT, "Attended Transfer", "atxfer", "", "", builtin_atxfer, AST_FEATURE_FLAG_NEEDSDTMF, "" },
1675 { AST_FEATURE_AUTOMON, "One Touch Monitor", "automon", "", "", builtin_automonitor, AST_FEATURE_FLAG_NEEDSDTMF, "" },
1676 { AST_FEATURE_DISCONNECT, "Disconnect Call", "disconnect", "*", "*", builtin_disconnect, AST_FEATURE_FLAG_NEEDSDTMF, "" },
1677 { AST_FEATURE_PARKCALL, "Park Call", "parkcall", "", "", builtin_parkcall, AST_FEATURE_FLAG_NEEDSDTMF, "" },
1678 { AST_FEATURE_AUTOMIXMON, "One Touch MixMonitor", "automixmon", "", "", builtin_automixmonitor, AST_FEATURE_FLAG_NEEDSDTMF, "" },
1682 static AST_RWLIST_HEAD_STATIC(feature_list, ast_call_feature);
1684 /*! \brief register new feature into feature_list*/
1685 void ast_register_feature(struct ast_call_feature *feature)
1688 ast_log(LOG_NOTICE,"You didn't pass a feature!\n");
1692 AST_RWLIST_WRLOCK(&feature_list);
1693 AST_RWLIST_INSERT_HEAD(&feature_list,feature,feature_entry);
1694 AST_RWLIST_UNLOCK(&feature_list);
1696 ast_verb(2, "Registered Feature '%s'\n",feature->sname);
1700 * \brief Add new feature group
1701 * \param fgname feature group name.
1703 * Add new feature group to the feature group list insert at head of list.
1704 * \note This function MUST be called while feature_groups is locked.
1706 static struct feature_group* register_group(const char *fgname)
1708 struct feature_group *fg;
1711 ast_log(LOG_NOTICE, "You didn't pass a new group name!\n");
1715 if (!(fg = ast_calloc(1, sizeof(*fg))))
1718 if (ast_string_field_init(fg, 128)) {
1723 ast_string_field_set(fg, gname, fgname);
1725 AST_LIST_INSERT_HEAD(&feature_groups, fg, entry);
1727 ast_verb(2, "Registered group '%s'\n", fg->gname);
1733 * \brief Add feature to group
1734 * \param fg feature group
1736 * \param feature feature to add.
1738 * Check fg and feature specified, add feature to list
1739 * \note This function MUST be called while feature_groups is locked.
1741 static void register_group_feature(struct feature_group *fg, const char *exten, struct ast_call_feature *feature)
1743 struct feature_group_exten *fge;
1746 ast_log(LOG_NOTICE, "You didn't pass a group!\n");
1751 ast_log(LOG_NOTICE, "You didn't pass a feature!\n");
1755 if (!(fge = ast_calloc(1, sizeof(*fge))))
1758 if (ast_string_field_init(fge, 128)) {
1763 ast_string_field_set(fge, exten, S_OR(exten, feature->exten));
1765 fge->feature = feature;
1767 AST_LIST_INSERT_HEAD(&fg->features, fge, entry);
1769 ast_verb(2, "Registered feature '%s' for group '%s' at exten '%s'\n",
1770 feature->sname, fg->gname, exten);
1773 void ast_unregister_feature(struct ast_call_feature *feature)
1779 AST_RWLIST_WRLOCK(&feature_list);
1780 AST_RWLIST_REMOVE(&feature_list, feature, feature_entry);
1781 AST_RWLIST_UNLOCK(&feature_list);
1786 /*! \brief Remove all features in the list */
1787 static void ast_unregister_features(void)
1789 struct ast_call_feature *feature;
1791 AST_RWLIST_WRLOCK(&feature_list);
1792 while ((feature = AST_RWLIST_REMOVE_HEAD(&feature_list, feature_entry))) {
1795 AST_RWLIST_UNLOCK(&feature_list);
1798 /*! \brief find a call feature by name */
1799 static struct ast_call_feature *find_dynamic_feature(const char *name)
1801 struct ast_call_feature *tmp;
1803 AST_RWLIST_TRAVERSE(&feature_list, tmp, feature_entry) {
1804 if (!strcasecmp(tmp->sname, name)) {
1812 /*! \brief Remove all feature groups in the list */
1813 static void ast_unregister_groups(void)
1815 struct feature_group *fg;
1816 struct feature_group_exten *fge;
1818 AST_RWLIST_WRLOCK(&feature_groups);
1819 while ((fg = AST_LIST_REMOVE_HEAD(&feature_groups, entry))) {
1820 while ((fge = AST_LIST_REMOVE_HEAD(&fg->features, entry))) {
1821 ast_string_field_free_memory(fge);
1825 ast_string_field_free_memory(fg);
1828 AST_RWLIST_UNLOCK(&feature_groups);
1832 * \brief Find a group by name
1833 * \param name feature name
1834 * \retval feature group on success.
1835 * \retval NULL on failure.
1837 static struct feature_group *find_group(const char *name) {
1838 struct feature_group *fg = NULL;
1840 AST_LIST_TRAVERSE(&feature_groups, fg, entry) {
1841 if (!strcasecmp(fg->gname, name))
1848 void ast_rdlock_call_features(void)
1850 ast_rwlock_rdlock(&features_lock);
1853 void ast_unlock_call_features(void)
1855 ast_rwlock_unlock(&features_lock);
1858 struct ast_call_feature *ast_find_call_feature(const char *name)
1861 for (x = 0; x < FEATURES_COUNT; x++) {
1862 if (!strcasecmp(name, builtin_features[x].sname))
1863 return &builtin_features[x];
1869 * \brief exec an app by feature
1870 * \param chan,peer,config,code,sense,data
1872 * Find a feature, determine which channel activated
1873 * \retval AST_FEATURE_RETURN_NO_HANGUP_PEER
1875 * \retval -2 when an application cannot be found.
1877 static int feature_exec_app(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
1879 struct ast_app *app;
1880 struct ast_call_feature *feature = data;
1881 struct ast_channel *work, *idle;
1884 if (!feature) { /* shouldn't ever happen! */
1885 ast_log(LOG_NOTICE, "Found feature before, but at execing we've lost it??\n");
1889 if (sense == FEATURE_SENSE_CHAN) {
1890 if (!ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLER))
1891 return AST_FEATURE_RETURN_KEEPTRYING;
1892 if (ast_test_flag(feature, AST_FEATURE_FLAG_ONSELF)) {
1900 if (!ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLEE))
1901 return AST_FEATURE_RETURN_KEEPTRYING;
1902 if (ast_test_flag(feature, AST_FEATURE_FLAG_ONSELF)) {
1911 if (!(app = pbx_findapp(feature->app))) {
1912 ast_log(LOG_WARNING, "Could not find application (%s)\n", feature->app);
1916 ast_autoservice_start(idle);
1918 if (!ast_strlen_zero(feature->moh_class))
1919 ast_moh_start(idle, feature->moh_class, NULL);
1921 res = pbx_exec(work, app, feature->app_args);
1923 if (!ast_strlen_zero(feature->moh_class))
1926 ast_autoservice_stop(idle);
1929 return AST_FEATURE_RETURN_SUCCESSBREAK;
1931 return AST_FEATURE_RETURN_SUCCESS; /*! \todo XXX should probably return res */
1934 static void unmap_features(void)
1938 ast_rwlock_wrlock(&features_lock);
1939 for (x = 0; x < FEATURES_COUNT; x++)
1940 strcpy(builtin_features[x].exten, builtin_features[x].default_exten);
1941 ast_rwlock_unlock(&features_lock);
1944 static int remap_feature(const char *name, const char *value)
1948 ast_rwlock_wrlock(&features_lock);
1949 for (x = 0; x < FEATURES_COUNT; x++) {
1950 if (strcasecmp(builtin_features[x].sname, name))
1953 ast_copy_string(builtin_features[x].exten, value, sizeof(builtin_features[x].exten));
1957 ast_rwlock_unlock(&features_lock);
1963 * \brief Check the dynamic features
1964 * \param chan,peer,config,code,sense
1966 * Lock features list, browse for code, unlock list
1967 * \retval res on success.
1968 * \retval -1 on failure.
1970 static int ast_feature_interpret(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense)
1973 struct ast_flags features;
1974 struct ast_call_feature *feature;
1975 struct feature_group *fg = NULL;
1976 struct feature_group_exten *fge;
1977 const char *dynamic_features;
1979 int res = AST_FEATURE_RETURN_PASSDIGITS;
1980 int feature_detected = 0;
1982 if (sense == FEATURE_SENSE_CHAN) {
1983 ast_copy_flags(&features, &(config->features_caller), AST_FLAGS_ALL);
1984 dynamic_features = pbx_builtin_getvar_helper(chan, "DYNAMIC_FEATURES");
1987 ast_copy_flags(&features, &(config->features_callee), AST_FLAGS_ALL);
1988 dynamic_features = pbx_builtin_getvar_helper(peer, "DYNAMIC_FEATURES");
1990 ast_debug(3, "Feature interpret: chan=%s, peer=%s, code=%s, sense=%d, features=%d, dynamic=%s\n", chan->name, peer->name, code, sense, features.flags, dynamic_features);
1992 ast_rwlock_rdlock(&features_lock);
1993 for (x = 0; x < FEATURES_COUNT; x++) {
1994 if ((ast_test_flag(&features, builtin_features[x].feature_mask)) &&
1995 !ast_strlen_zero(builtin_features[x].exten)) {
1996 /* Feature is up for consideration */
1997 if (!strcmp(builtin_features[x].exten, code)) {
1998 ast_debug(3, "Feature detected: fname=%s sname=%s exten=%s\n", builtin_features[x].fname, builtin_features[x].sname, builtin_features[x].exten);
1999 res = builtin_features[x].operation(chan, peer, config, code, sense, NULL);
2000 feature_detected = 1;
2002 } else if (!strncmp(builtin_features[x].exten, code, strlen(code))) {
2003 if (res == AST_FEATURE_RETURN_PASSDIGITS)
2004 res = AST_FEATURE_RETURN_STOREDIGITS;
2008 ast_rwlock_unlock(&features_lock);
2010 if (ast_strlen_zero(dynamic_features) || feature_detected)
2013 tmp = ast_strdupa(dynamic_features);
2015 while ((tok = strsep(&tmp, "#"))) {
2016 AST_RWLIST_RDLOCK(&feature_groups);
2018 fg = find_group(tok);
2021 AST_LIST_TRAVERSE(&fg->features, fge, entry) {
2022 if (strcasecmp(fge->exten, code))
2025 res = fge->feature->operation(chan, peer, config, code, sense, fge->feature);
2026 if (res != AST_FEATURE_RETURN_KEEPTRYING) {
2027 AST_RWLIST_UNLOCK(&feature_groups);
2030 res = AST_FEATURE_RETURN_PASSDIGITS;
2036 AST_RWLIST_UNLOCK(&feature_groups);
2038 AST_RWLIST_RDLOCK(&feature_list);
2040 if (!(feature = find_dynamic_feature(tok))) {
2041 AST_RWLIST_UNLOCK(&feature_list);
2045 /* Feature is up for consideration */
2046 if (!strcmp(feature->exten, code)) {
2047 ast_verb(3, " Feature Found: %s exten: %s\n",feature->sname, tok);
2048 res = feature->operation(chan, peer, config, code, sense, feature);
2049 if (res != AST_FEATURE_RETURN_KEEPTRYING) {
2050 AST_RWLIST_UNLOCK(&feature_list);
2053 res = AST_FEATURE_RETURN_PASSDIGITS;
2054 } else if (!strncmp(feature->exten, code, strlen(code)))
2055 res = AST_FEATURE_RETURN_STOREDIGITS;
2057 AST_RWLIST_UNLOCK(&feature_list);
2063 static void set_config_flags(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config)
2067 ast_clear_flag(config, AST_FLAGS_ALL);
2069 ast_rwlock_rdlock(&features_lock);
2070 for (x = 0; x < FEATURES_COUNT; x++) {
2071 if (!ast_test_flag(builtin_features + x, AST_FEATURE_FLAG_NEEDSDTMF))
2074 if (ast_test_flag(&(config->features_caller), builtin_features[x].feature_mask))
2075 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
2077 if (ast_test_flag(&(config->features_callee), builtin_features[x].feature_mask))
2078 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
2080 ast_rwlock_unlock(&features_lock);
2082 if (chan && peer && !(ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_0) && ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_1))) {
2083 const char *dynamic_features = pbx_builtin_getvar_helper(chan, "DYNAMIC_FEATURES");
2085 if (dynamic_features) {
2086 char *tmp = ast_strdupa(dynamic_features);
2088 struct ast_call_feature *feature;
2090 /* while we have a feature */
2091 while ((tok = strsep(&tmp, "#"))) {
2092 AST_RWLIST_RDLOCK(&feature_list);
2093 if ((feature = find_dynamic_feature(tok)) && ast_test_flag(feature, AST_FEATURE_FLAG_NEEDSDTMF)) {
2094 if (ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLER))
2095 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
2096 if (ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLEE))
2097 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
2099 AST_RWLIST_UNLOCK(&feature_list);
2106 * \brief Get feature and dial
2107 * \param caller,transferee,type,format,data,timeout,outstate,cid_num,cid_name,igncallerstate
2109 * Request channel, set channel variables, initiate call,check if they want to disconnect
2110 * go into loop, check if timeout has elapsed, check if person to be transfered hung up,
2111 * check for answer break loop, set cdr return channel.
2113 * \todo XXX Check - this is very similar to the code in channel.c
2114 * \return always a channel
2116 static struct ast_channel *ast_feature_request_and_dial(struct ast_channel *caller, struct ast_channel *transferee, const char *type, int format, void *data, int timeout, int *outstate, const char *cid_num, const char *cid_name, int igncallerstate, const char *language)
2121 struct ast_channel *chan;
2122 struct ast_channel *monitor_chans[2];
2123 struct ast_channel *active_channel;
2124 int res = 0, ready = 0;
2125 struct timeval started;
2127 char *disconnect_code = NULL, *dialed_code = NULL;
2129 if (!(chan = ast_request(type, format, data, &cause))) {
2130 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
2132 case AST_CAUSE_BUSY:
2133 state = AST_CONTROL_BUSY;
2135 case AST_CAUSE_CONGESTION:
2136 state = AST_CONTROL_CONGESTION;
2142 ast_set_callerid(chan, cid_num, cid_name, cid_num);
2143 ast_string_field_set(chan, language, language);
2144 ast_channel_inherit_variables(caller, chan);
2145 pbx_builtin_setvar_helper(chan, "TRANSFERERNAME", caller->name);
2147 if (ast_call(chan, data, timeout)) {
2148 ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
2152 ast_indicate(caller, AST_CONTROL_RINGING);
2153 /* support dialing of the featuremap disconnect code while performing an attended tranfer */
2154 ast_rwlock_rdlock(&features_lock);
2155 for (x = 0; x < FEATURES_COUNT; x++) {
2156 if (strcasecmp(builtin_features[x].sname, "disconnect"))
2159 disconnect_code = builtin_features[x].exten;
2160 len = strlen(disconnect_code) + 1;
2161 dialed_code = alloca(len);
2162 memset(dialed_code, 0, len);
2165 ast_rwlock_unlock(&features_lock);
2167 started = ast_tvnow();
2170 ast_poll_channel_add(caller, chan);
2172 while (!((transferee && ast_check_hangup(transferee)) && (!igncallerstate && ast_check_hangup(caller))) && timeout && (chan->_state != AST_STATE_UP)) {
2173 struct ast_frame *f = NULL;
2175 monitor_chans[0] = caller;
2176 monitor_chans[1] = chan;
2177 active_channel = ast_waitfor_n(monitor_chans, 2, &to);
2179 /* see if the timeout has been violated */
2180 if(ast_tvdiff_ms(ast_tvnow(), started) > timeout) {
2181 state = AST_CONTROL_UNHOLD;
2182 ast_log(LOG_NOTICE, "We exceeded our AT-timeout\n");
2183 break; /*doh! timeout*/
2186 if (!active_channel)
2189 if (chan && (chan == active_channel)){
2191 if (f == NULL) { /*doh! where'd he go?*/
2192 state = AST_CONTROL_HANGUP;
2197 if (f->frametype == AST_FRAME_CONTROL || f->frametype == AST_FRAME_DTMF || f->frametype == AST_FRAME_TEXT) {
2198 if (f->subclass == AST_CONTROL_RINGING) {
2199 state = f->subclass;
2200 ast_verb(3, "%s is ringing\n", chan->name);
2201 ast_indicate(caller, AST_CONTROL_RINGING);
2202 } else if ((f->subclass == AST_CONTROL_BUSY) || (f->subclass == AST_CONTROL_CONGESTION)) {
2203 state = f->subclass;
2204 ast_verb(3, "%s is busy\n", chan->name);
2205 ast_indicate(caller, AST_CONTROL_BUSY);
2209 } else if (f->subclass == AST_CONTROL_ANSWER) {
2210 /* This is what we are hoping for */
2211 state = f->subclass;
2216 } else if (f->subclass != -1) {
2217 ast_log(LOG_NOTICE, "Don't know what to do about control frame: %d\n", f->subclass);
2219 /* else who cares */
2222 } else if (caller && (active_channel == caller)) {
2223 f = ast_read(caller);
2224 if (f == NULL) { /*doh! where'd he go?*/
2225 if (!igncallerstate) {
2226 if (ast_check_hangup(caller) && !ast_check_hangup(chan)) {
2227 /* make this a blind transfer */
2231 state = AST_CONTROL_HANGUP;
2237 if (f->frametype == AST_FRAME_DTMF) {
2238 dialed_code[x++] = f->subclass;
2239 dialed_code[x] = '\0';
2240 if (strlen(dialed_code) == len) {
2242 } else if (x && strncmp(dialed_code, disconnect_code, x)) {
2244 dialed_code[x] = '\0';
2246 if (*dialed_code && !strcmp(dialed_code, disconnect_code)) {
2247 /* Caller Canceled the call */
2248 state = AST_CONTROL_UNHOLD;
2260 ast_poll_channel_del(caller, chan);
2263 ast_indicate(caller, -1);
2264 if (chan && ready) {
2265 if (chan->_state == AST_STATE_UP)
2266 state = AST_CONTROL_ANSWER;
2283 * \brief return the first unlocked cdr in a possible chain
2285 static struct ast_cdr *pick_unlocked_cdr(struct ast_cdr *cdr)
2287 struct ast_cdr *cdr_orig = cdr;
2289 if (!ast_test_flag(cdr,AST_CDR_FLAG_LOCKED))
2293 return cdr_orig; /* everybody LOCKED or some other weirdness, like a NULL */
2296 static void set_bridge_features_on_config(struct ast_bridge_config *config, const char *features)
2298 const char *feature;
2300 if (ast_strlen_zero(features)) {
2304 for (feature = features; *feature; feature++) {
2308 ast_set_flag(&(config->features_caller), AST_FEATURE_REDIRECT);
2312 ast_set_flag(&(config->features_caller), AST_FEATURE_PARKCALL);
2316 ast_set_flag(&(config->features_caller), AST_FEATURE_DISCONNECT);
2320 ast_set_flag(&(config->features_caller), AST_FEATURE_AUTOMON);
2323 ast_log(LOG_WARNING, "Skipping unknown feature code '%c'\n", *feature);
2328 static void add_features_datastores(struct ast_channel *caller, struct ast_channel *callee, struct ast_bridge_config *config)
2330 struct ast_datastore *ds_callee_features = NULL, *ds_caller_features = NULL;
2331 struct ast_dial_features *callee_features = NULL, *caller_features = NULL;
2333 ast_channel_lock(caller);
2334 ds_caller_features = ast_channel_datastore_find(caller, &dial_features_info, NULL);
2335 ast_channel_unlock(caller);
2336 if (!ds_caller_features) {
2337 if (!(ds_caller_features = ast_datastore_alloc(&dial_features_info, NULL))) {
2338 ast_log(LOG_WARNING, "Unable to create channel datastore for caller features. Aborting!\n");
2341 if (!(caller_features = ast_calloc(1, sizeof(*caller_features)))) {
2342 ast_log(LOG_WARNING, "Unable to allocate memory for callee feature flags. Aborting!\n");
2343 ast_datastore_free(ds_caller_features);
2346 ds_caller_features->inheritance = DATASTORE_INHERIT_FOREVER;
2347 caller_features->is_caller = 1;
2348 ast_copy_flags(&(caller_features->features_callee), &(config->features_callee), AST_FLAGS_ALL);
2349 ast_copy_flags(&(caller_features->features_caller), &(config->features_caller), AST_FLAGS_ALL);
2350 ds_caller_features->data = caller_features;
2351 ast_channel_lock(caller);
2352 ast_channel_datastore_add(caller, ds_caller_features);
2353 ast_channel_unlock(caller);
2355 /* If we don't return here, then when we do a builtin_atxfer we will copy the disconnect
2356 * flags over from the atxfer to the caller */
2360 ast_channel_lock(callee);
2361 ds_callee_features = ast_channel_datastore_find(callee, &dial_features_info, NULL);
2362 ast_channel_unlock(callee);
2363 if (!ds_callee_features) {
2364 if (!(ds_callee_features = ast_datastore_alloc(&dial_features_info, NULL))) {
2365 ast_log(LOG_WARNING, "Unable to create channel datastore for callee features. Aborting!\n");
2368 if (!(callee_features = ast_calloc(1, sizeof(*callee_features)))) {
2369 ast_log(LOG_WARNING, "Unable to allocate memory for callee feature flags. Aborting!\n");
2370 ast_datastore_free(ds_callee_features);
2373 ds_callee_features->inheritance = DATASTORE_INHERIT_FOREVER;
2374 callee_features->is_caller = 0;
2375 ast_copy_flags(&(callee_features->features_callee), &(config->features_caller), AST_FLAGS_ALL);
2376 ast_copy_flags(&(callee_features->features_caller), &(config->features_callee), AST_FLAGS_ALL);
2377 ds_callee_features->data = callee_features;
2378 ast_channel_lock(callee);
2379 ast_channel_datastore_add(callee, ds_callee_features);
2380 ast_channel_unlock(callee);
2387 * \brief bridge the call and set CDR
2388 * \param chan,peer,config
2390 * Set start time, check for two channels,check if monitor on
2391 * check for feature activation, create new CDR
2392 * \retval res on success.
2393 * \retval -1 on failure to bridge.
2395 int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast_bridge_config *config)
2397 /* Copy voice back and forth between the two channels. Give the peer
2398 the ability to transfer calls with '#<extension' syntax. */
2399 struct ast_frame *f;
2400 struct ast_channel *who;
2401 char chan_featurecode[FEATURE_MAX_LEN + 1]="";
2402 char peer_featurecode[FEATURE_MAX_LEN + 1]="";
2403 char orig_channame[AST_MAX_EXTENSION];
2404 char orig_peername[AST_MAX_EXTENSION];
2410 struct ast_option_header *aoh;
2411 struct ast_bridge_config backup_config;
2412 struct ast_cdr *bridge_cdr = NULL;
2413 struct ast_cdr *orig_peer_cdr = NULL;
2414 struct ast_cdr *chan_cdr = pick_unlocked_cdr(chan->cdr); /* the proper chan cdr, if there are forked cdrs */
2415 struct ast_cdr *peer_cdr = pick_unlocked_cdr(peer->cdr); /* the proper chan cdr, if there are forked cdrs */
2416 struct ast_cdr *new_chan_cdr = NULL; /* the proper chan cdr, if there are forked cdrs */
2417 struct ast_cdr *new_peer_cdr = NULL; /* the proper chan cdr, if there are forked cdrs */
2419 memset(&backup_config, 0, sizeof(backup_config));
2421 config->start_time = ast_tvnow();
2424 pbx_builtin_setvar_helper(chan, "BRIDGEPEER", peer->name);
2425 pbx_builtin_setvar_helper(peer, "BRIDGEPEER", chan->name);
2427 pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", NULL);
2430 set_bridge_features_on_config(config, pbx_builtin_getvar_helper(chan, "BRIDGE_FEATURES"));
2431 add_features_datastores(chan, peer, config);
2433 /* This is an interesting case. One example is if a ringing channel gets redirected to
2434 * an extension that picks up a parked call. This will make sure that the call taken
2435 * out of parking gets told that the channel it just got bridged to is still ringing. */
2436 if (chan->_state == AST_STATE_RINGING && peer->visible_indication != AST_CONTROL_RINGING) {
2437 ast_indicate(peer, AST_CONTROL_RINGING);
2441 const char *monitor_exec;
2442 struct ast_channel *src = NULL;
2444 if (!(monitor_app = pbx_findapp("Monitor")))
2447 if ((monitor_exec = pbx_builtin_getvar_helper(chan, "AUTO_MONITOR")))
2449 else if ((monitor_exec = pbx_builtin_getvar_helper(peer, "AUTO_MONITOR")))
2451 if (monitor_app && src) {
2452 char *tmp = ast_strdupa(monitor_exec);
2453 pbx_exec(src, monitor_app, tmp);
2457 set_config_flags(chan, peer, config);
2458 config->firstpass = 1;
2460 /* Answer if need be */
2461 if (ast_answer(chan))
2464 ast_copy_string(orig_channame,chan->name,sizeof(orig_channame));
2465 ast_copy_string(orig_peername,peer->name,sizeof(orig_peername));
2466 orig_peer_cdr = peer_cdr;
2468 if (!chan_cdr || (chan_cdr && !ast_test_flag(chan_cdr, AST_CDR_FLAG_POST_DISABLED))) {
2471 ast_set_flag(chan_cdr, AST_CDR_FLAG_MAIN);
2472 ast_cdr_update(chan);
2473 bridge_cdr = ast_cdr_dup(chan_cdr);
2474 ast_copy_string(bridge_cdr->lastapp, chan->appl, sizeof(bridge_cdr->lastapp));
2475 ast_copy_string(bridge_cdr->lastdata, chan->data, sizeof(bridge_cdr->lastdata));
2477 /* better yet, in a xfer situation, find out why the chan cdr got zapped (pun unintentional) */
2478 bridge_cdr = ast_cdr_alloc(); /* this should be really, really rare/impossible? */
2479 ast_copy_string(bridge_cdr->channel, chan->name, sizeof(bridge_cdr->channel));
2480 ast_copy_string(bridge_cdr->dstchannel, peer->name, sizeof(bridge_cdr->dstchannel));
2481 ast_copy_string(bridge_cdr->uniqueid, chan->uniqueid, sizeof(bridge_cdr->uniqueid));
2482 ast_copy_string(bridge_cdr->lastapp, chan->appl, sizeof(bridge_cdr->lastapp));
2483 ast_copy_string(bridge_cdr->lastdata, chan->data, sizeof(bridge_cdr->lastdata));
2484 ast_cdr_setcid(bridge_cdr, chan);
2485 bridge_cdr->disposition = (chan->_state == AST_STATE_UP) ? AST_CDR_ANSWERED : AST_CDR_NULL;
2486 bridge_cdr->amaflags = chan->amaflags ? chan->amaflags : ast_default_amaflags;
2487 ast_copy_string(bridge_cdr->accountcode, chan->accountcode, sizeof(bridge_cdr->accountcode));
2488 /* Destination information */
2489 ast_copy_string(bridge_cdr->dst, chan->exten, sizeof(bridge_cdr->dst));
2490 ast_copy_string(bridge_cdr->dcontext, chan->context, sizeof(bridge_cdr->dcontext));
2492 bridge_cdr->start = peer_cdr->start;
2493 ast_copy_string(bridge_cdr->userfield, peer_cdr->userfield, sizeof(bridge_cdr->userfield));
2495 ast_cdr_start(bridge_cdr);
2498 ast_debug(4,"bridge answer set, chan answer set\n");
2499 /* peer_cdr->answer will be set when a macro runs on the peer;
2500 in that case, the bridge answer will be delayed while the
2501 macro plays on the peer channel. The peer answered the call
2502 before the macro started playing. To the phone system,
2503 this is billable time for the call, even tho the caller
2504 hears nothing but ringing while the macro does its thing. */
2505 if (peer_cdr && !ast_tvzero(peer_cdr->answer)) {
2506 bridge_cdr->answer = peer_cdr->answer;
2507 chan_cdr->answer = peer_cdr->answer;
2508 bridge_cdr->disposition = peer_cdr->disposition;
2509 chan_cdr->disposition = peer_cdr->disposition;
2511 ast_cdr_answer(bridge_cdr);
2512 ast_cdr_answer(chan_cdr); /* for the sake of cli status checks */
2514 if (ast_test_flag(chan,AST_FLAG_BRIDGE_HANGUP_DONT)) {
2515 ast_set_flag(chan_cdr, AST_CDR_FLAG_BRIDGED);
2517 ast_set_flag(peer_cdr, AST_CDR_FLAG_BRIDGED);
2522 struct ast_channel *other; /* used later */
2524 res = ast_channel_bridge(chan, peer, config, &f, &who);
2526 if (config->feature_timer) {
2527 /* Update time limit for next pass */
2528 diff = ast_tvdiff_ms(ast_tvnow(), config->start_time);
2529 config->feature_timer -= diff;
2531 /* Running on backup config, meaning a feature might be being
2532 activated, but that's no excuse to keep things going
2534 if (backup_config.feature_timer && ((backup_config.feature_timer -= diff) <= 0)) {
2535 ast_debug(1, "Timed out, realtime this time!\n");
2536 config->feature_timer = 0;
2542 } else if (config->feature_timer <= 0) {
2543 /* Not *really* out of time, just out of time for
2544 digits to come in for features. */
2545 ast_debug(1, "Timed out for feature!\n");
2546 if (!ast_strlen_zero(peer_featurecode)) {
2547 ast_dtmf_stream(chan, peer, peer_featurecode, 0, 0);
2548 memset(peer_featurecode, 0, sizeof(peer_featurecode));
2550 if (!ast_strlen_zero(chan_featurecode)) {
2551 ast_dtmf_stream(peer, chan, chan_featurecode, 0, 0);
2552 memset(chan_featurecode, 0, sizeof(chan_featurecode));
2556 hasfeatures = !ast_strlen_zero(chan_featurecode) || !ast_strlen_zero(peer_featurecode);
2558 /* Restore original (possibly time modified) bridge config */
2559 memcpy(config, &backup_config, sizeof(struct ast_bridge_config));
2560 memset(&backup_config, 0, sizeof(backup_config));
2562 hadfeatures = hasfeatures;
2563 /* Continue as we were */
2566 /* The bridge returned without a frame and there is a feature in progress.
2567 * However, we don't think the feature has quite yet timed out, so just
2568 * go back into the bridge. */
2572 if (config->feature_timer <=0) {
2573 /* We ran out of time */
2574 config->feature_timer = 0;
2584 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_test_flag(peer, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan) && !ast_check_hangup(peer))
2585 ast_log(LOG_WARNING, "Bridge failed on channels %s and %s\n", chan->name, peer->name);
2589 if (!f || (f->frametype == AST_FRAME_CONTROL &&
2590 (f->subclass == AST_CONTROL_HANGUP || f->subclass == AST_CONTROL_BUSY ||
2591 f->subclass == AST_CONTROL_CONGESTION))) {
2595 /* many things should be sent to the 'other' channel */
2596 other = (who == chan) ? peer : chan;
2597 if (f->frametype == AST_FRAME_CONTROL) {
2598 switch (f->subclass) {
2599 case AST_CONTROL_RINGING:
2600 case AST_CONTROL_FLASH:
2602 ast_indicate(other, f->subclass);
2604 case AST_CONTROL_HOLD:
2605 case AST_CONTROL_UNHOLD:
2606 ast_indicate_data(other, f->subclass, f->data.ptr, f->datalen);
2608 case AST_CONTROL_OPTION:
2610 /* Forward option Requests */
2611 if (aoh && aoh->flag == AST_OPTION_FLAG_REQUEST) {
2612 ast_channel_setoption(other, ntohs(aoh->option), aoh->data,
2613 f->datalen - sizeof(struct ast_option_header), 0);
2617 } else if (f->frametype == AST_FRAME_DTMF_BEGIN) {
2619 } else if (f->frametype == AST_FRAME_DTMF) {
2623 hadfeatures = hasfeatures;
2624 /* This cannot overrun because the longest feature is one shorter than our buffer */
2626 sense = FEATURE_SENSE_CHAN;
2627 featurecode = chan_featurecode;
2629 sense = FEATURE_SENSE_PEER;
2630 featurecode = peer_featurecode;
2632 /*! append the event to featurecode. we rely on the string being zero-filled, and
2633 * not overflowing it.
2634 * \todo XXX how do we guarantee the latter ?
2636 featurecode[strlen(featurecode)] = f->subclass;
2637 /* Get rid of the frame before we start doing "stuff" with the channels */
2640 config->feature_timer = backup_config.feature_timer;
2641 res = ast_feature_interpret(chan, peer, config, featurecode, sense);
2643 case AST_FEATURE_RETURN_PASSDIGITS:
2644 ast_dtmf_stream(other, who, featurecode, 0, 0);
2646 case AST_FEATURE_RETURN_SUCCESS:
2647 memset(featurecode, 0, sizeof(chan_featurecode));
2650 if (res >= AST_FEATURE_RETURN_PASSDIGITS) {
2654 hasfeatures = !ast_strlen_zero(chan_featurecode) || !ast_strlen_zero(peer_featurecode);
2655 if (hadfeatures && !hasfeatures) {
2656 /* Restore backup */
2657 memcpy(config, &backup_config, sizeof(struct ast_bridge_config));
2658 memset(&backup_config, 0, sizeof(struct ast_bridge_config));
2659 } else if (hasfeatures) {
2661 /* Backup configuration */
2662 memcpy(&backup_config, config, sizeof(struct ast_bridge_config));
2663 /* Setup temporary config options */
2664 config->play_warning = 0;
2665 ast_clear_flag(&(config->features_caller), AST_FEATURE_PLAY_WARNING);
2666 ast_clear_flag(&(config->features_callee), AST_FEATURE_PLAY_WARNING);
2667 config->warning_freq = 0;
2668 config->warning_sound = NULL;
2669 config->end_sound = NULL;
2670 config->start_sound = NULL;
2671 config->firstpass = 0;
2673 config->start_time = ast_tvnow();
2674 config->feature_timer = featuredigittimeout;
2675 ast_debug(1, "Set time limit to %ld\n", config->feature_timer);
2684 if (ast_test_flag(chan,AST_FLAG_BRIDGE_HANGUP_DONT)) {
2685 ast_clear_flag(chan,AST_FLAG_BRIDGE_HANGUP_DONT); /* its job is done */
2687 ast_cdr_discard(bridge_cdr);
2688 /* QUESTION: should we copy bridge_cdr fields to the peer before we throw it away? */
2690 return res; /* if we shouldn't do the h-exten, we shouldn't do the bridge cdr, either! */
2693 if (config->end_bridge_callback) {
2694 config->end_bridge_callback(config->end_bridge_callback_data);
2697 /* run the hangup exten on the chan object IFF it was NOT involved in a parking situation
2698 * if it were, then chan belongs to a different thread now, and might have been hung up long
2701 if (!ast_test_flag(&(config->features_caller),AST_FEATURE_NO_H_EXTEN) &&
2702 ast_exists_extension(chan, chan->context, "h", 1, chan->cid.cid_num)) {
2703 struct ast_cdr *swapper = NULL;
2704 char savelastapp[AST_MAX_EXTENSION];
2705 char savelastdata[AST_MAX_EXTENSION];
2706 char save_exten[AST_MAX_EXTENSION];
2708 int found = 0; /* set if we find at least one match */
2709 int spawn_error = 0;
2711 autoloopflag = ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP);
2712 ast_set_flag(chan, AST_FLAG_IN_AUTOLOOP);
2713 if (bridge_cdr && ast_opt_end_cdr_before_h_exten) {
2714 ast_cdr_end(bridge_cdr);
2716 /* swap the bridge cdr and the chan cdr for a moment, and let the endbridge
2717 dialplan code operate on it */
2718 ast_channel_lock(chan);
2720 swapper = chan->cdr;
2721 ast_copy_string(savelastapp, bridge_cdr->lastapp, sizeof(bridge_cdr->lastapp));
2722 ast_copy_string(savelastdata, bridge_cdr->lastdata, sizeof(bridge_cdr->lastdata));
2723 chan->cdr = bridge_cdr;
2725 ast_copy_string(save_exten, chan->exten, sizeof(save_exten));
2726 save_prio = chan->priority;
2727 ast_copy_string(chan->exten, "h", sizeof(chan->exten));
2729 ast_channel_unlock(chan);
2730 while ((spawn_error = ast_spawn_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num, &found, 1)) == 0) {
2733 if (found && spawn_error) {
2734 /* Something bad happened, or a hangup has been requested. */
2735 ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", chan->context, chan->exten, chan->priority, chan->name);
2736 ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", chan->context, chan->exten, chan->priority, chan->name);
2739 ast_channel_lock(chan);
2740 ast_copy_string(chan->exten, save_exten, sizeof(chan->exten));
2741 chan->priority = save_prio;
2743 chan->cdr = swapper;
2744 ast_set_flag(chan, AST_FLAG_BRIDGE_HANGUP_RUN);
2745 ast_channel_unlock(chan);
2746 /* protect the lastapp/lastdata against the effects of the hangup/dialplan code */
2748 ast_copy_string(bridge_cdr->lastapp, savelastapp, sizeof(bridge_cdr->lastapp));
2749 ast_copy_string(bridge_cdr->lastdata, savelastdata, sizeof(bridge_cdr->lastdata));
2751 ast_set2_flag(chan, autoloopflag, AST_FLAG_IN_AUTOLOOP);
2754 /* obey the NoCDR() wishes. -- move the DISABLED flag to the bridge CDR if it was set on the channel during the bridge... */
2755 new_chan_cdr = pick_unlocked_cdr(chan->cdr); /* the proper chan cdr, if there are forked cdrs */
2756 if (bridge_cdr && new_chan_cdr && ast_test_flag(new_chan_cdr, AST_CDR_FLAG_POST_DISABLED))
2757 ast_set_flag(bridge_cdr, AST_CDR_FLAG_POST_DISABLED);
2759 /* we can post the bridge CDR at this point */
2761 ast_cdr_end(bridge_cdr);
2762 ast_cdr_detach(bridge_cdr);
2765 /* do a specialized reset on the beginning channel
2766 CDR's, if they still exist, so as not to mess up
2767 issues in future bridges;
2769 Here are the rules of the game:
2770 1. The chan and peer channel pointers will not change
2771 during the life of the bridge.
2772 2. But, in transfers, the channel names will change.
2773 between the time the bridge is started, and the
2774 time the channel ends.
2775 Usually, when a channel changes names, it will
2776 also change CDR pointers.
2777 3. Usually, only one of the two channels (chan or peer)
2779 4. Usually, if a channel changes names during a bridge,
2780 it is because of a transfer. Usually, in these situations,
2781 it is normal to see 2 bridges running simultaneously, and
2782 it is not unusual to see the two channels that change
2783 swapped between bridges.
2784 5. After a bridge occurs, we have 2 or 3 channels' CDRs
2785 to attend to; if the chan or peer changed names,
2786 we have the before and after attached CDR's.
2790 struct ast_channel *chan_ptr = NULL;
2792 if (strcasecmp(orig_channame, chan->name) != 0) {
2794 chan_ptr = ast_get_channel_by_name_locked(orig_channame);
2796 if (!ast_bridged_channel(chan_ptr)) {
2797 struct ast_cdr *cur;
2798 for (cur = chan_ptr->cdr; cur; cur = cur->next) {
2799 if (cur == chan_cdr) {
2804 ast_cdr_specialized_reset(chan_cdr,0);
2806 ast_channel_unlock(chan_ptr);
2809 ast_cdr_specialized_reset(new_chan_cdr,0);
2811 ast_cdr_specialized_reset(chan_cdr,0); /* nothing changed, reset the chan_cdr */
2816 struct ast_channel *chan_ptr = NULL;
2817 new_peer_cdr = pick_unlocked_cdr(peer->cdr); /* the proper chan cdr, if there are forked cdrs */
2818 if (new_chan_cdr && ast_test_flag(new_chan_cdr, AST_CDR_FLAG_POST_DISABLED) && new_peer_cdr && !ast_test_flag(new_peer_cdr, AST_CDR_FLAG_POST_DISABLED))
2819 ast_set_flag(new_peer_cdr, AST_CDR_FLAG_POST_DISABLED); /* DISABLED is viral-- it will propagate across a bridge */
2820 if (strcasecmp(orig_peername, peer->name) != 0) {
2822 chan_ptr = ast_get_channel_by_name_locked(orig_peername);
2824 if (!ast_bridged_channel(chan_ptr)) {
2825 struct ast_cdr *cur;
2826 for (cur = chan_ptr->cdr; cur; cur = cur->next) {
2827 if (cur == peer_cdr) {
2832 ast_cdr_specialized_reset(peer_cdr,0);
2834 ast_channel_unlock(chan_ptr);
2837 ast_cdr_specialized_reset(new_peer_cdr,0);
2839 ast_cdr_specialized_reset(peer_cdr,0); /* nothing changed, reset the peer_cdr */
2846 /*! \brief Output parking event to manager */
2847 static void post_manager_event(const char *s, struct parkeduser *pu)
2849 manager_event(EVENT_FLAG_CALL, s,
2852 "Parkinglot: %s\r\n"
2853 "CallerIDNum: %s\r\n"
2854 "CallerIDName: %s\r\n"
2855 "UniqueID: %s\r\n\r\n",
2858 pu->parkinglot->name,
2859 S_OR(pu->chan->cid.cid_num, "<unknown>"),
2860 S_OR(pu->chan->cid.cid_name, "<unknown>"),
2865 static char *callback_dialoptions(struct ast_flags *features_callee, struct ast_flags *features_caller, char *options, size_t len)
2869 OPT_CALLEE_REDIRECT = 't',
2870 OPT_CALLER_REDIRECT = 'T',
2871 OPT_CALLEE_AUTOMON = 'w',
2872 OPT_CALLER_AUTOMON = 'W',
2873 OPT_CALLEE_DISCONNECT = 'h',
2874 OPT_CALLER_DISCONNECT = 'H',
2875 OPT_CALLEE_PARKCALL = 'k',
2876 OPT_CALLER_PARKCALL = 'K',
2879 memset(options, 0, len);
2880 if (ast_test_flag(features_caller, AST_FEATURE_REDIRECT) && i < len) {
2881 options[i++] = OPT_CALLER_REDIRECT;
2883 if (ast_test_flag(features_caller, AST_FEATURE_AUTOMON) && i < len) {
2884 options[i++] = OPT_CALLER_AUTOMON;
2886 if (ast_test_flag(features_caller, AST_FEATURE_DISCONNECT) && i < len) {
2887 options[i++] = OPT_CALLER_DISCONNECT;
2889 if (ast_test_flag(features_caller, AST_FEATURE_PARKCALL) && i < len) {
2890 options[i++] = OPT_CALLER_PARKCALL;
2893 if (ast_test_flag(features_callee, AST_FEATURE_REDIRECT) && i < len) {
2894 options[i++] = OPT_CALLEE_REDIRECT;
2896 if (ast_test_flag(features_callee, AST_FEATURE_AUTOMON) && i < len) {
2897 options[i++] = OPT_CALLEE_AUTOMON;
2899 if (ast_test_flag(features_callee, AST_FEATURE_DISCONNECT) && i < len) {
2900 options[i++] = OPT_CALLEE_DISCONNECT;
2902 if (ast_test_flag(features_callee, AST_FEATURE_PARKCALL) && i < len) {
2903 options[i++] = OPT_CALLEE_PARKCALL;
2909 /*! \brief Run management on parkinglots, called once per parkinglot */
2910 int manage_parkinglot(struct ast_parkinglot *curlot, fd_set *rfds, fd_set *efds, fd_set *nrfds, fd_set *nefds, int *ms, int *max)
2913 struct parkeduser *pu;
2915 char parkingslot[AST_MAX_EXTENSION];
2917 /* Lock parking list */
2918 AST_LIST_LOCK(&curlot->parkings);
2919 AST_LIST_TRAVERSE_SAFE_BEGIN(&curlot->parkings, pu, list) {
2920 struct ast_channel *chan = pu->chan; /* shorthand */
2921 int tms; /* timeout for this item */
2922 int x; /* fd index in channel */
2923 struct ast_context *con;
2925 if (pu->notquiteyet) { /* Pretend this one isn't here yet */
2928 tms = ast_tvdiff_ms(ast_tvnow(), pu->start);
2929 if (tms > pu->parkingtime) {
2930 /* Stop music on hold */
2931 ast_indicate(pu->chan, AST_CONTROL_UNHOLD);
2932 /* Get chan, exten from derived kludge */
2933 if (pu->peername[0]) {
2934 char *peername = ast_strdupa(pu->peername);
2935 char *cp = strrchr(peername, '-');
2936 char peername_flat[AST_MAX_EXTENSION]; /* using something like DAHDI/52 for an extension name is NOT a good idea */
2941 ast_copy_string(peername_flat,peername,sizeof(peername_flat));
2942 for(i=0; peername_flat[i] && i < AST_MAX_EXTENSION; i++) {
2943 if (peername_flat[i] == '/')
2944 peername_flat[i]= '0';
2946 con = ast_context_find_or_create(NULL, NULL, pu->parkinglot->parking_con_dial, registrar);
2948 ast_log(LOG_ERROR, "Parking dial context '%s' does not exist and unable to create\n", pu->parkinglot->parking_con_dial);
2951 char returnexten[AST_MAX_EXTENSION];
2952 struct ast_datastore *features_datastore;
2953 struct ast_dial_features *dialfeatures = NULL;
2955 ast_channel_lock(chan);
2957 if ((features_datastore = ast_channel_datastore_find(chan, &dial_features_info, NULL)))
2958 dialfeatures = features_datastore->data;
2960 ast_channel_unlock(chan);
2962 if (!strncmp(peername, "Parked/", 7)) {
2967 char buf[MAX_DIAL_FEATURE_OPTIONS] = {0,};
2968 snprintf(returnexten, sizeof(returnexten), "%s|30|%s", peername, callback_dialoptions(&(dialfeatures->features_callee), &(dialfeatures->features_caller), buf, sizeof(buf)));
2969 } else { /* Existing default */
2970 ast_log(LOG_WARNING, "Dialfeatures not found on %s, using default!\n", chan->name);
2971 snprintf(returnexten, sizeof(returnexten), "%s|30|t", peername);
2974 ast_add_extension2(con, 1, peername_flat, 1, NULL, NULL, "Dial", ast_strdup(returnexten), ast_free_ptr, registrar);
2976 if (comebacktoorigin) {
2977 set_c_e_p(chan, pu->parkinglot->parking_con_dial, peername_flat, 1);
2979 ast_log(LOG_WARNING, "now going to parkedcallstimeout,s,1 | ps is %d\n",pu->parkingnum);
2980 snprintf(parkingslot, sizeof(parkingslot), "%d", pu->parkingnum);
2981 pbx_builtin_setvar_helper(chan, "PARKINGSLOT", parkingslot);
2982 set_c_e_p(chan, "parkedcallstimeout", peername_flat, 1);
2985 /* They've been waiting too long, send them back to where they came. Theoretically they
2986 should have their original extensions and such, but we copy to be on the safe side */
2987 set_c_e_p(chan, pu->context, pu->exten, pu->priority);
2989 post_manager_event("ParkedCallTimeOut", pu);
2991 ast_verb(2, "Timeout for %s parked on %d (%s). Returning to %s,%s,%d\n", pu->chan->name, pu->parkingnum, pu->parkinglot->name, pu->chan->context, pu->chan->exten, pu->chan->priority);
2992 /* Start up the PBX, or hang them up */
2993 if (ast_pbx_start(chan)) {
2994 ast_log(LOG_WARNING, "Unable to restart the PBX for user on '%s', hanging them up...\n", pu->chan->name);
2997 /* And take them out of the parking lot */
2998 con = ast_context_find(pu->parkinglot->parking_con);
3000 if (ast_context_remove_extension2(con, pu->parkingexten, 1, NULL, 0))
3001 ast_log(LOG_WARNING, "Whoa, failed to remove the parking extension!\n");
3003 notify_metermaids(pu->parkingexten, curlot->parking_con, AST_DEVICE_NOT_INUSE);
3005 ast_log(LOG_WARNING, "Whoa, no parking context?\n");
3006 AST_LIST_REMOVE_CURRENT(list);
3008 } else { /* still within parking time, process descriptors */
3009 for (x = 0; x < AST_MAX_FDS; x++) {
3010 struct ast_frame *f;
3012 if ((chan->fds[x] == -1) || (!FD_ISSET(chan->fds[x], rfds) && !FD_ISSET(pu->chan->fds[x], efds)))
3015 if (FD_ISSET(chan->fds[x], efds))
3016 ast_set_flag(chan, AST_FLAG_EXCEPTION);
3018 ast_clear_flag(chan, AST_FLAG_EXCEPTION);
3021 /* See if they need servicing */
3022 f = ast_read(pu->chan);
3024 if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
3027 post_manager_event("ParkedCallGiveUp", pu);
3029 /* There's a problem, hang them up*/
3030 ast_verb(2, "%s got tired of being parked\n", chan->name);
3032 /* And take them out of the parking lot */
3033 con = ast_context_find(curlot->parking_con);
3035 if (ast_context_remove_extension2(con, pu->parkingexten, 1, NULL, 0))
3036 ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
3038 notify_metermaids(pu->parkingexten, curlot->parking_con, AST_DEVICE_NOT_INUSE);
3040 ast_log(LOG_WARNING, "Whoa, no parking context for parking lot %s?\n", curlot->name);
3041 AST_LIST_REMOVE_CURRENT(list);
3045 /* XXX Maybe we could do something with packets, like dial "0" for operator or something XXX */
3047 if (pu->moh_trys < 3 && !chan->generatordata) {
3048 ast_debug(1, "MOH on parked call stopped by outside source. Restarting on channel %s.\n", chan->name);
3049 ast_indicate_data(chan, AST_CONTROL_HOLD,
3050 S_OR(curlot->mohclass, NULL),
3051 (!ast_strlen_zero(curlot->mohclass) ? strlen(curlot->mohclass) + 1 : 0));
3054 goto std; /* XXX Ick: jumping into an else statement??? XXX */
3057 if (x >= AST_MAX_FDS) {
3058 std: for (x=0; x<AST_MAX_FDS; x++) { /* mark fds for next round */
3059 if (chan->fds[x] > -1) {
3060 FD_SET(chan->fds[x], nrfds);
3061 FD_SET(chan->fds[x], nefds);
3062 if (chan->fds[x] > *max)
3063 *max = chan->fds[x];
3066 /* Keep track of our shortest wait */
3067 if (tms < *ms || *ms < 0)
3072 AST_LIST_TRAVERSE_SAFE_END;
3073 AST_LIST_UNLOCK(&curlot->parkings);
3078 * \brief Take care of parked calls and unpark them if needed
3079 * \param ignore unused var.
3081 * Start inf loop, lock parking lot, check if any parked channels have gone above timeout
3082 * if so, remove channel from parking lot and return it to the extension that parked it.
3083 * Check if parked channel decided to hangup, wait until next FD via select().
3085 static void *do_parking_thread(void *ignore)
3087 fd_set rfds, efds; /* results from previous select, to be preserved across loops. */
3088 fd_set nrfds, nefds; /* args for the next select */
3094 int ms = -1; /* select timeout, uninitialized */
3095 int max = -1; /* max fd, none there yet */
3096 struct ao2_iterator iter;
3097 struct ast_parkinglot *curlot;
3100 iter = ao2_iterator_init(parkinglots, 0);
3102 while ((curlot = ao2_iterator_next(&iter))) {
3103 res = manage_parkinglot(curlot, &rfds, &efds, &nrfds, &nefds, &ms, &max);
3104 ao2_ref(curlot, -1);
3110 struct timeval wait = ast_samp2tv(ms, 1000);
3111 /* Wait for something to happen */
3112 ast_select(max + 1, &rfds, NULL, &efds, (ms > -1) ? &wait : NULL);
3114 pthread_testcancel();
3116 return NULL; /* Never reached */
3119 /*! \brief Find parkinglot by name */
3120 struct ast_parkinglot *find_parkinglot(const char *name)
3122 struct ast_parkinglot *parkinglot = NULL;
3123 struct ast_parkinglot tmp_parkinglot;
3125 if (ast_strlen_zero(name))
3128 ast_copy_string(tmp_parkinglot.name, name, sizeof(tmp_parkinglot.name));
3130 parkinglot = ao2_find(parkinglots, &tmp_parkinglot, OBJ_POINTER);
3132 if (parkinglot && option_debug)
3133 ast_log(LOG_DEBUG, "Found Parkinglot: %s\n", parkinglot->name);
3138 AST_APP_OPTIONS(park_call_options, BEGIN_OPTIONS
3139 AST_APP_OPTION('r', AST_PARK_OPT_RINGING),
3140 AST_APP_OPTION('R', AST_PARK_OPT_RANDOMIZE),
3141 AST_APP_OPTION('s', AST_PARK_OPT_SILENCE),
3144 /*! \brief Park a call */
3145 static int park_call_exec(struct ast_channel *chan, void *data)
3147 /* Cache the original channel name in case we get masqueraded in the middle
3148 * of a park--it is still theoretically possible for a transfer to happen before
3149 * we get here, but it is _really_ unlikely */
3150 char *orig_chan_name = ast_strdupa(chan->name);
3151 char orig_exten[AST_MAX_EXTENSION];
3152 int orig_priority = chan->priority;
3154 /* Data is unused at the moment but could contain a parking
3155 lot context eventually */
3159 AST_DECLARE_APP_ARGS(app_args,
3160 AST_APP_ARG(timeout);
3161 AST_APP_ARG(return_con);
3162 AST_APP_ARG(return_ext);
3163 AST_APP_ARG(return_pri);
3164 AST_APP_ARG(options);
3167 parse = ast_strdupa(data);
3168 AST_STANDARD_APP_ARGS(app_args, parse);
3170 ast_copy_string(orig_exten, chan->exten, sizeof(orig_exten));
3172 /* Setup the exten/priority to be s/1 since we don't know
3173 where this call should return */
3174 strcpy(chan->exten, "s");
3177 /* Answer if call is not up */
3178 if (chan->_state != AST_STATE_UP)
3179 res = ast_answer(chan);
3181 /* Sleep to allow VoIP streams to settle down */
3183 res = ast_safe_sleep(chan, 1000);
3187 struct ast_park_call_args args = {
3188 .orig_chan_name = orig_chan_name,
3190 struct ast_flags flags = { 0 };
3193 if (!ast_strlen_zero(app_args.timeout)) {
3194 if (sscanf(app_args.timeout, "%d", &args.timeout) != 1) {
3195 ast_log(LOG_WARNING, "Invalid timeout '%s' provided\n", app_args.timeout);
3199 if (!ast_strlen_zero(app_args.return_con)) {
3200 args.return_con = app_args.return_con;
3202 if (!ast_strlen_zero(app_args.return_ext)) {
3203 args.return_ext = app_args.return_ext;
3205 if (!ast_strlen_zero(app_args.return_pri)) {
3206 if (sscanf(app_args.return_pri, "%d", &args.return_pri) != 1) {
3207 ast_log(LOG_WARNING, "Invalid priority '%s' specified\n", app_args.return_pri);
3208 args.return_pri = 0;
3213 ast_app_parse_options(park_call_options, &flags, NULL, app_args.options);
3214 args.flags = flags.flags;
3216 res = masq_park_call_announce_args(chan, chan, &args);
3217 /* Continue on in the dialplan */
3219 ast_copy_string(chan->exten, orig_exten, sizeof(chan->exten));
3220 chan->priority = orig_priority;
3230 /*! \brief Pickup parked call */
3231 static int park_exec_full(struct ast_channel *chan, void *data, struct ast_parkinglot *parkinglot)
3234 struct ast_channel *peer=NULL;
3235 struct parkeduser *pu;
3236 struct ast_context *con;
3238 struct ast_bridge_config config;
3241 park = atoi((char *)data);
3243 parkinglot = find_parkinglot(findparkinglotname(chan));
3245 parkinglot = default_parkinglot;
3247 AST_LIST_LOCK(&parkinglot->parkings);
3248 AST_LIST_TRAVERSE_SAFE_BEGIN(&parkinglot->parkings, pu, list) {
3249 if (!data || pu->parkingnum == park) {
3250 if (pu->chan->pbx) { /* do not allow call to be picked up until the PBX thread is finished */
3251 AST_LIST_UNLOCK(&parkinglot->parkings);
3254 AST_LIST_REMOVE_CURRENT(list);
3258 AST_LIST_TRAVERSE_SAFE_END
3259 AST_LIST_UNLOCK(&parkinglot->parkings);
3263 con = ast_context_find(parkinglot->parking_con);
3265 if (ast_context_remove_extension2(con, pu->parkingexten, 1, NULL, 0))
3266 ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
3268 notify_metermaids(pu->parkingexten, parkinglot->parking_con, AST_DEVICE_NOT_INUSE);
3270 ast_log(LOG_WARNING, "Whoa, no parking context?\n");
3272 manager_event(EVENT_FLAG_CALL, "UnParkedCall",
3276 "CallerIDNum: %s\r\n"
3277 "CallerIDName: %s\r\n",
3278 pu->parkingexten, pu->chan->name, chan->name,
3279 S_OR(pu->chan->cid.cid_num, "<unknown>"),
3280 S_OR(pu->chan->cid.cid_name, "<unknown>")
3285 /* JK02: it helps to answer the channel if not already up */
3286 if (chan->_state != AST_STATE_UP)
3289 //XXX Why do we unlock here ?
3290 // uncomment it for now, till my setup with debug_threads and detect_deadlocks starts to complain
3291 //ASTOBJ_UNLOCK(parkinglot);
3294 struct ast_datastore *features_datastore;
3295 struct ast_dial_features *dialfeatures = NULL;
3297 /* Play a courtesy to the source(s) configured to prefix the bridge connecting */
3299 if (!ast_strlen_zero(courtesytone)) {
3301 ast_indicate(peer, AST_CONTROL_UNHOLD);
3302 if (parkedplay == 0) {
3303 error = ast_stream_and_wait(chan, courtesytone, "");
3304 } else if (parkedplay == 1) {
3305 error = ast_stream_and_wait(peer, courtesytone, "");
3306 } else if (parkedplay == 2) {
3307 if (!ast_streamfile(chan, courtesytone, chan->language) &&
3308 !ast_streamfile(peer, courtesytone, chan->language)) {
3309 /*! \todo XXX we would like to wait on both! */
3310 res = ast_waitstream(chan, "");
3312 res = ast_waitstream(peer, "");
3318 ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
3323 ast_indicate(peer, AST_CONTROL_UNHOLD);
3325 res = ast_channel_make_compatible(chan, peer);
3327 ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for bridge\n", chan->name, peer->name);
3331 /* This runs sorta backwards, since we give the incoming channel control, as if it
3332 were the person called. */
3333 ast_verb(3, "Channel %s connected to parked call %d\n", chan->name, park);
3335 pbx_builtin_setvar_helper(chan, "PARKEDCHANNEL", peer->name);
3336 ast_cdr_setdestchan(chan->cdr, peer->name);
3337 memset(&config, 0, sizeof(struct ast_bridge_config));
3339 /* Get datastore for peer and apply it's features to the callee side of the bridge config */
3340 ast_channel_lock(peer);
3341 if ((features_datastore = ast_channel_datastore_find(peer, &dial_features_info, NULL))) {
3342 dialfeatures = features_datastore->data;
3344 ast_channel_unlock(peer);
3347 ast_copy_flags(&(config.features_callee), dialfeatures->is_caller ? &(dialfeatures->features_caller) : &(dialfeatures->features_callee), AST_FLAGS_ALL);
3350 if ((parkinglot->parkedcalltransfers == AST_FEATURE_FLAG_BYCALLEE) || (parkinglot->parkedcalltransfers == AST_FEATURE_FLAG_BYBOTH)) {
3351 ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
3353 if ((parkinglot->parkedcalltransfers == AST_FEATURE_FLAG_BYCALLER) || (parkinglot->parkedcalltransfers == AST_FEATURE_FLAG_BYBOTH)) {
3354 ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
3356 if ((parkinglot->parkedcallreparking == AST_FEATURE_FLAG_BYCALLEE) || (parkinglot->parkedcallreparking == AST_FEATURE_FLAG_BYBOTH)) {
3357 ast_set_flag(&(config.features_callee), AST_FEATURE_PARKCALL);
3359 if ((parkinglot->parkedcallreparking == AST_FEATURE_FLAG_BYCALLER) || (parkinglot->parkedcallreparking == AST_FEATURE_FLAG_BYBOTH)) {
3360 ast_set_flag(&(config.features_caller), AST_FEATURE_PARKCALL);
3362 if ((parkinglot->parkedcallhangup == AST_FEATURE_FLAG_BYCALLEE) || (parkinglot->parkedcallhangup == AST_FEATURE_FLAG_BYBOTH)) {
3363 ast_set_flag(&(config.features_callee), AST_FEATURE_DISCONNECT);
3365 if ((parkinglot->parkedcallhangup == AST_FEATURE_FLAG_BYCALLER) || (parkinglot->parkedcallhangup == AST_FEATURE_FLAG_BYBOTH)) {
3366 ast_set_flag(&(config.features_caller), AST_FEATURE_DISCONNECT);
3368 if ((parkinglot->parkedcallrecording == AST_FEATURE_FLAG_BYCALLEE) || (parkinglot->parkedcallrecording == AST_FEATURE_FLAG_BYBOTH)) {
3369 ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMON);
3371 if ((parkinglot->parkedcallrecording == AST_FEATURE_FLAG_BYCALLER) || (parkinglot->parkedcallrecording == AST_FEATURE_FLAG_BYBOTH)) {
3372 ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMON);
3375 res = ast_bridge_call(chan, peer, &config);
3377 pbx_builtin_setvar_helper(chan, "PARKEDCHANNEL", peer->name);
3378 ast_cdr_setdestchan(chan->cdr, peer->name);
3380 /* Simulate the PBX hanging up */
3384 /*! \todo XXX Play a message XXX */
3385 if (ast_stream_and_wait(chan, "pbx-invalidpark", ""))
3386 ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", "pbx-invalidpark", chan->name);
3387 ast_verb(3, "Channel %s tried to talk to nonexistent parked call %d\n", chan->name, park);
3394 static int park_exec(struct ast_channel *chan, void *data)
3396 return park_exec_full(chan, data, default_parkinglot);
3399 /*! \brief Unreference parkinglot object. If no more references,
3400 then go ahead and delete it */
3401 static void parkinglot_unref(struct ast_parkinglot *parkinglot)
3403 int refcount = ao2_ref(parkinglot, -1);
3404 if (option_debug > 2)
3405 ast_log(LOG_DEBUG, "Multiparking: %s refcount now %d\n", parkinglot->name, refcount - 1);
3408 static struct ast_parkinglot *parkinglot_addref(struct ast_parkinglot *parkinglot)
3410 int refcount = ao2_ref(parkinglot, +1);
3411 if (option_debug > 2)
3412 ast_log(LOG_DEBUG, "Multiparking: %s refcount now %d\n", parkinglot->name, refcount + 1);