dect
/
asterisk
Archived
13
0
Fork 0

Fix 4 bugs in voicemail. #7064 ( supczinskib and jcollie )

git-svn-id: http://svn.digium.com/svn/asterisk/trunk@24981 f38db490-d61c-443f-a65b-d21fe96a405b
This commit is contained in:
bweschke 2006-05-05 19:10:11 +00:00
parent 4098fd2400
commit 0ff9a2f25d
3 changed files with 70 additions and 33 deletions

41
app.c
View File

@ -535,7 +535,23 @@ int ast_play_and_wait(struct ast_channel *chan, const char *fn)
static int global_silence_threshold = 128;
static int global_maxsilence = 0;
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)
/*! Optionally play a sound file or a beep, then record audio and video from the channel.
* @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 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 acceptdtmf DTMF digits that will end the recording.
* @param canceldtmf DTMF digits that will cancel the recording.
*/
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 d = 0;
char *fmts;
@ -700,18 +716,17 @@ static int __ast_play_and_record(struct ast_channel *chan, const char *playfile,
outmsg = 2;
break;
}
if (f->subclass == '#') {
if (strchr(acceptdtmf, f->subclass)) {
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "User ended message by pressing %c\n", f->subclass);
res = '#';
res = f->subclass;
outmsg = 2;
break;
}
if (f->subclass == '0') {
/* Check for a '0' during message recording also, in case caller wants operator */
if (strchr(canceldtmf, f->subclass)) {
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "User cancelled by pressing %c\n", f->subclass);
res = '0';
ast_verbose(VERBOSE_PREFIX_3 "User cancelled message by pressing %c\n", f->subclass);
res = f->subclass;
outmsg = 0;
break;
}
@ -793,14 +808,22 @@ static int __ast_play_and_record(struct ast_channel *chan, const char *playfile,
return res;
}
static char default_acceptdtmf[] = "#";
static 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));
}
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);
return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, 0, silencethreshold, maxsilence, path, 0, default_acceptdtmf, default_canceldtmf);
}
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);
return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, beep, silencethreshold, maxsilence, NULL, 1, default_acceptdtmf, default_canceldtmf);
}
/* Channel group core functions */

View File

