summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/app_voicemail.c30
-rw-r--r--configs/voicemail.conf.sample6
-rw-r--r--include/asterisk/app.h66
-rw-r--r--main/app.c21
4 files changed, 103 insertions, 20 deletions
diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c
index 764a44520..da2d99213 100644
--- a/apps/app_voicemail.c
+++ b/apps/app_voicemail.c
@@ -863,6 +863,18 @@ static char vm_mismatch[80] = "vm-mismatch";
static char vm_invalid_password[80] = "vm-invalid-password";
static char vm_pls_try_again[80] = "vm-pls-try-again";
+/*
+ * XXX If we have the time, motivation, etc. to fix up this prompt, one of the following would be appropriate:
+ * 1. create a sound along the lines of "Please try again. When done, press the pound key" which could be spliced
+ * from existing sound clips. This would require some programming changes in the area of vm_forward options and also
+ * app.c's __ast_play_and_record function
+ * 2. create a sound prompt saying "Please try again. When done recording, press any key to stop and send the prepended
+ * message." At the time of this comment, I think this would require new voice work to be commissioned.
+ * 3. Something way different like providing instructions before a time out or a post-recording menu. This would require
+ * more effort than either of the other two.
+ */
+static char vm_prepend_timeout[80] = "then-press-pound";
+
static struct ast_flags globalflags = {0};
static int saydurationminfo;
@@ -6866,7 +6878,10 @@ static int vm_forwardoptions(struct ast_channel *chan, struct ast_vm_user *vmu,
ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
cmd = ast_play_and_prepend(chan, NULL, msgfile, 0, vm_fmts, &prepend_duration, 1, silencethreshold, maxsilence);
- if (cmd == 'S') {
+
+ if (cmd == 'S') { /* If we timed out, tell the user it didn't work properly and clean up the files */
+ ast_stream_and_wait(chan, vm_pls_try_again, ""); /* this might be removed if a proper vm_prepend_timeout is ever recorded */
+ ast_stream_and_wait(chan, vm_prepend_timeout, "");
ast_filerename(backup, msgfile, NULL);
}
@@ -6903,6 +6918,9 @@ static int vm_forwardoptions(struct ast_channel *chan, struct ast_vm_user *vmu,
cmd = '*';
break;
default:
+ /* If time_out and return to menu, reset already_recorded */
+ already_recorded = 0;
+
cmd = ast_play_and_wait(chan, "vm-forwardoptions");
/* "Press 1 to prepend a message or 2 to forward the message without prepending" */
if (!cmd)
@@ -6912,8 +6930,9 @@ static int vm_forwardoptions(struct ast_channel *chan, struct ast_vm_user *vmu,
cmd = ast_waitfordigit(chan, 6000);
if (!cmd)
retries++;
- if (retries > 3)
- cmd = 't';
+ if (retries > 3) {
+ cmd = '*'; /* Let's cancel this beast */
+ }
}
}
@@ -6928,7 +6947,7 @@ static int vm_forwardoptions(struct ast_channel *chan, struct ast_vm_user *vmu,
rename(backup_textfile, textfile);
}
- if (cmd == 't' || cmd == 'S')
+ if (cmd == 't' || cmd == 'S') /* XXX entering this block with a value of 'S' is probably no longer possible. */
cmd = 0;
return cmd;
}
@@ -12138,6 +12157,9 @@ static int load_config(int reload)
if ((val = ast_variable_retrieve(cfg, "general", "vm-pls-try-again"))) {
ast_copy_string(vm_pls_try_again, val, sizeof(vm_pls_try_again));
}
+ if ((val = ast_variable_retrieve(cfg, "general", "vm-prepend-timeout"))) {
+ ast_copy_string(vm_prepend_timeout, val, sizeof(vm_prepend_timeout));
+ }
/* load configurable audio prompts */
if ((val = ast_variable_retrieve(cfg, "general", "listen-control-forward-key")) && is_valid_dtmf(val))
ast_copy_string(listen_control_forward_key, val, sizeof(listen_control_forward_key));
diff --git a/configs/voicemail.conf.sample b/configs/voicemail.conf.sample
index 8a75f2a66..318f682b7 100644
--- a/configs/voicemail.conf.sample
+++ b/configs/voicemail.conf.sample
@@ -318,6 +318,12 @@ sendvoicemail=yes ; Allow the user to compose and send a voicemail while inside
; vm-pls-try-again=custom_sound
; Customize which sound file is used instead of the
; default prompt that says "Please try again."
+; vm-prepend-timeout=custom_sound
+ ; Customize which sound file is used when the user
+ ; times out while recording a prepend message instead
+ ; of the default prompt that says "then press pound"
+ ; note that this will currently follow vm-pls-try-again.
+ ; this behavior is subject to change in the near future.
; listen-control-forward-key=# ; Customize the key that fast-forwards message playback
; listen-control-reverse-key=* ; Customize the key that rewinds message playback
; listen-control-pause-key=0 ; Customize the key that pauses/unpauses message playback
diff --git a/include/asterisk/app.h b/include/asterisk/app.h
index 850afcd83..fe74e0bdd 100644
--- a/include/asterisk/app.h
+++ b/include/asterisk/app.h
@@ -270,18 +270,68 @@ int ast_control_streamfile(struct ast_channel *chan, const char *file, const cha
/*! \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);
+/*!
+ * \brief Record a file based on input from a channel
+ * This function will play "auth-thankyou" upon successful recording.
+ *
+ * \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 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 acceptdtmf Character of DTMF to end and accept the recording
+ * \param canceldtmf Character of DTMF to end and cancel the recording
+ *
+ * \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_full(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime_sec, const char *fmt, int *duration, int silencethreshold, int maxsilence_ms, const char *path, const char *acceptdtmf, const char *canceldtmf);
-/*! \brief Record a file for a max amount of time (in seconds), in a given list of formats separated by '|', outputting the duration of the recording, and with a maximum
- \n
- permitted silence time in milliseconds of 'maxsilence' under 'silencethreshold' or use '-1' for either or both parameters for defaults.
- calls ast_unlock_path() on 'path' if passed */
+/*!
+ * \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
+ * \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 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
+ *
+ * \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(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime_sec, const char *fmt, int *duration, int silencethreshold, int maxsilence_ms, const char *path);
-/*! \brief Record a message and prepend the message to the given record file after
- playing the optional playfile (or a beep), storing the duration in
- 'duration' and with a maximum permitted silence time in milliseconds of 'maxsilence' under
- 'silencethreshold' or use '-1' for either or both parameters for defaults. */
+/*!
+ * \brief Record a file based on input frm a channel. Recording is performed in 'prepend' mode which works a little differently from normal recordings
+ * This function will not play a success message due to post-recording control in the application this was added for.
+ *
+ * \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 beep whether to play a beep to prompt the recording
+ * \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.
+ *
+ * \retval -1 failure or hangup
+ * \retval 'S' Recording ended from silence timeout
+ * \retval 't' Recording either exceeded maximum duration or the call was ended via DTMF
+ */
int ast_play_and_prepend(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime_sec, char *fmt, int *duration, int beep, int silencethreshold, int maxsilence_ms);
enum ast_getdata_result {
diff --git a/main/app.c b/main/app.c
index 3594b0b86..eef527c56 100644
--- a/main/app.c
+++ b/main/app.c
@@ -716,19 +716,24 @@ static int global_maxsilence = 0;
* \param chan Channel to playback to/record from.
* \param playfile Filename of sound to play before recording begins.
* \param recordfile Filename to record to.
- * \param maxtime Maximum length of recording (in milliseconds).
+ * \param maxtime Maximum length of recording (in seconds).
* \param fmt Format(s) to record message in. Multiple formats may be specified by separating them with a '|'.
* \param duration Where to store actual length of the recorded message (in milliseconds).
* \param beep Whether to play a beep before starting to record.
* \param silencethreshold
* \param maxsilence Length of silence that will end a recording (in milliseconds).
* \param path Optional filesystem path to unlock.
- * \param prepend If true, prepend the recorded audio to an existing file.
+ * \param prepend If true, prepend the recorded audio to an existing file and follow prepend mode recording rules
* \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.
+ *
+ * \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 beep, int silencethreshold, int maxsilence, const char *path, int prepend, const char *acceptdtmf, const char *canceldtmf)
+static int __ast_play_and_record(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int beep, int silencethreshold, int maxsilence, const char *path, int prepend, const char *acceptdtmf, const char *canceldtmf, int skip_confirmation_sound)
{
int d = 0;
char *fmts;
@@ -1010,7 +1015,7 @@ static int __ast_play_and_record(struct ast_channel *chan, const char *playfile,
if (rfmt.id && ast_set_read_format(chan, &rfmt)) {
ast_log(LOG_WARNING, "Unable to restore format %s to channel '%s'\n", ast_getformatname(&rfmt), chan->name);
}
- if (outmsg == 2) {
+ if ((outmsg == 2) && (!skip_confirmation_sound)) {
ast_stream_and_wait(chan, "auth-thankyou", "");
}
if (sildet) {
@@ -1024,17 +1029,17 @@ static const char default_canceldtmf[] = "";
int ast_play_and_record_full(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *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, 0, silencethreshold, maxsilence, path, 0, S_OR(acceptdtmf, default_acceptdtmf), S_OR(canceldtmf, default_canceldtmf));
+ return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, 0, silencethreshold, maxsilence, path, 0, S_OR(acceptdtmf, default_acceptdtmf), S_OR(canceldtmf, default_canceldtmf), 0);
}
int ast_play_and_record(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int silencethreshold, int maxsilence, const char *path)
{
- return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, 0, silencethreshold, maxsilence, path, 0, default_acceptdtmf, default_canceldtmf);
+ return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, 0, silencethreshold, maxsilence, path, 0, default_acceptdtmf, default_canceldtmf, 0);
}
int ast_play_and_prepend(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int *duration, int beep, int silencethreshold, int maxsilence)
{
- return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, beep, silencethreshold, maxsilence, NULL, 1, default_acceptdtmf, default_canceldtmf);
+ return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, beep, silencethreshold, maxsilence, NULL, 1, default_acceptdtmf, default_canceldtmf, 1);
}
/* Channel group core functions */