[Asterisk-code-review] features: Add transfer initiation options. (asterisk[master])
N A
asteriskteam at digium.com
Sat Feb 5 06:17:43 CST 2022
N A has uploaded this change for review. ( https://gerrit.asterisk.org/c/asterisk/+/18001 )
Change subject: features: Add transfer initiation options.
......................................................................
features: Add transfer initiation options.
Adds additional control options over the transfer
feature functionality to give users more control
in how the transfer feature sounds and works.
The "transfer" sound that plays when a transfer is
initiated can now be customized in the user in
features.conf, just as with the other transfer sounds.
Secondly, the user can now specify the transfer extension
in advance by using the TRANSFER_EXTEN variable. If
a valid extension is contained in this variable, the call
will automatically be transferred to this destination.
Otherwise, it will fall back to collecting the extension
from the user as is always done now.
ASTERISK-29899 #close
Change-Id: Ibff309caa459a2b958706f2ed0ca393b1ef502e3
---
M configs/samples/features.conf.sample
A doc/CHANGES-staging/transfer.txt
M include/asterisk/features_config.h
M main/bridge_basic.c
M main/features_config.c
5 files changed, 75 insertions(+), 15 deletions(-)
git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/01/18001/1
diff --git a/configs/samples/features.conf.sample b/configs/samples/features.conf.sample
index afdcf5a..c3bfd19 100644
--- a/configs/samples/features.conf.sample
+++ b/configs/samples/features.conf.sample
@@ -26,6 +26,7 @@
; By default, this is 2.
;transferdialattempts = 3 ; Number of times that a transferer may attempt to dial an extension before
; being kicked back to the original call.
+;transferannouncesound = beep ; Sound to play to a transferer to indicate transfer process has begun. If empty, no sound will be played.
;transferretrysound = beep ; Sound to play when a transferer fails to dial a valid extension.
;transferinvalidsound = beeperr ; Sound to play when a transferer fails to dial a valid extension and is out of retries.
;atxferabort = *1 ; cancel the attended transfer
diff --git a/doc/CHANGES-staging/transfer.txt b/doc/CHANGES-staging/transfer.txt
new file mode 100644
index 0000000..6f5247b
--- /dev/null
+++ b/doc/CHANGES-staging/transfer.txt
@@ -0,0 +1,12 @@
+Subject: Transfer feature
+
+The following capabilities have been added to the
+transfer feature:
+
+- The transfer initiation announcement prompt can
+now be customized in features.conf.
+
+- The TRANSFER_EXTEN variable now can be used to
+allow the transfer function to automatically
+attempt to go to the extension contained in this
+variable, if it exists.
diff --git a/include/asterisk/features_config.h b/include/asterisk/features_config.h
index 5253369..336454b 100644
--- a/include/asterisk/features_config.h
+++ b/include/asterisk/features_config.h
@@ -72,6 +72,8 @@
AST_STRING_FIELD(transferretrysound);
/*! Sound played when an invalid extension is dialed, and the transferer is being returned to the call. */
AST_STRING_FIELD(transferinvalidsound);
+ /*! Sound to play to announce the transfer process has started. */
+ AST_STRING_FIELD(transferannouncesound);
);
/*! Seconds allowed between digit presses when dialing transfer destination */
unsigned int transferdigittimeout;
diff --git a/main/bridge_basic.c b/main/bridge_basic.c
index df21195..e2099ba 100644
--- a/main/bridge_basic.c
+++ b/main/bridge_basic.c
@@ -1398,6 +1398,27 @@
}
/*!
+ * \internal
+ * \brief Determine the transfer extension to use.
+ *
+ * \param transferer Channel initiating the transfer.
+ * \param extension User supplied extension if available. May be NULL.
+ *
+ * \return The extension to use for the transfer.
+ */
+static const char *get_transfer_exten(struct ast_channel *transferer, const char *exten)
+{
+ if (!ast_strlen_zero(exten)) {
+ return exten;
+ }
+ exten = pbx_builtin_getvar_helper(transferer, "TRANSFER_EXTEN");
+ if (!ast_strlen_zero(exten)) {
+ return exten;
+ }
+ return ""; /* empty default, to get transfer extension from user now */
+}
+
+/*!
* \brief Allocate and initialize attended transfer properties
*
* \param transferer The channel performing the attended transfer
@@ -1452,6 +1473,7 @@
props->atxfernoanswertimeout = xfer_cfg->atxfernoanswertimeout;
props->atxferloopdelay = xfer_cfg->atxferloopdelay;
ast_string_field_set(props, context, get_transfer_context(transferer, context));
+ ast_string_field_set(props, exten, get_transfer_exten(transferer, NULL));
ast_string_field_set(props, xfersound, xfer_cfg->xfersound);
ao2_ref(xfer_cfg, -1);
@@ -3155,16 +3177,26 @@
* \retval 0 on success
* \retval -1 on failure
*/
-static int grab_transfer(struct ast_channel *chan, char *exten, size_t exten_len, const char *context)
+static int grab_transfer(struct ast_channel *chan, char *exten, size_t exten_len, const char *context, const char *extenoverride)
{
int res;
int digit_timeout;
int attempts = 0;
int max_attempts;
struct ast_features_xfer_config *xfer_cfg;
- char *retry_sound;
- char *invalid_sound;
+ char *announce_sound, *retry_sound, *invalid_sound;
+ if (!ast_strlen_zero(extenoverride)) {
+ int extenres = ast_exists_extension(chan, context, extenoverride, 1,
+ S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL)) ? 1 : 0;
+ if (extenres) {
+ ast_copy_string(exten, extenoverride, exten_len);
+ ast_verb(3, "Transfering call to '%s@%s'", exten, context);
+ return 0;
+ }
+ ast_log(LOG_WARNING, "Override extension '%s' does not exist in context '%s'\n", extenoverride, context);
+ /* since we didn't get a valid extension from the channel, fall back and grab it from the user as usual now */
+ }
ast_channel_lock(chan);
xfer_cfg = ast_get_chan_features_xfer_config(chan);
if (!xfer_cfg) {
@@ -3175,21 +3207,24 @@
}
digit_timeout = xfer_cfg->transferdigittimeout * 1000;
max_attempts = xfer_cfg->transferdialattempts;
+ announce_sound = ast_strdupa(xfer_cfg->transferannouncesound);
retry_sound = ast_strdupa(xfer_cfg->transferretrysound);
invalid_sound = ast_strdupa(xfer_cfg->transferinvalidsound);
ao2_ref(xfer_cfg, -1);
ast_channel_unlock(chan);
/* Play the simple "transfer" prompt out and wait */
- res = ast_stream_and_wait(chan, "pbx-transfer", AST_DIGIT_ANY);
- ast_stopstream(chan);
- if (res < 0) {
- /* Hangup or error */
- return -1;
- }
- if (res) {
- /* Store the DTMF digit that interrupted playback of the file. */
- exten[0] = res;
+ if (!ast_strlen_zero(announce_sound)) {
+ res = ast_stream_and_wait(chan, announce_sound, AST_DIGIT_ANY);
+ ast_stopstream(chan);
+ if (res < 0) {
+ /* Hangup or error */
+ return -1;
+ }
+ if (res) {
+ /* Store the DTMF digit that interrupted playback of the file. */
+ exten[0] = res;
+ }
}
/* Drop to dialtone so they can enter the extension they want to transfer to */
@@ -3348,7 +3383,7 @@
ast_bridge_channel_write_hold(bridge_channel, NULL);
/* Grab the extension to transfer to */
- if (grab_transfer(bridge_channel->chan, exten, sizeof(exten), props->context)) {
+ if (grab_transfer(bridge_channel->chan, exten, sizeof(exten), props->context, props->exten)) {
/*
* This is a normal exit for when the user fails
* to specify a valid transfer target. e.g., The user
@@ -3470,7 +3505,7 @@
{
char xfer_exten[AST_MAX_EXTENSION] = "";
struct ast_bridge_features_blind_transfer *blind_transfer = hook_pvt;
- const char *xfer_context;
+ const char *xfer_context, *xfer_exten_override;
char *goto_on_blindxfer;
ast_verb(3, "Channel %s: Started DTMF blind transfer.\n",
@@ -3481,12 +3516,13 @@
ast_channel_lock(bridge_channel->chan);
xfer_context = ast_strdupa(get_transfer_context(bridge_channel->chan,
blind_transfer ? blind_transfer->context : NULL));
+ xfer_exten_override = ast_strdupa(get_transfer_exten(bridge_channel->chan, NULL));
goto_on_blindxfer = ast_strdupa(S_OR(pbx_builtin_getvar_helper(bridge_channel->chan,
"GOTO_ON_BLINDXFR"), ""));
ast_channel_unlock(bridge_channel->chan);
/* Grab the extension to transfer to */
- if (grab_transfer(bridge_channel->chan, xfer_exten, sizeof(xfer_exten), xfer_context)) {
+ if (grab_transfer(bridge_channel->chan, xfer_exten, sizeof(xfer_exten), xfer_context, xfer_exten_override)) {
ast_bridge_channel_write_unhold(bridge_channel);
return 0;
}
diff --git a/main/features_config.c b/main/features_config.c
index 50ca69b..d91d97f 100644
--- a/main/features_config.c
+++ b/main/features_config.c
@@ -143,6 +143,9 @@
<configOption name="transferinvalidsound" default="privacy-incorrect">
<synopsis>Sound that is played when an incorrect extension is dialed and the transferer has no attempts remaining.</synopsis>
</configOption>
+ <configOption name="transferannouncesound" default="pbx-transfer">
+ <synopsis>Sound that is played to the transferer when a transfer is initiated. If empty, no sound will be played.</synopsis>
+ </configOption>
</configObject>
<configObject name="featuremap">
<synopsis>DTMF options that can be triggered during bridged calls</synopsis>
@@ -320,6 +323,7 @@
<enum name="transferdialattempts"><para><xi:include xpointer="xpointer(/docs/configInfo[@name='features']/configFile[@name='features.conf']/configObject[@name='globals']/configOption[@name='transferdialattempts']/synopsis/text())" /></para></enum>
<enum name="transferretrysound"><para><xi:include xpointer="xpointer(/docs/configInfo[@name='features']/configFile[@name='features.conf']/configObject[@name='globals']/configOption[@name='transferretrysound']/synopsis/text())" /></para></enum>
<enum name="transferinvalidsound"><para><xi:include xpointer="xpointer(/docs/configInfo[@name='features']/configFile[@name='features.conf']/configObject[@name='globals']/configOption[@name='transferinvalidsound']/synopsis/text())" /></para></enum>
+ <enum name="transferannouncesound"><para><xi:include xpointer="xpointer(/docs/configInfo[@name='features']/configFile[@name='features.conf']/configObject[@name='globals']/configOption[@name='transferannouncesound']/synopsis/text())" /></para></enum>
</enumlist>
</parameter>
</syntax>
@@ -383,6 +387,7 @@
#define DEFAULT_TRANSFER_DIAL_ATTEMPTS 3
#define DEFAULT_TRANSFER_RETRY_SOUND "pbx-invalid"
#define DEFAULT_TRANSFER_INVALID_SOUND "privacy-incorrect"
+#define DEFAULT_TRANSFER_ANNOUNCE_SOUND "pbx-transfer"
/*! Default pickup options */
#define DEFAULT_PICKUPEXTEN "*8"
@@ -906,6 +911,8 @@
ast_string_field_set(xfer, transferretrysound, value);
} else if (!strcasecmp(name, "transferinvalidsound")) {
ast_string_field_set(xfer, transferinvalidsound, value);
+ } else if (!strcasecmp(name, "transferannouncesound")) {
+ ast_string_field_set(xfer, transferannouncesound, value);
} else {
/* Unrecognized option */
res = -1;
@@ -1797,6 +1804,8 @@
DEFAULT_TRANSFER_RETRY_SOUND, xfer_handler, 0);
aco_option_register_custom(&cfg_info, "transferinvalidsound", ACO_EXACT, global_options,
DEFAULT_TRANSFER_INVALID_SOUND, xfer_handler, 0);
+ aco_option_register_custom(&cfg_info, "transferannouncesound", ACO_EXACT, global_options,
+ DEFAULT_TRANSFER_ANNOUNCE_SOUND, xfer_handler, 0);
aco_option_register_custom(&cfg_info, "pickupexten", ACO_EXACT, global_options,
DEFAULT_PICKUPEXTEN, pickup_handler, 0);
--
To view, visit https://gerrit.asterisk.org/c/asterisk/+/18001
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings
Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-Change-Id: Ibff309caa459a2b958706f2ed0ca393b1ef502e3
Gerrit-Change-Number: 18001
Gerrit-PatchSet: 1
Gerrit-Owner: N A <mail at interlinked.x10host.com>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20220205/6ee1f153/attachment-0001.html>
More information about the asterisk-code-review
mailing list