[Asterisk-code-review] app confbridge: Wrong language on playback of some files (asterisk[11])
Kevin Harwell
asteriskteam at digium.com
Tue Apr 21 12:51:22 CDT 2015
Kevin Harwell has uploaded a new change for review.
https://gerrit.asterisk.org/185
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 include/asterisk/app.h
M include/asterisk/file.h
M main/app.c
M main/file.c
5 files changed, 85 insertions(+), 38 deletions(-)
git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/85/185/1
diff --git a/apps/app_confbridge.c b/apps/app_confbridge.c
index cd4c814..ddbd41d 100644
--- a/apps/app_confbridge.c
+++ b/apps/app_confbridge.c
@@ -666,12 +666,13 @@
*
* \retval -1 failure during playback, 0 on file was fully played, 1 on dtmf interrupt.
*/
-static int play_file(struct ast_channel *channel, const char *filename, int allow_dtmf_interrupt)
+static int play_file(struct conference_bridge_user *conference_bridge_user, const char *filename, int allow_dtmf_interrupt)
{
const char *stop_digits = allow_dtmf_interrupt ? AST_DIGIT_ANY : AST_DIGIT_NONE;
int digit;
+ struct ast_channel *channel = conference_bridge_user->chan;
- digit = ast_stream_and_wait(channel, filename, stop_digits);
+ digit = ast_stream_and_wait_with_language(channel, filename, stop_digits, conference_bridge_user->b_profile.language);
if (digit < 0) {
ast_log(LOG_WARNING, "Failed to playback file '%s' to channel\n", filename);
return -1;
@@ -733,7 +734,7 @@
} else if (conference_bridge->activeusers == 2) {
if (conference_bridge_user) {
/* Eep, there is one other person */
- if (play_file(conference_bridge_user->chan, only_one, allow_dtmf_interrupt) < 0) {
+ if (play_file(conference_bridge_user, only_one, allow_dtmf_interrupt) < 0) {
return -1;
}
} else {
@@ -742,15 +743,15 @@
} else {
/* Alas multiple others in here */
if (conference_bridge_user) {
- if (ast_stream_and_wait(conference_bridge_user->chan,
+ if (ast_stream_and_wait_with_language(conference_bridge_user->chan,
there_are,
- "")) {
+ "", conference_bridge_user->b_profile.language)) {
return -1;
}
if (ast_say_number(conference_bridge_user->chan, conference_bridge->activeusers - 1, "", ast_channel_language(conference_bridge_user->chan), NULL)) {
return -1;
}
- if (play_file(conference_bridge_user->chan, other_in_party, allow_dtmf_interrupt) < 0) {
+ if (play_file(conference_bridge_user, other_in_party, allow_dtmf_interrupt) < 0) {
return -1;
}
} else if (sound_file_exists(there_are) && sound_file_exists(other_in_party)) {
@@ -775,7 +776,7 @@
*/
static int play_prompt_to_user(struct conference_bridge_user *cbu, const char *filename)
{
- return ast_stream_and_wait(cbu->chan, filename, "");
+ return ast_stream_and_wait_with_language(cbu->chan, filename, "", cbu->b_profile.language);
}
static void handle_video_on_join(struct conference_bridge *conference_bridge, struct ast_channel *chan, int marked)
@@ -1163,9 +1164,9 @@
ao2_unlock(conference_bridges);
ao2_ref(conference_bridge, -1);
ast_debug(1, "Conference '%s' is locked and caller is not an admin\n", name);
- ast_stream_and_wait(conference_bridge_user->chan,
+ ast_stream_and_wait_with_language(conference_bridge_user->chan,
conf_get_sound(CONF_SOUND_LOCKED, conference_bridge_user->b_profile.sounds),
- "");
+ "", conference_bridge_user->b_profile.language);
return NULL;
}
@@ -1524,7 +1525,7 @@
"%s/confbridge-name-%s-%s", destdir,
conf_name, ast_channel_uniqueid(user->chan));
- res = ast_play_and_record(user->chan,
+ res = ast_play_and_record_with_language(user->chan,
"vm-rec-name",
user->name_rec_location,
10,
@@ -1533,7 +1534,8 @@
NULL,
ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE),
0,
- NULL);
+ NULL,
+ user->b_profile.language);
if (res == -1) {
user->name_rec_location[0] = '\0';
@@ -1709,7 +1711,7 @@
if (!quiet) {
const char *join_sound = conf_get_sound(CONF_SOUND_JOIN, conference_bridge_user.b_profile.sounds);
- ast_stream_and_wait(chan, join_sound, "");
+ ast_stream_and_wait_with_language(chan, join_sound, "", conference_bridge_user.b_profile.language);
ast_autoservice_start(chan);
play_sound_file(conference_bridge, join_sound);
ast_autoservice_stop(chan);
@@ -1762,9 +1764,9 @@
/* If the user was kicked from the conference play back the audio prompt for it */
if (!quiet && conference_bridge_user.kicked) {
- res = ast_stream_and_wait(chan,
+ res = ast_stream_and_wait_with_language(chan,
conf_get_sound(CONF_SOUND_KICKED, conference_bridge_user.b_profile.sounds),
- "");
+ "", conference_bridge_user.b_profile.language);
}
/* Restore volume adjustments to previous values in case they were changed */
@@ -1805,7 +1807,7 @@
conference_bridge_user->b_profile.name,
ast_channel_name(chan));
- return play_file(chan, (mute ?
+ return play_file(conference_bridge_user, (mute ?
conf_get_sound(CONF_SOUND_MUTED, conference_bridge_user->b_profile.sounds) :
conf_get_sound(CONF_SOUND_UNMUTED, conference_bridge_user->b_profile.sounds)), 1) < 0;
}
@@ -1836,7 +1838,7 @@
conference_bridge_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(conference_bridge_user->chan, sound_to_play, "");
+ ast_stream_and_wait_with_language(conference_bridge_user->chan, sound_to_play, "", conference_bridge_user->b_profile.language);
/* Announce to the group that all participants are muted */
ast_autoservice_start(conference_bridge_user->chan);
@@ -1846,13 +1848,13 @@
return 0;
}
-static int action_playback(struct ast_bridge_channel *bridge_channel, const char *playback_file)
+static int action_playback(struct conference_bridge_user *conference_bridge_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(conference_bridge_user->chan, file, "", conference_bridge_user->b_profile.language)) {
ast_log(LOG_WARNING, "Failed to playback file %s to channel\n", file);
return -1;
}
@@ -1938,7 +1940,7 @@
int isadmin = ast_test_flag(&conference_bridge_user->u_profile, USER_OPT_ADMIN);
if (!isadmin) {
- play_file(conference_bridge_user->chan,
+ play_file(conference_bridge_user,
conf_get_sound(CONF_SOUND_ERROR_MENU, conference_bridge_user->b_profile.sounds), 1);
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(conference_bridge_user->chan),
@@ -1950,7 +1952,7 @@
if (((last_participant = AST_LIST_LAST(&conference_bridge->active_list)) == conference_bridge_user)
|| (ast_test_flag(&last_participant->u_profile, USER_OPT_ADMIN))) {
ao2_unlock(conference_bridge);
- play_file(conference_bridge_user->chan,
+ play_file(conference_bridge_user,
conf_get_sound(CONF_SOUND_ERROR_MENU, conference_bridge_user->b_profile.sounds), 1);
} else if (last_participant && !last_participant->kicked) {
last_participant->kicked = 1;
@@ -2033,7 +2035,7 @@
break;
case MENU_ACTION_PLAYBACK:
if (!stop_prompts) {
- res |= action_playback(bridge_channel, menu_action->data.playback_file);
+ res |= action_playback( conference_bridge_user, menu_action->data.playback_file);
}
break;
case MENU_ACTION_RESET_LISTENING:
@@ -2077,7 +2079,7 @@
break;
}
conference_bridge->locked = (!conference_bridge->locked ? 1 : 0);
- res |= play_file(bridge_channel->chan,
+ res |= play_file(conference_bridge_user,
(conference_bridge->locked ?
conf_get_sound(CONF_SOUND_LOCKED_NOW, conference_bridge_user->b_profile.sounds) :
conf_get_sound(CONF_SOUND_UNLOCKED_NOW, conference_bridge_user->b_profile.sounds)), 1) < 0;
diff --git a/include/asterisk/app.h b/include/asterisk/app.h
index d10a0a6..b76ffef 100644
--- a/include/asterisk/app.h
+++ b/include/asterisk/app.h
@@ -661,8 +661,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)
/*!
* \brief Record a file based on input from a channel
@@ -690,6 +694,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
@@ -708,7 +736,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
diff --git a/include/asterisk/file.h b/include/asterisk/file.h
index ec2a38e..16c75d4 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 a31fa0c..cedb71d 100644
--- a/main/app.c
+++ b/main/app.c
@@ -1081,11 +1081,11 @@
return control_streamfile(chan, file, fwd, rev, stop, suspend, restart, skipms, offsetms, NULL);
}
-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;
}
@@ -1115,13 +1115,14 @@
* \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 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)
+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, const char *language)
{
int d = 0;
char *fmts;
@@ -1159,10 +1160,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;
@@ -1428,7 +1429,7 @@
ast_log(LOG_WARNING, "Unable to restore format %s to channel '%s'\n", ast_getformatname(&rfmt), ast_channel_name(chan));
}
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);
@@ -1441,17 +1442,16 @@
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 silencethreshold, int maxsilence, const char *path, const char *acceptdtmf, const char *canceldtmf)
{
- return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, sound_duration, 0, silencethreshold, maxsilence, path, 0, S_OR(acceptdtmf, default_acceptdtmf), S_OR(canceldtmf, default_canceldtmf), 0);
+ return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, sound_duration, 0, silencethreshold, maxsilence, path, 0, S_OR(acceptdtmf, default_acceptdtmf), S_OR(canceldtmf, default_canceldtmf), 0, 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)
-{
- return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, sound_duration, 0, silencethreshold, maxsilence, path, 0, default_acceptdtmf, default_canceldtmf, 0);
+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, 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);
+ return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, sound_duration, beep, silencethreshold, maxsilence, NULL, 1, default_acceptdtmf, default_canceldtmf, 1, NULL);
}
/* Channel group core functions */
diff --git a/main/file.c b/main/file.c
index 436aae9..fb53fb3 100644
--- a/main/file.c
+++ b/main/file.c
@@ -1458,11 +1458,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/185
To unsubscribe, visit https://gerrit.asterisk.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I09303f368b39da02c379ea364adcc36d1d76ab89
Gerrit-PatchSet: 1
Gerrit-Project: asterisk
Gerrit-Branch: 11
Gerrit-Owner: Kevin Harwell <kharwell at digium.com>
More information about the asterisk-code-review
mailing list