[Asterisk-code-review] app confbridge: Wrong language on playback of some files (asterisk[master])
Kevin Harwell
asteriskteam at digium.com
Tue Apr 21 12:51:52 CDT 2015
Kevin Harwell has uploaded a new change for review.
https://gerrit.asterisk.org/187
Change subject: app_confbridge: Wrong language on playback of some files
......................................................................
app_confbridge: Wrong language on playback of some files
It is possible to configure a specific language for a confbridge. This language
option was not being honored during playback of some files. Namely all those
files not played on the confbridge's playback channel. Added a language
parameter to the various playback functions, so that the configured language
set on the confbridge is now used instead of the one designated on the channel.
ASTERISK-24749 #close
Reported by: philippebolduc
Change-Id: I09303f368b39da02c379ea364adcc36d1d76ab89
---
M apps/app_confbridge.c
M apps/app_meetme.c
M include/asterisk/app.h
M include/asterisk/file.h
M main/app.c
M main/file.c
6 files changed, 102 insertions(+), 47 deletions(-)
git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/87/187/1
diff --git a/apps/app_confbridge.c b/apps/app_confbridge.c
index 0718887..d60baca 100644
--- a/apps/app_confbridge.c
+++ b/apps/app_confbridge.c
@@ -736,11 +736,12 @@
* \param bridge_channel Bridge channel to play file on
* \param channel Optional channel to play file on if bridge_channel not given
* \param filename The file name to playback
+ * \param language The playback language to use
*
* \retval -1 failure during playback, 0 on file was fully played, 1 on dtmf interrupt.
*/
static int play_file(struct ast_bridge_channel *bridge_channel, struct ast_channel *channel,
- const char *filename)
+ const char *filename, const char *language)
{
struct ast_channel *chan;
const char *stop_digits;
@@ -754,7 +755,7 @@
stop_digits = AST_DIGIT_NONE;
}
- digit = ast_stream_and_wait(chan, filename, stop_digits);
+ digit = ast_stream_and_wait_with_language(chan, filename, stop_digits, language);
if (digit < 0) {
ast_log(LOG_WARNING, "Failed to playback file '%s' to channel\n", filename);
return -1;
@@ -809,7 +810,7 @@
} else if (conference->activeusers == 2) {
if (user) {
/* Eep, there is one other person */
- if (play_file(bridge_channel, user->chan, only_one) < 0) {
+ if (play_file(bridge_channel, user->chan, only_one, user->b_profile.language) < 0) {
return -1;
}
} else {
@@ -818,15 +819,15 @@
} else {
/* Alas multiple others in here */
if (user) {
- if (ast_stream_and_wait(user->chan,
+ if (ast_stream_and_wait_with_language(user->chan,
there_are,
- "")) {
+ "", user->b_profile.language)) {
return -1;
}
if (ast_say_number(user->chan, conference->activeusers - 1, "", ast_channel_language(user->chan), NULL)) {
return -1;
}
- if (play_file(bridge_channel, user->chan, other_in_party) < 0) {
+ if (play_file(bridge_channel, user->chan, other_in_party, user->b_profile.language) < 0) {
return -1;
}
} else if (sound_file_exists(there_are) && sound_file_exists(other_in_party)) {
@@ -851,7 +852,7 @@
*/
static int play_prompt_to_user(struct confbridge_user *user, const char *filename)
{
- return ast_stream_and_wait(user->chan, filename, "");
+ return ast_stream_and_wait_with_language(user->chan, filename, "", user->b_profile.language);
}
static void handle_video_on_join(struct confbridge_conference *conference, struct ast_channel *chan, int marked)
@@ -1231,9 +1232,9 @@
ao2_unlock(conference_bridges);
ao2_ref(conference, -1);
ast_debug(1, "Conference '%s' is locked and caller is not an admin\n", conference_name);
- ast_stream_and_wait(user->chan,
+ ast_stream_and_wait_with_language(user->chan,
conf_get_sound(CONF_SOUND_LOCKED, user->b_profile.sounds),
- "");
+ "", user->b_profile.language);
return NULL;
}
@@ -1562,7 +1563,7 @@
conf_name, ast_channel_uniqueid(user->chan));
if (!(ast_test_flag(&user->u_profile, USER_OPT_ANNOUNCE_JOIN_LEAVE_REVIEW))) {
- res = ast_play_and_record(user->chan,
+ res = ast_play_and_record_with_language(user->chan,
"vm-rec-name",
user->name_rec_location,
10,
@@ -1571,7 +1572,8 @@
NULL,
ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE),
0,
- NULL);
+ NULL,
+ user->b_profile.language);
} else {
res = ast_record_review(user->chan,
"vm-rec-name",
@@ -1579,7 +1581,8 @@
10,
"sln",
&duration,
- NULL);
+ NULL,
+ user->b_profile.language);
}
if (res == -1) {
@@ -1773,7 +1776,7 @@
if (!quiet) {
const char *join_sound = conf_get_sound(CONF_SOUND_JOIN, user.b_profile.sounds);
- ast_stream_and_wait(chan, join_sound, "");
+ ast_stream_and_wait_with_language(chan, join_sound, "", user.b_profile.language);
ast_autoservice_start(chan);
play_sound_file(conference, join_sound);
ast_autoservice_stop(chan);
@@ -1838,9 +1841,9 @@
/* If the user was kicked from the conference play back the audio prompt for it */
if (!quiet && user.kicked) {
- res = ast_stream_and_wait(chan,
+ res = ast_stream_and_wait_with_language(chan,
conf_get_sound(CONF_SOUND_KICKED, user.b_profile.sounds),
- "");
+ "", user.b_profile.language);
}
/* Restore volume adjustments to previous values in case they were changed */
@@ -1888,7 +1891,7 @@
return play_file(bridge_channel, NULL, (mute ?
conf_get_sound(CONF_SOUND_MUTED, user->b_profile.sounds) :
- conf_get_sound(CONF_SOUND_UNMUTED, user->b_profile.sounds))) < 0;
+ conf_get_sound(CONF_SOUND_UNMUTED, user->b_profile.sounds)), user->b_profile.language) < 0;
}
static int action_toggle_mute_participants(struct confbridge_conference *conference, struct confbridge_user *user)
@@ -1917,7 +1920,7 @@
user->b_profile.sounds);
/* The host needs to hear it seperately, as they don't get the audio from play_sound_helper */
- ast_stream_and_wait(user->chan, sound_to_play, "");
+ ast_stream_and_wait_with_language(user->chan, sound_to_play, "", user->b_profile.language);
/* Announce to the group that all participants are muted */
ast_autoservice_start(user->chan);
@@ -1927,13 +1930,13 @@
return 0;
}
-static int action_playback(struct ast_bridge_channel *bridge_channel, const char *playback_file)
+static int action_playback(struct confbridge_user *user, const char *playback_file)
{
char *file_copy = ast_strdupa(playback_file);
char *file = NULL;
while ((file = strsep(&file_copy, "&"))) {
- if (ast_stream_and_wait(bridge_channel->chan, file, "")) {
+ if (ast_stream_and_wait_with_language(user->chan, file, "", user->b_profile.language)) {
ast_log(LOG_WARNING, "Failed to playback file %s to channel\n", file);
return -1;
}
@@ -2021,7 +2024,7 @@
if (!isadmin) {
play_file(bridge_channel, NULL,
- conf_get_sound(CONF_SOUND_ERROR_MENU, user->b_profile.sounds));
+ conf_get_sound(CONF_SOUND_ERROR_MENU, user->b_profile.sounds), user->b_profile.language);
ast_log(LOG_WARNING, "Only admin users can use the kick_last menu action. Channel %s of conf %s is not an admin.\n",
ast_channel_name(bridge_channel->chan),
conference->name);
@@ -2033,7 +2036,7 @@
|| (ast_test_flag(&last_user->u_profile, USER_OPT_ADMIN))) {
ao2_unlock(conference);
play_file(bridge_channel, NULL,
- conf_get_sound(CONF_SOUND_ERROR_MENU, user->b_profile.sounds));
+ conf_get_sound(CONF_SOUND_ERROR_MENU, user->b_profile.sounds), user->b_profile.language);
} else if (last_user && !last_user->kicked) {
last_user->kicked = 1;
pbx_builtin_setvar_helper(last_user->chan, "CONFBRIDGE_RESULT", "KICKED");
@@ -2114,7 +2117,7 @@
break;
case MENU_ACTION_PLAYBACK:
if (!stop_prompts) {
- res |= action_playback(bridge_channel, menu_action->data.playback_file);
+ res |= action_playback(user, menu_action->data.playback_file);
ast_test_suite_event_notify("CONF_MENU_PLAYBACK",
"Message: %s\r\nChannel: %s",
menu_action->data.playback_file, ast_channel_name(bridge_channel->chan));
@@ -2164,7 +2167,8 @@
res |= play_file(bridge_channel, NULL,
(conference->locked ?
conf_get_sound(CONF_SOUND_LOCKED_NOW, user->b_profile.sounds) :
- conf_get_sound(CONF_SOUND_UNLOCKED_NOW, user->b_profile.sounds))) < 0;
+ conf_get_sound(CONF_SOUND_UNLOCKED_NOW, user->b_profile.sounds)),
+ user->b_profile.language) < 0;
break;
case MENU_ACTION_ADMIN_KICK_LAST:
res |= action_kick_last(conference, bridge_channel, user);
diff --git a/apps/app_meetme.c b/apps/app_meetme.c
index ba83ead..5f33b97 100644
--- a/apps/app_meetme.c
+++ b/apps/app_meetme.c
@@ -3473,7 +3473,7 @@
if (ast_test_flag64(confflags, CONFFLAG_INTROUSERNOREVIEW) && !ast_fileexists(user->namerecloc, NULL, NULL))
res = ast_play_and_record(chan, "vm-rec-name", user->namerecloc, 10, "sln", &duration, NULL, ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE), 0, NULL);
else if (ast_test_flag64(confflags, CONFFLAG_INTROUSER) && !ast_fileexists(user->namerecloc, NULL, NULL))
- res = ast_record_review(chan, "vm-rec-name", user->namerecloc, 10, "sln", &duration, NULL);
+ res = ast_record_review(chan, "vm-rec-name", user->namerecloc, 10, "sln", &duration, NULL, NULL);
if (res == -1)
goto outrun;
diff --git a/include/asterisk/app.h b/include/asterisk/app.h
index 6171dd4..674d8b7 100644
--- a/include/asterisk/app.h
+++ b/include/asterisk/app.h
@@ -977,8 +977,12 @@
long *offsetms,
ast_waitstream_fr_cb cb);
+/*! \brief Play a stream and wait for a digit, returning the digit that was pressed. Use
+ the given language parameter to optionally override the channel's language */
+int ast_play_and_wait_with_language(struct ast_channel *chan, const char *fn, const char *language);
+
/*! \brief Play a stream and wait for a digit, returning the digit that was pressed */
-int ast_play_and_wait(struct ast_channel *chan, const char *fn);
+#define ast_play_and_wait(chan, fn) ast_play_and_wait_with_language(chan, fn, NULL)
/*!
* Possible actions to take if a recording already exists
@@ -1025,6 +1029,30 @@
/*!
* \brief Record a file based on input from a channel. Use default accept and cancel DTMF.
+ * This function will play "auth-thankyou" upon successful recording. Override the
+ * Channel's language with the given one.
+ *
+ * \param chan the channel being recorded
+ * \param playfile Filename of sound to play before recording begins
+ * \param recordfile Filename to save the recording
+ * \param maxtime_sec Longest possible message length in seconds
+ * \param fmt string containing all formats to be recorded delimited by '|'
+ * \param duration pointer to integer for storing length of the recording
+ * \param sound_duration pointer to integer for storing length of the recording minus all silence
+ * \param silencethreshold tolerance of noise levels that can be considered silence for the purpose of silence timeout, -1 for default
+ * \param maxsilence_ms length of time in milliseconds which will trigger a timeout from silence, -1 for default
+ * \param path Optional filesystem path to unlock
+ * \param language Optional language to use (default: Channel's language)
+ *
+ * \retval -1 failure or hangup
+ * \retval 'S' Recording ended from silence timeout
+ * \retval 't' Recording ended from the message exceeding the maximum duration
+ * \retval dtmfchar Recording ended via the return value's DTMF character for either cancel or accept.
+ */
+int ast_play_and_record_with_language(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime_sec, const char *fmt, int *duration, int *sound_duration, int silencethreshold, int maxsilence_ms, const char *path, const char *language);
+
+/*!
+ * \brief Record a file based on input from a channel. Use default accept and cancel DTMF.
* This function will play "auth-thankyou" upon successful recording.
*
* \param chan the channel being recorded
@@ -1043,7 +1071,8 @@
* \retval 't' Recording ended from the message exceeding the maximum duration
* \retval dtmfchar Recording ended via the return value's DTMF character for either cancel or accept.
*/
-int ast_play_and_record(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime_sec, const char *fmt, int *duration, int *sound_duration, int silencethreshold, int maxsilence_ms, const char *path);
+#define ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, sound_duration, silence_threshold, maxsilence, path) \
+ ast_play_and_record_with_language(chan, playfile, recordfile, maxtime, fmt, duration, sound_duration, silence_threshold, maxsilence, path, NULL)
/*!
* \brief Record a file based on input frm a channel. Recording is performed in 'prepend' mode which works a little differently from normal recordings
@@ -1360,7 +1389,8 @@
int ast_app_dtget(struct ast_channel *chan, const char *context, char *collect, size_t size, int maxlen, int timeout);
/*! \brief Allow to record message and have a review option */
-int ast_record_review(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, const char *path);
+int ast_record_review(struct ast_channel *chan, const char *playfile, const char *recordfile,
+ int maxtime, const char *fmt, int *duration, const char *path, const char *language);
/*!
* \brief Decode an encoded control or extended ASCII character
diff --git a/include/asterisk/file.h b/include/asterisk/file.h
index c71866e..8c42a7b 100644
--- a/include/asterisk/file.h
+++ b/include/asterisk/file.h
@@ -77,6 +77,20 @@
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang);
/*!
+ * \brief Stream a file until digit
+ *
+ * If the file name is non-empty, try to play it. If the language is NULL
+ * default to using the channel's.
+ *
+ * \note If digits == "" then we can simply check for non-zero.
+ * \return 0 if success.
+ * \retval -1 if error.
+ * \retval digit if interrupted by a digit.
+ */
+int ast_stream_and_wait_with_language(struct ast_channel *chan, const char *file,
+ const char *digits, const char *language);
+
+/*!
* \brief stream file until digit
* If the file name is non-empty, try to play it.
* \note If digits == "" then we can simply check for non-zero.
@@ -84,7 +98,8 @@
* \retval -1 if error.
* \retval digit if interrupted by a digit.
*/
-int ast_stream_and_wait(struct ast_channel *chan, const char *file, const char *digits);
+#define ast_stream_and_wait(chan, file, digits) \
+ ast_stream_and_wait_with_language(chan, file, digits, NULL)
/*!
* \brief Stops a stream
diff --git a/main/app.c b/main/app.c
index 2046ac8..8f23a73 100644
--- a/main/app.c
+++ b/main/app.c
@@ -1372,11 +1372,11 @@
return res;
}
-int ast_play_and_wait(struct ast_channel *chan, const char *fn)
+int ast_play_and_wait_with_language(struct ast_channel *chan, const char *fn, const char *language)
{
int d = 0;
- if ((d = ast_streamfile(chan, fn, ast_channel_language(chan)))) {
+ if ((d = ast_streamfile(chan, fn, language ?: ast_channel_language(chan)))) {
return d;
}
@@ -1478,13 +1478,15 @@
* \param acceptdtmf DTMF digits that will end the recording.
* \param canceldtmf DTMF digits that will cancel the recording.
* \param skip_confirmation_sound If true, don't play auth-thankyou at end. Nice for custom recording prompts in apps.
+ * \param if_exists action to take if recording already exists
+ * \param language Optional language to use for playback (default: channel's language)
*
* \retval -1 failure or hangup
* \retval 'S' Recording ended from silence timeout
* \retval 't' Recording ended from the message exceeding the maximum duration, or via DTMF in prepend mode
* \retval dtmfchar Recording ended via the return value's DTMF character for either cancel or accept.
*/
-static int __ast_play_and_record(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int *sound_duration, int beep, int silencethreshold, int maxsilence, const char *path, int prepend, const char *acceptdtmf, const char *canceldtmf, int skip_confirmation_sound, enum ast_record_if_exists if_exists)
+static int __ast_play_and_record(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int *sound_duration, int beep, int silencethreshold, int maxsilence, const char *path, int prepend, const char *acceptdtmf, const char *canceldtmf, int skip_confirmation_sound, enum ast_record_if_exists if_exists, const char *language)
{
int d = 0;
char *fmts;
@@ -1539,10 +1541,10 @@
if (playfile || beep) {
if (!beep) {
- d = ast_play_and_wait(chan, playfile);
+ d = ast_play_and_wait_with_language(chan, playfile, language);
}
if (d > -1) {
- d = ast_stream_and_wait(chan, "beep", "");
+ d = ast_stream_and_wait_with_language(chan, "beep", "", language);
}
if (d < 0) {
return -1;
@@ -1880,7 +1882,7 @@
}
ao2_cleanup(rfmt);
if ((outmsg == 2) && (!skip_confirmation_sound)) {
- ast_stream_and_wait(chan, "auth-thankyou", "");
+ ast_stream_and_wait_with_language(chan, "auth-thankyou", "", language);
}
if (sildet) {
ast_dsp_free(sildet);
@@ -1893,17 +1895,17 @@
int ast_play_and_record_full(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int *sound_duration, int beep, int silencethreshold, int maxsilence, const char *path, const char *acceptdtmf, const char *canceldtmf, int skip_confirmation_sound, enum ast_record_if_exists if_exists)
{
- return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, sound_duration, beep, silencethreshold, maxsilence, path, 0, S_OR(acceptdtmf, ""), S_OR(canceldtmf, default_canceldtmf), skip_confirmation_sound, if_exists);
+ return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, sound_duration, beep, silencethreshold, maxsilence, path, 0, S_OR(acceptdtmf, ""), S_OR(canceldtmf, default_canceldtmf), skip_confirmation_sound, if_exists, NULL);
}
-int ast_play_and_record(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int *sound_duration, int silencethreshold, int maxsilence, const char *path)
+int ast_play_and_record_with_language(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int *sound_duration, int silencethreshold, int maxsilence, const char *path, const char *language)
{
- return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, sound_duration, 0, silencethreshold, maxsilence, path, 0, default_acceptdtmf, default_canceldtmf, 0, AST_RECORD_IF_EXISTS_OVERWRITE);
+ return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, sound_duration, 0, silencethreshold, maxsilence, path, 0, default_acceptdtmf, default_canceldtmf, 0, AST_RECORD_IF_EXISTS_OVERWRITE, language);
}
int ast_play_and_prepend(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int *duration, int *sound_duration, int beep, int silencethreshold, int maxsilence)
{
- return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, sound_duration, beep, silencethreshold, maxsilence, NULL, 1, default_acceptdtmf, default_canceldtmf, 1, AST_RECORD_IF_EXISTS_OVERWRITE);
+ return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, sound_duration, beep, silencethreshold, maxsilence, NULL, 1, default_acceptdtmf, default_canceldtmf, 1, AST_RECORD_IF_EXISTS_OVERWRITE, NULL);
}
/* Channel group core functions */
@@ -2397,7 +2399,8 @@
return r;
}
-int ast_record_review(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, const char *path)
+int ast_record_review(struct ast_channel *chan, const char *playfile, const char *recordfile,
+ int maxtime, const char *fmt, int *duration, const char *path, const char *language)
{
int silencethreshold;
int maxsilence = 0;
@@ -2427,21 +2430,23 @@
cmd = '3';
break;
} else {
- ast_stream_and_wait(chan, "vm-msgsaved", "");
+ ast_stream_and_wait_with_language(chan, "vm-msgsaved", "", language);
cmd = 't';
return res;
}
case '2':
/* Review */
ast_verb(3, "Reviewing the recording\n");
- cmd = ast_stream_and_wait(chan, recordfile, AST_DIGIT_ANY);
+ cmd = ast_stream_and_wait_with_language(chan, recordfile, AST_DIGIT_ANY, language);
break;
case '3':
message_exists = 0;
/* Record */
ast_verb(3, "R%secording\n", recorded == 1 ? "e-r" : "");
recorded = 1;
- if ((cmd = ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, NULL, silencethreshold, maxsilence, path)) == -1) {
+ if ((cmd = ast_play_and_record_with_language(
+ chan, playfile, recordfile, maxtime,
+ fmt, duration, NULL, silencethreshold, maxsilence, path, language)) == -1) {
/* User has hung up, no options to give */
return cmd;
}
@@ -2463,13 +2468,13 @@
case '9':
case '*':
case '#':
- cmd = ast_play_and_wait(chan, "vm-sorry");
+ cmd = ast_play_and_wait_with_language(chan, "vm-sorry", language);
break;
default:
if (message_exists) {
- cmd = ast_play_and_wait(chan, "vm-review");
+ cmd = ast_play_and_wait_with_language(chan, "vm-review", language);
} else {
- if (!(cmd = ast_play_and_wait(chan, "vm-torerecord"))) {
+ if (!(cmd = ast_play_and_wait_with_language(chan, "vm-torerecord", language))) {
cmd = ast_waitfordigit(chan, 600);
}
}
diff --git a/main/file.c b/main/file.c
index acd2cc6..897749e 100644
--- a/main/file.c
+++ b/main/file.c
@@ -1627,11 +1627,12 @@
* Return 0 if success, -1 if error, digit if interrupted by a digit.
* If digits == "" then we can simply check for non-zero.
*/
-int ast_stream_and_wait(struct ast_channel *chan, const char *file, const char *digits)
+int ast_stream_and_wait_with_language(struct ast_channel *chan, const char *file,
+ const char *digits, const char *language)
{
int res = 0;
if (!ast_strlen_zero(file)) {
- res = ast_streamfile(chan, file, ast_channel_language(chan));
+ res = ast_streamfile(chan, file, language ?: ast_channel_language(chan));
if (!res) {
res = ast_waitstream(chan, digits);
}
--
To view, visit https://gerrit.asterisk.org/187
To unsubscribe, visit https://gerrit.asterisk.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I09303f368b39da02c379ea364adcc36d1d76ab89
Gerrit-PatchSet: 1
Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-Owner: Kevin Harwell <kharwell at digium.com>
More information about the asterisk-code-review
mailing list