Skip to content

Commit 3a95cad

Browse files
InterLinked1Friendly Automation
authored and
Friendly Automation
committed
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. First, the "transfer" sound that plays when a transfer is initiated can now be customized by 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
1 parent 1493192 commit 3a95cad

File tree

5 files changed

+82
-13
lines changed

5 files changed

+82
-13
lines changed

configs/samples/features.conf.sample

+7-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@
66

77
[general]
88
;transferdigittimeout => 3 ; Number of seconds to wait between digits when transferring a call
9-
; (default is 3 seconds)
9+
; (default is 3 seconds). If the TRANSFER_EXTEN dialplan variable has been set
10+
; on the channel of the user that is invoking the transfer feature, then
11+
; this option is not used as the user is transferred directly to the extension
12+
; specified by TRANSFER_EXTEN (the transfer context remains the context specified
13+
; by TRANSFER_CONTEXT, if set, and otherwise the default context).
1014
;xfersound = beep ; to indicate an attended transfer is complete
1115
;xferfailsound = beeperr ; to indicate a failed transfer
1216
;pickupexten = *8 ; Configure the pickup extension. (default is *8)
@@ -26,12 +30,13 @@
2630
; By default, this is 2.
2731
;transferdialattempts = 3 ; Number of times that a transferer may attempt to dial an extension before
2832
; being kicked back to the original call.
33+
;transferannouncesound = beep ; Sound to play to a transferer to indicate transfer process has begun. If empty, no sound will be played.
2934
;transferretrysound = beep ; Sound to play when a transferer fails to dial a valid extension.
3035
;transferinvalidsound = beeperr ; Sound to play when a transferer fails to dial a valid extension and is out of retries.
3136
;atxferabort = *1 ; cancel the attended transfer
3237
;atxfercomplete = *2 ; complete the attended transfer, dropping out of the call
3338
;atxferthreeway = *3 ; complete the attended transfer, but stay in the call. This will turn the call into a multi-party bridge
34-
;atxferswap = *4 ; swap to the other party. Once an attended transfer has begun, this options may be used multiple times
39+
;atxferswap = *4 ; swap to the other party. Once an attended transfer has begun, this option may be used multiple times
3540

3641
; Note that the DTMF features listed below only work when two channels have answered and are bridged together.
3742
; They can not be used while the remote party is ringing or in progress. If you require this feature you can use

doc/CHANGES-staging/transfer.txt

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
Subject: Transfer feature
2+
3+
The following capabilities have been added to the
4+
transfer feature:
5+
6+
- The transfer initiation announcement prompt can
7+
now be customized in features.conf.
8+
9+
- The TRANSFER_EXTEN variable now can be set on the
10+
transferer's channel in order to allow the transfer
11+
function to automatically attempt to go to the extension
12+
contained in this variable, if it exists. The transfer
13+
context behavior is not changed (TRANSFER_CONTEXT is used
14+
if it exists; otherwise the default context is used).

include/asterisk/features_config.h

+2
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ struct ast_features_xfer_config {
7272
AST_STRING_FIELD(transferretrysound);
7373
/*! Sound played when an invalid extension is dialed, and the transferer is being returned to the call. */
7474
AST_STRING_FIELD(transferinvalidsound);
75+
/*! Sound to play to announce the transfer process has started. */
76+
AST_STRING_FIELD(transferannouncesound);
7577
);
7678
/*! Seconds allowed between digit presses when dialing transfer destination */
7779
unsigned int transferdigittimeout;

main/bridge_basic.c

+50-11
Original file line numberDiff line numberDiff line change
@@ -1397,6 +1397,27 @@ static const char *get_transfer_context(struct ast_channel *transferer, const ch
13971397
return "default";
13981398
}
13991399

