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"
35 #include <sys/signal.h>
36 #include <netinet/in.h>
38 #include "asterisk/lock.h"
39 #include "asterisk/file.h"
40 #include "asterisk/channel.h"
41 #include "asterisk/pbx.h"
42 #include "asterisk/causes.h"
43 #include "asterisk/module.h"
44 #include "asterisk/translate.h"
45 #include "asterisk/app.h"
46 #include "asterisk/say.h"
47 #include "asterisk/features.h"
48 #include "asterisk/musiconhold.h"
49 #include "asterisk/config.h"
50 #include "asterisk/cli.h"
51 #include "asterisk/manager.h"
52 #include "asterisk/utils.h"
53 #include "asterisk/adsi.h"
54 #include "asterisk/devicestate.h"
55 #include "asterisk/monitor.h"
56 #include "asterisk/audiohook.h"
57 #include "asterisk/global_datastores.h"
58 #include "asterisk/astobj2.h"
59 #include "asterisk/cel.h"
60 #include "asterisk/test.h"
63 * Party A - transferee
64 * Party B - transferer
65 * Party C - target of transfer
67 * DTMF attended transfer works within the channel bridge.
68 * Unfortunately, when either party A or B in the channel bridge
69 * hangs up, that channel is not completely hung up until the
70 * transfer completes. This is a real problem depending upon
71 * the channel technology involved.
73 * For chan_dahdi, the channel is crippled until the hangup is
74 * complete. Either the channel is not useable (analog) or the
75 * protocol disconnect messages are held up (PRI/BRI/SS7) and
76 * the media is not released.
78 * For chan_sip, a call limit of one is going to block that
79 * endpoint from any further calls until the hangup is complete.
81 * For party A this is a minor problem. The party A channel
82 * will only be in this condition while party B is dialing and
83 * when party B and C are conferring. The conversation between
84 * party B and C is expected to be a short one. Party B is
85 * either asking a question of party C or announcing party A.
86 * Also party A does not have much incentive to hangup at this
89 * For party B this can be a major problem during a blonde
90 * transfer. (A blonde transfer is our term for an attended
91 * transfer that is converted into a blind transfer. :)) Party
92 * B could be the operator. When party B hangs up, he assumes
93 * that he is out of the original call entirely. The party B
94 * channel will be in this condition while party C is ringing,
95 * while attempting to recall party B, and while waiting between
99 * The ATXFER_NULL_TECH conditional is a hack to fix the
100 * problem. It will replace the party B channel technology with
101 * a NULL channel driver. The consequences of this code is that
102 * the 'h' extension will not be able to access any channel
103 * technology specific information like SIP statistics for the
106 * Uncomment the ATXFER_NULL_TECH define below to replace the
107 * party B channel technology in the channel bridge to complete
108 * hanging up the channel technology.
110 //#define ATXFER_NULL_TECH 1
113 <application name="Bridge" language="en_US">
118 <parameter name="channel" required="true">
119 <para>The current channel is bridged to the specified <replaceable>channel</replaceable>.</para>
121 <parameter name="options">
124 <para>Play a courtesy tone to <replaceable>channel</replaceable>.</para>
127 <para>Allow the called party to hang up by sending the
128 <replaceable>*</replaceable> DTMF digit.</para>
131 <para>Allow the calling party to hang up by pressing the
132 <replaceable>*</replaceable> DTMF digit.</para>
135 <para>Allow the called party to enable parking of the call by sending
136 the DTMF sequence defined for call parking in features.conf.</para>
139 <para>Allow the calling party to enable parking of the call by sending
140 the DTMF sequence defined for call parking in features.conf.</para>
142 <option name="L(x[:y][:z])">
143 <para>Limit the call to <replaceable>x</replaceable> ms. Play a warning
144 when <replaceable>y</replaceable> ms are left. Repeat the warning every
145 <replaceable>z</replaceable> ms. The following special variables can be
146 used with this option:</para>
148 <variable name="LIMIT_PLAYAUDIO_CALLER">
149 <para>Play sounds to the caller. yes|no (default yes)</para>
151 <variable name="LIMIT_PLAYAUDIO_CALLEE">
152 <para>Play sounds to the callee. yes|no</para>
154 <variable name="LIMIT_TIMEOUT_FILE">
155 <para>File to play when time is up.</para>
157 <variable name="LIMIT_CONNECT_FILE">
158 <para>File to play when call begins.</para>
160 <variable name="LIMIT_WARNING_FILE">
161 <para>File to play as warning if <replaceable>y</replaceable> is
162 defined. The default is to say the time remaining.</para>
167 <para>Hang up the call after <replaceable>x</replaceable> seconds *after* the called party has answered the call.</para>
170 <para>Allow the called party to transfer the calling party by sending the
171 DTMF sequence defined in features.conf.</para>
174 <para>Allow the calling party to transfer the called party by sending the
175 DTMF sequence defined in features.conf.</para>
178 <para>Allow the called party to enable recording of the call by sending
179 the DTMF sequence defined for one-touch recording in features.conf.</para>
182 <para>Allow the calling party to enable recording of the call by sending
183 the DTMF sequence defined for one-touch recording in features.conf.</para>
186 <para>Cause the called party to be hung up after the bridge, instead of being
187 restarted in the dialplan.</para>
193 <para>Allows the ability to bridge two channels via the dialplan.</para>
194 <para>This application sets the following channel variable upon completion:</para>
196 <variable name="BRIDGERESULT">
197 <para>The result of the bridge attempt as a text string.</para>
198 <value name="SUCCESS" />
199 <value name="FAILURE" />
200 <value name="LOOP" />
201 <value name="NONEXISTENT" />
202 <value name="INCOMPATIBLE" />
207 <application name="ParkedCall" language="en_US">
209 Answer a parked call.
212 <parameter name="exten" required="true" />
215 <para>Used to connect to a parked call. This application is always
216 registered internally and does not need to be explicitly added
217 into the dialplan, although you should include the <literal>parkedcalls</literal>
218 context. If no extension is provided, then the first available
219 parked call will be acquired.</para>
222 <ref type="application">Park</ref>
223 <ref type="application">ParkAndAnnounce</ref>
226 <application name="Park" language="en_US">
231 <parameter name="timeout">
232 <para>A custom parking timeout for this parked call. Value in milliseconds.</para>
234 <parameter name="return_context">
235 <para>The context to return the call to after it times out.</para>
237 <parameter name="return_exten">
238 <para>The extension to return the call to after it times out.</para>
240 <parameter name="return_priority">
241 <para>The priority to return the call to after it times out.</para>
243 <parameter name="options">
244 <para>A list of options for this parked call.</para>
247 <para>Send ringing instead of MOH to the parked call.</para>
250 <para>Randomize the selection of a parking space.</para>
253 <para>Silence announcement of the parking space number.</para>
259 <para>Used to park yourself (typically in combination with a supervised
260 transfer to know the parking space). This application is always
261 registered internally and does not need to be explicitly added
262 into the dialplan, although you should include the <literal>parkedcalls</literal>
263 context (or the context specified in <filename>features.conf</filename>).</para>
264 <para>If you set the <variable>PARKINGLOT</variable> variable, the call will be parked
265 in the specifed parking context. Note setting this variable overrides the <variable>
266 PARKINGLOT</variable> set by the <literal>CHANNEL</literal> function.</para>
267 <para>If you set the <variable>PARKINGEXTEN</variable> variable to an extension in your
268 parking context, Park() will park the call on that extension, unless
269 it already exists. In that case, execution will continue at next priority.</para>
270 <para>If you set the <variable>PARKINGLOT</variable> variable, Park() will park the call
271 in that parkinglot.</para>
272 <para>If you set the <variable>PARKINGDYNAMIC</variable> variable, this parkinglot from features.conf
273 will be used as template for the newly created dynamic lot.</para>
274 <para>If you set the <variable>PARKINGDYNCONTEXT</variable> variable the newly created dynamic
275 parking lot will use this context.</para>
276 <para>If you set the <variable>PARKINGDYNPOS</variable> variable the newly created dynamic parkinglot
277 will use those parking postitions.</para>
280 <ref type="application">ParkAndAnnounce</ref>
281 <ref type="application">ParkedCall</ref>
284 <manager name="ParkedCalls" language="en_US">
289 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
292 <para>List parked calls.</para>
295 <manager name="Park" language="en_US">
300 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
301 <parameter name="Channel" required="true">
302 <para>Channel name to park.</para>
304 <parameter name="Channel2" required="true">
305 <para>Channel to announce park info to (and return to if timeout).</para>
307 <parameter name="Timeout">
308 <para>Number of milliseconds to wait before callback.</para>
310 <parameter name="Parkinglot">
311 <para>Parking lot to park channel in.</para>
315 <para>Park a channel.</para>
318 <manager name="Bridge" language="en_US">
320 Bridge two channels already in the PBX.
323 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
324 <parameter name="Channel1" required="true">
325 <para>Channel to Bridge to Channel2.</para>
327 <parameter name="Channel2" required="true">
328 <para>Channel to Bridge to Channel1.</para>
330 <parameter name="Tone">
331 <para>Play courtesy tone to Channel 2.</para>
339 <para>Bridge together two channels already in the PBX.</para>
344 #define DEFAULT_PARK_TIME 45000 /*!< ms */
345 #define DEFAULT_PARK_EXTENSION "700"
346 #define DEFAULT_TRANSFER_DIGIT_TIMEOUT 3000 /*!< ms */
347 #define DEFAULT_FEATURE_DIGIT_TIMEOUT 1000 /*!< ms */
348 #define DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER 15000 /*!< ms */
349 #define DEFAULT_ATXFER_DROP_CALL 0 /*!< Do not drop call. */
350 #define DEFAULT_ATXFER_LOOP_DELAY 10000 /*!< ms */
351 #define DEFAULT_ATXFER_CALLBACK_RETRIES 2
353 #define AST_MAX_WATCHERS 256
354 #define MAX_DIAL_FEATURE_OPTIONS 30
356 struct feature_group_exten {
357 AST_LIST_ENTRY(feature_group_exten) entry;
358 AST_DECLARE_STRING_FIELDS(
359 AST_STRING_FIELD(exten);
361 struct ast_call_feature *feature;
364 struct feature_group {
365 AST_LIST_ENTRY(feature_group) entry;
366 AST_DECLARE_STRING_FIELDS(
367 AST_STRING_FIELD(gname);
369 AST_LIST_HEAD_NOLOCK(, feature_group_exten) features;
372 static AST_RWLIST_HEAD_STATIC(feature_groups, feature_group);
374 static char *parkedcall = "ParkedCall";
376 static char pickup_ext[AST_MAX_EXTENSION]; /*!< Call pickup extension */
378 /*! \brief Description of one parked call, added to a list while active, then removed.
379 The list belongs to a parkinglot
382 struct ast_channel *chan; /*!< Parking channel */
383 struct timeval start; /*!< Time the parking started */
384 int parkingnum; /*!< Parking lot */
385 char parkingexten[AST_MAX_EXTENSION]; /*!< If set beforehand, parking extension used for this call */
386 char context[AST_MAX_CONTEXT]; /*!< Where to go if our parking time expires */
387 char exten[AST_MAX_EXTENSION];
389 int parkingtime; /*!< Maximum length in parking lot before return */
390 unsigned int notquiteyet:1;
391 unsigned int options_specified:1;
393 unsigned char moh_trys;
394 struct ast_parkinglot *parkinglot;
395 AST_LIST_ENTRY(parkeduser) list;
398 /*! \brief Structure for parking lots which are put in a container. */
399 struct ast_parkinglot {
400 char name[AST_MAX_CONTEXT];
401 char parkext[AST_MAX_EXTENSION]; /*!< Parkingextension */
402 char parking_con[AST_MAX_EXTENSION]; /*!< Context for which parking is made accessible */
403 char parking_con_dial[AST_MAX_EXTENSION]; /*!< Context for dialback for parking (KLUDGE) */
404 int parking_start; /*!< First available extension for parking */
405 int parking_stop; /*!< Last available extension for parking */
408 int parkingtime; /*!< Default parking time */
409 char mohclass[MAX_MUSICCLASS]; /*!< Music class used for parking */
410 int parkaddhints; /*!< Add parking hints automatically */
411 int parkedcalltransfers; /*!< Enable DTMF based transfers on bridge when picking up parked calls */
412 int parkedcallreparking; /*!< Enable DTMF based parking on bridge when picking up parked calls */
413 int parkedcallhangup; /*!< Enable DTMF based hangup on a bridge when pickup up parked calls */
414 int parkedcallrecording; /*!< Enable DTMF based recording on a bridge when picking up parked calls */
415 unsigned short the_mark:1; /*!< Used during reloads, that which bears the_mark shall be deleted! */
416 AST_LIST_HEAD(parkinglot_parklist, parkeduser) parkings; /*!< List of active parkings in this parkinglot */
419 /*! \brief The list of parking lots configured. Always at least one - the default parking lot */
420 static struct ao2_container *parkinglots;
422 struct ast_parkinglot *default_parkinglot;
423 char parking_ext[AST_MAX_EXTENSION]; /*!< Extension you type to park the call */
425 static char courtesytone[256]; /*!< Courtesy tone */
426 static int parkedplay = 0; /*!< Who to play the courtesy tone to */
427 static int parkeddynamic = 0; /*!< Enable creation of parkinglots dynamically */
428 static char xfersound[256]; /*!< Call transfer sound */
429 static char xferfailsound[256]; /*!< Call transfer failure sound */
430 static char pickupsound[256]; /*!< Pickup sound */
431 static char pickupfailsound[256]; /*!< Pickup failure sound */
435 static int transferdigittimeout;
436 static int featuredigittimeout;
437 static int comebacktoorigin = 1;
439 static int atxfernoanswertimeout;
440 static unsigned int atxferdropcall;
441 static unsigned int atxferloopdelay;
442 static unsigned int atxfercallbackretries;
444 static char *registrar = "features"; /*!< Registrar for operations */
446 /* module and CLI command definitions */
447 static char *parkcall = PARK_APP_NAME;
449 static struct ast_app *monitor_app = NULL;
450 static int monitor_ok = 1;
452 static struct ast_app *mixmonitor_app = NULL;
453 static int mixmonitor_ok = 1;
455 static struct ast_app *stopmixmonitor_app = NULL;
456 static int stopmixmonitor_ok = 1;
458 static pthread_t parking_thread;
459 struct ast_dial_features {
460 struct ast_flags features_caller;
461 struct ast_flags features_callee;
465 #if defined(ATXFER_NULL_TECH)
466 static struct ast_frame *null_read(struct ast_channel *chan)
468 /* Hangup channel. */
472 static struct ast_frame *null_exception(struct ast_channel *chan)
474 /* Hangup channel. */
478 static int null_write(struct ast_channel *chan, struct ast_frame *frame)
480 /* Hangup channel. */
484 static int null_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
486 /* No problem fixing up the channel. */
490 static int null_hangup(struct ast_channel *chan)
492 chan->tech_pvt = NULL;
496 static const struct ast_channel_tech null_tech = {
498 .description = "NULL channel driver for atxfer",
501 .exception = null_exception,
504 .hangup = null_hangup,
506 #endif /* defined(ATXFER_NULL_TECH) */
508 #if defined(ATXFER_NULL_TECH)
511 * \brief Set the channel technology to the NULL technology.
513 * \param chan Channel to change technology.
517 static void set_null_chan_tech(struct ast_channel *chan)
521 ast_channel_lock(chan);
523 /* Hangup the channel's physical side */
524 if (chan->tech->hangup) {
525 chan->tech->hangup(chan);
527 if (chan->tech_pvt) {
528 ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n",
530 ast_free(chan->tech_pvt);
531 chan->tech_pvt = NULL;
534 /* Install the NULL technology and wake up anyone waiting on it. */
535 chan->tech = &null_tech;
536 for (idx = 0; idx < AST_MAX_FDS; ++idx) {
540 case AST_GENERATOR_FD:
541 /* Don't clear these fd's. */
544 ast_channel_set_fd(chan, idx, -1);
548 ast_queue_frame(chan, &ast_null_frame);
550 ast_channel_unlock(chan);
552 #endif /* defined(ATXFER_NULL_TECH) */
554 #if defined(ATXFER_NULL_TECH)
557 * \brief Set the channel name to something unique.
559 * \param chan Channel to change name.
563 static void set_new_chan_name(struct ast_channel *chan)
565 static int seq_num_last;
571 /* Create the new channel name string. */
572 ast_channel_lock(chan);
573 seq_num = ast_atomic_fetchadd_int(&seq_num_last, +1);
574 len = snprintf(dummy, sizeof(dummy), "%s<XFER_%x>", chan->name, seq_num) + 1;
575 chan_name = alloca(len);
576 snprintf(chan_name, len, "%s<XFER_%x>", chan->name, seq_num);
577 ast_channel_unlock(chan);
579 ast_change_name(chan, chan_name);
581 #endif /* defined(ATXFER_NULL_TECH) */
583 static void *dial_features_duplicate(void *data)
585 struct ast_dial_features *df = data, *df_copy;
587 if (!(df_copy = ast_calloc(1, sizeof(*df)))) {
591 memcpy(df_copy, df, sizeof(*df));
596 static void dial_features_destroy(void *data)
598 struct ast_dial_features *df = data;
604 static const struct ast_datastore_info dial_features_info = {
605 .type = "dial-features",
606 .destroy = dial_features_destroy,
607 .duplicate = dial_features_duplicate,
610 /* Forward declarations */
611 static struct ast_parkinglot *parkinglot_addref(struct ast_parkinglot *parkinglot);
612 static void parkinglot_unref(struct ast_parkinglot *parkinglot);
613 static void parkinglot_destroy(void *obj);
614 int manage_parkinglot(struct ast_parkinglot *curlot, const struct pollfd *pfds, const int nfds, struct pollfd **new_pfds, int *new_nfds, int *fs);
615 struct ast_parkinglot *find_parkinglot(const char *name);
616 static struct ast_parkinglot *create_parkinglot(const char *name);
617 static struct ast_parkinglot *copy_parkinglot(const char *name, const struct ast_parkinglot *parkinglot);
619 static int find_parkinglot_by_position_cb(void *obj, void *args, int flags)
621 struct ast_parkinglot *parkinglot = obj;
624 if (*parkpos >= parkinglot->parking_start && *parkpos <= parkinglot->parking_stop) {
625 return CMP_MATCH | CMP_STOP;
631 static int find_parkinglot_by_exten_cb(void *obj, void *args, int flags)
633 struct ast_parkinglot *parkinglot = obj;
634 const char *parkext = args;
636 if (!strcmp(parkinglot->parkext, parkext)) {
637 return CMP_MATCH | CMP_STOP;
643 int ast_parking_ext_valid(const char *exten_str, struct ast_channel *chan, const char *context)
645 struct ast_exten *exten;
646 struct pbx_find_info q = { .stacklen = 0 }; /* the rest is reset in pbx_find_extension */
647 const char *app_at_exten;
649 exten = pbx_find_extension(chan, NULL, &q, context, exten_str, 1, NULL, NULL, E_MATCH);
654 app_at_exten = ast_get_extension_app(exten);
655 if (!app_at_exten || strcmp(PARK_APP_NAME, app_at_exten)) {
662 const char *ast_pickup_ext(void)
667 struct ast_bridge_thread_obj
669 struct ast_bridge_config bconfig;
670 struct ast_channel *chan;
671 struct ast_channel *peer;
672 unsigned int return_to_pbx:1;
675 static int parkinglot_hash_cb(const void *obj, const int flags)
677 const struct ast_parkinglot *parkinglot = obj;
679 return ast_str_case_hash(parkinglot->name);
682 static int parkinglot_cmp_cb(void *obj, void *arg, int flags)
684 struct ast_parkinglot *parkinglot = obj, *parkinglot2 = arg;
686 return !strcasecmp(parkinglot->name, parkinglot2->name) ? CMP_MATCH | CMP_STOP : 0;
690 * \brief store context, extension and priority
691 * \param chan, context, ext, pri
693 static void set_c_e_p(struct ast_channel *chan, const char *context, const char *ext, int pri)
695 ast_copy_string(chan->context, context, sizeof(chan->context));
696 ast_copy_string(chan->exten, ext, sizeof(chan->exten));
697 chan->priority = pri;
701 * \brief Check goto on transfer
704 * Check if channel has 'GOTO_ON_BLINDXFR' set, if not exit.
705 * When found make sure the types are compatible. Check if channel is valid
706 * if so start the new channel else hangup the call.
708 static void check_goto_on_transfer(struct ast_channel *chan)
710 struct ast_channel *xferchan;
711 const char *val = pbx_builtin_getvar_helper(chan, "GOTO_ON_BLINDXFR");
712 char *x, *goto_on_transfer;
715 if (ast_strlen_zero(val))
718 goto_on_transfer = ast_strdupa(val);
720 if (!(xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", chan->linkedid, 0, "%s", chan->name)))
723 for (x = goto_on_transfer; x && *x; x++) {
727 /* Make formats okay */
728 xferchan->readformat = chan->readformat;
729 xferchan->writeformat = chan->writeformat;
730 ast_channel_masquerade(xferchan, chan);
731 ast_parseable_goto(xferchan, goto_on_transfer);
732 xferchan->_state = AST_STATE_UP;
733 ast_clear_flag(xferchan, AST_FLAGS_ALL);
734 xferchan->_softhangup = 0;
735 if ((f = ast_read(xferchan))) {
738 ast_pbx_start(xferchan);
740 ast_hangup(xferchan);
744 static struct ast_channel *feature_request_and_dial(struct ast_channel *caller,
745 const char *caller_name, struct ast_channel *requestor,
746 struct ast_channel *transferee, const char *type, format_t format, void *data,
747 int timeout, int *outstate, const char *language);
750 * \brief bridge the call
751 * \param data thread bridge.
753 * Set Last Data for respective channels, reset cdr for channels
754 * bridge call, check if we're going back to dialplan
755 * if not hangup both legs of the call
757 static void *bridge_call_thread(void *data)
759 struct ast_bridge_thread_obj *tobj = data;
762 tobj->chan->appl = !tobj->return_to_pbx ? "Transferred Call" : "ManagerBridge";
763 tobj->chan->data = tobj->peer->name;
764 tobj->peer->appl = !tobj->return_to_pbx ? "Transferred Call" : "ManagerBridge";
765 tobj->peer->data = tobj->chan->name;
767 ast_bridge_call(tobj->peer, tobj->chan, &tobj->bconfig);
769 if (tobj->return_to_pbx) {
770 if (!ast_check_hangup(tobj->peer)) {
771 ast_log(LOG_VERBOSE, "putting peer %s into PBX again\n", tobj->peer->name);
772 res = ast_pbx_start(tobj->peer);
773 if (res != AST_PBX_SUCCESS)
774 ast_log(LOG_WARNING, "FAILED continuing PBX on peer %s\n", tobj->peer->name);
776 ast_hangup(tobj->peer);
777 if (!ast_check_hangup(tobj->chan)) {
778 ast_log(LOG_VERBOSE, "putting chan %s into PBX again\n", tobj->chan->name);
779 res = ast_pbx_start(tobj->chan);
780 if (res != AST_PBX_SUCCESS)
781 ast_log(LOG_WARNING, "FAILED continuing PBX on chan %s\n", tobj->chan->name);
783 ast_hangup(tobj->chan);
785 ast_hangup(tobj->chan);
786 ast_hangup(tobj->peer);
795 * \brief create thread for the parked call
798 * Create thread and attributes, call bridge_call_thread
800 static void bridge_call_thread_launch(void *data)
804 struct sched_param sched;
806 pthread_attr_init(&attr);
807 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
808 ast_pthread_create(&thread, &attr, bridge_call_thread, data);
809 pthread_attr_destroy(&attr);
810 memset(&sched, 0, sizeof(sched));
811 pthread_setschedparam(thread, SCHED_RR, &sched);
815 * \brief Announce call parking by ADSI
817 * \param parkingexten .
818 * Create message to show for ADSI, display message.
819 * \retval 0 on success.
820 * \retval -1 on failure.
822 static int adsi_announce_park(struct ast_channel *chan, char *parkingexten)
825 int justify[5] = {ADSI_JUST_CENT, ADSI_JUST_CENT, ADSI_JUST_CENT, ADSI_JUST_CENT};
827 char *message[5] = {NULL, NULL, NULL, NULL, NULL};
829 snprintf(tmp, sizeof(tmp), "Parked on %s", parkingexten);
831 res = ast_adsi_load_session(chan, NULL, 0, 1);
834 return ast_adsi_print(chan, message, justify, 1);
837 /*! \brief Find parking lot name from channel */
838 static const char *findparkinglotname(struct ast_channel *chan)
840 const char *temp, *parkinglot = NULL;
842 /* Check if the channel has a parking lot */
843 if (!ast_strlen_zero(chan->parkinglot))
844 parkinglot = chan->parkinglot;
846 /* Channel variables override everything */
848 if ((temp = pbx_builtin_getvar_helper(chan, "PARKINGLOT")))
854 /*! \brief Notify metermaids that we've changed an extension */
855 static void notify_metermaids(const char *exten, char *context, enum ast_device_state state)
857 ast_debug(4, "Notification of state change to metermaids %s@%s\n to state '%s'",
858 exten, context, ast_devstate2str(state));
860 ast_devstate_changed(state, "park:%s@%s", exten, context);
863 /*! \brief metermaids callback from devicestate.c */
864 static enum ast_device_state metermaidstate(const char *data)
869 context = ast_strdupa(data);
871 exten = strsep(&context, "@");
873 return AST_DEVICE_INVALID;
875 ast_debug(4, "Checking state of exten %s in context %s\n", exten, context);
877 if (!ast_exists_extension(NULL, context, exten, 1, NULL))
878 return AST_DEVICE_NOT_INUSE;
880 return AST_DEVICE_INUSE;
883 /*! Options to pass to park_call_full */
884 enum ast_park_call_options {
885 /*! Provide ringing to the parked caller instead of music on hold */
886 AST_PARK_OPT_RINGING = (1 << 0),
887 /*! Randomly choose a parking spot for the caller instead of choosing
888 * the first one that is available. */
889 AST_PARK_OPT_RANDOMIZE = (1 << 1),
890 /*! Do not announce the parking number */
891 AST_PARK_OPT_SILENCE = (1 << 2),
894 struct ast_park_call_args {
895 /*! How long to wait in the parking lot before the call gets sent back
896 * to the specified return extension (or a best guess at where it came
897 * from if not explicitly specified). */
899 /*! An output parameter to store the parking space where the parked caller
902 const char *orig_chan_name;
903 const char *return_con;
904 const char *return_ext;
907 /*! Parked user that has already obtained a parking space */
908 struct parkeduser *pu;
909 struct ast_parkinglot *parkinglot; /*! parkinglot to be parked in, based on parkext */
912 static struct parkeduser *park_space_reserve(struct ast_channel *chan, struct ast_channel *peer, struct ast_park_call_args *args)
914 struct parkeduser *pu;
915 int i, parking_space = -1, parking_range;
916 const char *parkinglotname = NULL;
917 const char *parkingexten;
918 struct ast_parkinglot *parkinglot = NULL;
920 if (args->parkinglot) {
921 parkinglot = args->parkinglot;
922 parkinglotname = parkinglot->name;
924 parkinglotname = findparkinglotname(peer);
925 } else { /* peer was NULL, check chan (ParkAndAnnounce / res_agi) */
926 parkinglotname = findparkinglotname(chan);
929 if (!args->parkinglot) {
930 if (parkinglotname) {
931 parkinglot = find_parkinglot(parkinglotname);
933 ast_debug(4, "This could be an indication channel driver needs updating, using default lot.\n");
934 parkinglot = parkinglot_addref(default_parkinglot);
936 ast_debug(1, "Found chanvar Parkinglot: %s\n", parkinglot->name);
939 /* Dynamically create parkinglot */
940 if (!parkinglot && parkeddynamic && !ast_strlen_zero(parkinglotname)) {
941 const char *dyn_context, *dyn_range;
942 const char *parkinglotname_copy = NULL;
943 struct ast_parkinglot *parkinglot_copy = NULL;
944 int dyn_start, dyn_end;
946 ast_channel_lock(chan);
947 parkinglotname_copy = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGDYNAMIC"), ""));
948 dyn_context = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGDYNCONTEXT"), ""));
949 dyn_range = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGDYNPOS"), ""));
950 ast_channel_unlock(chan);
952 if (!ast_strlen_zero(parkinglotname_copy)) {
953 parkinglot_copy = find_parkinglot(parkinglotname_copy);
955 if (!parkinglot_copy) {
956 parkinglot_copy = parkinglot_addref(default_parkinglot);
957 ast_debug(1, "Using default parking lot for copy\n");
959 if (!(parkinglot = copy_parkinglot(parkinglotname, parkinglot_copy))) {
960 ast_log(LOG_ERROR, "Could not build dynamic parking lot!\n");
962 if (!ast_strlen_zero(dyn_context)) {
963 ast_copy_string(parkinglot->parking_con, dyn_context, sizeof(parkinglot->parking_con));
965 if (!ast_strlen_zero(dyn_range)) {
966 if (sscanf(dyn_range, "%30d-%30d", &dyn_start, &dyn_end) != 2) {
967 ast_log(LOG_WARNING, "Format for parking positions is a-b, where a and b are numbers\n");
969 parkinglot->parking_start = dyn_start;
970 parkinglot->parking_stop = dyn_end;
973 ao2_link(parkinglots, parkinglot);
976 if (parkinglot_copy) {
977 /* unref our tempory copy */
978 parkinglot_unref(parkinglot_copy);
979 parkinglot_copy = NULL;
984 parkinglot = parkinglot_addref(default_parkinglot);
987 ast_debug(1, "Parkinglot: %s\n", parkinglot->name);
989 /* Allocate memory for parking data */
990 if (!(pu = ast_calloc(1, sizeof(*pu)))) {
991 parkinglot_unref(parkinglot);
995 /* Lock parking list */
996 AST_LIST_LOCK(&parkinglot->parkings);
997 /* Check for channel variable PARKINGEXTEN */
998 ast_channel_lock(chan);
999 parkingexten = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGEXTEN"), ""));
1000 ast_channel_unlock(chan);
1001 if (!ast_strlen_zero(parkingexten)) {
1002 /*!\note The API forces us to specify a numeric parking slot, even
1003 * though the architecture would tend to support non-numeric extensions
1004 * (as are possible with SIP, for example). Hence, we enforce that
1005 * limitation here. If extout was not numeric, we could permit
1006 * arbitrary non-numeric extensions.
1008 if (sscanf(parkingexten, "%30d", &parking_space) != 1 || parking_space < 0) {
1009 AST_LIST_UNLOCK(&parkinglot->parkings);
1010 parkinglot_unref(parkinglot);
1012 ast_log(LOG_WARNING, "PARKINGEXTEN does not indicate a valid parking slot: '%s'.\n", parkingexten);
1015 snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", parking_space);
1017 if (ast_exists_extension(NULL, parkinglot->parking_con, pu->parkingexten, 1, NULL)) {
1018 ast_log(LOG_WARNING, "Requested parking extension already exists: %s@%s\n", parkingexten, parkinglot->parking_con);
1019 AST_LIST_UNLOCK(&parkinglot->parkings);
1020 parkinglot_unref(parkinglot);
1026 struct parkeduser *cur = NULL;
1028 /* Select parking space within range */
1029 parking_range = parkinglot->parking_stop - parkinglot->parking_start + 1;
1031 if (ast_test_flag(args, AST_PARK_OPT_RANDOMIZE)) {
1032 start = ast_random() % (parkinglot->parking_stop - parkinglot->parking_start + 1);
1034 start = parkinglot->parking_start;
1037 for (i = start; 1; i++) {
1038 if (i == parkinglot->parking_stop + 1) {
1039 i = parkinglot->parking_start - 1;
1043 AST_LIST_TRAVERSE(&parkinglot->parkings, cur, list) {
1044 if (cur->parkingnum == i) {
1054 if (i == start - 1 && cur) {
1055 ast_log(LOG_WARNING, "No more parking spaces\n");
1057 AST_LIST_UNLOCK(&parkinglot->parkings);
1058 parkinglot_unref(parkinglot);
1061 /* Set pointer for next parking */
1062 if (parkinglot->parkfindnext)
1063 parkinglot->parking_offset = parking_space - parkinglot->parking_start + 1;
1064 snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", parking_space);
1067 pu->notquiteyet = 1;
1068 pu->parkingnum = parking_space;
1069 pu->parkinglot = parkinglot;
1070 AST_LIST_INSERT_TAIL(&parkinglot->parkings, pu, list);
1076 static int park_call_full(struct ast_channel *chan, struct ast_channel *peer, struct ast_park_call_args *args)
1078 struct ast_context *con;
1079 int parkingnum_copy;
1080 struct parkeduser *pu = args->pu;
1081 const char *event_from;
1084 args->pu = pu = park_space_reserve(chan, peer, args);
1086 return 1; /* Continue execution if possible */
1088 snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", pu->parkingnum);
1090 chan->appl = "Parked Call";
1095 /* Put the parked channel on hold if we have two different channels */
1097 if (ast_test_flag(args, AST_PARK_OPT_RINGING)) {
1098 ast_indicate(pu->chan, AST_CONTROL_RINGING);
1100 ast_indicate_data(pu->chan, AST_CONTROL_HOLD,
1101 S_OR(pu->parkinglot->mohclass, NULL),
1102 !ast_strlen_zero(pu->parkinglot->mohclass) ? strlen(pu->parkinglot->mohclass) + 1 : 0);
1106 pu->start = ast_tvnow();
1107 pu->parkingtime = (args->timeout > 0) ? args->timeout : pu->parkinglot->parkingtime;
1108 parkingnum_copy = pu->parkingnum;
1110 *(args->extout) = pu->parkingnum;
1113 /* This is so ugly that it hurts, but implementing get_base_channel() on local channels
1114 could have ugly side effects. We could have transferer<->local,1<->local,2<->parking
1115 and we need the callback name to be that of transferer. Since local,1/2 have the same
1116 name we can be tricky and just grab the bridged channel from the other side of the local
1118 if (!strcasecmp(peer->tech->type, "Local")) {
1119 struct ast_channel *tmpchan, *base_peer;
1120 char other_side[AST_CHANNEL_NAME];
1122 ast_copy_string(other_side, S_OR(args->orig_chan_name, peer->name), sizeof(other_side));
1123 if ((c = strrchr(other_side, ';'))) {
1126 if ((tmpchan = ast_channel_get_by_name(other_side))) {
1127 ast_channel_lock(tmpchan);
1128 if ((base_peer = ast_bridged_channel(tmpchan))) {
1129 ast_copy_string(pu->peername, base_peer->name, sizeof(pu->peername));
1131 ast_channel_unlock(tmpchan);
1132 tmpchan = ast_channel_unref(tmpchan);
1135 ast_copy_string(pu->peername, S_OR(args->orig_chan_name, peer->name), sizeof(pu->peername));
1139 /* Remember what had been dialed, so that if the parking
1140 expires, we try to come back to the same place */
1142 pu->options_specified = (!ast_strlen_zero(args->return_con) || !ast_strlen_zero(args->return_ext) || args->return_pri);
1144 /* If extension has options specified, they override all other possibilities
1145 such as the returntoorigin flag and transferred context. Information on
1146 extension options is lost here, so we set a flag */
1148 ast_copy_string(pu->context,
1149 S_OR(args->return_con, S_OR(chan->macrocontext, chan->context)),
1150 sizeof(pu->context));
1151 ast_copy_string(pu->exten,
1152 S_OR(args->return_ext, S_OR(chan->macroexten, chan->exten)),
1154 pu->priority = args->return_pri ? args->return_pri :
1155 (chan->macropriority ? chan->macropriority : chan->priority);
1157 /* If parking a channel directly, don't quiet yet get parking running on it.
1158 * All parking lot entries are put into the parking lot with notquiteyet on. */
1160 pu->notquiteyet = 0;
1162 /* Wake up the (presumably select()ing) thread */
1163 pthread_kill(parking_thread, SIGURG);
1164 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));
1166 ast_cel_report_event(pu->chan, AST_CEL_PARK_START, NULL, pu->parkinglot->name, peer);
1169 event_from = peer->name;
1171 event_from = pbx_builtin_getvar_helper(chan, "BLINDTRANSFER");
1174 ast_manager_event(pu->chan, EVENT_FLAG_CALL, "ParkedCall",
1177 "Parkinglot: %s\r\n"
1180 "CallerIDNum: %s\r\n"
1181 "CallerIDName: %s\r\n"
1183 pu->parkingexten, pu->chan->name, pu->parkinglot->name, event_from ? event_from : "",
1184 (long)pu->start.tv_sec + (long)(pu->parkingtime/1000) - (long)time(NULL),
1185 S_COR(pu->chan->caller.id.number.valid, pu->chan->caller.id.number.str, "<unknown>"),
1186 S_COR(pu->chan->caller.id.name.valid, pu->chan->caller.id.name.str, "<unknown>"),
1190 if (peer && adsipark && ast_adsi_available(peer)) {
1191 adsi_announce_park(peer, pu->parkingexten); /* Only supports parking numbers */
1192 ast_adsi_unload_session(peer);
1195 con = ast_context_find_or_create(NULL, NULL, pu->parkinglot->parking_con, registrar);
1196 if (!con) /* Still no context? Bad */
1197 ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", pu->parkinglot->parking_con);
1199 if (!ast_add_extension2(con, 1, pu->parkingexten, 1, NULL, NULL, parkedcall, ast_strdup(pu->parkingexten), ast_free_ptr, registrar))
1200 notify_metermaids(pu->parkingexten, pu->parkinglot->parking_con, AST_DEVICE_INUSE);
1203 AST_LIST_UNLOCK(&pu->parkinglot->parkings);
1205 /* Only say number if it's a number and the channel hasn't been masqueraded away */
1206 if (peer && !ast_test_flag(args, AST_PARK_OPT_SILENCE) && (ast_strlen_zero(args->orig_chan_name) || !strcasecmp(peer->name, args->orig_chan_name))) {
1207 /* 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. */
1208 ast_set_flag(peer, AST_FLAG_MASQ_NOSTREAM);
1209 /* Tell the peer channel the number of the parking space */
1210 ast_say_digits(peer, pu->parkingnum, "", peer->language);
1211 ast_clear_flag(peer, AST_FLAG_MASQ_NOSTREAM);
1213 if (peer == chan) { /* pu->notquiteyet = 1 */
1214 /* Wake up parking thread if we're really done */
1215 ast_indicate_data(pu->chan, AST_CONTROL_HOLD,
1216 S_OR(pu->parkinglot->mohclass, NULL),
1217 !ast_strlen_zero(pu->parkinglot->mohclass) ? strlen(pu->parkinglot->mohclass) + 1 : 0);
1218 pu->notquiteyet = 0;
1219 pthread_kill(parking_thread, SIGURG);
1224 /*! \brief Park a call */
1225 int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeout, const char *parkexten, int *extout)
1227 struct ast_parkinglot *found_lot = ao2_callback(parkinglots, 0, find_parkinglot_by_exten_cb, (void *) parkexten);
1229 struct ast_park_call_args args = {
1232 .parkinglot = found_lot,
1235 return park_call_full(chan, peer, &args);
1239 * \param rchan is the transferee
1240 * \param peer is the transferer
1242 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)
1244 struct ast_channel *chan;
1245 struct ast_frame *f;
1246 struct ast_park_call_args park_args = {0,};
1250 args->timeout = timeout;
1251 args->extout = extout;
1254 if ((args->pu = park_space_reserve(rchan, peer, args)) == NULL) {
1256 ast_stream_and_wait(peer, "pbx-parkingfailed", "");
1258 return AST_FEATURE_RETURN_PARKFAILED;
1261 /* Make a new, fake channel that we'll use to masquerade in the real one */
1262 if (!(chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, rchan->accountcode, rchan->exten, rchan->context, rchan->linkedid, rchan->amaflags, "Parked/%s",rchan->name))) {
1263 ast_log(LOG_WARNING, "Unable to create parked channel\n");
1267 /* Make formats okay */
1268 chan->readformat = rchan->readformat;
1269 chan->writeformat = rchan->writeformat;
1270 ast_channel_masquerade(chan, rchan);
1272 /* Setup the extensions and such */
1273 set_c_e_p(chan, rchan->context, rchan->exten, rchan->priority);
1275 /* Setup the macro extension and such */
1276 ast_copy_string(chan->macrocontext,rchan->macrocontext,sizeof(chan->macrocontext));
1277 ast_copy_string(chan->macroexten,rchan->macroexten,sizeof(chan->macroexten));
1278 chan->macropriority = rchan->macropriority;
1280 /* Make the masq execute */
1281 if ((f = ast_read(chan)))
1284 if (peer == rchan) {
1288 if (peer && (!play_announcement && args == &park_args)) {
1289 args->orig_chan_name = ast_strdupa(peer->name);
1292 /* parking space reserved, return code check unnecessary */
1293 park_call_full(chan, peer, args);
1298 /* Park call via masqueraded channel */
1299 int ast_masq_park_call(struct ast_channel *rchan, struct ast_channel *peer, int timeout, int *extout)
1301 return masq_park_call(rchan, peer, timeout, extout, 0, NULL);
1304 static int masq_park_call_announce(struct ast_channel *rchan, struct ast_channel *peer, struct ast_park_call_args *args)
1306 return masq_park_call(rchan, peer, 0, NULL, 1, args);
1309 #ifdef TEST_FRAMEWORK
1310 static int fake_fixup(struct ast_channel *clonechan, struct ast_channel *original)
1315 static struct ast_channel *create_test_channel(const struct ast_channel_tech *fake_tech)
1317 struct ast_channel *test_channel1;
1318 if (!(test_channel1 = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL,
1319 NULL, NULL, 0, 0, "TestChannel1"))) {
1323 /* normally this is done in the channel driver */
1324 test_channel1->nativeformats = AST_FORMAT_GSM;
1325 test_channel1->writeformat = AST_FORMAT_GSM;
1326 test_channel1->rawwriteformat = AST_FORMAT_GSM;
1327 test_channel1->readformat = AST_FORMAT_GSM;
1328 test_channel1->rawreadformat = AST_FORMAT_GSM;
1329 test_channel1->tech = fake_tech;
1331 return test_channel1;
1334 static int unpark_test_channel(struct ast_channel *toremove, struct ast_park_call_args *args)
1336 struct ast_context *con;
1337 struct parkeduser *pu_toremove;
1338 args->pu->notquiteyet = 1; /* go ahead and stop processing the test parking */
1339 AST_LIST_LOCK(&args->pu->parkinglot->parkings);
1340 AST_LIST_TRAVERSE_SAFE_BEGIN(&args->pu->parkinglot->parkings, pu_toremove, list) {
1341 con = ast_context_find(args->pu->parkinglot->parking_con);
1343 if (ast_context_remove_extension2(con, args->pu->parkingexten, 1, NULL, 0)) {
1344 ast_log(LOG_WARNING, "Whoa, failed to remove the parking extension!\n");
1347 notify_metermaids(args->pu->parkingexten, pu_toremove->parkinglot->parking_con, AST_DEVICE_NOT_INUSE);
1350 ast_log(LOG_WARNING, "Whoa, no parking context?\n");
1353 if (pu_toremove == args->pu) {
1354 AST_LIST_REMOVE_CURRENT(list);
1358 AST_LIST_TRAVERSE_SAFE_END;
1359 AST_LIST_UNLOCK(&args->pu->parkinglot->parkings);
1361 /* the only way this would be unsafe is if a timeout occurred, which is set at 45 sec */
1365 ast_hangup(toremove);
1369 AST_TEST_DEFINE(features_test)
1371 int saved_parkeddynamic;
1372 struct ast_channel *test_channel1 = NULL;
1373 struct ast_channel *parked_chan = NULL;
1374 struct ast_parkinglot *dynlot = NULL;
1375 struct ast_park_call_args args = {
1376 .timeout = DEFAULT_PARK_TIME,
1381 static const struct ast_channel_tech fake_tech = {
1382 .fixup = fake_fixup, /* silence warning from masquerade */
1385 static const char unique_parkinglot[] = "myuniquetestparkinglot3141592654";
1386 static const char parkinglot_range[] = "750-760";
1390 info->name = "features_test";
1391 info->category = "/main/features/";
1392 info->summary = "Features unit test";
1394 "Tests whether parking respects PARKINGLOT settings";
1395 return AST_TEST_NOT_RUN;
1400 /* changing a config option is a bad practice, but must be done in this case */
1401 saved_parkeddynamic = parkeddynamic;
1404 if (!(test_channel1 = create_test_channel(&fake_tech))) {
1405 goto exit_features_test;
1408 ast_test_status_update(test, "Test parking functionality with defaults\n");
1409 if (park_call_full(test_channel1, NULL, &args)) {
1410 goto exit_features_test;
1412 if (unpark_test_channel(test_channel1, &args)) {
1413 goto exit_features_test;
1416 ast_test_status_update(test, "Check that certain parking options are respected\n");
1417 if (!(test_channel1 = create_test_channel(&fake_tech))) {
1418 goto exit_features_test;
1420 pbx_builtin_setvar_helper(test_channel1, "PARKINGLOT", unique_parkinglot);
1421 pbx_builtin_setvar_helper(test_channel1, "PARKINGDYNPOS", parkinglot_range);
1422 if (park_call_full(test_channel1, NULL, &args)) {
1423 goto exit_features_test;
1425 /* grab newly created parking lot for destruction in the end */
1426 dynlot = args.pu->parkinglot;
1427 if (!args.pu->parkingnum == 750 || strcasecmp(args.pu->parkinglot->name, unique_parkinglot)) {
1428 ast_test_status_update(test, "Parking settings were not respected\n");
1429 goto exit_features_test;
1431 ast_test_status_update(test, "Parking settings for non-masquerading park verified\n");
1433 if (unpark_test_channel(test_channel1, &args)) {
1434 goto exit_features_test;
1437 ast_test_status_update(test, "Check #2 that certain parking options are respected\n");
1438 if (!(test_channel1 = create_test_channel(&fake_tech))) {
1439 goto exit_features_test;
1441 pbx_builtin_setvar_helper(test_channel1, "PARKINGLOT", unique_parkinglot);
1442 pbx_builtin_setvar_helper(test_channel1, "PARKINGDYNPOS", parkinglot_range);
1443 if (masq_park_call(test_channel1, NULL, 0, NULL, 0, &args) == AST_FEATURE_RETURN_PARKFAILED) {
1444 goto exit_features_test;
1446 /* hangup zombie channel */
1447 ast_hangup(test_channel1);
1448 test_channel1 = NULL;
1449 if (!args.pu->parkingnum == 750 || strcasecmp(args.pu->parkinglot->name, unique_parkinglot)) {
1450 ast_test_status_update(test, "Parking settings were not respected\n");
1451 goto exit_features_test;
1453 ast_test_status_update(test, "Parking settings for masquerading park verified\n");
1455 /* find the real channel */
1456 parked_chan = ast_channel_get_by_name("TestChannel1");
1457 if (unpark_test_channel(parked_chan, &args)) {
1458 goto exit_features_test;
1465 if (test_channel1) {
1466 ast_hangup(test_channel1);
1469 /* careful, if PARKINGDYNCONTEXT is tested, need to delete context */
1470 ao2_unlink(parkinglots, dynlot);
1471 parkeddynamic = saved_parkeddynamic;
1472 return res ? AST_TEST_FAIL : AST_TEST_PASS;
1478 * \brief set caller and callee according to the direction
1479 * \param caller, callee, peer, chan, sense
1481 * Detect who triggered feature and set callee/caller variables accordingly
1483 static void set_peers(struct ast_channel **caller, struct ast_channel **callee,
1484 struct ast_channel *peer, struct ast_channel *chan, int sense)
1486 if (sense == FEATURE_SENSE_PEER) {
1495 static int parkcall_helper(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, struct ast_park_call_args *args)
1500 ast_debug(1, "Parkinglot specified for builtin_parkcall: %s\n", args->parkinglot->name);
1503 /* we used to set chan's exten and priority to "s" and 1
1504 here, but this generates (in some cases) an invalid
1505 extension, and if "s" exists, could errantly
1506 cause execution of extensions you don't expect. It
1507 makes more sense to let nature take its course
1508 when chan finishes, and let the pbx do its thing
1509 and hang up when the park is over.
1511 if (chan->_state != AST_STATE_UP)
1512 res = ast_answer(chan);
1514 res = ast_safe_sleep(chan, 1000);
1516 if (!res) { /* one direction used to call park_call.... */
1517 struct ast_channel *parker;
1518 struct ast_channel *parkee;
1519 set_peers(&parker, &parkee, peer, chan, sense);
1520 res = masq_park_call_announce(parkee, parker, args);
1521 /* PBX should hangup zombie channel if a masquerade actually occurred (res=0) */
1528 * \brief support routing for one touch call parking
1529 * \param chan channel parking call
1530 * \param peer channel to be parked
1531 * \param config unsed
1532 * \param code unused
1533 * \param sense feature options
1536 * Setup channel, set return exten,priority to 's,1'
1537 * answer chan, sleep chan, park call
1539 static int builtin_parkcall(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
1541 return parkcall_helper(chan, peer, config, code, sense, NULL);
1544 /*! \brief Play message to both caller and callee in bridged call, plays synchronously, autoservicing the
1545 other channel during the message, so please don't use this for very long messages
1547 static int play_message_in_bridged_call(struct ast_channel *caller_chan, struct ast_channel *callee_chan, const char *audiofile)
1549 /* First play for caller, put other channel on auto service */
1550 if (ast_autoservice_start(callee_chan))
1552 ast_autoservice_ignore(callee_chan, AST_FRAME_DTMF_END);
1553 if (ast_stream_and_wait(caller_chan, audiofile, "")) {
1554 ast_log(LOG_WARNING, "Failed to play automon message!\n");
1555 ast_autoservice_stop(callee_chan);
1558 if (ast_autoservice_stop(callee_chan))
1560 /* Then play for callee, put other channel on auto service */
1561 if (ast_autoservice_start(caller_chan))
1563 ast_autoservice_ignore(caller_chan, AST_FRAME_DTMF_END);
1564 if (ast_stream_and_wait(callee_chan, audiofile, "")) {
1565 ast_log(LOG_WARNING, "Failed to play automon message !\n");
1566 ast_autoservice_stop(caller_chan);
1569 if (ast_autoservice_stop(caller_chan))
1575 * \brief Monitor a channel by DTMF
1576 * \param chan channel requesting monitor
1577 * \param peer channel to be monitored
1580 * \param sense feature options
1583 * Check monitor app enabled, setup channels, both caller/callee chans not null
1584 * get TOUCH_MONITOR variable for filename if exists, exec monitor app.
1585 * \retval AST_FEATURE_RETURN_SUCCESS on success.
1586 * \retval -1 on error.
1588 static int builtin_automonitor(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
1590 char *caller_chan_id = NULL, *callee_chan_id = NULL, *args = NULL, *touch_filename = NULL;
1593 struct ast_channel *caller_chan, *callee_chan;
1594 const char *automon_message_start = NULL;
1595 const char *automon_message_stop = NULL;
1598 ast_log(LOG_ERROR,"Cannot record the call. The monitor application is disabled.\n");
1602 if (!monitor_app && !(monitor_app = pbx_findapp("Monitor"))) {
1604 ast_log(LOG_ERROR,"Cannot record the call. The monitor application is disabled.\n");
1608 set_peers(&caller_chan, &callee_chan, peer, chan, sense);
1609 if (caller_chan) { /* Find extra messages */
1610 automon_message_start = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_MESSAGE_START");
1611 automon_message_stop = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_MESSAGE_STOP");
1614 if (!ast_strlen_zero(courtesytone)) { /* Play courtesy tone if configured */
1615 if(play_message_in_bridged_call(caller_chan, callee_chan, courtesytone) == -1) {
1620 if (callee_chan->monitor) {
1621 ast_verb(4, "User hit '%s' to stop recording call.\n", code);
1622 if (!ast_strlen_zero(automon_message_stop)) {
1623 play_message_in_bridged_call(caller_chan, callee_chan, automon_message_stop);
1625 callee_chan->monitor->stop(callee_chan, 1);
1626 return AST_FEATURE_RETURN_SUCCESS;
1629 if (caller_chan && callee_chan) {
1630 const char *touch_format = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_FORMAT");
1631 const char *touch_monitor = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR");
1632 const char *touch_monitor_prefix = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_PREFIX");
1635 touch_format = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR_FORMAT");
1638 touch_monitor = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR");
1640 if (!touch_monitor_prefix)
1641 touch_monitor_prefix = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR_PREFIX");
1643 if (touch_monitor) {
1644 len = strlen(touch_monitor) + 50;
1646 touch_filename = alloca(len);
1647 snprintf(touch_filename, len, "%s-%ld-%s", S_OR(touch_monitor_prefix, "auto"), (long)time(NULL), touch_monitor);
1648 snprintf(args, len, "%s,%s,m", S_OR(touch_format, "wav"), touch_filename);
1650 caller_chan_id = ast_strdupa(S_COR(caller_chan->caller.id.number.valid,
1651 caller_chan->caller.id.number.str, caller_chan->name));
1652 callee_chan_id = ast_strdupa(S_COR(callee_chan->caller.id.number.valid,
1653 callee_chan->caller.id.number.str, callee_chan->name));
1654 len = strlen(caller_chan_id) + strlen(callee_chan_id) + 50;
1656 touch_filename = alloca(len);
1657 snprintf(touch_filename, len, "%s-%ld-%s-%s", S_OR(touch_monitor_prefix, "auto"), (long)time(NULL), caller_chan_id, callee_chan_id);
1658 snprintf(args, len, "%s,%s,m", S_OR(touch_format, "wav"), touch_filename);
1661 for(x = 0; x < strlen(args); x++) {
1666 ast_verb(4, "User hit '%s' to record call. filename: %s\n", code, args);
1668 pbx_exec(callee_chan, monitor_app, args);
1669 pbx_builtin_setvar_helper(callee_chan, "TOUCH_MONITOR_OUTPUT", touch_filename);
1670 pbx_builtin_setvar_helper(caller_chan, "TOUCH_MONITOR_OUTPUT", touch_filename);
1672 if (!ast_strlen_zero(automon_message_start)) { /* Play start message for both channels */
1673 play_message_in_bridged_call(caller_chan, callee_chan, automon_message_start);
1676 return AST_FEATURE_RETURN_SUCCESS;
1679 ast_log(LOG_NOTICE,"Cannot record the call. One or both channels have gone away.\n");
1683 static int builtin_automixmonitor(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
1685 char *caller_chan_id = NULL, *callee_chan_id = NULL, *args = NULL, *touch_filename = NULL;
1688 struct ast_channel *caller_chan, *callee_chan;
1689 const char *mixmonitor_spy_type = "MixMonitor";
1692 if (!mixmonitor_ok) {
1693 ast_log(LOG_ERROR,"Cannot record the call. The mixmonitor application is disabled.\n");
1697 if (!(mixmonitor_app = pbx_findapp("MixMonitor"))) {
1699 ast_log(LOG_ERROR,"Cannot record the call. The mixmonitor application is disabled.\n");
1703 set_peers(&caller_chan, &callee_chan, peer, chan, sense);
1705 if (!ast_strlen_zero(courtesytone)) {
1706 if (ast_autoservice_start(callee_chan))
1708 ast_autoservice_ignore(callee_chan, AST_FRAME_DTMF_END);
1709 if (ast_stream_and_wait(caller_chan, courtesytone, "")) {
1710 ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
1711 ast_autoservice_stop(callee_chan);
1714 if (ast_autoservice_stop(callee_chan))
1718 ast_channel_lock(callee_chan);
1719 count = ast_channel_audiohook_count_by_source(callee_chan, mixmonitor_spy_type, AST_AUDIOHOOK_TYPE_SPY);
1720 ast_channel_unlock(callee_chan);
1722 /* This means a mixmonitor is attached to the channel, running or not is unknown. */
1725 ast_verb(3, "User hit '%s' to stop recording call.\n", code);
1727 /* Make sure they are running */
1728 ast_channel_lock(callee_chan);
1729 count = ast_channel_audiohook_count_by_source_running(callee_chan, mixmonitor_spy_type, AST_AUDIOHOOK_TYPE_SPY);
1730 ast_channel_unlock(callee_chan);
1732 if (!stopmixmonitor_ok) {
1733 ast_log(LOG_ERROR,"Cannot stop recording the call. The stopmixmonitor application is disabled.\n");
1736 if (!(stopmixmonitor_app = pbx_findapp("StopMixMonitor"))) {
1737 stopmixmonitor_ok = 0;
1738 ast_log(LOG_ERROR,"Cannot stop recording the call. The stopmixmonitor application is disabled.\n");
1741 pbx_exec(callee_chan, stopmixmonitor_app, "");
1742 return AST_FEATURE_RETURN_SUCCESS;
1746 ast_log(LOG_WARNING,"Stopped MixMonitors are attached to the channel.\n");
1749 if (caller_chan && callee_chan) {
1750 const char *touch_format = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MIXMONITOR_FORMAT");
1751 const char *touch_monitor = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MIXMONITOR");
1754 touch_format = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MIXMONITOR_FORMAT");
1757 touch_monitor = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MIXMONITOR");
1759 if (touch_monitor) {
1760 len = strlen(touch_monitor) + 50;
1762 touch_filename = alloca(len);
1763 snprintf(touch_filename, len, "auto-%ld-%s", (long)time(NULL), touch_monitor);
1764 snprintf(args, len, "%s.%s,b", touch_filename, (touch_format) ? touch_format : "wav");
1766 caller_chan_id = ast_strdupa(S_COR(caller_chan->caller.id.number.valid,
1767 caller_chan->caller.id.number.str, caller_chan->name));
1768 callee_chan_id = ast_strdupa(S_COR(callee_chan->caller.id.number.valid,
1769 callee_chan->caller.id.number.str, callee_chan->name));
1770 len = strlen(caller_chan_id) + strlen(callee_chan_id) + 50;
1772 touch_filename = alloca(len);
1773 snprintf(touch_filename, len, "auto-%ld-%s-%s", (long)time(NULL), caller_chan_id, callee_chan_id);
1774 snprintf(args, len, "%s.%s,b", touch_filename, S_OR(touch_format, "wav"));
1777 for( x = 0; x < strlen(args); x++) {
1782 ast_verb(3, "User hit '%s' to record call. filename: %s\n", code, touch_filename);
1784 pbx_exec(callee_chan, mixmonitor_app, args);
1785 pbx_builtin_setvar_helper(callee_chan, "TOUCH_MIXMONITOR_OUTPUT", touch_filename);
1786 pbx_builtin_setvar_helper(caller_chan, "TOUCH_MIXMONITOR_OUTPUT", touch_filename);
1787 return AST_FEATURE_RETURN_SUCCESS;
1791 ast_log(LOG_NOTICE,"Cannot record the call. One or both channels have gone away.\n");
1796 static int builtin_disconnect(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
1798 ast_verb(4, "User hit '%s' to disconnect call.\n", code);
1799 return AST_FEATURE_RETURN_HANGUP;
1802 static int finishup(struct ast_channel *chan)
1804 ast_indicate(chan, AST_CONTROL_UNHOLD);
1806 return ast_autoservice_stop(chan);
1810 * \brief Find the context for the transfer
1814 * Grab the TRANSFER_CONTEXT, if fails try grabbing macrocontext.
1815 * \return a context string
1817 static const char *real_ctx(struct ast_channel *transferer, struct ast_channel *transferee)
1819 const char *s = pbx_builtin_getvar_helper(transferer, "TRANSFER_CONTEXT");
1820 if (ast_strlen_zero(s)) {
1821 s = pbx_builtin_getvar_helper(transferee, "TRANSFER_CONTEXT");
1823 if (ast_strlen_zero(s)) { /* Use the non-macro context to transfer the call XXX ? */
1824 s = transferer->macrocontext;
1826 if (ast_strlen_zero(s)) {
1827 s = transferer->context;
1833 * \brief Blind transfer user to another extension
1834 * \param chan channel to be transfered
1835 * \param peer channel initiated blind transfer
1839 * \param sense feature options
1841 * Place chan on hold, check if transferred to parkinglot extension,
1842 * otherwise check extension exists and transfer caller.
1843 * \retval AST_FEATURE_RETURN_SUCCESS.
1844 * \retval -1 on failure.
1846 static int builtin_blindtransfer(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
1848 struct ast_channel *transferer;
1849 struct ast_channel *transferee;
1850 const char *transferer_real_context;
1851 struct ast_parkinglot *found_lot = NULL;
1853 int res, parkstatus = 0;
1855 set_peers(&transferer, &transferee, peer, chan, sense);
1856 transferer_real_context = real_ctx(transferer, transferee);
1857 /* Start autoservice on chan while we talk to the originator */
1858 ast_autoservice_start(transferee);
1859 ast_autoservice_ignore(transferee, AST_FRAME_DTMF_END);
1860 ast_indicate(transferee, AST_CONTROL_HOLD);
1862 memset(xferto, 0, sizeof(xferto));
1865 res = ast_stream_and_wait(transferer, "pbx-transfer", AST_DIGIT_ANY);
1867 finishup(transferee);
1868 return -1; /* error ? */
1870 if (res > 0) /* If they've typed a digit already, handle it */
1871 xferto[0] = (char) res;
1873 ast_stopstream(transferer);
1874 res = ast_app_dtget(transferer, transferer_real_context, xferto, sizeof(xferto), 100, transferdigittimeout);
1875 if (res < 0) { /* hangup, would be 0 for invalid and 1 for valid */
1876 finishup(transferee);
1880 found_lot = ao2_callback(parkinglots, 0, find_parkinglot_by_exten_cb, &xferto);
1882 struct ast_park_call_args args = {
1883 .parkinglot = found_lot,
1885 res = finishup(transferee);
1888 else if (!(parkstatus = masq_park_call_announce(transferee, transferer, &args))) { /* success */
1889 /* We return non-zero, but tell the PBX not to hang the channel when
1890 the thread dies -- We have to be careful now though. We are responsible for
1891 hanging up the channel, else it will never be hung up! */
1895 ast_log(LOG_WARNING, "Unable to park call %s, parkstatus = %d\n", transferee->name, parkstatus);
1897 /*! \todo XXX Maybe we should have another message here instead of invalid extension XXX */
1898 } else if (ast_exists_extension(transferee, transferer_real_context, xferto, 1,
1899 S_COR(transferer->caller.id.number.valid, transferer->caller.id.number.str, NULL))) {
1900 ast_cel_report_event(transferer, AST_CEL_BLINDTRANSFER, NULL, xferto, transferee);
1901 pbx_builtin_setvar_helper(transferer, "BLINDTRANSFER", transferee->name);
1902 pbx_builtin_setvar_helper(transferee, "BLINDTRANSFER", transferer->name);
1903 res=finishup(transferee);
1904 if (!transferer->cdr) { /* this code should never get called (in a perfect world) */
1905 transferer->cdr=ast_cdr_alloc();
1906 if (transferer->cdr) {
1907 ast_cdr_init(transferer->cdr, transferer); /* initialize our channel's cdr */
1908 ast_cdr_start(transferer->cdr);
1911 if (transferer->cdr) {
1912 struct ast_cdr *swap = transferer->cdr;
1913 ast_log(LOG_DEBUG,"transferer=%s; transferee=%s; lastapp=%s; lastdata=%s; chan=%s; dstchan=%s\n",
1914 transferer->name, transferee->name, transferer->cdr->lastapp, transferer->cdr->lastdata,
1915 transferer->cdr->channel, transferer->cdr->dstchannel);
1916 ast_log(LOG_DEBUG,"TRANSFEREE; lastapp=%s; lastdata=%s, chan=%s; dstchan=%s\n",
1917 transferee->cdr->lastapp, transferee->cdr->lastdata, transferee->cdr->channel, transferee->cdr->dstchannel);
1918 ast_log(LOG_DEBUG,"transferer_real_context=%s; xferto=%s\n", transferer_real_context, xferto);
1919 /* swap cdrs-- it will save us some time & work */
1920 transferer->cdr = transferee->cdr;
1921 transferee->cdr = swap;
1923 if (!transferee->pbx) {
1924 /* Doh! Use our handy async_goto functions */
1925 ast_verb(3, "Transferring %s to '%s' (context %s) priority 1\n"
1926 ,transferee->name, xferto, transferer_real_context);
1927 if (ast_async_goto(transferee, transferer_real_context, xferto, 1))
1928 ast_log(LOG_WARNING, "Async goto failed :-(\n");
1930 /* Set the channel's new extension, since it exists, using transferer context */
1931 ast_set_flag(transferee, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */
1932 ast_log(LOG_DEBUG,"ABOUT TO AST_ASYNC_GOTO, have a pbx... set HANGUP_DONT on chan=%s\n", transferee->name);
1933 if (ast_channel_connected_line_macro(transferee, transferer, &transferer->connected, 1, 0)) {
1934 ast_channel_update_connected_line(transferer, &transferer->connected, NULL);
1936 set_c_e_p(transferee, transferer_real_context, xferto, 0);
1938 check_goto_on_transfer(transferer);
1941 ast_verb(3, "Unable to find extension '%s' in context '%s'\n", xferto, transferer_real_context);
1943 if (parkstatus != AST_FEATURE_RETURN_PARKFAILED && ast_stream_and_wait(transferer, xferfailsound, AST_DIGIT_ANY) < 0) { /* Play 'extension does not exist' */
1944 finishup(transferee);
1947 ast_stopstream(transferer);
1948 res = finishup(transferee);
1950 ast_verb(2, "Hungup during autoservice stop on '%s'\n", transferee->name);
1953 return AST_FEATURE_RETURN_SUCCESS;
1957 * \brief make channels compatible
1960 * \retval 0 on success.
1961 * \retval -1 on failure.
1963 static int check_compat(struct ast_channel *c, struct ast_channel *newchan)
1965 if (ast_channel_make_compatible(c, newchan) < 0) {
1966 ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n",
1967 c->name, newchan->name);
1968 ast_hangup(newchan);
1976 * \brief Builtin attended transfer failed cleanup.
1979 * \param transferee Party A in the transfer.
1980 * \param transferer Party B in the transfer.
1981 * \param connected_line Saved connected line info about party A.
1983 * \note The connected_line data is freed.
1987 static void atxfer_fail_cleanup(struct ast_channel *transferee, struct ast_channel *transferer, struct ast_party_connected_line *connected_line)
1989 finishup(transferee);
1992 * Restore party B connected line info about party A.
1994 * Party B was the caller to party C and is the last known mode
1997 if (ast_channel_connected_line_macro(transferee, transferer, connected_line, 1, 0)) {
1998 ast_channel_update_connected_line(transferer, connected_line, NULL);
2000 ast_party_connected_line_free(connected_line);
2004 * \brief Attended transfer
2005 * \param chan transfered user
2006 * \param peer person transfering call
2009 * \param sense feature options
2012 * Get extension to transfer to, if you cannot generate channel (or find extension)
2013 * return to host channel. After called channel answered wait for hangup of transferer,
2014 * bridge call between transfer peer (taking them off hold) to attended transfer channel.
2016 * \return -1 on failure
2018 static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
2020 struct ast_channel *transferer;/* Party B */
2021 struct ast_channel *transferee;/* Party A */
2022 const char *transferer_real_context;
2023 char xferto[256] = "";
2026 struct ast_channel *newchan;
2027 struct ast_channel *xferchan;
2028 struct ast_bridge_thread_obj *tobj;
2029 struct ast_bridge_config bconfig;
2031 struct ast_party_connected_line connected_line;
2032 struct ast_datastore *features_datastore;
2033 struct ast_dial_features *dialfeatures = NULL;
2034 struct ast_parkinglot *parkinglot;
2035 char *transferer_tech;
2036 char *transferer_name;
2037 char *transferer_name_orig;
2040 ast_debug(1, "Executing Attended Transfer %s, %s (sense=%d) \n", chan->name, peer->name, sense);
2041 set_peers(&transferer, &transferee, peer, chan, sense);
2042 transferer_real_context = real_ctx(transferer, transferee);
2044 /* Start autoservice on transferee while we talk to the transferer */
2045 ast_autoservice_start(transferee);
2046 ast_indicate(transferee, AST_CONTROL_HOLD);
2049 res = ast_stream_and_wait(transferer, "pbx-transfer", AST_DIGIT_ANY);
2051 finishup(transferee);
2054 if (res > 0) /* If they've typed a digit already, handle it */
2055 xferto[0] = (char) res;
2057 /* this is specific of atxfer */
2058 res = ast_app_dtget(transferer, transferer_real_context, xferto, sizeof(xferto), 100, transferdigittimeout);
2059 if (res < 0) { /* hangup or error, (would be 0 for invalid and 1 for valid) */
2060 finishup(transferee);
2066 ast_log(LOG_WARNING, "Extension '%s' does not exist in context '%s'\n",
2067 xferto, transferer_real_context);
2069 /* Does anyone care about this case? */
2070 ast_log(LOG_WARNING, "No digits dialed for atxfer.\n");
2072 ast_stream_and_wait(transferer, "pbx-invalid", "");
2073 finishup(transferee);
2074 return AST_FEATURE_RETURN_SUCCESS;
2077 /* If we are attended transfering to parking, just use parkcall_helper instead of trying to track all of
2078 * the different variables for handling this properly with a builtin_atxfer */
2079 parkinglot = ao2_callback(parkinglots, 0, find_parkinglot_by_exten_cb, &xferto);
2081 struct ast_park_call_args args = {
2082 .parkinglot = parkinglot,
2084 finishup(transferee);
2085 return parkcall_helper(chan, peer, config, code, sense, &args);
2088 /* Append context to dialed transfer number. */
2089 snprintf(xferto + l, sizeof(xferto) - l, "@%s/n", transferer_real_context);
2091 /* If we are performing an attended transfer and we have two channels involved then
2092 copy sound file information to play upon attended transfer completion */
2094 const char *chan1_attended_sound = pbx_builtin_getvar_helper(transferer, "ATTENDED_TRANSFER_COMPLETE_SOUND");
2095 const char *chan2_attended_sound = pbx_builtin_getvar_helper(transferee, "ATTENDED_TRANSFER_COMPLETE_SOUND");
2097 if (!ast_strlen_zero(chan1_attended_sound)) {
2098 pbx_builtin_setvar_helper(transferer, "BRIDGE_PLAY_SOUND", chan1_attended_sound);
2100 if (!ast_strlen_zero(chan2_attended_sound)) {
2101 pbx_builtin_setvar_helper(transferee, "BRIDGE_PLAY_SOUND", chan2_attended_sound);
2105 /* Extract redial transferer information from the channel name. */
2106 transferer_name_orig = ast_strdupa(transferer->name);
2107 transferer_name = ast_strdupa(transferer_name_orig);
2108 transferer_tech = strsep(&transferer_name, "/");
2109 dash = strrchr(transferer_name, '-');
2111 /* Trim off channel name sequence/serial number. */
2115 /* Stop autoservice so we can monitor all parties involved in the transfer. */
2116 if (ast_autoservice_stop(transferee) < 0) {
2117 ast_indicate(transferee, AST_CONTROL_UNHOLD);
2121 /* Save connected line info for party B about party A in case transfer fails. */
2122 ast_party_connected_line_init(&connected_line);
2123 ast_channel_lock(transferer);
2124 ast_party_connected_line_copy(&connected_line, &transferer->connected);
2125 ast_channel_unlock(transferer);
2126 connected_line.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
2129 newchan = feature_request_and_dial(transferer, transferer_name_orig, transferer,
2130 transferee, "Local", ast_best_codec(transferer->nativeformats), xferto,
2131 atxfernoanswertimeout, &outstate, transferer->language);
2132 ast_debug(2, "Dial party C result: newchan:%d, outstate:%d\n", !!newchan, outstate);
2134 if (!ast_check_hangup(transferer)) {
2135 int hangup_dont = 0;
2137 /* Transferer (party B) is up */
2138 ast_debug(1, "Actually doing an attended transfer.\n");
2140 /* Start autoservice on transferee while the transferer deals with party C. */
2141 ast_autoservice_start(transferee);
2143 ast_indicate(transferer, -1);
2145 /* any reason besides user requested cancel and busy triggers the failed sound */
2147 case AST_CONTROL_UNHOLD:/* Caller requested cancel or party C answer timeout. */
2148 case AST_CONTROL_BUSY:
2149 case AST_CONTROL_CONGESTION:
2150 if (ast_stream_and_wait(transferer, xfersound, "")) {
2151 ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
2155 if (ast_stream_and_wait(transferer, xferfailsound, "")) {
2156 ast_log(LOG_WARNING, "Failed to play transfer failed sound!\n");
2160 atxfer_fail_cleanup(transferee, transferer, &connected_line);
2161 return AST_FEATURE_RETURN_SUCCESS;
2164 if (check_compat(transferer, newchan)) {
2165 if (ast_stream_and_wait(transferer, xferfailsound, "")) {
2166 ast_log(LOG_WARNING, "Failed to play transfer failed sound!\n");
2168 atxfer_fail_cleanup(transferee, transferer, &connected_line);
2169 return AST_FEATURE_RETURN_SUCCESS;
2171 memset(&bconfig,0,sizeof(struct ast_bridge_config));
2172 ast_set_flag(&(bconfig.features_caller), AST_FEATURE_DISCONNECT);
2173 ast_set_flag(&(bconfig.features_callee), AST_FEATURE_DISCONNECT);
2175 /* ast_bridge_call clears AST_FLAG_BRIDGE_HANGUP_DONT, but we don't
2176 want that to happen here because we're also in another bridge already
2178 if (ast_test_flag(chan, AST_FLAG_BRIDGE_HANGUP_DONT)) {
2181 /* Let party B and party C talk as long as they want. */
2182 ast_bridge_call(transferer, newchan, &bconfig);
2184 ast_set_flag(chan, AST_FLAG_BRIDGE_HANGUP_DONT);
2187 if (ast_check_hangup(newchan) || !ast_check_hangup(transferer)) {
2188 ast_hangup(newchan);
2189 if (ast_stream_and_wait(transferer, xfersound, "")) {
2190 ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
2192 atxfer_fail_cleanup(transferee, transferer, &connected_line);
2193 return AST_FEATURE_RETURN_SUCCESS;
2196 /* Transferer (party B) is confirmed hung up at this point. */
2197 if (check_compat(transferee, newchan)) {
2198 finishup(transferee);
2199 ast_party_connected_line_free(&connected_line);
2203 ast_indicate(transferee, AST_CONTROL_UNHOLD);
2204 if ((ast_autoservice_stop(transferee) < 0)
2205 || (ast_waitfordigit(transferee, 100) < 0)
2206 || (ast_waitfordigit(newchan, 100) < 0)
2207 || ast_check_hangup(transferee)
2208 || ast_check_hangup(newchan)) {
2209 ast_hangup(newchan);
2210 ast_party_connected_line_free(&connected_line);
2213 } else if (!ast_check_hangup(transferee)) {
2214 /* Transferer (party B) has hung up at this point. Doing blonde transfer. */
2215 ast_debug(1, "Actually doing a blonde transfer.\n");
2217 if (!newchan && !atxferdropcall) {
2218 /* Party C is not available, try to call party B back. */
2219 unsigned int tries = 0;
2221 if (ast_strlen_zero(transferer_name) || ast_strlen_zero(transferer_tech)) {
2222 ast_log(LOG_WARNING,
2223 "Transferer channel name: '%s' cannot be used for callback.\n",
2224 transferer_name_orig);
2225 ast_indicate(transferee, AST_CONTROL_UNHOLD);
2226 ast_party_connected_line_free(&connected_line);
2232 /* Try to get party B back. */
2233 ast_debug(1, "We're trying to callback %s/%s\n",
2234 transferer_tech, transferer_name);
2235 newchan = feature_request_and_dial(transferer, transferer_name_orig,
2236 transferee, transferee, transferer_tech,
2237 ast_best_codec(transferee->nativeformats), transferer_name,
2238 atxfernoanswertimeout, &outstate, transferer->language);
2239 ast_debug(2, "Dial party B result: newchan:%d, outstate:%d\n",
2240 !!newchan, outstate);
2241 if (newchan || ast_check_hangup(transferee)) {
2246 if (atxfercallbackretries <= tries) {
2247 /* No more callback tries remaining. */
2251 if (atxferloopdelay) {
2252 /* Transfer failed, sleeping */
2253 ast_debug(1, "Sleeping for %d ms before retrying atxfer.\n",
2255 ast_safe_sleep(transferee, atxferloopdelay);
2256 if (ast_check_hangup(transferee)) {
2257 ast_party_connected_line_free(&connected_line);
2262 /* Retry dialing party C. */
2263 ast_debug(1, "We're retrying to call %s/%s\n", "Local", xferto);
2264 newchan = feature_request_and_dial(transferer, transferer_name_orig,
2265 transferer, transferee, "Local",
2266 ast_best_codec(transferee->nativeformats), xferto,
2267 atxfernoanswertimeout, &outstate, transferer->language);
2268 ast_debug(2, "Redial party C result: newchan:%d, outstate:%d\n",
2269 !!newchan, outstate);
2270 if (newchan || ast_check_hangup(transferee)) {
2275 ast_indicate(transferee, AST_CONTROL_UNHOLD);
2277 /* No party C or could not callback party B. */
2278 ast_party_connected_line_free(&connected_line);
2282 /* newchan is up, we should prepare transferee and bridge them */
2283 if (ast_check_hangup(newchan)) {
2284 ast_hangup(newchan);
2285 ast_party_connected_line_free(&connected_line);
2288 if (check_compat(transferee, newchan)) {
2289 ast_party_connected_line_free(&connected_line);
2294 * Both the transferer and transferee have hungup. If newchan
2295 * is up, hang it up as it has no one to talk to.
2297 ast_debug(1, "Everyone is hungup.\n");
2299 ast_hangup(newchan);
2301 ast_party_connected_line_free(&connected_line);
2305 /* Initiate the channel transfer of party A to party C (or recalled party B). */
2306 ast_cel_report_event(transferee, AST_CEL_ATTENDEDTRANSFER, NULL, NULL, newchan);
2308 xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", transferee->linkedid, 0, "Transfered/%s", transferee->name);
2310 ast_hangup(newchan);
2311 ast_party_connected_line_free(&connected_line);
2315 /* Give party A a momentary ringback tone during transfer. */
2316 xferchan->visible_indication = AST_CONTROL_RINGING;
2318 /* Make formats okay */
2319 xferchan->readformat = transferee->readformat;
2320 xferchan->writeformat = transferee->writeformat;
2322 ast_channel_masquerade(xferchan, transferee);
2323 ast_explicit_goto(xferchan, transferee->context, transferee->exten, transferee->priority);
2324 xferchan->_state = AST_STATE_UP;
2325 ast_clear_flag(xferchan, AST_FLAGS_ALL);
2327 /* Do the masquerade manually to make sure that is is completed. */
2328 ast_do_masquerade(xferchan);
2330 newchan->_state = AST_STATE_UP;
2331 ast_clear_flag(newchan, AST_FLAGS_ALL);
2332 tobj = ast_calloc(1, sizeof(*tobj));
2334 ast_hangup(xferchan);
2335 ast_hangup(newchan);
2336 ast_party_connected_line_free(&connected_line);
2340 ast_channel_lock(newchan);
2341 if ((features_datastore = ast_channel_datastore_find(newchan, &dial_features_info, NULL))) {
2342 dialfeatures = features_datastore->data;
2344 ast_channel_unlock(newchan);
2347 /* newchan should always be the callee and shows up as callee in dialfeatures, but for some reason
2348 I don't currently understand, the abilities of newchan seem to be stored on the caller side */
2349 ast_copy_flags(&(config->features_callee), &(dialfeatures->features_caller), AST_FLAGS_ALL);
2350 dialfeatures = NULL;
2353 ast_channel_lock(xferchan);
2354 if ((features_datastore = ast_channel_datastore_find(xferchan, &dial_features_info, NULL))) {
2355 dialfeatures = features_datastore->data;
2357 ast_channel_unlock(xferchan);
2360 ast_copy_flags(&(config->features_caller), &(dialfeatures->features_caller), AST_FLAGS_ALL);
2363 tobj->chan = newchan;
2364 tobj->peer = xferchan;
2365 tobj->bconfig = *config;
2367 if (tobj->bconfig.end_bridge_callback_data_fixup) {
2368 tobj->bconfig.end_bridge_callback_data_fixup(&tobj->bconfig, tobj->peer, tobj->chan);
2372 * xferchan is transferee, and newchan is the transfer target
2373 * So...in a transfer, who is the caller and who is the callee?
2375 * When the call is originally made, it is clear who is caller and callee.
2376 * When a transfer occurs, it is my humble opinion that the transferee becomes
2377 * the caller, and the transfer target is the callee.
2379 * The problem is that these macros were set with the intention of the original
2380 * caller and callee taking those roles. A transfer can totally mess things up,
2381 * to be technical. What sucks even more is that you can't effectively change
2382 * the macros in the dialplan during the call from the transferer to the transfer
2383 * target because the transferee is stuck with whatever role he originally had.
2385 * I think the answer here is just to make sure that it is well documented that
2386 * during a transfer, the transferee is the "caller" and the transfer target
2389 * This means that if party B calls party A, and party B transfers party A to
2390 * party C, then A has switched roles for the call. Now party A will have the
2391 * caller macro called on his channel instead of the callee macro.
2393 * Luckily, the method by which the party B to party C bridge is
2394 * launched above ensures that the transferee is the "chan" on
2395 * the bridge and the transfer target is the "peer," so my idea
2396 * for the roles post-transfer does not require extensive code
2400 /* Transfer party C connected line to party A */
2401 ast_channel_lock(transferer);
2403 * Due to a limitation regarding when callerID is set on a Local channel,
2404 * we use the transferer's connected line information here.
2406 ast_party_connected_line_copy(&connected_line, &transferer->connected);
2407 ast_channel_unlock(transferer);
2408 connected_line.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
2409 if (ast_channel_connected_line_macro(newchan, xferchan, &connected_line, 1, 0)) {
2410 ast_channel_update_connected_line(xferchan, &connected_line, NULL);
2413 /* Transfer party A connected line to party C */
2414 ast_channel_lock(xferchan);
2415 ast_connected_line_copy_from_caller(&connected_line, &xferchan->caller);
2416 ast_channel_unlock(xferchan);
2417 connected_line.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
2418 if (ast_channel_connected_line_macro(xferchan, newchan, &connected_line, 0, 0)) {
2419 ast_channel_update_connected_line(newchan, &connected_line, NULL);
2422 if (ast_stream_and_wait(newchan, xfersound, ""))
2423 ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
2424 bridge_call_thread_launch(tobj);
2426 ast_party_connected_line_free(&connected_line);
2427 return -1;/* The transferee is masqueraded and the original bridged channels can be hungup. */
2430 /* add atxfer and automon as undefined so you can only use em if you configure them */
2431 #define FEATURES_COUNT ARRAY_LEN(builtin_features)
2433 AST_RWLOCK_DEFINE_STATIC(features_lock);
2435 static struct ast_call_feature builtin_features[] = {
2436 { AST_FEATURE_REDIRECT, "Blind Transfer", "blindxfer", "#", "#", builtin_blindtransfer, AST_FEATURE_FLAG_NEEDSDTMF, "" },
2437 { AST_FEATURE_REDIRECT, "Attended Transfer", "atxfer", "", "", builtin_atxfer, AST_FEATURE_FLAG_NEEDSDTMF, "" },
2438 { AST_FEATURE_AUTOMON, "One Touch Monitor", "automon", "", "", builtin_automonitor, AST_FEATURE_FLAG_NEEDSDTMF, "" },
2439 { AST_FEATURE_DISCONNECT, "Disconnect Call", "disconnect", "*", "*", builtin_disconnect, AST_FEATURE_FLAG_NEEDSDTMF, "" },
2440 { AST_FEATURE_PARKCALL, "Park Call", "parkcall", "", "", builtin_parkcall, AST_FEATURE_FLAG_NEEDSDTMF, "" },
2441 { AST_FEATURE_AUTOMIXMON, "One Touch MixMonitor", "automixmon", "", "", builtin_automixmonitor, AST_FEATURE_FLAG_NEEDSDTMF, "" },
2445 static AST_RWLIST_HEAD_STATIC(feature_list, ast_call_feature);
2447 /*! \brief register new feature into feature_list*/
2448 void ast_register_feature(struct ast_call_feature *feature)
2451 ast_log(LOG_NOTICE,"You didn't pass a feature!\n");
2455 AST_RWLIST_WRLOCK(&feature_list);
2456 AST_RWLIST_INSERT_HEAD(&feature_list,feature,feature_entry);
2457 AST_RWLIST_UNLOCK(&feature_list);
2459 ast_verb(2, "Registered Feature '%s'\n",feature->sname);
2463 * \brief Add new feature group
2464 * \param fgname feature group name.
2466 * Add new feature group to the feature group list insert at head of list.
2467 * \note This function MUST be called while feature_groups is locked.
2469 static struct feature_group *register_group(const char *fgname)
2471 struct feature_group *fg;
2474 ast_log(LOG_NOTICE, "You didn't pass a new group name!\n");
2478 if (!(fg = ast_calloc_with_stringfields(1, struct feature_group, 128))) {
2482 ast_string_field_set(fg, gname, fgname);
2484 AST_LIST_INSERT_HEAD(&feature_groups, fg, entry);
2486 ast_verb(2, "Registered group '%s'\n", fg->gname);
2492 * \brief Add feature to group
2493 * \param fg feature group
2495 * \param feature feature to add.
2497 * Check fg and feature specified, add feature to list
2498 * \note This function MUST be called while feature_groups is locked.
2500 static void register_group_feature(struct feature_group *fg, const char *exten, struct ast_call_feature *feature)
2502 struct feature_group_exten *fge;
2505 ast_log(LOG_NOTICE, "You didn't pass a group!\n");
2510 ast_log(LOG_NOTICE, "You didn't pass a feature!\n");
2514 if (!(fge = ast_calloc_with_stringfields(1, struct feature_group_exten, 128))) {
2518 ast_string_field_set(fge, exten, S_OR(exten, feature->exten));
2520 fge->feature = feature;
2522 AST_LIST_INSERT_HEAD(&fg->features, fge, entry);
2524 ast_verb(2, "Registered feature '%s' for group '%s' at exten '%s'\n",
2525 feature->sname, fg->gname, fge->exten);
2528 void ast_unregister_feature(struct ast_call_feature *feature)
2534 AST_RWLIST_WRLOCK(&feature_list);
2535 AST_RWLIST_REMOVE(&feature_list, feature, feature_entry);
2536 AST_RWLIST_UNLOCK(&feature_list);
2541 /*! \brief Remove all features in the list */
2542 static void ast_unregister_features(void)
2544 struct ast_call_feature *feature;
2546 AST_RWLIST_WRLOCK(&feature_list);
2547 while ((feature = AST_RWLIST_REMOVE_HEAD(&feature_list, feature_entry))) {
2550 AST_RWLIST_UNLOCK(&feature_list);
2553 /*! \brief find a call feature by name */
2554 static struct ast_call_feature *find_dynamic_feature(const char *name)
2556 struct ast_call_feature *tmp;
2558 AST_RWLIST_TRAVERSE(&feature_list, tmp, feature_entry) {
2559 if (!strcasecmp(tmp->sname, name)) {
2567 /*! \brief Remove all feature groups in the list */
2568 static void ast_unregister_groups(void)
2570 struct feature_group *fg;
2571 struct feature_group_exten *fge;
2573 AST_RWLIST_WRLOCK(&feature_groups);
2574 while ((fg = AST_LIST_REMOVE_HEAD(&feature_groups, entry))) {
2575 while ((fge = AST_LIST_REMOVE_HEAD(&fg->features, entry))) {
2576 ast_string_field_free_memory(fge);
2580 ast_string_field_free_memory(fg);
2583 AST_RWLIST_UNLOCK(&feature_groups);
2587 * \brief Find a group by name
2588 * \param name feature name
2589 * \retval feature group on success.
2590 * \retval NULL on failure.
2592 static struct feature_group *find_group(const char *name)
2594 struct feature_group *fg = NULL;
2596 AST_LIST_TRAVERSE(&feature_groups, fg, entry) {
2597 if (!strcasecmp(fg->gname, name))
2604 void ast_rdlock_call_features(void)
2606 ast_rwlock_rdlock(&features_lock);
2609 void ast_unlock_call_features(void)
2611 ast_rwlock_unlock(&features_lock);
2614 struct ast_call_feature *ast_find_call_feature(const char *name)
2617 for (x = 0; x < FEATURES_COUNT; x++) {
2618 if (!strcasecmp(name, builtin_features[x].sname))
2619 return &builtin_features[x];
2625 * \brief exec an app by feature
2626 * \param chan,peer,config,code,sense,data
2628 * Find a feature, determine which channel activated
2629 * \retval AST_FEATURE_RETURN_NO_HANGUP_PEER
2631 * \retval -2 when an application cannot be found.
2633 static int feature_exec_app(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
2635 struct ast_app *app;
2636 struct ast_call_feature *feature = data;
2637 struct ast_channel *work, *idle;
2640 if (!feature) { /* shouldn't ever happen! */
2641 ast_log(LOG_NOTICE, "Found feature before, but at execing we've lost it??\n");
2645 if (sense == FEATURE_SENSE_CHAN) {
2646 if (!ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLER))
2647 return AST_FEATURE_RETURN_KEEPTRYING;
2648 if (ast_test_flag(feature, AST_FEATURE_FLAG_ONSELF)) {
2656 if (!ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLEE))
2657 return AST_FEATURE_RETURN_KEEPTRYING;
2658 if (ast_test_flag(feature, AST_FEATURE_FLAG_ONSELF)) {
2667 if (!(app = pbx_findapp(feature->app))) {
2668 ast_log(LOG_WARNING, "Could not find application (%s)\n", feature->app);
2672 ast_autoservice_start(idle);
2673 ast_autoservice_ignore(idle, AST_FRAME_DTMF_END);
2676 pbx_builtin_setvar_helper(work, "DYNAMIC_PEERNAME", idle->name);
2677 pbx_builtin_setvar_helper(idle, "DYNAMIC_PEERNAME", work->name);
2678 pbx_builtin_setvar_helper(work, "DYNAMIC_FEATURENAME", feature->sname);
2679 pbx_builtin_setvar_helper(idle, "DYNAMIC_FEATURENAME", feature->sname);
2682 if (!ast_strlen_zero(feature->moh_class))
2683 ast_moh_start(idle, feature->moh_class, NULL);
2685 res = pbx_exec(work, app, feature->app_args);
2687 if (!ast_strlen_zero(feature->moh_class))
2690 ast_autoservice_stop(idle);
2693 return AST_FEATURE_RETURN_SUCCESSBREAK;
2695 return AST_FEATURE_RETURN_SUCCESS; /*! \todo XXX should probably return res */
2698 static void unmap_features(void)
2702 ast_rwlock_wrlock(&features_lock);
2703 for (x = 0; x < FEATURES_COUNT; x++)
2704 strcpy(builtin_features[x].exten, builtin_features[x].default_exten);
2705 ast_rwlock_unlock(&features_lock);
2708 static int remap_feature(const char *name, const char *value)
2712 ast_rwlock_wrlock(&features_lock);
2713 for (x = 0; x < FEATURES_COUNT; x++) {
2714 if (strcasecmp(builtin_features[x].sname, name))
2717 ast_copy_string(builtin_features[x].exten, value, sizeof(builtin_features[x].exten));
2721 ast_rwlock_unlock(&features_lock);
2727 * \brief Helper function for feature_interpret and ast_feature_detect
2728 * \param chan,peer,config,code,sense,dynamic_features_buf,features,operation,feature
2730 * Lock features list, browse for code, unlock list
2731 * If a feature is found and the operation variable is set, that feature's
2732 * operation is executed. The first feature found is copied to the feature parameter.
2733 * \retval res on success.
2734 * \retval -1 on failure.
2736 static int feature_interpret_helper(struct ast_channel *chan, struct ast_channel *peer,
2737 struct ast_bridge_config *config, const char *code, int sense, char *dynamic_features_buf,
2738 struct ast_flags *features, int operation, struct ast_call_feature *feature)
2741 struct feature_group *fg = NULL;
2742 struct feature_group_exten *fge;
2743 struct ast_call_feature *tmpfeature;
2745 int res = AST_FEATURE_RETURN_PASSDIGITS;
2746 int feature_detected = 0;
2748 if (!(peer && chan && config) && operation) {
2749 return -1; /* can not run feature operation */
2752 ast_rwlock_rdlock(&features_lock);
2753 for (x = 0; x < FEATURES_COUNT; x++) {
2754 if ((ast_test_flag(features, builtin_features[x].feature_mask)) &&
2755 !ast_strlen_zero(builtin_features[x].exten)) {
2756 /* Feature is up for consideration */
2757 if (!strcmp(builtin_features[x].exten, code)) {
2758 ast_debug(3, "Feature detected: fname=%s sname=%s exten=%s\n", builtin_features[x].fname, builtin_features[x].sname, builtin_features[x].exten);
2760 res = builtin_features[x].operation(chan, peer, config, code, sense, NULL);
2762 memcpy(feature, &builtin_features[x], sizeof(feature));
2763 feature_detected = 1;
2765 } else if (!strncmp(builtin_features[x].exten, code, strlen(code))) {
2766 if (res == AST_FEATURE_RETURN_PASSDIGITS)
2767 res = AST_FEATURE_RETURN_STOREDIGITS;
2771 ast_rwlock_unlock(&features_lock);
2773 if (ast_strlen_zero(dynamic_features_buf) || feature_detected) {
2777 tmp = dynamic_features_buf;
2779 while ((tok = strsep(&tmp, "#"))) {
2780 AST_RWLIST_RDLOCK(&feature_groups);
2782 fg = find_group(tok);
2785 AST_LIST_TRAVERSE(&fg->features, fge, entry) {
2786 if (!strcmp(fge->exten, code)) {
2788 res = fge->feature->operation(chan, peer, config, code, sense, fge->feature);
2790 memcpy(feature, fge->feature, sizeof(feature));
2791 if (res != AST_FEATURE_RETURN_KEEPTRYING) {
2792 AST_RWLIST_UNLOCK(&feature_groups);
2795 res = AST_FEATURE_RETURN_PASSDIGITS;
2796 } else if (!strncmp(fge->exten, code, strlen(code))) {
2797 res = AST_FEATURE_RETURN_STOREDIGITS;
2805 AST_RWLIST_UNLOCK(&feature_groups);
2807 AST_RWLIST_RDLOCK(&feature_list);
2809 if (!(tmpfeature = find_dynamic_feature(tok))) {
2810 AST_RWLIST_UNLOCK(&feature_list);
2814 /* Feature is up for consideration */
2815 if (!strcmp(tmpfeature->exten, code)) {
2816 ast_verb(3, " Feature Found: %s exten: %s\n",tmpfeature->sname, tok);
2818 res = tmpfeature->operation(chan, peer, config, code, sense, tmpfeature);
2820 memcpy(feature, tmpfeature, sizeof(feature));
2821 if (res != AST_FEATURE_RETURN_KEEPTRYING) {
2822 AST_RWLIST_UNLOCK(&feature_list);
2825 res = AST_FEATURE_RETURN_PASSDIGITS;
2826 } else if (!strncmp(tmpfeature->exten, code, strlen(code)))
2827 res = AST_FEATURE_RETURN_STOREDIGITS;
2829 AST_RWLIST_UNLOCK(&feature_list);
2836 * \brief Check the dynamic features
2837 * \param chan,peer,config,code,sense
2839 * \retval res on success.
2840 * \retval -1 on failure.
2843 static int feature_interpret(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense) {
2845 char dynamic_features_buf[128];
2846 const char *peer_dynamic_features, *chan_dynamic_features;
2847 struct ast_flags features;
2848 struct ast_call_feature feature;
2849 if (sense == FEATURE_SENSE_CHAN) {
2850 ast_copy_flags(&features, &(config->features_caller), AST_FLAGS_ALL);
2853 ast_copy_flags(&features, &(config->features_callee), AST_FLAGS_ALL);
2856 ast_channel_lock(peer);
2857 peer_dynamic_features = ast_strdupa(S_OR(pbx_builtin_getvar_helper(peer, "DYNAMIC_FEATURES"),""));
2858 ast_channel_unlock(peer);
2860 ast_channel_lock(chan);
2861 chan_dynamic_features = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "DYNAMIC_FEATURES"),""));
2862 ast_channel_unlock(chan);
2864 snprintf(dynamic_features_buf, sizeof(dynamic_features_buf), "%s%s%s", S_OR(chan_dynamic_features, ""), chan_dynamic_features && peer_dynamic_features ? "#" : "", S_OR(peer_dynamic_features,""));
2866 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_buf);
2868 return feature_interpret_helper(chan, peer, config, code, sense, dynamic_features_buf, &features, 1, &feature);
2872 int ast_feature_detect(struct ast_channel *chan, struct ast_flags *features, const char *code, struct ast_call_feature *feature) {
2874 return feature_interpret_helper(chan, NULL, NULL, code, 0, NULL, features, 0, feature);
2877 static void set_config_flags(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config)
2881 ast_clear_flag(config, AST_FLAGS_ALL);
2883 ast_rwlock_rdlock(&features_lock);
2884 for (x = 0; x < FEATURES_COUNT; x++) {
2885 if (!ast_test_flag(builtin_features + x, AST_FEATURE_FLAG_NEEDSDTMF))
2888 if (ast_test_flag(&(config->features_caller), builtin_features[x].feature_mask))
2889 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
2891 if (ast_test_flag(&(config->features_callee), builtin_features[x].feature_mask))
2892 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
2894 ast_rwlock_unlock(&features_lock);
2896 if (chan && peer && !(ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_0) && ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_1))) {
2897 const char *dynamic_features = pbx_builtin_getvar_helper(chan, "DYNAMIC_FEATURES");
2899 if (dynamic_features) {
2900 char *tmp = ast_strdupa(dynamic_features);
2902 struct ast_call_feature *feature;
2904 /* while we have a feature */
2905 while ((tok = strsep(&tmp, "#"))) {
2906 struct feature_group *fg;
2908 AST_RWLIST_RDLOCK(&feature_groups);
2909 AST_RWLIST_TRAVERSE(&feature_groups, fg, entry) {
2910 struct feature_group_exten *fge;
2912 AST_LIST_TRAVERSE(&fg->features, fge, entry) {
2913 if (ast_test_flag(fge->feature, AST_FEATURE_FLAG_BYCALLER)) {
2914 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
2916 if (ast_test_flag(fge->feature, AST_FEATURE_FLAG_BYCALLEE)) {
2917 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
2921 AST_RWLIST_UNLOCK(&feature_groups);
2923 AST_RWLIST_RDLOCK(&feature_list);
2924 if ((feature = find_dynamic_feature(tok)) && ast_test_flag(feature, AST_FEATURE_FLAG_NEEDSDTMF)) {
2925 if (ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLER)) {
2926 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
2928 if (ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLEE)) {
2929 ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
2932 AST_RWLIST_UNLOCK(&feature_list);
2940 * \brief Get feature and dial.
2942 * \param caller Channel to represent as the calling channel for the dialed channel.
2943 * \param caller_name Original caller channel name.
2944 * \param requestor Channel to say is requesting the dial (usually the caller).
2945 * \param transferee Channel that the dialed channel will be transferred to.
2946 * \param type Channel technology type to dial.
2947 * \param format Codec formats for dialed channel.
2948 * \param data Dialed channel extra parameters for ast_request() and ast_call().
2949 * \param timeout Time limit for dialed channel to answer in ms. Must be greater than zero.
2950 * \param outstate Status of dialed channel if unsuccessful.
2951 * \param language Language of the caller.
2955 * 0, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION,
2956 * AST_CONTROL_ANSWER, or AST_CONTROL_UNHOLD. If
2957 * AST_CONTROL_UNHOLD then the caller channel cancelled the
2958 * transfer or the dialed channel did not answer before the
2962 * Request channel, set channel variables, initiate call,
2963 * check if they want to disconnect, go into loop, check if timeout has elapsed,
2964 * check if person to be transfered hung up, check for answer break loop,
2965 * set cdr return channel.
2967 * \retval Channel Connected channel for transfer.
2968 * \retval NULL on failure to get third party connected.
2970 * \note This is similar to __ast_request_and_dial() in channel.c
2972 static struct ast_channel *feature_request_and_dial(struct ast_channel *caller,
2973 const char *caller_name, struct ast_channel *requestor,
2974 struct ast_channel *transferee, const char *type, format_t format, void *data,
2975 int timeout, int *outstate, const char *language)
2981 int transferee_hungup;
2982 struct ast_channel *chan;
2983 struct ast_channel *monitor_chans[3];
2984 struct ast_channel *active_channel;
2987 struct timeval started;
2989 char *disconnect_code = NULL, *dialed_code = NULL;
2990 struct ast_frame *f;
2991 AST_LIST_HEAD_NOLOCK(, ast_frame) deferred_frames;
2993 caller_hungup = ast_check_hangup(caller);
2995 if (!(chan = ast_request(type, format, requestor, data, &cause))) {
2996 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
2998 case AST_CAUSE_BUSY:
2999 state = AST_CONTROL_BUSY;
3001 case AST_CAUSE_CONGESTION:
3002 state = AST_CONTROL_CONGESTION;
3011 ast_string_field_set(chan, language, language);
3012 ast_channel_inherit_variables(caller, chan);
3013 pbx_builtin_setvar_helper(chan, "TRANSFERERNAME", caller_name);
3015 ast_channel_lock(chan);
3016 ast_connected_line_copy_from_caller(&chan->connected, &requestor->caller);
3017 ast_channel_unlock(chan);
3019 if (ast_call(chan, data, timeout)) {
3020 ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
3021 switch (chan->hangupcause) {
3022 case AST_CAUSE_BUSY:
3023 state = AST_CONTROL_BUSY;
3025 case AST_CAUSE_CONGESTION:
3026 state = AST_CONTROL_CONGESTION;
3035 /* support dialing of the featuremap disconnect code while performing an attended tranfer */
3036 ast_rwlock_rdlock(&features_lock);
3037 for (x = 0; x < FEATURES_COUNT; x++) {
3038 if (strcasecmp(builtin_features[x].sname, "disconnect"))
3041 disconnect_code = builtin_features[x].exten;
3042 len = strlen(disconnect_code) + 1;
3043 dialed_code = alloca(len);
3044 memset(dialed_code, 0, len);
3047 ast_rwlock_unlock(&features_lock);
3049 started = ast_tvnow();
3051 AST_LIST_HEAD_INIT_NOLOCK(&deferred_frames);
3053 ast_poll_channel_add(caller, chan);
3055 transferee_hungup = 0;
3056 while (!ast_check_hangup(transferee) && (chan->_state != AST_STATE_UP)) {
3059 monitor_chans[num_chans++] = transferee;
3060 monitor_chans[num_chans++] = chan;
3061 if (!caller_hungup) {
3062 if (ast_check_hangup(caller)) {
3065 #if defined(ATXFER_NULL_TECH)
3066 /* Change caller's name to ensure that it will remain unique. */
3067 set_new_chan_name(caller);
3070 * Get rid of caller's physical technology so it is free for
3073 set_null_chan_tech(caller);
3074 #endif /* defined(ATXFER_NULL_TECH) */
3076 /* caller is not hungup so monitor it. */
3077 monitor_chans[num_chans++] = caller;
3081 /* see if the timeout has been violated */
3082 if (ast_tvdiff_ms(ast_tvnow(), started) > timeout) {
3083 state = AST_CONTROL_UNHOLD;
3084 ast_log(LOG_NOTICE, "We exceeded our AT-timeout for %s\n", chan->name);
3085 break; /*doh! timeout*/
3088 active_channel = ast_waitfor_n(monitor_chans, num_chans, &to);
3089 if (!active_channel)
3093 if (transferee == active_channel) {
3094 struct ast_frame *dup_f;
3096 f = ast_read(transferee);
3097 if (f == NULL) { /*doh! where'd he go?*/
3098 transferee_hungup = 1;