@ -669,13 +669,9 @@ static void vm_change_password(struct ast_vm_user *vmu, const char *newpassword)
char *user = NULL, *pass = NULL, *rest = NULL, *comment = NULL, *tmpctx = NULL, *tmpctxend = NULL;
/* Read in the line */
fgets(inbuf, sizeof(inbuf), configin);
linenum++;
if (ast_strlen_zero(inbuf)) {
fprintf(configout, "\n");
if (fgets(inbuf, sizeof(inbuf), configin) == NULL)
continue;
}
linenum++;
/* Make a backup of it */
ast_copy_string(orig, inbuf, sizeof(orig));
@ -2409,6 +2405,7 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_
int duration = 0;
int ausemacro = 0;
int ousemacro = 0;
int ouseexten = 0;
char date[256];
char dir[256];
char fn[256];
@ -2464,14 +2461,20 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_
create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX");
/* Check current or macro-calling context for special extensions */
if (!ast_strlen_zero(vmu->exit)) {
if (ast_exists_extension(chan, vmu->exit, "o", 1, chan->cid.cid_num))
if (ast_test_flag(vmu, VM_OPERATOR)) {
if (!ast_strlen_zero(vmu->exit)) {
if (ast_exists_extension(chan, vmu->exit, "o", 1, chan->cid.cid_num)) {
strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
ouseexten = 1;
}
} else if (ast_exists_extension(chan, chan->context, "o", 1, chan->cid.cid_num)) {
strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
} else if (ast_exists_extension(chan, chan->context, "o", 1, chan->cid.cid_num))
strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "o", 1, chan->cid.cid_num)) {
strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
ousemacro = 1;
ouseexten = 1;
}
else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "o", 1, chan->cid.cid_num)) {
strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
ousemacro = 1;
}
}
if (!ast_strlen_zero(vmu->exit)) {
@ -2531,10 +2534,11 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_
pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT");
return 0;
}
/* Check for a '0' here */
if (res == '0') {
transfer:
if (ast_test_flag(vmu, VM_OPERATOR)) {
if(ouseexten || ousemacro) {
chan->exten[0] = 'o';
chan->exten[1] = '\0';
if (!ast_strlen_zero(vmu->exit)) {
@ -2546,12 +2550,8 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_
chan->priority = 0;
free_user(vmu);
pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT");
return 0;
} else {
ast_play_and_wait(chan, "vm-sorry");
pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT");
return 0;
}
return 0;
}
if (res < 0) {
free_user(vmu);
@ -5387,7 +5387,7 @@ static int vm_execmain(struct ast_channel *chan, void *data)
while ((cmd > -1) && (cmd != 't') && (cmd != '#')) {
switch(cmd) {
case '1': /* Reply */
if (vms.lastmsg > -1) {
if (vms.lastmsg > -1 && !vms.starting) {
cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 1, record_gain);
if (cmd == ERROR_LOCK_PATH) {
res = cmd;
@ -5398,9 +5398,9 @@ static int vm_execmain(struct ast_channel *chan, void *data)
cmd = 't';
break;
case '2': /* Callback */
if (option_verbose > 2)
if (option_verbose > 2 && !vms.starting)
ast_verbose( VERBOSE_PREFIX_3 "Callback Requested\n");
if (!ast_strlen_zero(vmu->callback) && vms.lastmsg > -1) {
if (!ast_strlen_zero(vmu->callback) && vms.lastmsg > -1 && !vms.starting) {
cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 2, record_gain);
if (cmd == 9) {
silentexit = 1;
@ -5415,7 +5415,7 @@ static int vm_execmain(struct ast_channel *chan, void *data)
cmd = 't';
break;
case '3': /* Envelope */
if (vms.lastmsg > -1) {
if (vms.lastmsg > -1 && !vms.starting) {
cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 3, record_gain);
if (cmd == ERROR_LOCK_PATH) {
res = cmd;
@ -6581,6 +6581,9 @@ static int advanced_options(struct ast_channel *chan, struct ast_vm_user *vmu, s
res = play_message_datetime(chan, vmu, origtime, filename);
if (!res)
res = play_message_callerid(chan, vms, cid, context, 0);
res = 't';
} else if (option == 2) { /* Call back */
if (!ast_strlen_zero(cid)) {
@ -6725,6 +6728,9 @@ static int play_record_review(struct ast_channel *chan, char *playfile, char *re
int recorded = 0;
int message_exists = 0;
signed char zero_gain = 0;
char *acceptdtmf = "#";
char *canceldtmf = "";
/* Note that urgent and private are for flagging messages as such in the future */
/* barf if no pointer passed to store duration in */
@ -6776,7 +6782,9 @@ static int play_record_review(struct ast_channel *chan, char *playfile, char *re
/* After an attempt has been made to record message, we have to take care of INTRO and beep for incoming messages, but not for greetings */
if (record_gain)
ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
cmd = ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, silencethreshold, maxsilence, unlockdir);
if (ast_test_flag(vmu, VM_OPERATOR))
canceldtmf = "0";
cmd = ast_play_and_record_full(chan, playfile, recordfile, maxtime, fmt, duration, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf);
if (record_gain)
ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0);
if (cmd == -1) {
@ -6839,6 +6847,10 @@ static int play_record_review(struct ast_channel *chan, char *playfile, char *re
return 1;
#endif
case '0':
if(!ast_test_flag(vmu, VM_OPERATOR)) {
cmd = ast_play_and_wait(chan, "vm-sorry");
break;
}
if (message_exists || recorded) {
cmd = ast_play_and_wait(chan, "vm-saveoper");
if (!cmd)

View File

@ -140,6 +140,8 @@ int ast_control_streamfile(struct ast_channel *chan, const char *file, const cha
/*! 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);
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);
/*! 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.