diff --git a/conf/autoload_configs/voicemail_ivr.conf.xml b/conf/autoload_configs/voicemail_ivr.conf.xml index 2cebac6cfa..b25b4e485d 100644 --- a/conf/autoload_configs/voicemail_ivr.conf.xml +++ b/conf/autoload_configs/voicemail_ivr.conf.xml @@ -9,6 +9,7 @@ + diff --git a/src/mod/applications/mod_voicemail_ivr/ivr.c b/src/mod/applications/mod_voicemail_ivr/ivr.c index dd6e98b670..4c2b2c8010 100644 --- a/src/mod/applications/mod_voicemail_ivr/ivr.c +++ b/src/mod/applications/mod_voicemail_ivr/ivr.c @@ -154,6 +154,7 @@ switch_status_t ivre_init(ivre_data_t *loc, char **dtmf_accepted) { for (i = 0; dtmf_accepted[i] && i < 16; i++) { strncpy(loc->dtmf_accepted[i], dtmf_accepted[i], 128); } + loc->record_tone = "%(1000, 0, 640)"; return SWITCH_STATUS_SUCCESS; } @@ -210,7 +211,7 @@ switch_status_t ivre_playback(switch_core_session_t *session, ivre_data_t *loc, return status; } -switch_status_t ivre_record(switch_core_session_t *session, ivre_data_t *loc, switch_event_t *event, const char *file_path, switch_file_handle_t *fh, int max_record_len) { +switch_status_t ivre_record(switch_core_session_t *session, ivre_data_t *loc, switch_event_t *event, const char *file_path, switch_file_handle_t *fh, int max_record_len, switch_size_t *record_len) { switch_status_t status = SWITCH_STATUS_SUCCESS; switch_channel_t *channel = switch_core_session_get_channel(session); @@ -222,9 +223,13 @@ switch_status_t ivre_record(switch_core_session_t *session, ivre_data_t *loc, sw if (loc->audio_stopped == SWITCH_FALSE && loc->result == RES_WAITFORMORE) { loc->recorded_audio = SWITCH_TRUE; - switch_ivr_gentones(session, "%(1000, 0, 640)", 0, NULL); /* TODO Make this optional and configurable */ + switch_ivr_gentones(session, loc->record_tone, 0, NULL); status = switch_ivr_record_file(session, fh, file_path, &args, max_record_len); + if (record_len) { + *record_len = fh->samples_out / (fh->samplerate ? fh->samplerate : 8000); + } + } if (loc->result == RES_WAITFORMORE) { loc->result = RES_TIMEOUT; diff --git a/src/mod/applications/mod_voicemail_ivr/ivr.h b/src/mod/applications/mod_voicemail_ivr/ivr.h index 4c09f938c6..a277140985 100644 --- a/src/mod/applications/mod_voicemail_ivr/ivr.h +++ b/src/mod/applications/mod_voicemail_ivr/ivr.h @@ -44,6 +44,7 @@ struct ivre_data { int potentialMatchCount; const char *completeMatch; char terminate_key; + const char *record_tone; }; typedef struct ivre_data ivre_data_t; @@ -59,7 +60,7 @@ typedef struct ivre_data ivre_data_t; switch_status_t ivre_init(ivre_data_t *loc, char **dtmf_accepted); switch_status_t ivre_playback(switch_core_session_t *session, ivre_data_t *loc, const char *macro_name, const char *data, switch_event_t *event, const char *lang, int timeout); -switch_status_t ivre_record(switch_core_session_t *session, ivre_data_t *loc, switch_event_t *event, const char *file_path, switch_file_handle_t *fh, int max_record_len); +switch_status_t ivre_record(switch_core_session_t *session, ivre_data_t *loc, switch_event_t *event, const char *file_path, switch_file_handle_t *fh, int max_record_len, switch_size_t *record_len); switch_status_t ivre_playback_dtmf_buffered(switch_core_session_t *session, const char *macro_name, const char *data, switch_event_t *event, const char *lang, int timeout); #endif diff --git a/src/mod/applications/mod_voicemail_ivr/menu.c b/src/mod/applications/mod_voicemail_ivr/menu.c index 15b55b8235..6c8bc99250 100644 --- a/src/mod/applications/mod_voicemail_ivr/menu.c +++ b/src/mod/applications/mod_voicemail_ivr/menu.c @@ -64,7 +64,7 @@ void vmivr_menu_purge(switch_core_session_t *session, vmivr_profile_t *profile) vmivr_api_execute(session, profile->api_msg_purge, cmd); } } -end: + menu_free(&menu); } @@ -97,9 +97,15 @@ void vmivr_menu_main(switch_core_session_t *session, vmivr_profile_t *profile) { ivre_playback(session, &menu.ivre_d, switch_event_get_header(menu.event_phrases, "menu_options"), NULL, menu.phrase_params, NULL, menu.ivr_entry_timeout); if (menu.ivre_d.result == RES_TIMEOUT) { - /* TODO Ask for the prompt Again IF retry != 0 */ + ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "timeout"), NULL, NULL, NULL, 0); + if (retry != 0) { + ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "try_again"), NULL, NULL, NULL, 0); + } } else if (menu.ivre_d.result == RES_INVALID) { - /* TODO Say invalid option, and ask for the prompt again IF retry != 0 */ + ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "invalid"), NULL, NULL, NULL, 0); + if (retry != 0) { + ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "try_again"), NULL, NULL, NULL, 0); + } } else if (menu.ivre_d.result == RES_FOUND) { /* Matching DTMF Key Pressed */ const char *action = switch_event_get_header(menu.event_keys_dtmf, menu.ivre_d.dtmf_stored); @@ -178,7 +184,7 @@ void vmivr_menu_navigator(switch_core_session_t *session, vmivr_profile_t *profi goto done; } } else { - /* TODO error MSG */ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "API message list return invalid result : %s(%s)\n", profile->api_msg_list, cmd); goto done; } @@ -212,12 +218,11 @@ void vmivr_menu_navigator(switch_core_session_t *session, vmivr_profile_t *profi switch_event_del_header(menu.phrase_params, "VM-Message-Flags"); /* Simple Protection to not go out of msg list scope */ - /* TODO: Add Prompt to notify they reached the begining or the end */ if (next_msg == 0) { next_msg = 1; } else if (next_msg > msg_count) { next_msg = msg_count; - /*ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "no_more_messages"), NULL, NULL, NULL, 0); */ + ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "no_more_messages"), NULL, NULL, NULL, 0); } current_msg = next_msg; @@ -263,9 +268,15 @@ void vmivr_menu_navigator(switch_core_session_t *session, vmivr_profile_t *profi ivre_playback(session, &menu.ivre_d, switch_event_get_header(menu.event_phrases, "menu_options"), NULL, menu.phrase_params, NULL, menu.ivr_entry_timeout); if (menu.ivre_d.result == RES_TIMEOUT) { - /* TODO Ask for the prompt Again IF retry != 0 */ + ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "timeout"), NULL, NULL, NULL, 0); + if (retry != 0) { + ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "try_again"), NULL, NULL, NULL, 0); + } } else if (menu.ivre_d.result == RES_INVALID) { - /* TODO Say invalid option, and ask for the prompt again IF retry != 0 */ + ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "invalid"), NULL, NULL, NULL, 0); + if (retry != 0) { + ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "try_again"), NULL, NULL, NULL, 0); + } } else if (menu.ivre_d.result == RES_FOUND) { /* Matching DTMF Key Pressed */ const char *action = switch_event_get_header(menu.event_keys_dtmf, menu.ivre_d.dtmf_stored); @@ -366,9 +377,15 @@ void vmivr_menu_forward(switch_core_session_t *session, vmivr_profile_t *profile ivre_playback(session, &menu.ivre_d, switch_event_get_header(menu.event_phrases, "menu_options"), NULL, menu.phrase_params, NULL, menu.ivr_entry_timeout); if (menu.ivre_d.result == RES_TIMEOUT) { - /* TODO Ask for the prompt Again IF retry != 0 */ + ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "timeout"), NULL, NULL, NULL, 0); + if (retry != 0) { + ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "try_again"), NULL, NULL, NULL, 0); + } } else if (menu.ivre_d.result == RES_INVALID) { - /* TODO Say invalid option, and ask for the prompt again IF retry != 0 */ + ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "invalid"), NULL, NULL, NULL, 0); + if (retry != 0) { + ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "try_again"), NULL, NULL, NULL, 0); + } } else if (menu.ivre_d.result == RES_FOUND) { /* Matching DTMF Key Pressed */ const char *action = switch_event_get_header(menu.event_keys_dtmf, menu.ivre_d.dtmf_stored); @@ -405,7 +422,7 @@ void vmivr_menu_forward(switch_core_session_t *session, vmivr_profile_t *profile retry = -1; forward_msg = SWITCH_TRUE; } else { - /* TODO Error Recording msg */ + ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "record_failed"), NULL, NULL, NULL, 0); } menu_free(&sub_menu); @@ -424,6 +441,7 @@ void vmivr_menu_forward(switch_core_session_t *session, vmivr_profile_t *profile } + /* Ask Extension to Forward */ if (forward_msg) { for (retry = menu.ivr_maximum_attempts; switch_channel_ready(channel) && retry > 0; retry--) { @@ -443,7 +461,7 @@ void vmivr_menu_forward(switch_core_session_t *session, vmivr_profile_t *profile ivre_playback_dtmf_buffered(session, switch_event_get_header(sub_menu.event_phrases, "invalid_extension"), NULL, NULL, NULL, 0); } } else { - /* TODO Prompt about input not valid */ + ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "invalid_input"), NULL, NULL, NULL, 0); } menu_free(&sub_menu); /* TODO add Confirmation of the transfered number */ @@ -491,11 +509,13 @@ void vmivr_menu_set_password(switch_core_session_t *session, vmivr_profile_t *pr password = vmivr_menu_get_input_set(session, profile, menu, password_mask); - /* TODO Add Prompts to tell if password was set and if it was not */ if (password) { char *cmd = switch_core_session_sprintf(session, "%s %s %s %s", profile->api_profile, profile->domain, profile->id, password); - vmivr_api_execute(session, profile->api_pref_password_set, cmd); - + if (vmivr_api_execute(session, profile->api_pref_password_set, cmd)) { + ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "password_set"), NULL, NULL, NULL, 0); + } else { + ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "password_not_set"), NULL, NULL, NULL, 0); + } } menu_free(&menu); @@ -641,9 +661,15 @@ void vmivr_menu_preference(switch_core_session_t *session, vmivr_profile_t *prof ivre_playback(session, &menu.ivre_d, switch_event_get_header(menu.event_phrases, "menu_options"), NULL, menu.phrase_params, NULL, menu.ivr_entry_timeout); if (menu.ivre_d.result == RES_TIMEOUT) { - /* TODO Ask for the prompt Again IF retry != 0 */ + ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "timeout"), NULL, NULL, NULL, 0); + if (retry != 0) { + ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "try_again"), NULL, NULL, NULL, 0); + } } else if (menu.ivre_d.result == RES_INVALID) { - /* TODO Say invalid option, and ask for the prompt again IF retry != 0 */ + ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "invalid"), NULL, NULL, NULL, 0); + if (retry != 0) { + ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "try_again"), NULL, NULL, NULL, 0); + } } else if (menu.ivre_d.result == RES_FOUND) { /* Matching DTMF Key Pressed */ const char *action = switch_event_get_header(menu.event_keys_dtmf, menu.ivre_d.dtmf_stored); @@ -698,9 +724,15 @@ char *vmivr_menu_get_input_set(switch_core_session_t *session, vmivr_profile_t * ivre_playback(session, &menu.ivre_d, switch_event_get_header(menu.event_phrases, "instructions"), NULL, menu.phrase_params, NULL, menu.ivr_entry_timeout); if (menu.ivre_d.result == RES_TIMEOUT) { - /* TODO Ask for the prompt Again IF retry != 0 */ + ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "timeout"), NULL, NULL, NULL, 0); + if (retry != 0) { + ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "try_again"), NULL, NULL, NULL, 0); + } } else if (menu.ivre_d.result == RES_INVALID) { - /* TODO Say invalid option, and ask for the prompt again IF retry != 0 */ + ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "invalid"), NULL, NULL, NULL, 0); + if (retry != 0) { + ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "try_again"), NULL, NULL, NULL, 0); + } } else if (menu.ivre_d.result == RES_FOUND) { /* Matching DTMF Key Pressed */ /* Reset the try count */ @@ -737,8 +769,11 @@ switch_status_t vmivr_menu_record(switch_core_session_t *session, vmivr_profile_ const char *rec_silence_hits = switch_event_get_header(menu.event_settings, "Record-Silence-Hits"); const char *rec_silence_threshold = switch_event_get_header(menu.event_settings, "Record-Silence-Threshold"); const char *rec_silence_samplerate = switch_event_get_header(menu.event_settings, "Record-Sample-Rate"); - const char *rec_maximum_length = switch_event_get_header(menu.event_settings, "Record-Maximum-Length"); + const char *rec_maximum_length = switch_event_get_header(menu.event_settings, "Record-Maximum-Length"); + const char *rec_minimum_length = switch_event_get_header(menu.event_settings, "Record-Minimum-Length"); + switch_size_t record_length = 0; + /* Prepare Recording File Handle */ fh.thresh = atoi(rec_silence_threshold); fh.silence_hits = atoi(rec_silence_hits); if (rec_silence_samplerate) { @@ -748,13 +783,14 @@ switch_status_t vmivr_menu_record(switch_core_session_t *session, vmivr_profile_ menu_instance_init(&menu); ivre_init(&menu.ivre_d, menu.dtmfa); + if (record_prompt) { if (play_instruction) { ivre_playback(session, &menu.ivre_d, switch_event_get_header(menu.event_phrases, "instructions"), NULL, menu.phrase_params, NULL, 0); } play_instruction = SWITCH_TRUE; - ivre_record(session, &menu.ivre_d, menu.phrase_params, file_name, &fh, atoi(rec_maximum_length)); + ivre_record(session, &menu.ivre_d, menu.phrase_params, file_name, &fh, atoi(rec_maximum_length), &record_length); } else { if (listen_recording) { switch_event_add_header(menu.phrase_params, SWITCH_STACK_BOTTOM, "VM-Record-File-Path", "%s", file_name); @@ -769,14 +805,23 @@ switch_status_t vmivr_menu_record(switch_core_session_t *session, vmivr_profile_ /* Reset the try count */ retry = menu.ivr_maximum_attempts; - /* TODO Check if message is too short */ - - record_prompt = SWITCH_FALSE; + if (rec_minimum_length && record_length < atoi(rec_minimum_length)) { + ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "too_short"), NULL, NULL, NULL, 0); + unlink(file_name); + } else { + record_prompt = SWITCH_FALSE; + } } else if (menu.ivre_d.result == RES_TIMEOUT) { - /* TODO Ask for the prompt Again IF retry != 0 */ + ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "timeout"), NULL, NULL, NULL, 0); + if (retry != 0) { + ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "try_again"), NULL, NULL, NULL, 0); + } } else if (menu.ivre_d.result == RES_INVALID) { - /* TODO Say invalid option, and ask for the prompt again IF retry != 0 */ + ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "invalid"), NULL, NULL, NULL, 0); + if (retry != 0) { + ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "try_again"), NULL, NULL, NULL, 0); + } } else if (menu.ivre_d.result == RES_FOUND) { /* Matching DTMF Key Pressed */ const char *action = switch_event_get_header(menu.event_keys_dtmf, menu.ivre_d.dtmf_stored); @@ -789,7 +834,6 @@ switch_status_t vmivr_menu_record(switch_core_session_t *session, vmivr_profile_ } else if (!strcasecmp(action, "save")) { retry = -1; - /* TODO ALLOW SAVE ONLY IF FILE IS RECORDED AND HIGHER THAN MIN SIZE */ status = SWITCH_STATUS_SUCCESS; } else if (!strcasecmp(action, "rerecord")) {