Merged revisions 329528 via svnmerge from
authorJonathan Rose <jrose@digium.com>
Tue, 26 Jul 2011 14:17:13 +0000 (14:17 +0000)
committerJonathan Rose <jrose@digium.com>
Tue, 26 Jul 2011 14:17:13 +0000 (14:17 +0000)
https://origsvn.digium.com/svn/asterisk/branches/10

................
  r329528 | jrose | 2011-07-26 08:52:34 -0500 (Tue, 26 Jul 2011) | 24 lines

  Merged revisions 329527 via svnmerge from
  https://origsvn.digium.com/svn/asterisk/branches/1.8

  ........
    r329527 | jrose | 2011-07-26 08:25:35 -0500 (Tue, 26 Jul 2011) | 17 lines

    Fixes some voicemail forwarding behavior based around prepend mode.

    Formerly, prepend forwarding would have the user record a message with no useful prompt
    and an expectation for the user to push a button on the phone when finished recording.
    If a length of silence was detected instead, the recording would be canceled and the user
    would re-enter the voicemail forwarding menu. Subsequent time-outs in prepend recording
    would also bug out in the sense that they would write over the original message and get
    sent to the recipient regardless of whether they timed out or were accepted. This patch
    fixes this issue and adds a prompt which will be played after a timeout informing the
    user that they needed to press a button. Currently, the sound files that we have are
    somewhat inadquate for this, so after the call we simply have Allison say "Please try
    again. Then press pound." which actually relies on two separate sound files. Just one
    would be more appropriate.

    reporter: Vlad Povorozniuc
    Review: https://reviewboard.asterisk.org/r/1327/
  ........
................

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@329530 65c4cc65-6c06-0410-ace0-fbb531ad65f3

apps/app_voicemail.c
configs/voicemail.conf.sample
include/asterisk/app.h
main/app.c

index 764a445..da2d992 100644 (file)
@@ -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));
index 8a75f2a..318f682 100644 (file)
@@ -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
index 850afcd..fe74e0b 100644 (file)
@@ -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 {
index 3594b0b..eef527c 100644 (file)
@@ -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 */