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>
27 <support_level>core</support_level>
32 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
34 #include "asterisk/_private.h"
39 #include <sys/signal.h>
40 #include <netinet/in.h>
42 #include "asterisk/lock.h"
43 #include "asterisk/file.h"
44 #include "asterisk/channel.h"
45 #include "asterisk/pbx.h"
46 #include "asterisk/causes.h"
47 #include "asterisk/module.h"
48 #include "asterisk/translate.h"
49 #include "asterisk/app.h"
50 #include "asterisk/say.h"
51 #include "asterisk/features.h"
52 #include "asterisk/musiconhold.h"
53 #include "asterisk/config.h"
54 #include "asterisk/cli.h"
55 #include "asterisk/manager.h"
56 #include "asterisk/utils.h"
57 #include "asterisk/adsi.h"
58 #include "asterisk/devicestate.h"
59 #include "asterisk/monitor.h"
60 #include "asterisk/audiohook.h"
61 #include "asterisk/global_datastores.h"
62 #include "asterisk/astobj2.h"
63 #include "asterisk/cel.h"
64 #include "asterisk/test.h"
67 * Party A - transferee
68 * Party B - transferer
69 * Party C - target of transfer
71 * DTMF attended transfer works within the channel bridge.
72 * Unfortunately, when either party A or B in the channel bridge
73 * hangs up, that channel is not completely hung up until the
74 * transfer completes. This is a real problem depending upon
75 * the channel technology involved.
77 * For chan_dahdi, the channel is crippled until the hangup is
78 * complete. Either the channel is not useable (analog) or the
79 * protocol disconnect messages are held up (PRI/BRI/SS7) and
80 * the media is not released.
82 * For chan_sip, a call limit of one is going to block that
83 * endpoint from any further calls until the hangup is complete.
85 * For party A this is a minor problem. The party A channel
86 * will only be in this condition while party B is dialing and
87 * when party B and C are conferring. The conversation between
88 * party B and C is expected to be a short one. Party B is
89 * either asking a question of party C or announcing party A.
90 * Also party A does not have much incentive to hangup at this
93 * For party B this can be a major problem during a blonde
94 * transfer. (A blonde transfer is our term for an attended
95 * transfer that is converted into a blind transfer. :)) Party
96 * B could be the operator. When party B hangs up, he assumes
97 * that he is out of the original call entirely. The party B
98 * channel will be in this condition while party C is ringing,
99 * while attempting to recall party B, and while waiting between
103 * The ATXFER_NULL_TECH conditional is a hack to fix the
104 * problem. It will replace the party B channel technology with
105 * a NULL channel driver. The consequences of this code is that
106 * the 'h' extension will not be able to access any channel
107 * technology specific information like SIP statistics for the
110 * Uncomment the ATXFER_NULL_TECH define below to replace the
111 * party B channel technology in the channel bridge to complete
112 * hanging up the channel technology.
114 //#define ATXFER_NULL_TECH 1
117 <application name="Bridge" language="en_US">
122 <parameter name="channel" required="true">
123 <para>The current channel is bridged to the specified <replaceable>channel</replaceable>.</para>
125 <parameter name="options">
128 <para>Play a courtesy tone to <replaceable>channel</replaceable>.</para>
131 <para>Allow the called party to hang up by sending the
132 <replaceable>*</replaceable> DTMF digit.</para>
135 <para>Allow the calling party to hang up by pressing the
136 <replaceable>*</replaceable> DTMF digit.</para>
139 <para>Allow the called party to enable parking of the call by sending
140 the DTMF sequence defined for call parking in <filename>features.conf</filename>.</para>
143 <para>Allow the calling party to enable parking of the call by sending
144 the DTMF sequence defined for call parking in <filename>features.conf</filename>.</para>
146 <option name="L(x[:y][:z])">
147 <para>Limit the call to <replaceable>x</replaceable> ms. Play a warning
148 when <replaceable>y</replaceable> ms are left. Repeat the warning every
149 <replaceable>z</replaceable> ms. The following special variables can be
150 used with this option:</para>
152 <variable name="LIMIT_PLAYAUDIO_CALLER">
153 <para>Play sounds to the caller. yes|no (default yes)</para>
155 <variable name="LIMIT_PLAYAUDIO_CALLEE">
156 <para>Play sounds to the callee. yes|no</para>
158 <variable name="LIMIT_TIMEOUT_FILE">
159 <para>File to play when time is up.</para>
161 <variable name="LIMIT_CONNECT_FILE">
162 <para>File to play when call begins.</para>
164 <variable name="LIMIT_WARNING_FILE">
165 <para>File to play as warning if <replaceable>y</replaceable> is
166 defined. The default is to say the time remaining.</para>
171 <para>Hang up the call after <replaceable>x</replaceable> seconds *after* the called party has answered the call.</para>
174 <para>Allow the called party to transfer the calling party by sending the
175 DTMF sequence defined in <filename>features.conf</filename>.</para>
178 <para>Allow the calling party to transfer the called party by sending the
179 DTMF sequence defined in <filename>features.conf</filename>.</para>
182 <para>Allow the called party to enable recording of the call by sending
183 the DTMF sequence defined for one-touch recording in <filename>features.conf</filename>.</para>
186 <para>Allow the calling party to enable recording of the call by sending
187 the DTMF sequence defined for one-touch recording in <filename>features.conf</filename>.</para>
190 <para>Cause the called party to be hung up after the bridge, instead of being
191 restarted in the dialplan.</para>
197 <para>Allows the ability to bridge two channels via the dialplan.</para>
198 <para>This application sets the following channel variable upon completion:</para>
200 <variable name="BRIDGERESULT">
201 <para>The result of the bridge attempt as a text string.</para>
202 <value name="SUCCESS" />
203 <value name="FAILURE" />
204 <value name="LOOP" />
205 <value name="NONEXISTENT" />
206 <value name="INCOMPATIBLE" />
211 <application name="ParkedCall" language="en_US">
213 Retrieve a parked call.
216 <parameter name="exten">
217 <para>Parking space extension to retrieve a parked call.
218 If not provided then the first available parked call in the
219 parking lot will be retrieved.</para>
221 <parameter name="parking_lot_name">
222 <para>Specify from which parking lot to retrieve a parked call.</para>
223 <para>The parking lot used is selected in the following order:</para>
224 <para>1) parking_lot_name option</para>
225 <para>2) <variable>PARKINGLOT</variable> variable</para>
226 <para>3) <literal>CHANNEL(parkinglot)</literal> function
227 (Possibly preset by the channel driver.)</para>
228 <para>4) Default parking lot.</para>
232 <para>Used to retrieve a parked call from a parking lot.</para>
234 <para>Parking lots automatically create and manage dialplan extensions in
235 the parking lot context. You do not need to explicitly use this
236 application in your dialplan. Instead, all you should do is include the
237 parking lot context in your dialplan.</para>
241 <ref type="application">Park</ref>
242 <ref type="application">ParkAndAnnounce</ref>
245 <application name="Park" language="en_US">
250 <parameter name="timeout">
251 <para>A custom parking timeout for this parked call. Value in milliseconds.</para>
253 <parameter name="return_context">
254 <para>The context to return the call to after it times out.</para>
256 <parameter name="return_exten">
257 <para>The extension to return the call to after it times out.</para>
259 <parameter name="return_priority">
260 <para>The priority to return the call to after it times out.</para>
262 <parameter name="options">
263 <para>A list of options for this parked call.</para>
266 <para>Send ringing instead of MOH to the parked call.</para>
269 <para>Randomize the selection of a parking space.</para>
272 <para>Silence announcement of the parking space number.</para>
276 <parameter name="parking_lot_name">
277 <para>Specify in which parking lot to park a call.</para>
278 <para>The parking lot used is selected in the following order:</para>
279 <para>1) parking_lot_name option</para>
280 <para>2) <variable>PARKINGLOT</variable> variable</para>
281 <para>3) <literal>CHANNEL(parkinglot)</literal> function
282 (Possibly preset by the channel driver.)</para>
283 <para>4) Default parking lot.</para>
287 <para>Used to park yourself (typically in combination with a supervised
288 transfer to know the parking space).</para>
289 <para>If you set the <variable>PARKINGEXTEN</variable> variable to a
290 parking space extension in the parking lot, Park() will attempt to park the call
291 on that extension. If the extension is already is in use then execution
292 will continue at the next priority.</para>
293 <para>If the <literal>parkeddynamic</literal> option is enabled in <filename>features.conf</filename>
294 the following variables can be used to dynamically create new parking lots.</para>
295 <para>If you set the <variable>PARKINGDYNAMIC</variable> variable and this parking lot
296 exists then it will be used as a template for the newly created dynamic lot. Otherwise,
297 the default parking lot will be used.</para>
298 <para>If you set the <variable>PARKINGDYNCONTEXT</variable> variable then the newly created dynamic
299 parking lot will use this context.</para>
300 <para>If you set the <variable>PARKINGDYNEXTEN</variable> variable then the newly created dynamic
301 parking lot will use this extension to access the parking lot.</para>
302 <para>If you set the <variable>PARKINGDYNPOS</variable> variable then the newly created dynamic parking lot
303 will use those parking postitions.</para>
305 <para>This application must be used as the first extension priority
306 to be recognized as a parking access extension. DTMF transfers
307 and some channel drivers need this distinction to operate properly.
308 The parking access extension in this case is treated like a dialplan
312 <para>Parking lots automatically create and manage dialplan extensions in
313 the parking lot context. You do not need to explicitly use this
314 application in your dialplan. Instead, all you should do is include the
315 parking lot context in your dialplan.</para>
319 <ref type="application">ParkAndAnnounce</ref>
320 <ref type="application">ParkedCall</ref>
323 <manager name="ParkedCalls" language="en_US">
328 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
331 <para>List parked calls.</para>
334 <manager name="Park" language="en_US">
339 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
340 <parameter name="Channel" required="true">
341 <para>Channel name to park.</para>
343 <parameter name="Channel2" required="true">
344 <para>Channel to return to if timeout.</para>
346 <parameter name="Timeout">
347 <para>Number of milliseconds to wait before callback.</para>
349 <parameter name="Parkinglot">
350 <para>Specify in which parking lot to park the channel.</para>
354 <para>Park a channel.</para>
357 <manager name="Bridge" language="en_US">
359 Bridge two channels already in the PBX.
362 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
363 <parameter name="Channel1" required="true">
364 <para>Channel to Bridge to Channel2.</para>
366 <parameter name="Channel2" required="true">
367 <para>Channel to Bridge to Channel1.</para>
369 <parameter name="Tone">
370 <para>Play courtesy tone to Channel 2.</para>
378 <para>Bridge together two channels already in the PBX.</para>
383 #define DEFAULT_PARK_TIME 45000 /*!< ms */
384 #define DEFAULT_PARK_EXTENSION "700"
385 #define DEFAULT_TRANSFER_DIGIT_TIMEOUT 3000 /*!< ms */
386 #define DEFAULT_FEATURE_DIGIT_TIMEOUT 1000 /*!< ms */
387 #define DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER 15000 /*!< ms */
388 #define DEFAULT_ATXFER_DROP_CALL 0 /*!< Do not drop call. */
389 #define DEFAULT_ATXFER_LOOP_DELAY 10000 /*!< ms */
390 #define DEFAULT_ATXFER_CALLBACK_RETRIES 2
391 #define DEFAULT_COMEBACK_CONTEXT "parkedcallstimeout"
392 #define DEFAULT_COMEBACK_TO_ORIGIN 1
393 #define DEFAULT_COMEBACK_DIAL_TIME 30
395 #define AST_MAX_WATCHERS 256
396 #define MAX_DIAL_FEATURE_OPTIONS 30
398 struct feature_group_exten {
399 AST_LIST_ENTRY(feature_group_exten) entry;
400 AST_DECLARE_STRING_FIELDS(
401 AST_STRING_FIELD(exten);
403 struct ast_call_feature *feature;
406 struct feature_group {
407 AST_LIST_ENTRY(feature_group) entry;
408 AST_DECLARE_STRING_FIELDS(
409 AST_STRING_FIELD(gname);
411 AST_LIST_HEAD_NOLOCK(, feature_group_exten) features;
414 static AST_RWLIST_HEAD_STATIC(feature_groups, feature_group);
417 FEATURE_INTERPRET_DETECT, /* Used by ast_feature_detect */
418 FEATURE_INTERPRET_DO, /* Used by feature_interpret */
419 FEATURE_INTERPRET_CHECK, /* Used by feature_check */
420 } feature_interpret_op;
422 static const char *parkedcall = "ParkedCall";
424 static char pickup_ext[AST_MAX_EXTENSION]; /*!< Call pickup extension */
426 /*! Parking lot access ramp dialplan usage entry. */
427 struct parking_dp_ramp {
428 /*! Next node in the parking lot spaces dialplan list. */
429 AST_LIST_ENTRY(parking_dp_ramp) node;
430 /*! TRUE if the parking lot access extension is exclusive. */
431 unsigned int exclusive:1;
432 /*! Parking lot access extension */
436 /*! Parking lot dialplan access ramp map */
437 AST_LIST_HEAD_NOLOCK(parking_dp_ramp_map, parking_dp_ramp);
439 /*! Parking lot spaces dialplan usage entry. */
440 struct parking_dp_spaces {
441 /*! Next node in the parking lot spaces dialplan list. */
442 AST_LIST_ENTRY(parking_dp_spaces) node;
443 /*! First parking space */
445 /*! Last parking space */
449 /*! Parking lot dialplan context space map */
450 AST_LIST_HEAD_NOLOCK(parking_dp_space_map, parking_dp_spaces);
452 /*! Parking lot context dialplan usage entry. */
453 struct parking_dp_context {
454 /*! Next node in the parking lot contexts dialplan list. */
455 AST_LIST_ENTRY(parking_dp_context) node;
456 /*! Parking access extensions defined in this context. */
457 struct parking_dp_ramp_map access_extens;
458 /*! Parking spaces defined in this context. */
459 struct parking_dp_space_map spaces;
460 /*! Parking hints defined in this context. */
461 struct parking_dp_space_map hints;
462 /*! Parking lot context name */
466 /*! Parking lot dialplan usage map. */
467 AST_LIST_HEAD_NOLOCK(parking_dp_map, parking_dp_context);
470 * \brief Description of one parked call, added to a list while active, then removed.
471 * The list belongs to a parkinglot.
474 struct ast_channel *chan; /*!< Parked channel */
475 struct timeval start; /*!< Time the park started */
476 int parkingnum; /*!< Parking lot space used */
477 char parkingexten[AST_MAX_EXTENSION]; /*!< If set beforehand, parking extension used for this call */
478 char context[AST_MAX_CONTEXT]; /*!< Where to go if our parking time expires */
479 char exten[AST_MAX_EXTENSION];
481 int parkingtime; /*!< Maximum length in parking lot before return */
482 /*! Method to entertain the caller when parked: AST_CONTROL_RINGING, AST_CONTROL_HOLD, or 0(none) */
483 enum ast_control_frame_type hold_method;
484 unsigned int notquiteyet:1;
485 unsigned int options_specified:1;
486 char peername[AST_CHANNEL_NAME];
487 unsigned char moh_trys;
488 /*! Parking lot this entry belongs to. Holds a parking lot reference. */
489 struct ast_parkinglot *parkinglot;
490 AST_LIST_ENTRY(parkeduser) list;
493 /*! Parking lot configuration options. */
494 struct parkinglot_cfg {
495 /*! Music class used for parking */
496 char mohclass[MAX_MUSICCLASS];
497 /*! Extension to park calls in this parking lot. */
498 char parkext[AST_MAX_EXTENSION];
499 /*! Context for which parking is made accessible */
500 char parking_con[AST_MAX_CONTEXT];
501 /*! Context that timed-out parked calls are called back on when comebacktoorigin=no */
502 char comebackcontext[AST_MAX_CONTEXT];
503 /*! First available extension for parking */
505 /*! Last available extension for parking */
507 /*! Default parking time in ms. */
510 * \brief Enable DTMF based transfers on bridge when picking up parked calls.
514 * AST_FEATURE_FLAG_BYCALLEE
515 * AST_FEATURE_FLAG_BYCALLER
516 * AST_FEATURE_FLAG_BYBOTH
518 int parkedcalltransfers;
520 * \brief Enable DTMF based parking on bridge when picking up parked calls.
524 * AST_FEATURE_FLAG_BYCALLEE
525 * AST_FEATURE_FLAG_BYCALLER
526 * AST_FEATURE_FLAG_BYBOTH
528 int parkedcallreparking;
530 * \brief Enable DTMF based hangup on a bridge when pickup up parked calls.
534 * AST_FEATURE_FLAG_BYCALLEE
535 * AST_FEATURE_FLAG_BYCALLER
536 * AST_FEATURE_FLAG_BYBOTH
538 int parkedcallhangup;
540 * \brief Enable DTMF based recording on a bridge when picking up parked calls.
544 * AST_FEATURE_FLAG_BYCALLEE
545 * AST_FEATURE_FLAG_BYCALLER
546 * AST_FEATURE_FLAG_BYBOTH
548 int parkedcallrecording;
550 /*! Time in seconds to dial the device that parked a timedout parked call */
551 unsigned int comebackdialtime;
552 /*! TRUE if findslot is set to next */
553 unsigned int parkfindnext:1;
554 /*! TRUE if the parking lot is exclusively accessed by parkext */
555 unsigned int parkext_exclusive:1;
556 /*! Add parking hints automatically */
557 unsigned int parkaddhints:1;
558 /*! TRUE if configuration is invalid and the parking lot should not be used. */
559 unsigned int is_invalid:1;
560 /*! TRUE if a timed out parked call goes back to the parker */
561 unsigned int comebacktoorigin:1;
564 /*! \brief Structure for parking lots which are put in a container. */
565 struct ast_parkinglot {
566 /*! Name of the parking lot. */
567 char name[AST_MAX_CONTEXT];
568 /*! Parking lot user configuration. */
569 struct parkinglot_cfg cfg;
571 /*! Parking space to start next park search. */
572 int next_parking_space;
574 /*! That which bears the_mark shall be deleted if parking lot empty! (Used during reloads.) */
575 unsigned int the_mark:1;
576 /*! TRUE if the parking lot is disabled. */
577 unsigned int disabled:1;
579 /*! List of active parkings in this parkinglot */
580 AST_LIST_HEAD(parkinglot_parklist, parkeduser) parkings;
583 /*! \brief The configured parking lots container. Always at least one - the default parking lot */
584 static struct ao2_container *parkinglots;
587 * \brief Default parking lot.
588 * \note Holds a parkinglot reference.
589 * \note Will not be NULL while running.
591 static struct ast_parkinglot *default_parkinglot;
593 /*! Force a config reload to reload regardless of config file timestamp. */
594 static int force_reload_load;
596 static int parkedplay = 0; /*!< Who to play courtesytone to when someone picks up a parked call. */
597 static int parkeddynamic = 0; /*!< Enable creation of parkinglots dynamically */
598 static char courtesytone[256]; /*!< Courtesy tone used to pickup parked calls and on-touch-record */
599 static char xfersound[256]; /*!< Call transfer sound */
600 static char xferfailsound[256]; /*!< Call transfer failure sound */
601 static char pickupsound[256]; /*!< Pickup sound */
602 static char pickupfailsound[256]; /*!< Pickup failure sound */
605 * \brief Context for parking dialback to parker.
606 * \note The need for the context is a KLUDGE.
608 * \todo Might be able to eliminate the parking_con_dial context
609 * kludge by running app_dial directly in its own thread to
612 static char parking_con_dial[] = "park-dial";
614 /*! Ensure that features.conf reloads on one thread at a time. */
615 AST_MUTEX_DEFINE_STATIC(features_reload_lock);
619 static int transferdigittimeout;
620 static int featuredigittimeout;
622 static int atxfernoanswertimeout;
623 static unsigned int atxferdropcall;
624 static unsigned int atxferloopdelay;
625 static unsigned int atxfercallbackretries;
627 static char *registrar = "features"; /*!< Registrar for operations */
629 /*! PARK_APP_NAME application arguments */
630 AST_DEFINE_APP_ARGS_TYPE(park_app_args,
631 AST_APP_ARG(timeout); /*!< Time in ms to remain in the parking lot. */
632 AST_APP_ARG(return_con); /*!< Context to return parked call if timeout. */
633 AST_APP_ARG(return_ext); /*!< Exten to return parked call if timeout. */
634 AST_APP_ARG(return_pri); /*!< Priority to return parked call if timeout. */
635 AST_APP_ARG(options); /*!< Parking option flags. */
636 AST_APP_ARG(pl_name); /*!< Parking lot name to use if present. */
637 AST_APP_ARG(dummy); /*!< Place to put any remaining args string. */
640 /* module and CLI command definitions */
641 static const char *parkcall = "Park";
643 static struct ast_app *monitor_app = NULL;
644 static int monitor_ok = 1;
646 static struct ast_app *mixmonitor_app = NULL;
647 static int mixmonitor_ok = 1;
649 static struct ast_app *stopmixmonitor_app = NULL;
650 static int stopmixmonitor_ok = 1;
652 static pthread_t parking_thread;
653 struct ast_dial_features {
654 struct ast_flags features_caller;
655 struct ast_flags features_callee;
659 #if defined(ATXFER_NULL_TECH)
662 * \brief Set the channel technology to the kill technology.
664 * \param chan Channel to change technology.
668 static void set_kill_chan_tech(struct ast_channel *chan)
672 ast_channel_lock(chan);
674 /* Hangup the channel's physical side */
675 if (chan->tech->hangup) {
676 chan->tech->hangup(chan);
678 if (chan->tech_pvt) {
679 ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n",
680 ast_channel_name(chan));
681 ast_free(chan->tech_pvt);
682 chan->tech_pvt = NULL;
685 /* Install the kill technology and wake up anyone waiting on it. */
686 chan->tech = &ast_kill_tech;
687 for (idx = 0; idx < AST_MAX_FDS; ++idx) {
691 case AST_GENERATOR_FD:
692 /* Don't clear these fd's. */
695 ast_channel_set_fd(chan, idx, -1);
699 ast_queue_frame(chan, &ast_null_frame);
701 ast_channel_unlock(chan);
703 #endif /* defined(ATXFER_NULL_TECH) */
705 #if defined(ATXFER_NULL_TECH)
708 * \brief Set the channel name to something unique.
710 * \param chan Channel to change name.
714 static void set_new_chan_name(struct ast_channel *chan)
716 static int seq_num_last;
722 /* Create the new channel name string. */
723 ast_channel_lock(chan);
724 seq_num = ast_atomic_fetchadd_int(&seq_num_last, +1);
725 len = snprintf(dummy, sizeof(dummy), "%s<XFER_%x>", ast_channel_name(chan), seq_num) + 1;
726 chan_name = alloca(len);
727 snprintf(chan_name, len, "%s<XFER_%x>", ast_channel_name(chan), seq_num);
728 ast_channel_unlock(chan);
730 ast_change_name(chan, chan_name);
732 #endif /* defined(ATXFER_NULL_TECH) */
734 static void *dial_features_duplicate(void *data)
736 struct ast_dial_features *df = data, *df_copy;
738 if (!(df_copy = ast_calloc(1, sizeof(*df)))) {
742 memcpy(df_copy, df, sizeof(*df));
747 static void dial_features_destroy(void *data)
749 struct ast_dial_features *df = data;
755 static const struct ast_datastore_info dial_features_info = {
756 .type = "dial-features",
757 .destroy = dial_features_destroy,
758 .duplicate = dial_features_duplicate,
761 /* Forward declarations */
762 static struct ast_parkinglot *parkinglot_addref(struct ast_parkinglot *parkinglot);
763 static void parkinglot_unref(struct ast_parkinglot *parkinglot);
764 static struct ast_parkinglot *find_parkinglot(const char *name);
765 static struct ast_parkinglot *create_parkinglot(const char *name);
766 static struct ast_parkinglot *copy_parkinglot(const char *name, const struct ast_parkinglot *parkinglot);
767 static int parkinglot_activate(struct ast_parkinglot *parkinglot);
768 static int play_message_on_chan(struct ast_channel *play_to, struct ast_channel *other, const char *msg, const char *audiofile);
772 * \brief Get the parking extension if it exists.
774 * \param exten_str Parking extension to see if exists.
775 * \param chan Channel to autoservice while looking for exten. (Could be NULL)
776 * \param context Parking context to look in for exten.
778 * \retval exten on success.
779 * \retval NULL on error or exten does not exist.
781 static struct ast_exten *get_parking_exten(const char *exten_str, struct ast_channel *chan, const char *context)
783 struct ast_exten *exten;
784 struct pbx_find_info q = { .stacklen = 0 }; /* the rest is reset in pbx_find_extension */
785 const char *app_at_exten;
787 exten = pbx_find_extension(chan, NULL, &q, context, exten_str, 1, NULL, NULL,
793 app_at_exten = ast_get_extension_app(exten);
794 if (!app_at_exten || strcasecmp(parkcall, app_at_exten)) {
801 int ast_parking_ext_valid(const char *exten_str, struct ast_channel *chan, const char *context)
803 return get_parking_exten(exten_str, chan, context) ? 1 : 0;
806 const char *ast_pickup_ext(void)
811 struct ast_bridge_thread_obj
813 struct ast_bridge_config bconfig;
814 struct ast_channel *chan;
815 struct ast_channel *peer;
816 unsigned int return_to_pbx:1;
819 static int parkinglot_hash_cb(const void *obj, const int flags)
821 const struct ast_parkinglot *parkinglot = obj;
823 return ast_str_case_hash(parkinglot->name);
826 static int parkinglot_cmp_cb(void *obj, void *arg, int flags)
828 struct ast_parkinglot *parkinglot = obj;
829 struct ast_parkinglot *parkinglot2 = arg;
831 return !strcasecmp(parkinglot->name, parkinglot2->name) ? CMP_MATCH | CMP_STOP : 0;
835 * \brief store context, extension and priority
836 * \param chan, context, ext, pri
838 static void set_c_e_p(struct ast_channel *chan, const char *context, const char *ext, int pri)
840 ast_copy_string(chan->context, context, sizeof(chan->context));
841 ast_copy_string(chan->exten, ext, sizeof(chan->exten));
842 chan->priority = pri;
846 * \brief Check goto on transfer
849 * Check if channel has 'GOTO_ON_BLINDXFR' set, if not exit.
850 * When found make sure the types are compatible. Check if channel is valid
851 * if so start the new channel else hangup the call.
853 static void check_goto_on_transfer(struct ast_channel *chan)
855 struct ast_channel *xferchan;
857 char *goto_on_transfer;
860 ast_channel_lock(chan);
861 val = pbx_builtin_getvar_helper(chan, "GOTO_ON_BLINDXFR");
862 if (ast_strlen_zero(val)) {
863 ast_channel_unlock(chan);
866 goto_on_transfer = ast_strdupa(val);
867 ast_channel_unlock(chan);
869 ast_debug(1, "Attempting GOTO_ON_BLINDXFR=%s for %s.\n", val, ast_channel_name(chan));
871 xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", ast_channel_linkedid(chan), 0,
872 "%s", ast_channel_name(chan));
877 /* Make formats okay */
878 xferchan->readformat = chan->readformat;
879 xferchan->writeformat = chan->writeformat;
881 if (ast_channel_masquerade(xferchan, chan)) {
882 /* Failed to setup masquerade. */
883 ast_hangup(xferchan);
887 for (x = goto_on_transfer; *x; ++x) {
892 ast_parseable_goto(xferchan, goto_on_transfer);
893 xferchan->_state = AST_STATE_UP;
894 ast_clear_flag(xferchan, AST_FLAGS_ALL);
895 ast_channel_clear_softhangup(xferchan, AST_SOFTHANGUP_ALL);
897 if (ast_do_masquerade(xferchan) || ast_pbx_start(xferchan)) {
898 /* Failed to do masquerade or could not start PBX. */
899 ast_hangup(xferchan);
903 static struct ast_channel *feature_request_and_dial(struct ast_channel *caller,
904 const char *caller_name, struct ast_channel *requestor,
905 struct ast_channel *transferee, const char *type, struct ast_format_cap *cap, const char *addr,
906 int timeout, int *outstate, const char *language);
909 * \brief bridge the call
910 * \param data thread bridge.
912 * Set Last Data for respective channels, reset cdr for channels
913 * bridge call, check if we're going back to dialplan
914 * if not hangup both legs of the call
916 static void *bridge_call_thread(void *data)
918 struct ast_bridge_thread_obj *tobj = data;
921 tobj->chan->appl = !tobj->return_to_pbx ? "Transferred Call" : "ManagerBridge";
922 tobj->chan->data = ast_channel_name(tobj->peer);
923 tobj->peer->appl = !tobj->return_to_pbx ? "Transferred Call" : "ManagerBridge";
924 tobj->peer->data = ast_channel_name(tobj->chan);
926 ast_bridge_call(tobj->peer, tobj->chan, &tobj->bconfig);
928 if (tobj->return_to_pbx) {
929 if (!ast_check_hangup(tobj->peer)) {
930 ast_log(LOG_VERBOSE, "putting peer %s into PBX again\n", ast_channel_name(tobj->peer));
931 res = ast_pbx_start(tobj->peer);
932 if (res != AST_PBX_SUCCESS)
933 ast_log(LOG_WARNING, "FAILED continuing PBX on peer %s\n", ast_channel_name(tobj->peer));
935 ast_hangup(tobj->peer);
936 if (!ast_check_hangup(tobj->chan)) {
937 ast_log(LOG_VERBOSE, "putting chan %s into PBX again\n", ast_channel_name(tobj->chan));
938 res = ast_pbx_start(tobj->chan);
939 if (res != AST_PBX_SUCCESS)
940 ast_log(LOG_WARNING, "FAILED continuing PBX on chan %s\n", ast_channel_name(tobj->chan));
942 ast_hangup(tobj->chan);
944 ast_hangup(tobj->chan);
945 ast_hangup(tobj->peer);
954 * \brief create thread for the parked call
957 * Create thread and attributes, call bridge_call_thread
959 static void bridge_call_thread_launch(void *data)
963 struct sched_param sched;
965 pthread_attr_init(&attr);
966 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
967 ast_pthread_create(&thread, &attr, bridge_call_thread, data);
968 pthread_attr_destroy(&attr);
969 memset(&sched, 0, sizeof(sched));
970 pthread_setschedparam(thread, SCHED_RR, &sched);
974 * \brief Announce call parking by ADSI
976 * \param parkingexten .
977 * Create message to show for ADSI, display message.
978 * \retval 0 on success.
979 * \retval -1 on failure.
981 static int adsi_announce_park(struct ast_channel *chan, char *parkingexten)
984 int justify[5] = {ADSI_JUST_CENT, ADSI_JUST_CENT, ADSI_JUST_CENT, ADSI_JUST_CENT};
986 char *message[5] = {NULL, NULL, NULL, NULL, NULL};
988 snprintf(tmp, sizeof(tmp), "Parked on %s", parkingexten);
990 res = ast_adsi_load_session(chan, NULL, 0, 1);
993 return ast_adsi_print(chan, message, justify, 1);
997 * \brief Find parking lot name from channel
998 * \note Channel needs to be locked while the returned string is in use.
1000 static const char *findparkinglotname(struct ast_channel *chan)
1004 /* The channel variable overrides everything */
1005 name = pbx_builtin_getvar_helper(chan, "PARKINGLOT");
1006 if (!name && !ast_strlen_zero(ast_channel_parkinglot(chan))) {
1007 /* Use the channel's parking lot. */
1008 name = ast_channel_parkinglot(chan);
1013 /*! \brief Notify metermaids that we've changed an extension */
1014 static void notify_metermaids(const char *exten, char *context, enum ast_device_state state)
1016 ast_debug(4, "Notification of state change to metermaids %s@%s\n to state '%s'",
1017 exten, context, ast_devstate2str(state));
1019 ast_devstate_changed(state, "park:%s@%s", exten, context);
1022 /*! \brief metermaids callback from devicestate.c */
1023 static enum ast_device_state metermaidstate(const char *data)
1028 context = ast_strdupa(data);
1030 exten = strsep(&context, "@");
1032 return AST_DEVICE_INVALID;
1034 ast_debug(4, "Checking state of exten %s in context %s\n", exten, context);
1036 if (!ast_exists_extension(NULL, context, exten, 1, NULL))
1037 return AST_DEVICE_NOT_INUSE;
1039 return AST_DEVICE_INUSE;
1042 /*! Options to pass to park_call_full */
1043 enum ast_park_call_options {
1044 /*! Provide ringing to the parked caller instead of music on hold */
1045 AST_PARK_OPT_RINGING = (1 << 0),
1046 /*! Randomly choose a parking spot for the caller instead of choosing
1047 * the first one that is available. */
1048 AST_PARK_OPT_RANDOMIZE = (1 << 1),
1049 /*! Do not announce the parking number */
1050 AST_PARK_OPT_SILENCE = (1 << 2),
1053 /*! Optional additional parking options when parking a call. */
1054 struct ast_park_call_args {
1055 /*! How long to wait in the parking lot before the call gets sent back
1056 * to the specified return extension (or a best guess at where it came
1057 * from if not explicitly specified). */
1059 /*! An output parameter to store the parking space where the parked caller
1062 const char *orig_chan_name;
1063 const char *return_con;
1064 const char *return_ext;
1067 /*! Parked user that has already obtained a parking space */
1068 struct parkeduser *pu;
1069 /*! \brief Parkinglot to be parked in */
1070 struct ast_parkinglot *parkinglot;
1075 * \brief Create a dynamic parking lot.
1077 * \param name Dynamic parking lot name to create.
1078 * \param chan Channel to get dynamic parking lot parameters.
1080 * \retval parkinglot on success.
1081 * \retval NULL on error.
1083 static struct ast_parkinglot *create_dynamic_parkinglot(const char *name, struct ast_channel *chan)
1085 const char *dyn_context;
1086 const char *dyn_exten;
1087 const char *dyn_range;
1088 const char *template_name;
1089 struct ast_parkinglot *template_parkinglot = NULL;
1090 struct ast_parkinglot *parkinglot;
1094 ast_channel_lock(chan);
1095 template_name = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGDYNAMIC"), ""));
1096 dyn_context = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGDYNCONTEXT"), ""));
1097 dyn_exten = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGDYNEXTEN"), ""));
1098 dyn_range = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGDYNPOS"), ""));
1099 ast_channel_unlock(chan);
1101 if (!ast_strlen_zero(template_name)) {
1102 template_parkinglot = find_parkinglot(template_name);
1103 if (!template_parkinglot) {
1104 ast_debug(1, "PARKINGDYNAMIC lot %s does not exist.\n",
1106 } else if (template_parkinglot->cfg.is_invalid) {
1107 ast_debug(1, "PARKINGDYNAMIC lot %s has invalid config.\n",
1109 parkinglot_unref(template_parkinglot);
1110 template_parkinglot = NULL;
1113 if (!template_parkinglot) {
1114 template_parkinglot = parkinglot_addref(default_parkinglot);
1115 ast_debug(1, "Using default parking lot for template\n");
1118 parkinglot = copy_parkinglot(name, template_parkinglot);
1120 ast_log(LOG_ERROR, "Could not build dynamic parking lot!\n");
1122 /* Configure the dynamic parking lot. */
1123 if (!ast_strlen_zero(dyn_context)) {
1124 ast_copy_string(parkinglot->cfg.parking_con, dyn_context,
1125 sizeof(parkinglot->cfg.parking_con));
1127 if (!ast_strlen_zero(dyn_exten)) {
1128 ast_copy_string(parkinglot->cfg.parkext, dyn_exten,
1129 sizeof(parkinglot->cfg.parkext));
1131 if (!ast_strlen_zero(dyn_range)) {
1132 if (sscanf(dyn_range, "%30d-%30d", &dyn_start, &dyn_end) != 2) {
1133 ast_log(LOG_WARNING,
1134 "Format for parking positions is a-b, where a and b are numbers\n");
1135 } else if (dyn_end < dyn_start || dyn_start <= 0 || dyn_end <= 0) {
1136 ast_log(LOG_WARNING,
1137 "Format for parking positions is a-b, where a <= b\n");
1139 parkinglot->cfg.parking_start = dyn_start;
1140 parkinglot->cfg.parking_stop = dyn_end;
1145 * Sanity check for dynamic parking lot configuration.
1147 * XXX It may be desirable to instead check if the dynamic
1148 * parking lot overlaps any existing lots like what is done for
1151 if (!strcmp(parkinglot->cfg.parking_con, template_parkinglot->cfg.parking_con)) {
1152 if (!strcmp(parkinglot->cfg.parkext, template_parkinglot->cfg.parkext)
1153 && parkinglot->cfg.parkext_exclusive) {
1154 ast_log(LOG_WARNING,
1155 "Parking lot '%s' conflicts with template parking lot '%s'!\n"
1156 "Change either PARKINGDYNCONTEXT or PARKINGDYNEXTEN.\n",
1157 parkinglot->name, template_parkinglot->name);
1159 if ((template_parkinglot->cfg.parking_start <= parkinglot->cfg.parking_start
1160 && parkinglot->cfg.parking_start <= template_parkinglot->cfg.parking_stop)
1161 || (template_parkinglot->cfg.parking_start <= parkinglot->cfg.parking_stop
1162 && parkinglot->cfg.parking_stop <= template_parkinglot->cfg.parking_stop)
1163 || (parkinglot->cfg.parking_start < template_parkinglot->cfg.parking_start
1164 && template_parkinglot->cfg.parking_stop < parkinglot->cfg.parking_stop)) {
1165 ast_log(LOG_WARNING,
1166 "Parking lot '%s' parking spaces overlap template parking lot '%s'!\n"
1167 "Change PARKINGDYNPOS.\n",
1168 parkinglot->name, template_parkinglot->name);
1172 parkinglot_activate(parkinglot);
1173 ao2_link(parkinglots, parkinglot);
1175 parkinglot_unref(template_parkinglot);
1182 * \brief Abort parking a call that has not completed parking yet.
1184 * \param pu Parked user item to clean up.
1186 * \note The parking lot parkings list is locked on entry.
1190 static void park_space_abort(struct parkeduser *pu)
1192 struct ast_parkinglot *parkinglot;
1194 parkinglot = pu->parkinglot;
1196 /* Put back the parking space just allocated. */
1197 --parkinglot->next_parking_space;
1199 AST_LIST_REMOVE(&parkinglot->parkings, pu, list);
1201 AST_LIST_UNLOCK(&parkinglot->parkings);
1202 parkinglot_unref(parkinglot);
1208 * \brief Reserve a parking space in a parking lot for a call being parked.
1210 * \param park_me Channel being parked.
1211 * \param parker Channel parking the call.
1212 * \param args Optional additional parking options when parking a call.
1214 * \return Parked call descriptor or NULL if failed.
1215 * \note The parking lot list is locked if successful.
1217 static struct parkeduser *park_space_reserve(struct ast_channel *park_me, struct ast_channel *parker, struct ast_park_call_args *args)
1219 struct parkeduser *pu;
1221 int parking_space = -1;
1222 const char *parkinglotname;
1223 const char *parkingexten;
1224 struct parkeduser *cur;
1225 struct ast_parkinglot *parkinglot = NULL;
1227 if (args->parkinglot) {
1228 parkinglot = parkinglot_addref(args->parkinglot);
1229 parkinglotname = parkinglot->name;
1232 parkinglotname = findparkinglotname(parker);
1233 } else { /* parker was NULL, check park_me (ParkAndAnnounce / res_agi) */
1234 parkinglotname = findparkinglotname(park_me);
1236 if (!ast_strlen_zero(parkinglotname)) {
1237 parkinglot = find_parkinglot(parkinglotname);
1239 /* Parking lot is not specified, so use the default parking lot. */
1240 ast_debug(4, "This could be an indication channel driver needs updating, using default lot.\n");
1241 parkinglot = parkinglot_addref(default_parkinglot);
1245 /* Dynamically create parkinglot */
1246 if (!parkinglot && parkeddynamic && !ast_strlen_zero(parkinglotname)) {
1247 parkinglot = create_dynamic_parkinglot(parkinglotname, park_me);
1251 ast_log(LOG_WARNING, "Parking lot not available to park %s.\n", ast_channel_name(park_me));
1255 ast_debug(1, "Parking lot: %s\n", parkinglot->name);
1256 if (parkinglot->disabled || parkinglot->cfg.is_invalid) {
1257 ast_log(LOG_WARNING, "Parking lot %s is not in a useable state.\n",
1259 parkinglot_unref(parkinglot);
1263 /* Allocate memory for parking data */
1264 if (!(pu = ast_calloc(1, sizeof(*pu)))) {
1265 parkinglot_unref(parkinglot);
1269 /* Lock parking list */
1270 AST_LIST_LOCK(&parkinglot->parkings);
1272 /* Check for channel variable PARKINGEXTEN */
1273 parkingexten = ast_strdupa(S_OR(pbx_builtin_getvar_helper(park_me, "PARKINGEXTEN"), ""));
1274 if (!ast_strlen_zero(parkingexten)) {
1276 * \note The API forces us to specify a numeric parking slot, even
1277 * though the architecture would tend to support non-numeric extensions
1278 * (as are possible with SIP, for example). Hence, we enforce that
1279 * limitation here. If extout was not numeric, we could permit
1280 * arbitrary non-numeric extensions.
1282 if (sscanf(parkingexten, "%30d", &parking_space) != 1 || parking_space <= 0) {
1283 ast_log(LOG_WARNING, "PARKINGEXTEN='%s' is not a valid parking space.\n",
1285 AST_LIST_UNLOCK(&parkinglot->parkings);
1286 parkinglot_unref(parkinglot);
1291 if (parking_space < parkinglot->cfg.parking_start
1292 || parkinglot->cfg.parking_stop < parking_space) {
1294 * Cannot allow park because parking lots are not setup for
1295 * spaces outside of the lot. (Things like dialplan hints don't
1296 * exist for outside lot space.)
1298 ast_log(LOG_WARNING, "PARKINGEXTEN=%d is not in %s (%d-%d).\n",
1299 parking_space, parkinglot->name, parkinglot->cfg.parking_start,
1300 parkinglot->cfg.parking_stop);
1301 AST_LIST_UNLOCK(&parkinglot->parkings);
1302 parkinglot_unref(parkinglot);
1307 /* Check if requested parking space is in use. */
1308 AST_LIST_TRAVERSE(&parkinglot->parkings, cur, list) {
1309 if (cur->parkingnum == parking_space) {
1310 ast_log(LOG_WARNING, "PARKINGEXTEN=%d is already in use in %s\n",
1311 parking_space, parkinglot->name);
1312 AST_LIST_UNLOCK(&parkinglot->parkings);
1313 parkinglot_unref(parkinglot);
1319 /* PARKINGEXTEN is empty, so find a usable extension in the lot to park the call */
1320 int start; /* The first slot we look in the parkinglot. It can be randomized. */
1321 int start_checked = 0; /* flag raised once the first slot is checked */
1323 /* If using randomize mode, set start to random position on parking range */
1324 if (ast_test_flag(args, AST_PARK_OPT_RANDOMIZE)) {
1325 start = ast_random() % (parkinglot->cfg.parking_stop - parkinglot->cfg.parking_start + 1);
1326 start += parkinglot->cfg.parking_start;
1327 } else if (parkinglot->cfg.parkfindnext
1328 && parkinglot->cfg.parking_start <= parkinglot->next_parking_space
1329 && parkinglot->next_parking_space <= parkinglot->cfg.parking_stop) {
1330 /* Start looking with the next parking space in the lot. */
1331 start = parkinglot->next_parking_space;
1333 /* Otherwise, just set it to the start position. */
1334 start = parkinglot->cfg.parking_start;
1337 /* free parking extension linear search: O(n^2) */
1338 for (i = start; ; i++) {
1339 /* If we are past the end, wrap around to the first parking slot*/
1340 if (i == parkinglot->cfg.parking_stop + 1) {
1341 i = parkinglot->cfg.parking_start;
1345 /* At this point, if start_checked, we've exhausted all the possible slots. */
1346 if (start_checked) {
1353 /* Search the list of parked calls already in use for i. If we find it, it's in use. */
1354 AST_LIST_TRAVERSE(&parkinglot->parkings, cur, list) {
1355 if (cur->parkingnum == i) {
1360 /* We found a parking space. */
1365 if (parking_space == -1) {
1366 /* We did not find a parking space. Lot is full. */
1367 ast_log(LOG_WARNING, "No more parking spaces in %s\n", parkinglot->name);
1368 AST_LIST_UNLOCK(&parkinglot->parkings);
1369 parkinglot_unref(parkinglot);
1375 /* Prepare for next parking space search. */
1376 parkinglot->next_parking_space = parking_space + 1;
1378 snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", parking_space);
1379 pu->notquiteyet = 1;
1380 pu->parkingnum = parking_space;
1381 pu->parkinglot = parkinglot;
1382 AST_LIST_INSERT_TAIL(&parkinglot->parkings, pu, list);
1388 static int park_call_full(struct ast_channel *chan, struct ast_channel *peer, struct ast_park_call_args *args)
1390 struct parkeduser *pu = args->pu;
1391 const char *event_from;
1392 char app_data[AST_MAX_EXTENSION + AST_MAX_CONTEXT];
1395 args->pu = pu = park_space_reserve(chan, peer, args);
1401 chan->appl = "Parked Call";
1406 /* Put the parked channel on hold if we have two different channels */
1408 if (ast_test_flag(args, AST_PARK_OPT_RINGING)) {
1409 pu->hold_method = AST_CONTROL_RINGING;
1410 ast_indicate(pu->chan, AST_CONTROL_RINGING);
1412 pu->hold_method = AST_CONTROL_HOLD;
1413 ast_indicate_data(pu->chan, AST_CONTROL_HOLD,
1414 S_OR(pu->parkinglot->cfg.mohclass, NULL),
1415 !ast_strlen_zero(pu->parkinglot->cfg.mohclass) ? strlen(pu->parkinglot->cfg.mohclass) + 1 : 0);
1419 pu->start = ast_tvnow();
1420 pu->parkingtime = (args->timeout > 0) ? args->timeout : pu->parkinglot->cfg.parkingtime;
1422 *(args->extout) = pu->parkingnum;
1426 * This is so ugly that it hurts, but implementing
1427 * get_base_channel() on local channels could have ugly side
1428 * effects. We could have
1429 * transferer<->local,1<->local,2<->parking and we need the
1430 * callback name to be that of transferer. Since local,1/2 have
1431 * the same name we can be tricky and just grab the bridged
1432 * channel from the other side of the local.
1434 if (!strcasecmp(peer->tech->type, "Local")) {
1435 struct ast_channel *tmpchan, *base_peer;
1436 char other_side[AST_CHANNEL_NAME];
1439 ast_copy_string(other_side, S_OR(args->orig_chan_name, ast_channel_name(peer)), sizeof(other_side));
1440 if ((c = strrchr(other_side, ';'))) {
1443 if ((tmpchan = ast_channel_get_by_name(other_side))) {
1444 ast_channel_lock(tmpchan);
1445 if ((base_peer = ast_bridged_channel(tmpchan))) {
1446 ast_copy_string(pu->peername, ast_channel_name(base_peer), sizeof(pu->peername));
1448 ast_channel_unlock(tmpchan);
1449 tmpchan = ast_channel_unref(tmpchan);
1452 ast_copy_string(pu->peername, S_OR(args->orig_chan_name, ast_channel_name(peer)), sizeof(pu->peername));
1457 * Remember what had been dialed, so that if the parking
1458 * expires, we try to come back to the same place
1460 pu->options_specified = (!ast_strlen_zero(args->return_con) || !ast_strlen_zero(args->return_ext) || args->return_pri);
1463 * If extension has options specified, they override all other
1464 * possibilities such as the returntoorigin flag and transferred
1465 * context. Information on extension options is lost here, so
1468 ast_copy_string(pu->context,
1469 S_OR(args->return_con, S_OR(chan->macrocontext, chan->context)),
1470 sizeof(pu->context));
1471 ast_copy_string(pu->exten,
1472 S_OR(args->return_ext, S_OR(chan->macroexten, chan->exten)),
1474 pu->priority = args->return_pri ? args->return_pri :
1475 (chan->macropriority ? chan->macropriority : chan->priority);
1478 * If parking a channel directly, don't quite yet get parking
1479 * running on it. All parking lot entries are put into the
1480 * parking lot with notquiteyet on.
1483 pu->notquiteyet = 0;
1486 /* Wake up the (presumably select()ing) thread */
1487 pthread_kill(parking_thread, SIGURG);
1488 ast_verb(2, "Parked %s on %d (lot %s). Will timeout back to extension [%s] %s, %d in %d seconds\n",
1489 ast_channel_name(pu->chan), pu->parkingnum, pu->parkinglot->name,
1490 pu->context, pu->exten, pu->priority, (pu->parkingtime / 1000));
1492 ast_cel_report_event(pu->chan, AST_CEL_PARK_START, NULL, pu->parkinglot->name, peer);
1495 event_from = ast_channel_name(peer);
1497 event_from = pbx_builtin_getvar_helper(chan, "BLINDTRANSFER");
1500 ast_manager_event(pu->chan, EVENT_FLAG_CALL, "ParkedCall",
1503 "Parkinglot: %s\r\n"
1506 "CallerIDNum: %s\r\n"
1507 "CallerIDName: %s\r\n"
1508 "ConnectedLineNum: %s\r\n"
1509 "ConnectedLineName: %s\r\n"
1511 pu->parkingexten, ast_channel_name(pu->chan), pu->parkinglot->name, event_from ? event_from : "",
1512 (long)pu->start.tv_sec + (long)(pu->parkingtime/1000) - (long)time(NULL),
1513 S_COR(pu->chan->caller.id.number.valid, pu->chan->caller.id.number.str, "<unknown>"),
1514 S_COR(pu->chan->caller.id.name.valid, pu->chan->caller.id.name.str, "<unknown>"),
1515 S_COR(pu->chan->connected.id.number.valid, pu->chan->connected.id.number.str, "<unknown>"),
1516 S_COR(pu->chan->connected.id.name.valid, pu->chan->connected.id.name.str, "<unknown>"),
1517 ast_channel_uniqueid(pu->chan)
1520 if (peer && adsipark && ast_adsi_available(peer)) {
1521 adsi_announce_park(peer, pu->parkingexten); /* Only supports parking numbers */
1522 ast_adsi_unload_session(peer);
1525 snprintf(app_data, sizeof(app_data), "%s,%s", pu->parkingexten,
1526 pu->parkinglot->name);
1527 if (ast_add_extension(pu->parkinglot->cfg.parking_con, 1, pu->parkingexten, 1,
1528 NULL, NULL, parkedcall, ast_strdup(app_data), ast_free_ptr, registrar)) {
1529 ast_log(LOG_ERROR, "Could not create parked call exten: %s@%s\n",
1530 pu->parkingexten, pu->parkinglot->cfg.parking_con);
1532 notify_metermaids(pu->parkingexten, pu->parkinglot->cfg.parking_con, AST_DEVICE_INUSE);
1535 AST_LIST_UNLOCK(&pu->parkinglot->parkings);
1537 /* Only say number if it's a number and the channel hasn't been masqueraded away */
1538 if (peer && !ast_test_flag(args, AST_PARK_OPT_SILENCE)
1539 && (ast_strlen_zero(args->orig_chan_name) || !strcasecmp(ast_channel_name(peer), args->orig_chan_name))) {
1541 * If a channel is masqueraded into peer while playing back the
1542 * parking space number do not continue playing it back. This
1543 * is the case if an attended transfer occurs.
1545 ast_set_flag(peer, AST_FLAG_MASQ_NOSTREAM);
1546 /* Tell the peer channel the number of the parking space */
1547 ast_say_digits(peer, pu->parkingnum, "", ast_channel_language(peer));
1548 ast_clear_flag(peer, AST_FLAG_MASQ_NOSTREAM);
1550 if (peer == chan) { /* pu->notquiteyet = 1 */
1551 /* Wake up parking thread if we're really done */
1552 pu->hold_method = AST_CONTROL_HOLD;
1553 ast_indicate_data(pu->chan, AST_CONTROL_HOLD,
1554 S_OR(pu->parkinglot->cfg.mohclass, NULL),
1555 !ast_strlen_zero(pu->parkinglot->cfg.mohclass) ? strlen(pu->parkinglot->cfg.mohclass) + 1 : 0);
1556 pu->notquiteyet = 0;
1557 pthread_kill(parking_thread, SIGURG);
1562 int ast_park_call_exten(struct ast_channel *park_me, struct ast_channel *parker, const char *park_exten, const char *park_context, int timeout, int *extout)
1566 const char *app_data;
1567 struct ast_exten *exten;
1568 struct park_app_args app_args;
1569 struct ast_park_call_args args = {
1574 if (!park_exten || !park_context) {
1575 return park_call_full(park_me, parker, &args);
1579 * Determiine if the specified park extension has an exclusive
1580 * parking lot to use.
1582 if (parker && parker != park_me) {
1583 ast_autoservice_start(park_me);
1585 exten = get_parking_exten(park_exten, parker, park_context);
1587 app_data = ast_get_extension_app_data(exten);
1591 parse = ast_strdupa(app_data);
1592 AST_STANDARD_APP_ARGS(app_args, parse);
1594 if (!ast_strlen_zero(app_args.pl_name)) {
1595 /* Find the specified exclusive parking lot */
1596 args.parkinglot = find_parkinglot(app_args.pl_name);
1597 if (!args.parkinglot && parkeddynamic) {
1598 args.parkinglot = create_dynamic_parkinglot(app_args.pl_name, park_me);
1602 if (parker && parker != park_me) {
1603 ast_autoservice_stop(park_me);
1606 res = park_call_full(park_me, parker, &args);
1607 if (args.parkinglot) {
1608 parkinglot_unref(args.parkinglot);
1613 int ast_park_call(struct ast_channel *park_me, struct ast_channel *parker, int timeout, const char *park_exten, int *extout)
1615 struct ast_park_call_args args = {
1620 return park_call_full(park_me, parker, &args);
1624 * \brief Park call via masqueraded channel and announce parking spot on peer channel.
1626 * \param rchan the real channel to be parked
1627 * \param peer the channel to have the parking read to.
1628 * \param args Additional parking options when parking a call.
1630 * \retval 0 on success.
1631 * \retval -1 on failure.
1633 static int masq_park_call(struct ast_channel *rchan, struct ast_channel *peer, struct ast_park_call_args *args)
1635 struct ast_channel *chan;
1637 /* Make a new, channel that we'll use to masquerade in the real one */
1638 chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, ast_channel_accountcode(rchan), rchan->exten,
1639 rchan->context, ast_channel_linkedid(rchan), rchan->amaflags, "Parked/%s", ast_channel_name(rchan));
1641 ast_log(LOG_WARNING, "Unable to create parked channel\n");
1642 if (!ast_test_flag(args, AST_PARK_OPT_SILENCE)) {
1643 if (peer == rchan) {
1644 /* Only have one channel to worry about. */
1645 ast_stream_and_wait(peer, "pbx-parkingfailed", "");
1647 /* Have two different channels to worry about. */
1648 play_message_on_chan(peer, rchan, "failure message", "pbx-parkingfailed");
1654 args->pu = park_space_reserve(rchan, peer, args);
1657 if (!ast_test_flag(args, AST_PARK_OPT_SILENCE)) {
1658 if (peer == rchan) {
1659 /* Only have one channel to worry about. */
1660 ast_stream_and_wait(peer, "pbx-parkingfailed", "");
1662 /* Have two different channels to worry about. */
1663 play_message_on_chan(peer, rchan, "failure message", "pbx-parkingfailed");
1669 /* Make formats okay */
1670 chan->readformat = rchan->readformat;
1671 chan->writeformat = rchan->writeformat;
1673 if (ast_channel_masquerade(chan, rchan)) {
1674 park_space_abort(args->pu);
1677 if (!ast_test_flag(args, AST_PARK_OPT_SILENCE)) {
1678 if (peer == rchan) {
1679 /* Only have one channel to worry about. */
1680 ast_stream_and_wait(peer, "pbx-parkingfailed", "");
1682 /* Have two different channels to worry about. */
1683 play_message_on_chan(peer, rchan, "failure message", "pbx-parkingfailed");
1689 /* Setup the extensions and such */
1690 set_c_e_p(chan, rchan->context, rchan->exten, rchan->priority);
1692 /* Setup the macro extension and such */
1693 ast_copy_string(chan->macrocontext,rchan->macrocontext,sizeof(chan->macrocontext));
1694 ast_copy_string(chan->macroexten,rchan->macroexten,sizeof(chan->macroexten));
1695 chan->macropriority = rchan->macropriority;
1697 /* Manually do the masquerade to make sure it is complete. */
1698 ast_do_masquerade(chan);
1700 if (peer == rchan) {
1704 /* parking space reserved, return code check unnecessary */
1705 park_call_full(chan, peer, args);
1710 int ast_masq_park_call_exten(struct ast_channel *park_me, struct ast_channel *parker, const char *park_exten, const char *park_context, int timeout, int *extout)
1714 const char *app_data;
1715 struct ast_exten *exten;
1716 struct park_app_args app_args;
1717 struct ast_park_call_args args = {
1723 args.orig_chan_name = ast_strdupa(ast_channel_name(parker));
1725 if (!park_exten || !park_context) {
1726 return masq_park_call(park_me, parker, &args);
1730 * Determiine if the specified park extension has an exclusive
1731 * parking lot to use.
1733 if (parker && parker != park_me) {
1734 ast_autoservice_start(park_me);
1736 exten = get_parking_exten(park_exten, parker, park_context);
1738 app_data = ast_get_extension_app_data(exten);
1742 parse = ast_strdupa(app_data);
1743 AST_STANDARD_APP_ARGS(app_args, parse);
1745 if (!ast_strlen_zero(app_args.pl_name)) {
1746 /* Find the specified exclusive parking lot */
1747 args.parkinglot = find_parkinglot(app_args.pl_name);
1748 if (!args.parkinglot && parkeddynamic) {
1749 args.parkinglot = create_dynamic_parkinglot(app_args.pl_name, park_me);
1753 if (parker && parker != park_me) {
1754 ast_autoservice_stop(park_me);
1757 res = masq_park_call(park_me, parker, &args);
1758 if (args.parkinglot) {
1759 parkinglot_unref(args.parkinglot);
1764 int ast_masq_park_call(struct ast_channel *rchan, struct ast_channel *peer, int timeout, int *extout)
1766 struct ast_park_call_args args = {
1772 args.orig_chan_name = ast_strdupa(ast_channel_name(peer));
1774 return masq_park_call(rchan, peer, &args);
1777 static int finishup(struct ast_channel *chan)
1779 ast_indicate(chan, AST_CONTROL_UNHOLD);
1781 return ast_autoservice_stop(chan);
1786 * \brief Builtin transfer park call helper.
1788 * \param park_me Channel to be parked.
1789 * \param parker Channel parking the call.
1790 * \param park_exten Parking lot dialplan access ramp extension.
1792 * \note Assumes park_me is on hold and in autoservice.
1794 * \retval -1 on successful park.
1795 * \retval -1 on park_me hangup.
1796 * \retval AST_FEATURE_RETURN_SUCCESS on error to keep the bridge connected.
1798 static int xfer_park_call_helper(struct ast_channel *park_me, struct ast_channel *parker, struct ast_exten *park_exten)
1801 const char *app_data;
1802 const char *pl_name;
1803 struct ast_park_call_args args = { 0, };
1804 struct park_app_args app_args;
1807 app_data = ast_get_extension_app_data(park_exten);
1811 parse = ast_strdupa(app_data);
1812 AST_STANDARD_APP_ARGS(app_args, parse);
1814 /* Find the parking lot */
1815 if (!ast_strlen_zero(app_args.pl_name)) {
1816 pl_name = app_args.pl_name;
1818 pl_name = findparkinglotname(parker);
1820 if (ast_strlen_zero(pl_name)) {
1821 /* Parking lot is not specified, so use the default parking lot. */
1822 args.parkinglot = parkinglot_addref(default_parkinglot);
1824 args.parkinglot = find_parkinglot(pl_name);
1825 if (!args.parkinglot && parkeddynamic) {
1826 args.parkinglot = create_dynamic_parkinglot(pl_name, park_me);
1830 if (args.parkinglot) {
1832 res = finishup(park_me);
1834 /* park_me hungup on us. */
1835 parkinglot_unref(args.parkinglot);
1838 res = masq_park_call(park_me, parker, &args);
1839 parkinglot_unref(args.parkinglot);
1841 /* Parking failed because parking lot does not exist. */
1842 if (!ast_test_flag(&args, AST_PARK_OPT_SILENCE)) {
1843 ast_stream_and_wait(parker, "pbx-parkingfailed", "");
1849 return res ? AST_FEATURE_RETURN_SUCCESS : -1;
1853 * \brief set caller and callee according to the direction
1854 * \param caller, callee, peer, chan, sense
1856 * Detect who triggered feature and set callee/caller variables accordingly
1858 static void set_peers(struct ast_channel **caller, struct ast_channel **callee,
1859 struct ast_channel *peer, struct ast_channel *chan, int sense)
1861 if (sense == FEATURE_SENSE_PEER) {
1871 * \brief support routing for one touch call parking
1872 * \param chan channel parking call
1873 * \param peer channel to be parked
1874 * \param config unsed
1875 * \param code unused
1876 * \param sense feature options
1877 * \param data unused
1879 * \retval -1 on successful park.
1880 * \retval -1 on chan hangup.
1881 * \retval AST_FEATURE_RETURN_SUCCESS on error to keep the bridge connected.
1883 static int builtin_parkcall(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
1885 struct ast_channel *parker;
1886 struct ast_channel *parkee;
1887 struct ast_park_call_args args = { 0, };
1890 * We used to set chan's exten and priority to "s" and 1 here,
1891 * but this generates (in some cases) an invalid extension, and
1892 * if "s" exists, could errantly cause execution of extensions
1893 * you don't expect. It makes more sense to let nature take its
1894 * course when chan finishes, and let the pbx do its thing and
1895 * hang up when the park is over.
1898 /* Answer if call is not up */
1899 if (chan->_state != AST_STATE_UP) {
1901 * XXX Why are we doing this? Both of the channels should be up
1902 * since you cannot do DTMF features unless you are bridged.
1904 if (ast_answer(chan)) {
1908 /* Sleep to allow VoIP streams to settle down */
1909 if (ast_safe_sleep(chan, 1000)) {
1914 /* one direction used to call park_call.... */
1915 set_peers(&parker, &parkee, peer, chan, sense);
1916 return masq_park_call(parkee, parker, &args) ? AST_FEATURE_RETURN_SUCCESS : -1;
1921 * \brief Play file to specified channel.
1923 * \param play_to Channel to play audiofile to.
1924 * \param other Channel to put in autoservice while playing file.
1925 * \param msg Descriptive name of message type being played.
1926 * \param audiofile Audio file to play.
1928 * \retval 0 on success.
1929 * \retval -1 on error. (Couldn't play file, a channel hung up,...)
1931 static int play_message_on_chan(struct ast_channel *play_to, struct ast_channel *other, const char *msg, const char *audiofile)
1933 /* Put other channel in autoservice. */
1934 if (ast_autoservice_start(other)) {
1937 ast_autoservice_ignore(other, AST_FRAME_DTMF_BEGIN);
1938 ast_autoservice_ignore(other, AST_FRAME_DTMF_END);
1939 if (ast_stream_and_wait(play_to, audiofile, "")) {
1940 ast_log(LOG_WARNING, "Failed to play %s '%s'!\n", msg, audiofile);
1941 ast_autoservice_stop(other);
1944 if (ast_autoservice_stop(other)) {
1952 * \brief Play file to specified channels.
1954 * \param left Channel on left to play file.
1955 * \param right Channel on right to play file.
1956 * \param which Play file on indicated channels: which < 0 play left, which == 0 play both, which > 0 play right
1957 * \param msg Descriptive name of message type being played.
1958 * \param audiofile Audio file to play to channels.
1960 * \note Plays file to the indicated channels in turn so please
1961 * don't use this for very long messages.
1963 * \retval 0 on success.
1964 * \retval -1 on error. (Couldn't play file, channel hung up,...)
1966 static int play_message_to_chans(struct ast_channel *left, struct ast_channel *right, int which, const char *msg, const char *audiofile)
1968 /* First play the file to the left channel if requested. */
1969 if (which <= 0 && play_message_on_chan(left, right, msg, audiofile)) {
1973 /* Then play the file to the right channel if requested. */
1974 if (which >= 0 && play_message_on_chan(right, left, msg, audiofile)) {
1982 * \brief Play message to both caller and callee in bridged call, plays synchronously, autoservicing the
1983 * other channel during the message, so please don't use this for very long messages
1985 static int play_message_in_bridged_call(struct ast_channel *caller_chan, struct ast_channel *callee_chan, const char *audiofile)
1987 return play_message_to_chans(caller_chan, callee_chan, 0, "automon message",
1992 * \brief Monitor a channel by DTMF
1993 * \param chan channel requesting monitor
1994 * \param peer channel to be monitored
1997 * \param sense feature options
2000 * Check monitor app enabled, setup channels, both caller/callee chans not null
2001 * get TOUCH_MONITOR variable for filename if exists, exec monitor app.
2002 * \retval AST_FEATURE_RETURN_SUCCESS on success.
2003 * \retval -1 on error.
2005 static int builtin_automonitor(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
2007 char *caller_chan_id = NULL, *callee_chan_id = NULL, *args = NULL, *touch_filename = NULL;
2010 struct ast_channel *caller_chan, *callee_chan;
2011 const char *automon_message_start = NULL;
2012 const char *automon_message_stop = NULL;
2015 ast_log(LOG_ERROR,"Cannot record the call. The monitor application is disabled.\n");
2019 if (!monitor_app && !(monitor_app = pbx_findapp("Monitor"))) {
2021 ast_log(LOG_ERROR,"Cannot record the call. The monitor application is disabled.\n");
2025 set_peers(&caller_chan, &callee_chan, peer, chan, sense);
2026 if (caller_chan) { /* Find extra messages */
2027 automon_message_start = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_MESSAGE_START");
2028 automon_message_stop = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_MESSAGE_STOP");
2031 if (!ast_strlen_zero(courtesytone)) { /* Play courtesy tone if configured */
2032 if(play_message_in_bridged_call(caller_chan, callee_chan, courtesytone) == -1) {
2037 if (callee_chan->monitor) {
2038 ast_verb(4, "User hit '%s' to stop recording call.\n", code);
2039 if (!ast_strlen_zero(automon_message_stop)) {
2040 play_message_in_bridged_call(caller_chan, callee_chan, automon_message_stop);
2042 callee_chan->monitor->stop(callee_chan, 1);
2043 return AST_FEATURE_RETURN_SUCCESS;
2046 if (caller_chan && callee_chan) {
2047 const char *touch_format = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_FORMAT");
2048 const char *touch_monitor = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR");
2049 const char *touch_monitor_prefix = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MONITOR_PREFIX");
2052 touch_format = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR_FORMAT");
2055 touch_monitor = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR");
2057 if (!touch_monitor_prefix)
2058 touch_monitor_prefix = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MONITOR_PREFIX");
2060 if (touch_monitor) {
2061 len = strlen(touch_monitor) + 50;
2063 touch_filename = alloca(len);
2064 snprintf(touch_filename, len, "%s-%ld-%s", S_OR(touch_monitor_prefix, "auto"), (long)time(NULL), touch_monitor);
2065 snprintf(args, len, "%s,%s,m", S_OR(touch_format, "wav"), touch_filename);
2067 caller_chan_id = ast_strdupa(S_COR(caller_chan->caller.id.number.valid,
2068 caller_chan->caller.id.number.str, ast_channel_name(caller_chan)));
2069 callee_chan_id = ast_strdupa(S_COR(callee_chan->caller.id.number.valid,
2070 callee_chan->caller.id.number.str, ast_channel_name(callee_chan)));
2071 len = strlen(caller_chan_id) + strlen(callee_chan_id) + 50;
2073 touch_filename = alloca(len);
2074 snprintf(touch_filename, len, "%s-%ld-%s-%s", S_OR(touch_monitor_prefix, "auto"), (long)time(NULL), caller_chan_id, callee_chan_id);
2075 snprintf(args, len, "%s,%s,m", S_OR(touch_format, "wav"), touch_filename);
2078 for(x = 0; x < strlen(args); x++) {
2083 ast_verb(4, "User hit '%s' to record call. filename: %s\n", code, args);
2085 pbx_exec(callee_chan, monitor_app, args);
2086 pbx_builtin_setvar_helper(callee_chan, "TOUCH_MONITOR_OUTPUT", touch_filename);
2087 pbx_builtin_setvar_helper(caller_chan, "TOUCH_MONITOR_OUTPUT", touch_filename);
2089 if (!ast_strlen_zero(automon_message_start)) { /* Play start message for both channels */
2090 play_message_in_bridged_call(caller_chan, callee_chan, automon_message_start);
2093 return AST_FEATURE_RETURN_SUCCESS;
2096 ast_log(LOG_NOTICE,"Cannot record the call. One or both channels have gone away.\n");
2100 static int builtin_automixmonitor(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
2102 char *caller_chan_id = NULL, *callee_chan_id = NULL, *args = NULL, *touch_filename = NULL;
2105 struct ast_channel *caller_chan, *callee_chan;
2106 const char *mixmonitor_spy_type = "MixMonitor";
2109 if (!mixmonitor_ok) {
2110 ast_log(LOG_ERROR,"Cannot record the call. The mixmonitor application is disabled.\n");
2114 if (!(mixmonitor_app = pbx_findapp("MixMonitor"))) {
2116 ast_log(LOG_ERROR,"Cannot record the call. The mixmonitor application is disabled.\n");
2120 set_peers(&caller_chan, &callee_chan, peer, chan, sense);
2122 if (!ast_strlen_zero(courtesytone)) {
2123 if (ast_autoservice_start(callee_chan))
2125 ast_autoservice_ignore(callee_chan, AST_FRAME_DTMF_END);
2126 if (ast_stream_and_wait(caller_chan, courtesytone, "")) {
2127 ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
2128 ast_autoservice_stop(callee_chan);
2131 if (ast_autoservice_stop(callee_chan))
2135 ast_channel_lock(callee_chan);
2136 count = ast_channel_audiohook_count_by_source(callee_chan, mixmonitor_spy_type, AST_AUDIOHOOK_TYPE_SPY);
2137 ast_channel_unlock(callee_chan);
2139 /* This means a mixmonitor is attached to the channel, running or not is unknown. */
2142 ast_verb(3, "User hit '%s' to stop recording call.\n", code);
2144 /* Make sure they are running */
2145 ast_channel_lock(callee_chan);
2146 count = ast_channel_audiohook_count_by_source_running(callee_chan, mixmonitor_spy_type, AST_AUDIOHOOK_TYPE_SPY);
2147 ast_channel_unlock(callee_chan);
2149 if (!stopmixmonitor_ok) {
2150 ast_log(LOG_ERROR,"Cannot stop recording the call. The stopmixmonitor application is disabled.\n");
2153 if (!(stopmixmonitor_app = pbx_findapp("StopMixMonitor"))) {
2154 stopmixmonitor_ok = 0;
2155 ast_log(LOG_ERROR,"Cannot stop recording the call. The stopmixmonitor application is disabled.\n");
2158 pbx_exec(callee_chan, stopmixmonitor_app, "");
2159 return AST_FEATURE_RETURN_SUCCESS;
2163 ast_log(LOG_WARNING,"Stopped MixMonitors are attached to the channel.\n");
2166 if (caller_chan && callee_chan) {
2167 const char *touch_format = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MIXMONITOR_FORMAT");
2168 const char *touch_monitor = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MIXMONITOR");
2171 touch_format = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MIXMONITOR_FORMAT");
2174 touch_monitor = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MIXMONITOR");
2176 if (touch_monitor) {
2177 len = strlen(touch_monitor) + 50;
2179 touch_filename = alloca(len);
2180 snprintf(touch_filename, len, "auto-%ld-%s", (long)time(NULL), touch_monitor);
2181 snprintf(args, len, "%s.%s,b", touch_filename, (touch_format) ? touch_format : "wav");
2183 caller_chan_id = ast_strdupa(S_COR(caller_chan->caller.id.number.valid,
2184 caller_chan->caller.id.number.str, ast_channel_name(caller_chan)));
2185 callee_chan_id = ast_strdupa(S_COR(callee_chan->caller.id.number.valid,
2186 callee_chan->caller.id.number.str, ast_channel_name(callee_chan)));
2187 len = strlen(caller_chan_id) + strlen(callee_chan_id) + 50;
2189 touch_filename = alloca(len);
2190 snprintf(touch_filename, len, "auto-%ld-%s-%s", (long)time(NULL), caller_chan_id, callee_chan_id);
2191 snprintf(args, len, "%s.%s,b", touch_filename, S_OR(touch_format, "wav"));
2194 for( x = 0; x < strlen(args); x++) {
2199 ast_verb(3, "User hit '%s' to record call. filename: %s\n", code, touch_filename);
2201 pbx_exec(callee_chan, mixmonitor_app, args);
2202 pbx_builtin_setvar_helper(callee_chan, "TOUCH_MIXMONITOR_OUTPUT", touch_filename);
2203 pbx_builtin_setvar_helper(caller_chan, "TOUCH_MIXMONITOR_OUTPUT", touch_filename);
2204 return AST_FEATURE_RETURN_SUCCESS;
2208 ast_log(LOG_NOTICE,"Cannot record the call. One or both channels have gone away.\n");
2213 static int builtin_disconnect(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
2215 ast_verb(4, "User hit '%s' to disconnect call.\n", code);
2216 return AST_FEATURE_RETURN_HANGUP;
2220 * \brief Find the context for the transfer
2224 * Grab the TRANSFER_CONTEXT, if fails try grabbing macrocontext.
2225 * \return a context string
2227 static const char *real_ctx(struct ast_channel *transferer, struct ast_channel *transferee)
2229 const char *s = pbx_builtin_getvar_helper(transferer, "TRANSFER_CONTEXT");
2230 if (ast_strlen_zero(s)) {
2231 s = pbx_builtin_getvar_helper(transferee, "TRANSFER_CONTEXT");
2233 if (ast_strlen_zero(s)) { /* Use the non-macro context to transfer the call XXX ? */
2234 s = transferer->macrocontext;
2236 if (ast_strlen_zero(s)) {
2237 s = transferer->context;
2243 * \brief Blind transfer user to another extension
2244 * \param chan channel to be transfered
2245 * \param peer channel initiated blind transfer
2249 * \param sense feature options
2251 * Place chan on hold, check if transferred to parkinglot extension,
2252 * otherwise check extension exists and transfer caller.
2253 * \retval AST_FEATURE_RETURN_SUCCESS.
2254 * \retval -1 on failure.
2256 static int builtin_blindtransfer(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
2258 struct ast_channel *transferer;
2259 struct ast_channel *transferee;
2260 struct ast_exten *park_exten;
2261 const char *transferer_real_context;
2262 char xferto[256] = "";
2265 ast_debug(1, "Executing Blind Transfer %s, %s (sense=%d) \n", ast_channel_name(chan), ast_channel_name(peer), sense);
2266 set_peers(&transferer, &transferee, peer, chan, sense);
2267 transferer_real_context = real_ctx(transferer, transferee);
2269 /* Start autoservice on transferee while we talk to the transferer */
2270 ast_autoservice_start(transferee);
2271 ast_indicate(transferee, AST_CONTROL_HOLD);
2274 res = ast_stream_and_wait(transferer, "pbx-transfer", AST_DIGIT_ANY);
2276 finishup(transferee);
2277 return -1; /* error ? */
2279 if (res > 0) { /* If they've typed a digit already, handle it */
2280 xferto[0] = (char) res;
2283 res = ast_app_dtget(transferer, transferer_real_context, xferto, sizeof(xferto), 100, transferdigittimeout);
2284 if (res < 0) { /* hangup or error, (would be 0 for invalid and 1 for valid) */
2285 finishup(transferee);
2290 ast_log(LOG_WARNING, "Extension '%s' does not exist in context '%s'\n",
2291 xferto, transferer_real_context);
2293 /* Does anyone care about this case? */
2294 ast_log(LOG_WARNING, "No digits dialed.\n");
2296 ast_stream_and_wait(transferer, "pbx-invalid", "");
2297 finishup(transferee);
2298 return AST_FEATURE_RETURN_SUCCESS;
2301 park_exten = get_parking_exten(xferto, transferer, transferer_real_context);
2303 /* We are transfering the transferee to a parking lot. */
2304 return xfer_park_call_helper(transferee, transferer, park_exten);
2307 /* Do blind transfer. */
2308 ast_verb(3, "Blind transferring %s to '%s' (context %s) priority 1\n",
2309 ast_channel_name(transferee), xferto, transferer_real_context);
2310 ast_cel_report_event(transferer, AST_CEL_BLINDTRANSFER, NULL, xferto, transferee);
2311 pbx_builtin_setvar_helper(transferer, "BLINDTRANSFER", ast_channel_name(transferee));
2312 pbx_builtin_setvar_helper(transferee, "BLINDTRANSFER", ast_channel_name(transferer));
2313 finishup(transferee);
2314 ast_channel_lock(transferer);
2315 if (!transferer->cdr) { /* this code should never get called (in a perfect world) */
2316 transferer->cdr = ast_cdr_alloc();
2317 if (transferer->cdr) {
2318 ast_cdr_init(transferer->cdr, transferer); /* initialize our channel's cdr */
2319 ast_cdr_start(transferer->cdr);
2322 ast_channel_unlock(transferer);
2323 if (transferer->cdr) {
2324 struct ast_cdr *swap = transferer->cdr;
2327 "transferer=%s; transferee=%s; lastapp=%s; lastdata=%s; chan=%s; dstchan=%s\n",
2328 ast_channel_name(transferer), ast_channel_name(transferee), transferer->cdr->lastapp,
2329 transferer->cdr->lastdata, transferer->cdr->channel,
2330 transferer->cdr->dstchannel);
2331 ast_debug(1, "TRANSFEREE; lastapp=%s; lastdata=%s, chan=%s; dstchan=%s\n",
2332 transferee->cdr->lastapp, transferee->cdr->lastdata, transferee->cdr->channel,
2333 transferee->cdr->dstchannel);
2334 ast_debug(1, "transferer_real_context=%s; xferto=%s\n",
2335 transferer_real_context, xferto);
2336 /* swap cdrs-- it will save us some time & work */
2337 transferer->cdr = transferee->cdr;
2338 transferee->cdr = swap;
2340 if (!transferee->pbx) {
2341 /* Doh! Use our handy async_goto functions */
2342 ast_debug(1, "About to ast_async_goto %s.\n", ast_channel_name(transferee));
2343 if (ast_async_goto(transferee, transferer_real_context, xferto, 1)) {
2344 ast_log(LOG_WARNING, "Async goto failed :-(\n");
2347 /* The transferee is masqueraded and the original bridged channels can be hungup. */
2350 /* Set the transferee's new extension, since it exists, using transferer context */
2351 ast_debug(1, "About to explicit goto %s, it has a PBX.\n", ast_channel_name(transferee));
2352 ast_set_flag(transferee, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */
2353 set_c_e_p(transferee, transferer_real_context, xferto, 0);
2356 * Break the bridge. The transferee needs to resume executing
2357 * dialplan at the xferto location.
2359 res = AST_FEATURE_RETURN_SUCCESSBREAK;
2361 check_goto_on_transfer(transferer);
2366 * \brief make channels compatible
2369 * \retval 0 on success.
2370 * \retval -1 on failure.
2372 static int check_compat(struct ast_channel *c, struct ast_channel *newchan)
2374 if (ast_channel_make_compatible(c, newchan) < 0) {
2375 ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n",
2376 ast_channel_name(c), ast_channel_name(newchan));
2377 ast_hangup(newchan);
2385 * \brief Builtin attended transfer failed cleanup.
2388 * \param transferee Party A in the transfer.
2389 * \param transferer Party B in the transfer.
2390 * \param connected_line Saved connected line info about party A.
2392 * \note The connected_line data is freed.
2396 static void atxfer_fail_cleanup(struct ast_channel *transferee, struct ast_channel *transferer, struct ast_party_connected_line *connected_line)
2398 finishup(transferee);
2401 * Restore party B connected line info about party A.
2403 * Party B was the caller to party C and is the last known mode
2406 if (ast_channel_connected_line_macro(transferee, transferer, connected_line, 1, 0)) {
2407 ast_channel_update_connected_line(transferer, connected_line, NULL);
2409 ast_party_connected_line_free(connected_line);
2413 * \brief Attended transfer
2414 * \param chan transfered user
2415 * \param peer person transfering call
2418 * \param sense feature options
2421 * Get extension to transfer to, if you cannot generate channel (or find extension)
2422 * return to host channel. After called channel answered wait for hangup of transferer,
2423 * bridge call between transfer peer (taking them off hold) to attended transfer channel.
2425 * \return -1 on failure
2427 static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, const char *code, int sense, void *data)
2429 struct ast_channel *transferer;/* Party B */
2430 struct ast_channel *transferee;/* Party A */
2431 struct ast_exten *park_exten;
2432 const char *transferer_real_context;
2433 char xferto[256] = "";
2436 struct ast_channel *newchan;
2437 struct ast_channel *xferchan;
2438 struct ast_bridge_thread_obj *tobj;
2439 struct ast_bridge_config bconfig;
2441 struct ast_party_connected_line connected_line;
2442 struct ast_datastore *features_datastore;
2443 struct ast_dial_features *dialfeatures = NULL;
2444 char *transferer_tech;
2445 char *transferer_name;
2446 char *transferer_name_orig;
2449 ast_debug(1, "Executing Attended Transfer %s, %s (sense=%d) \n", ast_channel_name(chan), ast_channel_name(peer), sense);
2450 set_peers(&transferer, &transferee, peer, chan, sense);
2451 transferer_real_context = real_ctx(transferer, transferee);
2453 /* Start autoservice on transferee while we talk to the transferer */
2454 ast_autoservice_start(transferee);
2455 ast_indicate(transferee, AST_CONTROL_HOLD);
2458 res = ast_stream_and_wait(transferer, "pbx-transfer", AST_DIGIT_ANY);
2460 finishup(transferee);
2463 if (res > 0) { /* If they've typed a digit already, handle it */
2464 xferto[0] = (char) res;
2467 /* this is specific of atxfer */
2468 res = ast_app_dtget(transferer, transferer_real_context, xferto, sizeof(xferto), 100, transferdigittimeout);
2469 if (res < 0) { /* hangup or error, (would be 0 for invalid and 1 for valid) */
2470 finishup(transferee);
2476 ast_log(LOG_WARNING, "Extension '%s' does not exist in context '%s'\n",
2477 xferto, transferer_real_context);
2479 /* Does anyone care about this case? */
2480 ast_log(LOG_WARNING, "No digits dialed for atxfer.\n");
2482 ast_stream_and_wait(transferer, "pbx-invalid", "");
2483 finishup(transferee);
2484 return AST_FEATURE_RETURN_SUCCESS;
2487 park_exten = get_parking_exten(xferto, transferer, transferer_real_context);
2489 /* We are transfering the transferee to a parking lot. */
2490 return xfer_park_call_helper(transferee, transferer, park_exten);
2493 /* Append context to dialed transfer number. */
2494 snprintf(xferto + l, sizeof(xferto) - l, "@%s/n", transferer_real_context);
2496 /* If we are performing an attended transfer and we have two channels involved then
2497 copy sound file information to play upon attended transfer completion */
2499 const char *chan1_attended_sound = pbx_builtin_getvar_helper(transferer, "ATTENDED_TRANSFER_COMPLETE_SOUND");
2500 const char *chan2_attended_sound = pbx_builtin_getvar_helper(transferee, "ATTENDED_TRANSFER_COMPLETE_SOUND");
2502 if (!ast_strlen_zero(chan1_attended_sound)) {
2503 pbx_builtin_setvar_helper(transferer, "BRIDGE_PLAY_SOUND", chan1_attended_sound);
2505 if (!ast_strlen_zero(chan2_attended_sound)) {
2506 pbx_builtin_setvar_helper(transferee, "BRIDGE_PLAY_SOUND", chan2_attended_sound);
2510 /* Extract redial transferer information from the channel name. */
2511 transferer_name_orig = ast_strdupa(ast_channel_name(transferer));
2512 transferer_name = ast_strdupa(transferer_name_orig);
2513 transferer_tech = strsep(&transferer_name, "/");
2514 dash = strrchr(transferer_name, '-');
2516 /* Trim off channel name sequence/serial number. */
2520 /* Stop autoservice so we can monitor all parties involved in the transfer. */
2521 if (ast_autoservice_stop(transferee) < 0) {
2522 ast_indicate(transferee, AST_CONTROL_UNHOLD);
2526 /* Save connected line info for party B about party A in case transfer fails. */
2527 ast_party_connected_line_init(&connected_line);
2528 ast_channel_lock(transferer);
2529 ast_party_connected_line_copy(&connected_line, &transferer->connected);
2530 ast_channel_unlock(transferer);
2531 connected_line.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
2534 newchan = feature_request_and_dial(transferer, transferer_name_orig, transferer,
2535 transferee, "Local", transferer->nativeformats, xferto,
2536 atxfernoanswertimeout, &outstate, ast_channel_language(transferer));
2537 ast_debug(2, "Dial party C result: newchan:%d, outstate:%d\n", !!newchan, outstate);
2539 if (!ast_check_hangup(transferer)) {
2540 int hangup_dont = 0;
2542 /* Transferer (party B) is up */
2543 ast_debug(1, "Actually doing an attended transfer.\n");
2545 /* Start autoservice on transferee while the transferer deals with party C. */
2546 ast_autoservice_start(transferee);
2548 ast_indicate(transferer, -1);
2550 /* any reason besides user requested cancel and busy triggers the failed sound */
2552 case AST_CONTROL_UNHOLD:/* Caller requested cancel or party C answer timeout. */
2553 case AST_CONTROL_BUSY:
2554 case AST_CONTROL_CONGESTION:
2555 if (ast_stream_and_wait(transferer, xfersound, "")) {
2556 ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
2560 if (ast_stream_and_wait(transferer, xferfailsound, "")) {
2561 ast_log(LOG_WARNING, "Failed to play transfer failed sound!\n");
2565 atxfer_fail_cleanup(transferee, transferer, &connected_line);
2566 return AST_FEATURE_RETURN_SUCCESS;
2569 if (check_compat(transferer, newchan)) {
2570 if (ast_stream_and_wait(transferer, xferfailsound, "")) {
2571 ast_log(LOG_WARNING, "Failed to play transfer failed sound!\n");
2573 atxfer_fail_cleanup(transferee, transferer, &connected_line);
2574 return AST_FEATURE_RETURN_SUCCESS;
2576 memset(&bconfig,0,sizeof(struct ast_bridge_config));
2577 ast_set_flag(&(bconfig.features_caller), AST_FEATURE_DISCONNECT);
2578 ast_set_flag(&(bconfig.features_callee), AST_FEATURE_DISCONNECT);
2580 /* ast_bridge_call clears AST_FLAG_BRIDGE_HANGUP_DONT, but we don't
2581 want that to happen here because we're also in another bridge already
2583 if (ast_test_flag(chan, AST_FLAG_BRIDGE_HANGUP_DONT)) {
2586 /* Let party B and party C talk as long as they want. */
2587 ast_bridge_call(transferer, newchan, &bconfig);
2589 ast_set_flag(chan, AST_FLAG_BRIDGE_HANGUP_DONT);
2592 if (ast_check_hangup(newchan) || !ast_check_hangup(transferer)) {
2593 ast_hangup(newchan);
2594 if (ast_stream_and_wait(transferer, xfersound, "")) {
2595 ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
2597 atxfer_fail_cleanup(transferee, transferer, &connected_line);
2598 return AST_FEATURE_RETURN_SUCCESS;
2601 /* Transferer (party B) is confirmed hung up at this point. */
2602 if (check_compat(transferee, newchan)) {
2603 finishup(transferee);
2604 ast_party_connected_line_free(&connected_line);
2608 ast_indicate(transferee, AST_CONTROL_UNHOLD);
2609 if ((ast_autoservice_stop(transferee) < 0)
2610 || (ast_waitfordigit(transferee, 100) < 0)
2611 || (ast_waitfordigit(newchan, 100) < 0)
2612 || ast_check_hangup(transferee)
2613 || ast_check_hangup(newchan)) {
2614 ast_hangup(newchan);
2615 ast_party_connected_line_free(&connected_line);
2618 } else if (!ast_check_hangup(transferee)) {
2619 /* Transferer (party B) has hung up at this point. Doing blonde transfer. */
2620 ast_debug(1, "Actually doing a blonde transfer.\n");
2622 if (!newchan && !atxferdropcall) {
2623 /* Party C is not available, try to call party B back. */
2624 unsigned int tries = 0;
2626 if (ast_strlen_zero(transferer_name) || ast_strlen_zero(transferer_tech)) {
2627 ast_log(LOG_WARNING,
2628 "Transferer channel name: '%s' cannot be used for callback.\n",
2629 transferer_name_orig);
2630 ast_indicate(transferee, AST_CONTROL_UNHOLD);
2631 ast_party_connected_line_free(&connected_line);
2637 /* Try to get party B back. */
2638 ast_debug(1, "We're trying to callback %s/%s\n",
2639 transferer_tech, transferer_name);
2640 newchan = feature_request_and_dial(transferer, transferer_name_orig,
2641 transferee, transferee, transferer_tech,
2642 transferee->nativeformats, transferer_name,
2643 atxfernoanswertimeout, &outstate, ast_channel_language(transferer));
2644 ast_debug(2, "Dial party B result: newchan:%d, outstate:%d\n",
2645 !!newchan, outstate);
2646 if (newchan || ast_check_hangup(transferee)) {
2651 if (atxfercallbackretries <= tries) {
2652 /* No more callback tries remaining. */
2656 if (atxferloopdelay) {
2657 /* Transfer failed, sleeping */
2658 ast_debug(1, "Sleeping for %d ms before retrying atxfer.\n",
2660 ast_safe_sleep(transferee, atxferloopdelay);
2661 if (ast_check_hangup(transferee)) {
2662 ast_party_connected_line_free(&connected_line);
2667 /* Retry dialing party C. */
2668 ast_debug(1, "We're retrying to call %s/%s\n", "Local", xferto);
2669 newchan = feature_request_and_dial(transferer, transferer_name_orig,
2670 transferer, transferee, "Local",
2671 transferee->nativeformats, xferto,
2672 atxfernoanswertimeout, &outstate, ast_channel_language(transferer));
2673 ast_debug(2, "Redial party C result: newchan:%d, outstate:%d\n",
2674 !!newchan, outstate);
2675 if (newchan || ast_check_hangup(transferee)) {
2680 ast_indicate(transferee, AST_CONTROL_UNHOLD);
2682 /* No party C or could not callback party B. */
2683 ast_party_connected_line_free(&connected_line);
2687 /* newchan is up, we should prepare transferee and bridge them */
2688 if (ast_check_hangup(newchan)) {
2689 ast_hangup(newchan);
2690 ast_party_connected_line_free(&connected_line);
2693 if (check_compat(transferee, newchan)) {
2694 ast_party_connected_line_free(&connected_line);
2699 * Both the transferer and transferee have hungup. If newchan
2700 * is up, hang it up as it has no one to talk to.
2702 ast_debug(1, "Everyone is hungup.\n");
2704 ast_hangup(newchan);
2706 ast_party_connected_line_free(&connected_line);
2710 /* Initiate the channel transfer of party A to party C (or recalled party B). */
2711 ast_cel_report_event(transferee, AST_CEL_ATTENDEDTRANSFER, NULL, NULL, newchan);
2713 xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", ast_channel_linkedid(transferee), 0, "Transfered/%s", ast_channel_name(transferee));
2715 ast_hangup(newchan);
2716 ast_party_connected_line_free(&connected_line);
2720 /* Give party A a momentary ringback tone during transfer. */
2721 xferchan->visible_indication = AST_CONTROL_RINGING;
2723 /* Make formats okay */
2724 xferchan->readformat = transferee->readformat;
2725 xferchan->writeformat = transferee->writeformat;
2727 ast_channel_masquerade(xferchan, transferee);
2728 ast_explicit_goto(xferchan, transferee->context, transferee->exten, transferee->priority);
2729 xferchan->_state = AST_STATE_UP;
2730 ast_clear_flag(xferchan, AST_FLAGS_ALL);
2732 /* Do the masquerade manually to make sure that is is completed. */
2733 ast_do_masquerade(xferchan);
2735 newchan->_state = AST_STATE_UP;
2736 ast_clear_flag(newchan, AST_FLAGS_ALL);
2737 tobj = ast_calloc(1, sizeof(*tobj));
2739 ast_hangup(xferchan);
2740 ast_hangup(newchan);
2741 ast_party_connected_line_free(&connected_line);
2745 ast_channel_lock(newchan);
2746 if ((features_datastore = ast_channel_datastore_find(newchan, &dial_features_info, NULL))) {
2747 dialfeatures = features_datastore->data;
2749 ast_channel_unlock(newchan);
2752 /* newchan should always be the callee and shows up as callee in dialfeatures, but for some reason
2753 I don't currently understand, the abilities of newchan seem to be stored on the caller side */
2754 ast_copy_flags(&(config->features_callee), &(dialfeatures->features_caller), AST_FLAGS_ALL);
2755 dialfeatures = NULL;
2758 ast_channel_lock(xferchan);
2759 if ((features_datastore = ast_channel_datastore_find(xferchan, &dial_features_info, NULL))) {
2760 dialfeatures = features_datastore->data;
2762 ast_channel_unlock(xferchan);
2765 ast_copy_flags(&(config->features_caller), &(dialfeatures->features_caller), AST_FLAGS_ALL);
2768 tobj->chan = newchan;
2769 tobj->peer = xferchan;
2770 tobj->bconfig = *config;
2772 if (tobj->bconfig.end_bridge_callback_data_fixup) {
2773 tobj->bconfig.end_bridge_callback_data_fixup(&tobj->bconfig, tobj->peer, tobj->chan);
2777 * xferchan is transferee, and newchan is the transfer target
2778 * So...in a transfer, who is the caller and who is the callee?
2780 * When the call is originally made, it is clear who is caller and callee.
2781 * When a transfer occurs, it is my humble opinion that the transferee becomes
2782 * the caller, and the transfer target is the callee.
2784 * The problem is that these macros were set with the intention of the original
2785 * caller and callee taking those roles. A transfer can totally mess things up,
2786 * to be technical. What sucks even more is that you can't effectively change
2787 * the macros in the dialplan during the call from the transferer to the transfer
2788 * target because the transferee is stuck with whatever role he originally had.
2790 * I think the answer here is just to make sure that it is well documented that
2791 * during a transfer, the transferee is the "caller" and the transfer target
2794 * This means that if party B calls party A, and party B transfers party A to
2795 * party C, then A has switched roles for the call. Now party A will have the
2796 * caller macro called on his channel instead of the callee macro.
2798 * Luckily, the method by which the party B to party C bridge is
2799 * launched above ensures that the transferee is the "chan" on
2800 * the bridge and the transfer target is the "peer," so my idea
2801 * for the roles post-transfer does not require extensive code
2805 /* Transfer party C connected line to party A */
2806 ast_channel_lock(transferer);
2808 * Due to a limitation regarding when callerID is set on a Local channel,
2809 * we use the transferer's connected line information here.
2811 ast_party_connected_line_copy(&connected_line, &transferer->connected);
2812 ast_channel_unlock(transferer);
2813 connected_line.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
2814 if (ast_channel_connected_line_macro(newchan, xferchan, &connected_line, 1, 0)) {
2815 ast_channel_update_connected_line(xferchan, &connected_line, NULL);
2818 /* Transfer party A connected line to party C */
2819 ast_channel_lock(xferchan);
2820 ast_connected_line_copy_from_caller(&connected_line, &xferchan->caller);
2821 ast_channel_unlock(xferchan);
2822 connected_line.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
2823 if (ast_channel_connected_line_macro(xferchan, newchan, &connected_line, 0, 0)) {
2824 ast_channel_update_connected_line(newchan, &connected_line, NULL);
2827 if (ast_stream_and_wait(newchan, xfersound, ""))
2828 ast_log(LOG_WARNING, "Failed to play transfer sound!\n");
2829 bridge_call_thread_launch(tobj);
2831 ast_party_connected_line_free(&connected_line);
2832 return -1;/* The transferee is masqueraded and the original bridged channels can be hungup. */
2835 /* add atxfer and automon as undefined so you can only use em if you configure them */
2836 #define FEATURES_COUNT ARRAY_LEN(builtin_features)
2838 AST_RWLOCK_DEFINE_STATIC(features_lock);
2840 static struct ast_call_feature builtin_features[] = {
2841 { AST_FEATURE_REDIRECT, "Blind Transfer", "blindxfer", "#", "#", builtin_blindtransfer, AST_FEATURE_FLAG_NEEDSDTMF, "" },
2842 { AST_FEATURE_REDIRECT, "Attended Transfer", "atxfer", "", "", builtin_atxfer, AST_FEATURE_FLAG_NEEDSDTMF, "" },
2843 { AST_FEATURE_AUTOMON, "One Touch Monitor", "automon", "", "", builtin_automonitor, AST_FEATURE_FLAG_NEEDSDTMF, "" },
2844 { AST_FEATURE_DISCONNECT, "Disconnect Call", "disconnect", "*", "*", builtin_disconnect, AST_FEATURE_FLAG_NEEDSDTMF, "" },
2845 { AST_FEATURE_PARKCALL, "Park Call", "parkcall", "", "", builtin_parkcall, AST_FEATURE_FLAG_NEEDSDTMF, "" },
2846 { AST_FEATURE_AUTOMIXMON, "One Touch MixMonitor", "automixmon", "", "", builtin_automixmonitor, AST_FEATURE_FLAG_NEEDSDTMF, "" },
2850 static AST_RWLIST_HEAD_STATIC(feature_list, ast_call_feature);
2852 /*! \brief register new feature into feature_list*/
2853 void ast_register_feature(struct ast_call_feature *feature)
2856 ast_log(LOG_NOTICE,"You didn't pass a feature!\n");
2860 AST_RWLIST_WRLOCK(&feature_list);
2861 AST_RWLIST_INSERT_HEAD(&feature_list,feature,feature_entry);
2862 AST_RWLIST_UNLOCK(&feature_list);
2864 ast_verb(2, "Registered Feature '%s'\n",feature->sname);
2868 * \brief Add new feature group
2869 * \param fgname feature group name.
2871 * Add new feature group to the feature group list insert at head of list.
2872 * \note This function MUST be called while feature_groups is locked.
2874 static struct feature_group *register_group(const char *fgname)
2876 struct feature_group *fg;
2879 ast_log(LOG_NOTICE, "You didn't pass a new group name!\n");
2883 if (!(fg = ast_calloc_with_stringfields(1, struct feature_group, 128))) {
2887 ast_string_field_set(fg, gname, fgname);
2889 AST_LIST_INSERT_HEAD(&feature_groups, fg, entry);
2891 ast_verb(2, "Registered group '%s'\n", fg->gname);
2897 * \brief Add feature to group
2898 * \param fg feature group
2900 * \param feature feature to add.
2902 * Check fg and feature specified, add feature to list
2903 * \note This function MUST be called while feature_groups is locked.
2905 static void register_group_feature(struct feature_group *fg, const char *exten, struct ast_call_feature *feature)
2907 struct feature_group_exten *fge;
2910 ast_log(LOG_NOTICE, "You didn't pass a group!\n");
2915 ast_log(LOG_NOTICE, "You didn't pass a feature!\n");
2919 if (!(fge = ast_calloc_with_stringfields(1, struct feature_group_exten, 128))) {
2923 ast_string_field_set(fge, exten, S_OR(exten, feature->exten));
2925 fge->feature = feature;
2927 AST_LIST_INSERT_HEAD(&fg->features, fge, entry);
2929 ast_verb(2, "Registered feature '%s' for group '%s' at exten '%s'\n",
2930 feature->sname, fg->gname, fge->exten);
2933 void ast_unregister_feature(struct ast_call_feature *feature)
2939 AST_RWLIST_WRLOCK(&feature_list);
2940 AST_RWLIST_REMOVE(&feature_list, feature, feature_entry);
2941 AST_RWLIST_UNLOCK(&feature_list);
2946 /*! \brief Remove all features in the list */
2947 static void ast_unregister_features(void)
2949 struct ast_call_feature *feature;
2951 AST_RWLIST_WRLOCK(&feature_list);
2952 while ((feature = AST_RWLIST_REMOVE_HEAD(&feature_list, feature_entry))) {
2955 AST_RWLIST_UNLOCK(&feature_list);
2958 /*! \brief find a call feature by name */
2959 static struct ast_call_feature *find_dynamic_feature(const char *name)
2961 struct ast_call_feature *tmp;
2963 AST_RWLIST_TRAVERSE(&feature_list, tmp, feature_entry) {
2964 if (!strcasecmp(tmp->sname, name)) {
2972 /*! \brief Remove all feature groups in the list */
2973 static void ast_unregister_groups(void)
2975 struct feature_group *fg;
2976 struct feature_group_exten *fge;
2978 AST_RWLIST_WRLOCK(&feature_groups);
2979 while ((fg = AST_LIST_REMOVE_HEAD(&feature_groups, entry))) {
2980 while ((fge = AST_LIST_REMOVE_HEAD(&fg->features, entry))) {
2981 ast_string_field_free_memory(fge);
2985 ast_string_field_free_memory(fg);
2988 AST_RWLIST_UNLOCK(&feature_groups);
2992 * \brief Find a group by name
2993 * \param name feature name
2994 * \retval feature group on success.
2995 * \retval NULL on failure.
2997 static struct feature_group *find_group(const char *name)
2999 struct feature_group *fg = NULL;
3001 AST_LIST_TRAVERSE(&feature_groups, fg, entry) {
3002 if (!strcasecmp(fg->gname, name))
3009 void ast_rdlock_call_features(void)
3011 ast_rwlock_rdlock(&features_lock);
3014 void ast_unlock_call_features(void)
3016 ast_rwlock_unlock(&features_lock);
3019 struct ast_call_feature *ast_find_call_feature(const char *name)
3022 for (x = 0; x < FEATURES_COUNT; x++) {
3023 if (!strcasecmp(name, builtin_features[x].sname))
3024 return &builtin_features[x];
3027 return find_dynamic_feature(name);
3031 * \brief exec an app by feature
3032 * \param chan,peer,config,code,sense,data
3034 * Find a feature, determine which channel activated
3035 * \retval AST_FEATURE_RETURN_NO_HANGUP_PEER
3037 * \retval -2 when an application cannot be found.
3039 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)
3041 struct ast_app *app;
3042 struct ast_call_feature *feature = data;
3043 struct ast_channel *work, *idle;
3046 if (!feature) { /* shouldn't ever happen! */
3047 ast_log(LOG_NOTICE, "Found feature before, but at execing we've lost it??\n");
3051 if (sense == FEATURE_SENSE_CHAN) {
3052 if (!ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLER))
3053 return AST_FEATURE_RETURN_KEEPTRYING;
3054 if (ast_test_flag(feature, AST_FEATURE_FLAG_ONSELF)) {
3062 if (!ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLEE))
3063 return AST_FEATURE_RETURN_KEEPTRYING;
3064 if (ast_test_flag(feature, AST_FEATURE_FLAG_ONSELF)) {
3073 if (!(app = pbx_findapp(feature->app))) {
3074 ast_log(LOG_WARNING, "Could not find application (%s)\n", feature->app);
3078 ast_autoservice_start(idle);
3079 ast_autoservice_ignore(idle, AST_FRAME_DTMF_END);
3082 pbx_builtin_setvar_helper(work, "DYNAMIC_PEERNAME", ast_channel_name(idle));
3083 pbx_builtin_setvar_helper(idle, "DYNAMIC_PEERNAME", ast_channel_name(work));
3084 pbx_builtin_setvar_helper(work, "DYNAMIC_FEATURENAME", feature->sname);
3085 pbx_builtin_setvar_helper(idle, "DYNAMIC_FEATURENAME", feature->sname);
3088 if (!ast_strlen_zero(feature->moh_class))
3089 ast_moh_start(idle, feature->moh_class, NULL);
3091 res = pbx_exec(work, app, feature->app_args);
3093 if (!ast_strlen_zero(feature->moh_class))
3096 ast_autoservice_stop(idle);
3099 return AST_FEATURE_RETURN_SUCCESSBREAK;
3101 return AST_FEATURE_RETURN_SUCCESS; /*! \todo XXX should probably return res */
3104 static void unmap_features(void)