1400+
/*!
1401+
* \internal
1402+
* \brief Determine the transfer extension to use.
1403+
*
1404+
* \param transferer Channel initiating the transfer.
1405+
* \param extension User supplied extension if available. May be NULL.
1406+
*
1407+
* \return The extension to use for the transfer.
1408+
*/
1409+
static const char *get_transfer_exten(struct ast_channel *transferer, const char *exten)
1410+
{
1411+
if (!ast_strlen_zero(exten)) {
1412+
return exten;
1413+
}
1414+
exten = pbx_builtin_getvar_helper(transferer, "TRANSFER_EXTEN");
1415+
if (!ast_strlen_zero(exten)) {
1416+
return exten;
1417+
}
1418+
return ""; /* empty default, to get transfer extension from user now */
1419+
}
1420+
14001421
/*!
14011422
* \brief Allocate and initialize attended transfer properties
14021423
*
@@ -3162,10 +3183,25 @@ static int grab_transfer(struct ast_channel *chan, char *exten, size_t exten_len
31623183
int attempts = 0;
31633184
int max_attempts;
31643185
struct ast_features_xfer_config *xfer_cfg;
3165-
char *retry_sound;
3166-
char *invalid_sound;
3186+
char *announce_sound, *retry_sound, *invalid_sound;
3187+
const char *extenoverride;
31673188

31683189
ast_channel_lock(chan);
3190+
extenoverride = get_transfer_exten(chan, NULL);
3191+
3192+
if (!ast_strlen_zero(extenoverride)) {
3193+
int extenres = ast_exists_extension(chan, context, extenoverride, 1,
3194+
S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL)) ? 1 : 0;
3195+
if (extenres) {
3196+
ast_copy_string(exten, extenoverride, exten_len);
3197+
ast_channel_unlock(chan);
3198+
ast_verb(3, "Transfering call to '%s@%s'", exten, context);
3199+
return 0;
3200+
}
3201+
ast_log(LOG_WARNING, "Override extension '%s' does not exist in context '%s'\n", extenoverride, context);
3202+
/* since we didn't get a valid extension from the channel, fall back and grab it from the user as usual now */
3203+
}
3204+
31693205
xfer_cfg = ast_get_chan_features_xfer_config(chan);
31703206
if (!xfer_cfg) {
31713207
ast_log(LOG_ERROR, "Channel %s: Unable to get transfer configuration\n",
@@ -3175,21 +3211,24 @@ static int grab_transfer(struct ast_channel *chan, char *exten, size_t exten_len
31753211
}
31763212
digit_timeout = xfer_cfg->transferdigittimeout * 1000;
31773213
max_attempts = xfer_cfg->transferdialattempts;
3214+
announce_sound = ast_strdupa(xfer_cfg->transferannouncesound);
31783215
retry_sound = ast_strdupa(xfer_cfg->transferretrysound);
31793216
invalid_sound = ast_strdupa(xfer_cfg->transferinvalidsound);
31803217
ao2_ref(xfer_cfg, -1);
31813218
ast_channel_unlock(chan);
31823219

31833220
/* Play the simple "transfer" prompt out and wait */
3184-
res = ast_stream_and_wait(chan, "pbx-transfer", AST_DIGIT_ANY);
3185-
ast_stopstream(chan);
3186-
if (res < 0) {
3187-
/* Hangup or error */
3188-
return -1;
3189-
}
3190-
if (res) {
3191-
/* Store the DTMF digit that interrupted playback of the file. */
3192-
exten[0] = res;
3221+
if (!ast_strlen_zero(announce_sound)) {
3222+
res = ast_stream_and_wait(chan, announce_sound, AST_DIGIT_ANY);
3223+
ast_stopstream(chan);
3224+
if (res < 0) {
3225+
/* Hangup or error */
3226+
return -1;
3227+
}
3228+
if (res) {
3229+
/* Store the DTMF digit that interrupted playback of the file. */
3230+
exten[0] = res;
3231+
}
31933232
}
31943233

31953234
/* Drop to dialtone so they can enter the extension they want to transfer to */

main/features_config.c

+9
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,9 @@
143143
<configOption name="transferinvalidsound" default="privacy-incorrect">
144144
<synopsis>Sound that is played when an incorrect extension is dialed and the transferer has no attempts remaining.</synopsis>
145145
</configOption>
146+
<configOption name="transferannouncesound" default="pbx-transfer">
147+
<synopsis>Sound that is played to the transferer when a transfer is initiated. If empty, no sound will be played.</synopsis>
148+
</configOption>
146149
</configObject>
147150
<configObject name="featuremap">
148151
<synopsis>DTMF options that can be triggered during bridged calls</synopsis>
@@ -324,6 +327,7 @@
324327
<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>
325328
<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>
326329
<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>
330+
<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>
327331
</enumlist>
328332
</parameter>
329333
</syntax>
@@ -387,6 +391,7 @@
387391
#define DEFAULT_TRANSFER_DIAL_ATTEMPTS 3
388392
#define DEFAULT_TRANSFER_RETRY_SOUND "pbx-invalid"
389393
#define DEFAULT_TRANSFER_INVALID_SOUND "privacy-incorrect"
394+
#define DEFAULT_TRANSFER_ANNOUNCE_SOUND "pbx-transfer"
390395

391396
/*! Default pickup options */
392397
#define DEFAULT_PICKUPEXTEN "*8"
@@ -910,6 +915,8 @@ static int xfer_set(struct ast_features_xfer_config *xfer, const char *name,
910915
ast_string_field_set(xfer, transferretrysound, value);
911916
} else if (!strcasecmp(name, "transferinvalidsound")) {
912917
ast_string_field_set(xfer, transferinvalidsound, value);
918+
} else if (!strcasecmp(name, "transferannouncesound")) {
919+
ast_string_field_set(xfer, transferannouncesound, value);
913920
} else {
914921
/* Unrecognized option */
915922
res = -1;
@@ -1801,6 +1808,8 @@ static int load_config(void)
18011808
DEFAULT_TRANSFER_RETRY_SOUND, xfer_handler, 0);
18021809
aco_option_register_custom(&cfg_info, "transferinvalidsound", ACO_EXACT, global_options,
18031810
DEFAULT_TRANSFER_INVALID_SOUND, xfer_handler, 0);
1811+
aco_option_register_custom(&cfg_info, "transferannouncesound", ACO_EXACT, global_options,
1812+
DEFAULT_TRANSFER_ANNOUNCE_SOUND, xfer_handler, 0);
18041813

18051814
aco_option_register_custom(&cfg_info, "pickupexten", ACO_EXACT, global_options,
18061815
DEFAULT_PICKUPEXTEN, pickup_handler, 0);

0 commit comments

Comments
 (0)