mod_voicemail_ivr: Added a missing menu in the conf.xml config. Also refactor nearly all the function name to something more standard. Also tried to make the flow as simple as possible in the menu.c

This commit is contained in:
Marc Olivier Chouinard 2011-12-26 02:52:32 -05:00
parent d1364ff51f
commit f2cba2aa16
9 changed files with 242 additions and 227 deletions

View File

@ -48,12 +48,27 @@
</keys> </keys>
</menu> </menu>
<menu name="std_main_menu">
<phrases>
<phrase name="msg_count" value="message_count@mtvoicemail" />
<phrase name="say_date" value="say_date_event@mtvoicemail" />
<phrase name="say_msg_number" value="say_message_number@mtvoicemail" />
<phrase name="menu_options" value="menu@mtvoicemail" />
</phrases>
<keys>
<key dtmf="1" action="new_msg:std_navigator" variable="VM-Key-Play-New-Messages" />
<key dtmf="2" action="saved_msg:std_navigator" variable="VM-Key-Play-Saved-Messages" />
<key dtmf="5" action="menu:std_preference" variable="VM-Key-Config-Menu"/>
<key dtmf="#" action="return" variable="VM-Key-Terminator" />
</keys>
</menu>
<menu name="std_navigator"> <menu name="std_navigator">
<!-- Not yet implemented - Open for comments <!-- Not yet implemented - Open for comments
This will inherit the settings from the top profile settings. So if it global, put it inside the profile <settings> This will inherit the settings from the top profile settings. So if it global, put it inside the profile <settings>
<settings> <settings>
<param name="playback-order" value="newest-first" /> <param name="playback-order" value="newest-first" />
</settings> </settings>
--> -->
<phrases> <phrases>
<phrase name="msg_count" value="message_count@voicemail_ivr" /> <phrase name="msg_count" value="message_count@voicemail_ivr" />

View File

@ -35,14 +35,20 @@
const char *global_cf = "voicemail_ivr.conf"; const char *global_cf = "voicemail_ivr.conf";
void populate_profile_menu_event(vmivr_profile_t *profile, vmivr_menu_profile_t *menu) { static void append_event_profile(vmivr_menu_t *menu);
static void populate_dtmfa_from_event(vmivr_menu_t *menu);
void menu_init(vmivr_profile_t *profile, vmivr_menu_t *menu) {
switch_xml_t cfg, xml, x_profiles, x_profile, x_keys, x_phrases, x_menus, x_menu, x_settings; switch_xml_t cfg, xml, x_profiles, x_profile, x_keys, x_phrases, x_menus, x_menu, x_settings;
menu->profile = profile;
if (!(xml = switch_xml_open_cfg(global_cf, &cfg, NULL))) { if (!(xml = switch_xml_open_cfg(global_cf, &cfg, NULL))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", global_cf); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", global_cf);
goto end; goto end;
} }
if (!(x_profiles = switch_xml_child(cfg, "profiles"))) { if (!(x_profiles = switch_xml_child(cfg, "profiles"))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No profiles group\n");
goto end; goto end;
} }
@ -63,6 +69,7 @@ void populate_profile_menu_event(vmivr_profile_t *profile, vmivr_menu_profile_t
if ((x_profile = switch_xml_find_child(x_profiles, "profile", "name", profile->name))) { if ((x_profile = switch_xml_find_child(x_profiles, "profile", "name", profile->name))) {
if ((x_menus = switch_xml_child(x_profile, "menus"))) { if ((x_menus = switch_xml_child(x_profile, "menus"))) {
if ((x_menu = switch_xml_find_child(x_menus, "menu", "name", menu->name))) { if ((x_menu = switch_xml_find_child(x_menus, "menu", "name", menu->name))) {
if ((x_keys = switch_xml_child(x_menu, "keys"))) { if ((x_keys = switch_xml_child(x_menu, "keys"))) {
switch_event_import_xml(switch_xml_child(x_keys, "key"), "dtmf", "action", &menu->event_keys_dtmf); switch_event_import_xml(switch_xml_child(x_keys, "key"), "dtmf", "action", &menu->event_keys_dtmf);
switch_event_import_xml(switch_xml_child(x_keys, "key"), "action", "dtmf", &menu->event_keys_action); switch_event_import_xml(switch_xml_child(x_keys, "key"), "action", "dtmf", &menu->event_keys_action);
@ -85,7 +92,20 @@ end:
} }
void free_profile_menu_event(vmivr_menu_profile_t *menu) { void menu_instance_init(vmivr_menu_t *menu) {
append_event_profile(menu);
populate_dtmfa_from_event(menu);
}
void menu_instance_free(vmivr_menu_t *menu) {
if (menu->phrase_params) {
switch_event_destroy(&menu->phrase_params);
}
memset(&menu->ivre_d, 0, sizeof(menu->ivre_d));
}
void menu_free(vmivr_menu_t *menu) {
if (menu->event_keys_dtmf) { if (menu->event_keys_dtmf) {
switch_event_destroy(&menu->event_keys_dtmf); switch_event_destroy(&menu->event_keys_dtmf);
} }
@ -105,6 +125,41 @@ void free_profile_menu_event(vmivr_menu_profile_t *menu) {
} }
static void append_event_profile(vmivr_menu_t *menu) {
if (!menu->phrase_params) {
switch_event_create(&menu->phrase_params, SWITCH_EVENT_REQUEST_PARAMS);
}
/* Used for some appending function */
if (menu->profile && menu->profile->name && menu->profile->id && menu->profile->domain) {
switch_event_add_header(menu->phrase_params, SWITCH_STACK_BOTTOM, "VM-Profile", "%s", menu->profile->name);
switch_event_add_header(menu->phrase_params, SWITCH_STACK_BOTTOM, "VM-Account-ID", "%s", menu->profile->id);
switch_event_add_header(menu->phrase_params, SWITCH_STACK_BOTTOM, "VM-Account-Domain", "%s", menu->profile->domain);
}
}
static void populate_dtmfa_from_event(vmivr_menu_t *menu) {
int i = 0;
if (menu->event_keys_dtmf) {
switch_event_header_t *hp;
for (hp = menu->event_keys_dtmf->headers; hp; hp = hp->next) {
if (strlen(hp->name) < 3 && hp->value) { /* TODO This is a hack to discard default FS Events ! */
const char *varphrasename = switch_event_get_header(menu->event_keys_varname, hp->value);
menu->dtmfa[i++] = hp->name;
if (varphrasename && !zstr(varphrasename)) {
switch_event_add_header(menu->phrase_params, SWITCH_STACK_BOTTOM, varphrasename, "%s", hp->name);
}
}
}
}
menu->dtmfa[i++] = '\0';
}
vmivr_profile_t *get_profile(switch_core_session_t *session, const char *profile_name) vmivr_profile_t *get_profile(switch_core_session_t *session, const char *profile_name)
{ {
vmivr_profile_t *profile = NULL; vmivr_profile_t *profile = NULL;

View File

@ -29,6 +29,8 @@
* config.c -- VoiceMail IVR Config * config.c -- VoiceMail IVR Config
* *
*/ */
#include "ivr.h"
#ifndef _CONFIG_H_ #ifndef _CONFIG_H_
#define _CONFIG_H_ #define _CONFIG_H_
@ -75,21 +77,29 @@ struct vmivr_profile {
}; };
typedef struct vmivr_profile vmivr_profile_t; typedef struct vmivr_profile vmivr_profile_t;
struct vmivr_menu_profile { struct vmivr_menu {
const char *name; const char *name;
vmivr_profile_t *profile;
switch_event_t *event_keys_action; switch_event_t *event_keys_action;
switch_event_t *event_keys_dtmf; switch_event_t *event_keys_dtmf;
switch_event_t *event_keys_varname; switch_event_t *event_keys_varname;
switch_event_t *event_settings; switch_event_t *event_settings;
switch_event_t *event_phrases; switch_event_t *event_phrases;
char *dtmfa[16];
switch_event_t *phrase_params;
ivre_data_t ivre_d;
}; };
typedef struct vmivr_menu_profile vmivr_menu_profile_t; typedef struct vmivr_menu vmivr_menu_t;
vmivr_profile_t *get_profile(switch_core_session_t *session, const char *profile_name); vmivr_profile_t *get_profile(switch_core_session_t *session, const char *profile_name);
void free_profile(vmivr_profile_t *profile); void free_profile(vmivr_profile_t *profile);
void free_profile_menu_event(vmivr_menu_profile_t *menu); void menu_init(vmivr_profile_t *profile, vmivr_menu_t *menu);
void populate_profile_menu_event(vmivr_profile_t *profile, vmivr_menu_profile_t *menu); void menu_instance_init(vmivr_menu_t *menu);
void menu_instance_free(vmivr_menu_t *menu);
void menu_free(vmivr_menu_t *menu);
#endif /* _CONFIG_H_ */ #endif /* _CONFIG_H_ */

View File

@ -34,7 +34,7 @@
#include "ivr.h" #include "ivr.h"
int match_dtmf(switch_core_session_t *session, dtmf_ss_t *loc) { static int match_dtmf(switch_core_session_t *session, ivre_data_t *loc) {
switch_bool_t is_invalid[128] = { SWITCH_FALSE }; switch_bool_t is_invalid[128] = { SWITCH_FALSE };
int i; int i;
loc->potentialMatch = NULL; loc->potentialMatch = NULL;
@ -99,7 +99,7 @@ static switch_status_t cb_on_dtmf_ignore(switch_core_session_t *session, void *i
static switch_status_t cb_on_dtmf(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen) static switch_status_t cb_on_dtmf(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen)
{ {
dtmf_ss_t *loc = (dtmf_ss_t*) buf; ivre_data_t *loc = (ivre_data_t*) buf;
switch (itype) { switch (itype) {
case SWITCH_INPUT_TYPE_DTMF: case SWITCH_INPUT_TYPE_DTMF:
@ -146,7 +146,7 @@ static switch_status_t cb_on_dtmf(switch_core_session_t *session, void *input, s
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
switch_status_t captureMenuInitialize(dtmf_ss_t *loc, char **dtmf_accepted) { switch_status_t ivre_init(ivre_data_t *loc, char **dtmf_accepted) {
int i; int i;
memset(loc, 0, sizeof(*loc)); memset(loc, 0, sizeof(*loc));
@ -158,7 +158,7 @@ switch_status_t captureMenuInitialize(dtmf_ss_t *loc, char **dtmf_accepted) {
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
switch_status_t playbackBufferDTMF(switch_core_session_t *session, const char *macro_name, const char *data, switch_event_t *event, const char *lang, int timeout) { 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) {
switch_status_t status = SWITCH_STATUS_SUCCESS; switch_status_t status = SWITCH_STATUS_SUCCESS;
switch_channel_t *channel = switch_core_session_get_channel(session); switch_channel_t *channel = switch_core_session_get_channel(session);
@ -178,7 +178,7 @@ switch_status_t playbackBufferDTMF(switch_core_session_t *session, const char *m
} }
switch_status_t captureMenu(switch_core_session_t *session, dtmf_ss_t *loc, const char *macro_name, const char *data, switch_event_t *event, const char *lang, int timeout) { 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 status = SWITCH_STATUS_SUCCESS; switch_status_t status = SWITCH_STATUS_SUCCESS;
switch_channel_t *channel = switch_core_session_get_channel(session); switch_channel_t *channel = switch_core_session_get_channel(session);
@ -210,7 +210,7 @@ switch_status_t captureMenu(switch_core_session_t *session, dtmf_ss_t *loc, cons
return status; return status;
} }
switch_status_t captureMenuRecord(switch_core_session_t *session, dtmf_ss_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_status_t status = SWITCH_STATUS_SUCCESS; switch_status_t status = SWITCH_STATUS_SUCCESS;
switch_channel_t *channel = switch_core_session_get_channel(session); switch_channel_t *channel = switch_core_session_get_channel(session);

View File

@ -29,7 +29,11 @@
* ivr.h -- VoiceMail IVR Engine * ivr.h -- VoiceMail IVR Engine
* *
*/ */
struct dtmf_ss {
#ifndef _IVRE_H_
#define _IVRE_H_
struct ivre_data {
char dtmf_stored[128]; char dtmf_stored[128];
int dtmf_received; int dtmf_received;
char dtmf_accepted[16][128]; char dtmf_accepted[16][128];
@ -41,7 +45,7 @@ struct dtmf_ss {
const char *completeMatch; const char *completeMatch;
char terminate_key; char terminate_key;
}; };
typedef struct dtmf_ss dtmf_ss_t; typedef struct ivre_data ivre_data_t;
#define RES_WAITFORMORE 0 #define RES_WAITFORMORE 0
#define RES_FOUND 1 #define RES_FOUND 1
@ -53,9 +57,9 @@ typedef struct dtmf_ss dtmf_ss_t;
#define MAX_DTMF_SIZE_OPTION 32 #define MAX_DTMF_SIZE_OPTION 32
switch_status_t captureMenu(switch_core_session_t *session, dtmf_ss_t *loc, const char *macro_name, const char *data, switch_event_t *event, const char *lang, int timeout); switch_status_t ivre_init(ivre_data_t *loc, char **dtmf_accepted);
switch_status_t captureMenuRecord(switch_core_session_t *session, dtmf_ss_t *loc, switch_event_t *event, const char *file_path, switch_file_handle_t *fh, int max_record_len); 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 captureMenuInitialize(dtmf_ss_t *loc, char **dtmf_accepted); 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 playbackBufferDTMF(switch_core_session_t *session, const char *macro_name, const char *data, switch_event_t *event, const char *lang, int timeout);
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

View File

@ -65,11 +65,11 @@ void vmivr_menu_purge(switch_core_session_t *session, vmivr_profile_t *profile)
void vmivr_menu_main(switch_core_session_t *session, vmivr_profile_t *profile) { void vmivr_menu_main(switch_core_session_t *session, vmivr_profile_t *profile) {
switch_channel_t *channel = switch_core_session_get_channel(session); switch_channel_t *channel = switch_core_session_get_channel(session);
vmivr_menu_profile_t menu = { "std_main_menu" }; vmivr_menu_t menu = { "std_main_menu" };
int retry; int retry;
/* Initialize Menu Configs */ /* Initialize Menu Configs */
populate_profile_menu_event(profile, &menu); menu_init(profile, &menu);
if (!menu.event_keys_dtmf || !menu.event_phrases) { if (!menu.event_keys_dtmf || !menu.event_phrases) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing Menu Phrases and Keys\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing Menu Phrases and Keys\n");
@ -77,31 +77,25 @@ void vmivr_menu_main(switch_core_session_t *session, vmivr_profile_t *profile) {
} }
for (retry = MAX_ATTEMPT; switch_channel_ready(channel) && retry > 0; retry--) { for (retry = MAX_ATTEMPT; switch_channel_ready(channel) && retry > 0; retry--) {
dtmf_ss_t loc;
char *dtmfa[16] = { 0 };
switch_event_t *phrase_params = NULL;
char *cmd = NULL; char *cmd = NULL;
switch_event_create(&phrase_params, SWITCH_EVENT_REQUEST_PARAMS); menu_instance_init(&menu);
append_event_profile(phrase_params, profile, menu);
populate_dtmfa_from_event(phrase_params, profile, menu, dtmfa); ivre_init(&menu.ivre_d, menu.dtmfa);
captureMenuInitialize(&loc, dtmfa);
cmd = switch_core_session_sprintf(session, "json %s %s %s %s", profile->api_profile, profile->domain, profile->id, profile->folder_name); cmd = switch_core_session_sprintf(session, "json %s %s %s %s", profile->api_profile, profile->domain, profile->id, profile->folder_name);
jsonapi2event(session, phrase_params, profile->api_msg_count, cmd); jsonapi2event(session, menu.phrase_params, profile->api_msg_count, cmd);
//initial_count_played = SWITCH_TRUE; //initial_count_played = SWITCH_TRUE;
captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "msg_count"), NULL, phrase_params, NULL, 0); ivre_playback(session, &menu.ivre_d, switch_event_get_header(menu.event_phrases, "msg_count"), NULL, menu.phrase_params, NULL, 0);
captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "menu_options"), NULL, phrase_params, NULL, DEFAULT_IVR_TIMEOUT); ivre_playback(session, &menu.ivre_d, switch_event_get_header(menu.event_phrases, "menu_options"), NULL, menu.phrase_params, NULL, DEFAULT_IVR_TIMEOUT);
if (loc.result == RES_TIMEOUT) { if (menu.ivre_d.result == RES_TIMEOUT) {
/* TODO Ask for the prompt Again IF retry != 0 */ /* TODO Ask for the prompt Again IF retry != 0 */
} else if (loc.result == RES_INVALID) { } else if (menu.ivre_d.result == RES_INVALID) {
/* TODO Say invalid option, and ask for the prompt again IF retry != 0 */ /* TODO Say invalid option, and ask for the prompt again IF retry != 0 */
} else if (loc.result == RES_FOUND) { /* Matching DTMF Key Pressed */ } else if (menu.ivre_d.result == RES_FOUND) { /* Matching DTMF Key Pressed */
const char *action = switch_event_get_header(menu.event_keys_dtmf, loc.dtmf_stored); const char *action = switch_event_get_header(menu.event_keys_dtmf, menu.ivre_d.dtmf_stored);
/* Reset the try count */ /* Reset the try count */
retry = MAX_ATTEMPT; retry = MAX_ATTEMPT;
@ -131,11 +125,11 @@ void vmivr_menu_main(switch_core_session_t *session, vmivr_profile_t *profile) {
} }
} }
} }
switch_event_destroy(&phrase_params); menu_instance_free(&menu);
} }
free_profile_menu_event(&menu); menu_free(&menu);
} }
@ -157,10 +151,10 @@ void vmivr_menu_navigator(switch_core_session_t *session, vmivr_profile_t *profi
switch_bool_t msg_undeleted = SWITCH_FALSE; switch_bool_t msg_undeleted = SWITCH_FALSE;
switch_bool_t msg_saved = SWITCH_FALSE; switch_bool_t msg_saved = SWITCH_FALSE;
vmivr_menu_profile_t menu = { "std_navigator" }; vmivr_menu_t menu = { "std_navigator" };
/* Initialize Menu Configs */ /* Initialize Menu Configs */
populate_profile_menu_event(profile, &menu); menu_init(profile, &menu);
if (!menu.event_keys_dtmf || !menu.event_phrases) { if (!menu.event_keys_dtmf || !menu.event_phrases) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing Menu Phrases or Keys\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing Menu Phrases or Keys\n");
@ -186,15 +180,8 @@ void vmivr_menu_navigator(switch_core_session_t *session, vmivr_profile_t *profi
for (retry = MAX_ATTEMPT; switch_channel_ready(channel) && retry > 0; retry--) { for (retry = MAX_ATTEMPT; switch_channel_ready(channel) && retry > 0; retry--) {
switch_core_session_message_t msg = { 0 }; switch_core_session_message_t msg = { 0 };
char cid_buf[1024] = ""; char cid_buf[1024] = "";
dtmf_ss_t loc;
char *dtmfa[16] = { 0 };
switch_event_t *phrase_params = NULL;
switch_event_create(&phrase_params, SWITCH_EVENT_REQUEST_PARAMS); menu_instance_init(&menu);
append_event_profile(phrase_params, profile, menu);
populate_dtmfa_from_event(phrase_params, profile, menu, dtmfa);
previous_msg = current_msg; previous_msg = current_msg;
@ -208,31 +195,31 @@ void vmivr_menu_navigator(switch_core_session_t *session, vmivr_profile_t *profi
current_msg = next_msg; current_msg = next_msg;
captureMenuInitialize(&loc, dtmfa); ivre_init(&menu.ivre_d, menu.dtmfa);
/* Prompt related to previous Message here */ /* Prompt related to previous Message here */
append_event_message(session, profile, phrase_params, msg_list_params, previous_msg); append_event_message(session, profile, menu.phrase_params, msg_list_params, previous_msg);
if (msg_deleted) { if (msg_deleted) {
msg_deleted = SWITCH_FALSE; msg_deleted = SWITCH_FALSE;
captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "ack"), "deleted", phrase_params, NULL, 0); ivre_playback(session, &menu.ivre_d, switch_event_get_header(menu.event_phrases, "ack"), "deleted", menu.phrase_params, NULL, 0);
} }
if (msg_undeleted) { if (msg_undeleted) {
msg_undeleted = SWITCH_FALSE; msg_undeleted = SWITCH_FALSE;
captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "ack"), "undeleted", phrase_params, NULL, 0); ivre_playback(session, &menu.ivre_d, switch_event_get_header(menu.event_phrases, "ack"), "undeleted", menu.phrase_params, NULL, 0);
} }
if (msg_saved) { if (msg_saved) {
msg_saved = SWITCH_FALSE; msg_saved = SWITCH_FALSE;
captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "ack"), "saved", phrase_params, NULL, 0); ivre_playback(session, &menu.ivre_d, switch_event_get_header(menu.event_phrases, "ack"), "saved", menu.phrase_params, NULL, 0);
} }
switch_event_del_header(phrase_params, "VM-Message-Flags"); switch_event_del_header(menu.phrase_params, "VM-Message-Flags");
/* Prompt related the current message */ /* Prompt related the current message */
append_event_message(session, profile, phrase_params, msg_list_params, current_msg); append_event_message(session, profile, menu.phrase_params, msg_list_params, current_msg);
/* Used for extra control in phrases */ /* Used for extra control in phrases */
switch_event_add_header(phrase_params, SWITCH_STACK_BOTTOM, "VM-List-Count", "%"SWITCH_SIZE_T_FMT, msg_count); switch_event_add_header(menu.phrase_params, SWITCH_STACK_BOTTOM, "VM-List-Count", "%"SWITCH_SIZE_T_FMT, msg_count);
/* Save in profile the current msg info for other menu processing AND restoration of our current position */ /* Save in profile the current msg info for other menu processing AND restoration of our current position */
switch_snprintf(cid_buf, sizeof(cid_buf), "%s|%s", switch_str_nil(switch_event_get_header(phrase_params, "VM-Message-Caller-Number")), switch_str_nil(switch_event_get_header(phrase_params, "VM-Message-Caller-Name"))); switch_snprintf(cid_buf, sizeof(cid_buf), "%s|%s", switch_str_nil(switch_event_get_header(menu.phrase_params, "VM-Message-Caller-Number")), switch_str_nil(switch_event_get_header(menu.phrase_params, "VM-Message-Caller-Name")));
/* Display MSG CID/Name to caller */ /* Display MSG CID/Name to caller */
msg.from = __FILE__; msg.from = __FILE__;
@ -241,36 +228,36 @@ void vmivr_menu_navigator(switch_core_session_t *session, vmivr_profile_t *profi
switch_core_session_receive_message(session, &msg); switch_core_session_receive_message(session, &msg);
profile->current_msg = current_msg; profile->current_msg = current_msg;
profile->current_msg_uuid = switch_core_session_strdup(session, switch_event_get_header(phrase_params, "VM-Message-UUID")); profile->current_msg_uuid = switch_core_session_strdup(session, switch_event_get_header(menu.phrase_params, "VM-Message-UUID"));
/* TODO check if msg is gone (purged by another session, notify user and auto jump to next message or something) */ /* TODO check if msg is gone (purged by another session, notify user and auto jump to next message or something) */
if (!skip_header) { if (!skip_header) {
if (!initial_count_played) { if (!initial_count_played) {
cmd = switch_core_session_sprintf(session, "json %s %s %s", profile->api_profile, profile->domain, profile->id); cmd = switch_core_session_sprintf(session, "json %s %s %s", profile->api_profile, profile->domain, profile->id);
jsonapi2event(session, phrase_params, profile->api_msg_count, cmd); jsonapi2event(session, menu.phrase_params, profile->api_msg_count, cmd);
initial_count_played = SWITCH_TRUE; initial_count_played = SWITCH_TRUE;
// TODO captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "msg_count"), NULL, phrase_params, NULL, 0); // TODO ivre_playback(session, &menu.ivre_d, switch_event_get_header(menu.event_phrases, "msg_count"), NULL, menu.phrase_params, NULL, 0);
} }
if (msg_count > 0) { if (msg_count > 0) {
captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "say_msg_number"), NULL, phrase_params, NULL, 0); ivre_playback(session, &menu.ivre_d, switch_event_get_header(menu.event_phrases, "say_msg_number"), NULL, menu.phrase_params, NULL, 0);
captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "say_date"), NULL, phrase_params, NULL, 0); ivre_playback(session, &menu.ivre_d, switch_event_get_header(menu.event_phrases, "say_date"), NULL, menu.phrase_params, NULL, 0);
} }
} }
if (msg_count > 0 && !skip_playback) { if (msg_count > 0 && !skip_playback) {
/* TODO Update the Read date of a message (When msg start, or when it listen compleatly ??? To be determined */ /* TODO Update the Read date of a message (When msg start, or when it listen compleatly ??? To be determined */
captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "play_message"), NULL, phrase_params, NULL, 0); ivre_playback(session, &menu.ivre_d, switch_event_get_header(menu.event_phrases, "play_message"), NULL, menu.phrase_params, NULL, 0);
} }
skip_header = SWITCH_FALSE; skip_header = SWITCH_FALSE;
skip_playback = SWITCH_FALSE; skip_playback = SWITCH_FALSE;
captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "menu_options"), NULL, phrase_params, NULL, DEFAULT_IVR_TIMEOUT); ivre_playback(session, &menu.ivre_d, switch_event_get_header(menu.event_phrases, "menu_options"), NULL, menu.phrase_params, NULL, DEFAULT_IVR_TIMEOUT);
if (loc.result == RES_TIMEOUT) { if (menu.ivre_d.result == RES_TIMEOUT) {
/* TODO Ask for the prompt Again IF retry != 0 */ /* TODO Ask for the prompt Again IF retry != 0 */
} else if (loc.result == RES_INVALID) { } else if (menu.ivre_d.result == RES_INVALID) {
/* TODO Say invalid option, and ask for the prompt again IF retry != 0 */ /* TODO Say invalid option, and ask for the prompt again IF retry != 0 */
} else if (loc.result == RES_FOUND) { /* Matching DTMF Key Pressed */ } else if (menu.ivre_d.result == RES_FOUND) { /* Matching DTMF Key Pressed */
const char *action = switch_event_get_header(menu.event_keys_dtmf, loc.dtmf_stored); const char *action = switch_event_get_header(menu.event_keys_dtmf, menu.ivre_d.dtmf_stored);
/* Reset the try count */ /* Reset the try count */
retry = MAX_ATTEMPT; retry = MAX_ATTEMPT;
@ -281,16 +268,16 @@ void vmivr_menu_navigator(switch_core_session_t *session, vmivr_profile_t *profi
} else if (!strcasecmp(action, "next_msg")) { /* Next Message */ } else if (!strcasecmp(action, "next_msg")) { /* Next Message */
next_msg++; next_msg++;
if (next_msg > msg_count) { if (next_msg > msg_count) {
//playbackBufferDTMF(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);
retry = -1; retry = -1;
} }
} else if (!strcasecmp(action, "prev_msg")) { /* Previous Message */ } else if (!strcasecmp(action, "prev_msg")) { /* Previous Message */
next_msg--; next_msg--;
} else if (!strcasecmp(action, "delete_msg")) { /* Delete / Undelete Message */ } else if (!strcasecmp(action, "delete_msg")) { /* Delete / Undelete Message */
const char *msg_flags = switch_event_get_header(phrase_params, "VM-Message-Flags"); const char *msg_flags = switch_event_get_header(menu.phrase_params, "VM-Message-Flags");
if (!msg_flags || strncasecmp(msg_flags, "delete", 6)) { if (!msg_flags || strncasecmp(msg_flags, "delete", 6)) {
cmd = switch_core_session_sprintf(session, "%s %s %s %s", profile->api_profile, profile->domain, profile->id, switch_event_get_header(phrase_params, "VM-Message-UUID")); cmd = switch_core_session_sprintf(session, "%s %s %s %s", profile->api_profile, profile->domain, profile->id, switch_event_get_header(menu.phrase_params, "VM-Message-UUID"));
vmivr_api_execute(session, profile->api_msg_delete, cmd); vmivr_api_execute(session, profile->api_msg_delete, cmd);
msg_deleted = SWITCH_TRUE; msg_deleted = SWITCH_TRUE;
@ -298,18 +285,18 @@ void vmivr_menu_navigator(switch_core_session_t *session, vmivr_profile_t *profi
//next_msg++; //next_msg++;
skip_header = skip_playback = SWITCH_TRUE; skip_header = skip_playback = SWITCH_TRUE;
} else { } else {
cmd = switch_core_session_sprintf(session, "%s %s %s %s", profile->api_profile, profile->domain, profile->id, switch_event_get_header(phrase_params, "VM-Message-UUID")); cmd = switch_core_session_sprintf(session, "%s %s %s %s", profile->api_profile, profile->domain, profile->id, switch_event_get_header(menu.phrase_params, "VM-Message-UUID"));
vmivr_api_execute(session, profile->api_msg_undelete, cmd); vmivr_api_execute(session, profile->api_msg_undelete, cmd);
msg_undeleted = SWITCH_TRUE; msg_undeleted = SWITCH_TRUE;
} }
} else if (!strcasecmp(action, "save_msg")) { /* Save Message */ } else if (!strcasecmp(action, "save_msg")) { /* Save Message */
cmd = switch_core_session_sprintf(session, "%s %s %s %s", profile->api_profile, profile->domain, profile->id, switch_event_get_header(phrase_params, "VM-Message-UUID")); cmd = switch_core_session_sprintf(session, "%s %s %s %s", profile->api_profile, profile->domain, profile->id, switch_event_get_header(menu.phrase_params, "VM-Message-UUID"));
vmivr_api_execute(session, profile->api_msg_save, cmd); vmivr_api_execute(session, profile->api_msg_save, cmd);
msg_saved = SWITCH_TRUE; msg_saved = SWITCH_TRUE;
} else if (!strcasecmp(action, "callback")) { /* CallBack caller */ } else if (!strcasecmp(action, "callback")) { /* CallBack caller */
const char *cid_num = switch_event_get_header(phrase_params, "VM-Message-Caller-Number"); const char *cid_num = switch_event_get_header(menu.phrase_params, "VM-Message-Caller-Number");
if (cid_num) { if (cid_num) {
/* TODO add detection for private number */ /* TODO add detection for private number */
switch_core_session_execute_exten(session, cid_num, "XML", profile->domain); switch_core_session_execute_exten(session, cid_num, "XML", profile->domain);
@ -327,33 +314,33 @@ void vmivr_menu_navigator(switch_core_session_t *session, vmivr_profile_t *profi
} }
} }
/* IF the API to get the message returned us a COPY of the file locally (temp file create from a DB or from a web server), delete it */ /* IF the API to get the message returned us a COPY of the file menu.ivre_dally (temp file create from a DB or from a web server), delete it */
if (switch_true(switch_event_get_header(phrase_params, "VM-Message-Private-Local-Copy"))) { if (switch_true(switch_event_get_header(menu.phrase_params, "VM-Message-Private-Local-Copy"))) {
const char *file_path = switch_event_get_header(phrase_params, "VM-Message-File-Path"); const char *file_path = switch_event_get_header(menu.phrase_params, "VM-Message-File-Path");
if (file_path && unlink(file_path) != 0) { if (file_path && unlink(file_path) != 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to delete temp file [%s]\n", file_path); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to delete temp file [%s]\n", file_path);
} }
} }
switch_event_destroy(&phrase_params); menu_instance_free(&menu);
} }
done: done:
switch_event_destroy(&msg_list_params); switch_event_destroy(&msg_list_params);
free_profile_menu_event(&menu); menu_free(&menu);
return; return;
} }
void vmivr_menu_forward(switch_core_session_t *session, vmivr_profile_t *profile) { void vmivr_menu_forward(switch_core_session_t *session, vmivr_profile_t *profile) {
vmivr_menu_profile_t menu = { "std_forward_ask_prepend" }; vmivr_menu_t menu = { "std_forward_ask_prepend" };
switch_channel_t *channel = switch_core_session_get_channel(session); switch_channel_t *channel = switch_core_session_get_channel(session);
const char *prepend_filepath = NULL; const char *prepend_filepath = NULL;
int retry; int retry;
switch_bool_t forward_msg = SWITCH_FALSE; switch_bool_t forward_msg = SWITCH_FALSE;
/* Initialize Menu Configs */ /* Initialize Menu Configs */
populate_profile_menu_event(profile, &menu); menu_init(profile, &menu);
if (!menu.event_keys_dtmf || !menu.event_phrases) { if (!menu.event_keys_dtmf || !menu.event_phrases) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing Menu Phrases and Keys\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing Menu Phrases and Keys\n");
@ -361,25 +348,19 @@ void vmivr_menu_forward(switch_core_session_t *session, vmivr_profile_t *profile
} }
for (retry = MAX_ATTEMPT; switch_channel_ready(channel) && retry > 0; retry--) { for (retry = MAX_ATTEMPT; switch_channel_ready(channel) && retry > 0; retry--) {
dtmf_ss_t loc;
char *dtmfa[16] = { 0 };
switch_event_t *phrase_params = NULL;
switch_event_create(&phrase_params, SWITCH_EVENT_REQUEST_PARAMS); menu_instance_init(&menu);
append_event_profile(phrase_params, profile, menu);
populate_dtmfa_from_event(phrase_params, profile, menu, dtmfa); ivre_init(&menu.ivre_d, menu.dtmfa);
captureMenuInitialize(&loc, dtmfa); ivre_playback(session, &menu.ivre_d, switch_event_get_header(menu.event_phrases, "menu_options"), NULL, menu.phrase_params, NULL, DEFAULT_IVR_TIMEOUT);
captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "menu_options"), NULL, phrase_params, NULL, DEFAULT_IVR_TIMEOUT); if (menu.ivre_d.result == RES_TIMEOUT) {
if (loc.result == RES_TIMEOUT) {
/* TODO Ask for the prompt Again IF retry != 0 */ /* TODO Ask for the prompt Again IF retry != 0 */
} else if (loc.result == RES_INVALID) { } else if (menu.ivre_d.result == RES_INVALID) {
/* TODO Say invalid option, and ask for the prompt again IF retry != 0 */ /* TODO Say invalid option, and ask for the prompt again IF retry != 0 */
} else if (loc.result == RES_FOUND) { /* Matching DTMF Key Pressed */ } else if (menu.ivre_d.result == RES_FOUND) { /* Matching DTMF Key Pressed */
const char *action = switch_event_get_header(menu.event_keys_dtmf, loc.dtmf_stored); const char *action = switch_event_get_header(menu.event_keys_dtmf, menu.ivre_d.dtmf_stored);
/* Reset the try count */ /* Reset the try count */
retry = MAX_ATTEMPT; retry = MAX_ATTEMPT;
@ -389,12 +370,12 @@ void vmivr_menu_forward(switch_core_session_t *session, vmivr_profile_t *profile
retry = -1; retry = -1;
forward_msg = SWITCH_FALSE; forward_msg = SWITCH_FALSE;
} else if (!strcasecmp(action, "prepend")) { /* Prepend record msg */ } else if (!strcasecmp(action, "prepend")) { /* Prepend record msg */
vmivr_menu_profile_t sub_menu = { "std_record_message" }; vmivr_menu_t sub_menu = { "std_record_message" };
char *tmp_filepath = generate_random_file_name(session, "voicemail_ivr", "wav" /* TODO make it configurable */); char *tmp_filepath = generate_random_file_name(session, "voicemail_ivr", "wav" /* TODO make it configurable */);
switch_status_t status; switch_status_t status;
/* Initialize Menu Configs */ /* Initialize Menu Configs */
populate_profile_menu_event(profile, &sub_menu); menu_init(profile, &sub_menu);
status = vmivr_menu_record(session, profile, sub_menu, tmp_filepath); status = vmivr_menu_record(session, profile, sub_menu, tmp_filepath);
@ -402,14 +383,14 @@ void vmivr_menu_forward(switch_core_session_t *session, vmivr_profile_t *profile
//char *cmd = switch_core_session_sprintf(session, "%s %s %s %d %s", profile->api_profile, profile->domain, profile->id, gnum, tmp_filepath); //char *cmd = switch_core_session_sprintf(session, "%s %s %s %d %s", profile->api_profile, profile->domain, profile->id, gnum, tmp_filepath);
//char *str_num = switch_core_session_sprintf(session, "%d", gnum); //char *str_num = switch_core_session_sprintf(session, "%d", gnum);
//vmivr_api_execute(session, profile->api_pref_greeting_set, cmd); //vmivr_api_execute(session, profile->api_pref_greeting_set, cmd);
//playbackBufferDTMF(session, switch_event_get_header(menu.event_phrases, "selected_slot"), str_num, NULL, NULL, 0); //ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "selected_slot"), str_num, NULL, NULL, 0);
prepend_filepath = tmp_filepath; prepend_filepath = tmp_filepath;
retry = -1; retry = -1;
forward_msg = SWITCH_TRUE; forward_msg = SWITCH_TRUE;
} else { } else {
/* TODO Error Recording msg */ /* TODO Error Recording msg */
} }
free_profile_menu_event(&sub_menu); menu_free(&sub_menu);
} else if (!strcasecmp(action, "forward")) { /* Forward without prepend msg */ } else if (!strcasecmp(action, "forward")) { /* Forward without prepend msg */
retry = -1; retry = -1;
@ -422,7 +403,7 @@ void vmivr_menu_forward(switch_core_session_t *session, vmivr_profile_t *profile
} }
} }
} }
switch_event_destroy(&phrase_params); menu_instance_free(&menu);
} }
@ -430,42 +411,42 @@ void vmivr_menu_forward(switch_core_session_t *session, vmivr_profile_t *profile
if (forward_msg) { if (forward_msg) {
for (retry = MAX_ATTEMPT; switch_channel_ready(channel) && retry > 0; retry--) { for (retry = MAX_ATTEMPT; switch_channel_ready(channel) && retry > 0; retry--) {
const char *id = NULL; const char *id = NULL;
vmivr_menu_profile_t sub_menu = { "std_forward_ask_extension" }; vmivr_menu_t sub_menu = { "std_forward_ask_extension" };
/* Initialize Menu Configs */ /* Initialize Menu Configs */
populate_profile_menu_event(profile, &sub_menu); menu_init(profile, &sub_menu);
id = vmivr_menu_get_input_set(session, profile, sub_menu, "X."); id = vmivr_menu_get_input_set(session, profile, sub_menu, "X.");
if (id) { if (id) {
const char *cmd = switch_core_session_sprintf(session, "%s %s %s %s %s %s %s%s%s", profile->api_profile, profile->domain, profile->id, profile->current_msg_uuid, profile->domain, id, prepend_filepath?" ":"", prepend_filepath?prepend_filepath:"" ); const char *cmd = switch_core_session_sprintf(session, "%s %s %s %s %s %s %s%s%s", profile->api_profile, profile->domain, profile->id, profile->current_msg_uuid, profile->domain, id, prepend_filepath?" ":"", prepend_filepath?prepend_filepath:"" );
if (vmivr_api_execute(session, profile->api_msg_forward, cmd) == SWITCH_STATUS_SUCCESS) { if (vmivr_api_execute(session, profile->api_msg_forward, cmd) == SWITCH_STATUS_SUCCESS) {
playbackBufferDTMF(session, switch_event_get_header(sub_menu.event_phrases, "ack"), "saved", NULL, NULL, 0); ivre_playback_dtmf_buffered(session, switch_event_get_header(sub_menu.event_phrases, "ack"), "saved", NULL, NULL, 0);
retry = -1; retry = -1;
} else { } else {
playbackBufferDTMF(session, switch_event_get_header(sub_menu.event_phrases, "invalid_extension"), NULL, NULL, NULL, 0); ivre_playback_dtmf_buffered(session, switch_event_get_header(sub_menu.event_phrases, "invalid_extension"), NULL, NULL, NULL, 0);
} }
} else { } else {
/* TODO Prompt about input not valid */ /* TODO Prompt about input not valid */
} }
free_profile_menu_event(&sub_menu); menu_free(&sub_menu);
/* TODO add Confirmation of the transfered number */ /* TODO add Confirmation of the transfered number */
} }
/* TODO Ask if we want to transfer the msg to more person */ /* TODO Ask if we want to transfer the msg to more person */
} }
free_profile_menu_event(&menu); menu_free(&menu);
} }
void vmivr_menu_record_name(switch_core_session_t *session, vmivr_profile_t *profile) { void vmivr_menu_record_name(switch_core_session_t *session, vmivr_profile_t *profile) {
switch_status_t status; switch_status_t status;
vmivr_menu_profile_t menu = { "std_record_name" }; vmivr_menu_t menu = { "std_record_name" };
char *tmp_filepath = generate_random_file_name(session, "voicemail_ivr", "wav" /* TODO make it configurable */); char *tmp_filepath = generate_random_file_name(session, "voicemail_ivr", "wav" /* TODO make it configurable */);
/* Initialize Menu Configs */ /* Initialize Menu Configs */
populate_profile_menu_event(profile, &menu); menu_init(profile, &menu);
status = vmivr_menu_record(session, profile, menu, tmp_filepath); status = vmivr_menu_record(session, profile, menu, tmp_filepath);
@ -477,10 +458,10 @@ void vmivr_menu_record_name(switch_core_session_t *session, vmivr_profile_t *pro
void vmivr_menu_set_password(switch_core_session_t *session, vmivr_profile_t *profile) { void vmivr_menu_set_password(switch_core_session_t *session, vmivr_profile_t *profile) {
char *password; char *password;
vmivr_menu_profile_t menu = { "std_set_password" }; vmivr_menu_t menu = { "std_set_password" };
/* Initialize Menu Configs */ /* Initialize Menu Configs */
populate_profile_menu_event(profile, &menu); menu_init(profile, &menu);
password = vmivr_menu_get_input_set(session, profile, menu, "XXX." /* TODO Conf Min 3 Digit */); password = vmivr_menu_get_input_set(session, profile, menu, "XXX." /* TODO Conf Min 3 Digit */);
@ -491,16 +472,16 @@ void vmivr_menu_set_password(switch_core_session_t *session, vmivr_profile_t *pr
} }
free_profile_menu_event(&menu); menu_free(&menu);
} }
void vmivr_menu_authenticate(switch_core_session_t *session, vmivr_profile_t *profile) { void vmivr_menu_authenticate(switch_core_session_t *session, vmivr_profile_t *profile) {
switch_channel_t *channel = switch_core_session_get_channel(session); switch_channel_t *channel = switch_core_session_get_channel(session);
vmivr_menu_profile_t menu = { "std_authenticate" }; vmivr_menu_t menu = { "std_authenticate" };
int retry; int retry;
const char *auth_var = NULL; const char *auth_var = NULL;
/* Initialize Menu Configs */ /* Initialize Menu Configs */
populate_profile_menu_event(profile, &menu); menu_init(profile, &menu);
if (profile->id && (auth_var = switch_channel_get_variable(channel, "voicemail_authorized")) && switch_true(auth_var)) { if (profile->id && (auth_var = switch_channel_get_variable(channel, "voicemail_authorized")) && switch_true(auth_var)) {
profile->authorized = SWITCH_TRUE; profile->authorized = SWITCH_TRUE;
@ -511,20 +492,20 @@ void vmivr_menu_authenticate(switch_core_session_t *session, vmivr_profile_t *pr
char *cmd = NULL; char *cmd = NULL;
if (!id) { if (!id) {
vmivr_menu_profile_t sub_menu = { "std_authenticate_ask_user" }; vmivr_menu_t sub_menu = { "std_authenticate_ask_user" };
/* Initialize Menu Configs */ /* Initialize Menu Configs */
populate_profile_menu_event(profile, &sub_menu); menu_init(profile, &sub_menu);
id = vmivr_menu_get_input_set(session, profile, sub_menu, "X." /* TODO Conf Min 3 Digit */); id = vmivr_menu_get_input_set(session, profile, sub_menu, "X." /* TODO Conf Min 3 Digit */);
free_profile_menu_event(&sub_menu); menu_free(&sub_menu);
} }
if (!password) { if (!password) {
vmivr_menu_profile_t sub_menu = { "std_authenticate_ask_password" }; vmivr_menu_t sub_menu = { "std_authenticate_ask_password" };
/* Initialize Menu Configs */ /* Initialize Menu Configs */
populate_profile_menu_event(profile, &sub_menu); menu_init(profile, &sub_menu);
password = vmivr_menu_get_input_set(session, profile, sub_menu, "X." /* TODO Conf Min 3 Digit */); password = vmivr_menu_get_input_set(session, profile, sub_menu, "X." /* TODO Conf Min 3 Digit */);
free_profile_menu_event(&sub_menu); menu_free(&sub_menu);
} }
cmd = switch_core_session_sprintf(session, "%s %s %s %s", profile->api_profile, profile->domain, id, password); cmd = switch_core_session_sprintf(session, "%s %s %s %s", profile->api_profile, profile->domain, id, password);
@ -532,20 +513,20 @@ void vmivr_menu_authenticate(switch_core_session_t *session, vmivr_profile_t *pr
profile->id = id; profile->id = id;
profile->authorized = SWITCH_TRUE; profile->authorized = SWITCH_TRUE;
} else { } else {
playbackBufferDTMF(session, switch_event_get_header(menu.event_phrases, "fail_auth"), NULL, NULL, NULL, 0); ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "fail_auth"), NULL, NULL, NULL, 0);
} }
} }
free_profile_menu_event(&menu); menu_free(&menu);
} }
void vmivr_menu_select_greeting_slot(switch_core_session_t *session, vmivr_profile_t *profile) { void vmivr_menu_select_greeting_slot(switch_core_session_t *session, vmivr_profile_t *profile) {
vmivr_menu_profile_t menu = { "std_select_greeting_slot" }; vmivr_menu_t menu = { "std_select_greeting_slot" };
const char *result; const char *result;
int gnum = -1; int gnum = -1;
/* Initialize Menu Configs */ /* Initialize Menu Configs */
populate_profile_menu_event(profile, &menu); menu_init(profile, &menu);
result = vmivr_menu_get_input_set(session, profile, menu, "X"); result = vmivr_menu_get_input_set(session, profile, menu, "X");
@ -555,23 +536,23 @@ void vmivr_menu_select_greeting_slot(switch_core_session_t *session, vmivr_profi
char * cmd = switch_core_session_sprintf(session, "%s %s %s %d", profile->api_profile, profile->domain, profile->id, gnum); char * cmd = switch_core_session_sprintf(session, "%s %s %s %d", profile->api_profile, profile->domain, profile->id, gnum);
if (vmivr_api_execute(session, profile->api_pref_greeting_set, cmd) == SWITCH_STATUS_SUCCESS) { if (vmivr_api_execute(session, profile->api_pref_greeting_set, cmd) == SWITCH_STATUS_SUCCESS) {
char *str_num = switch_core_session_sprintf(session, "%d", gnum); char *str_num = switch_core_session_sprintf(session, "%d", gnum);
playbackBufferDTMF(session, switch_event_get_header(menu.event_phrases, "selected_slot"), str_num, NULL, NULL, 0); ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "selected_slot"), str_num, NULL, NULL, 0);
} else { } else {
playbackBufferDTMF(session, switch_event_get_header(menu.event_phrases, "invalid_slot"), NULL, NULL, NULL, 0); ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "invalid_slot"), NULL, NULL, NULL, 0);
} }
} }
free_profile_menu_event(&menu); menu_free(&menu);
} }
void vmivr_menu_record_greeting_with_slot(switch_core_session_t *session, vmivr_profile_t *profile) { void vmivr_menu_record_greeting_with_slot(switch_core_session_t *session, vmivr_profile_t *profile) {
vmivr_menu_profile_t menu = { "std_record_greeting_with_slot" }; vmivr_menu_t menu = { "std_record_greeting_with_slot" };
const char *result; const char *result;
int gnum = -1; int gnum = -1;
/* Initialize Menu Configs */ /* Initialize Menu Configs */
populate_profile_menu_event(profile, &menu); menu_init(profile, &menu);
result = vmivr_menu_get_input_set(session, profile, menu, "X"); result = vmivr_menu_get_input_set(session, profile, menu, "X");
@ -580,12 +561,12 @@ void vmivr_menu_record_greeting_with_slot(switch_core_session_t *session, vmivr_
/* If user entered 0, we don't accept it */ /* If user entered 0, we don't accept it */
if (gnum > 0) { if (gnum > 0) {
vmivr_menu_profile_t sub_menu = { "std_record_greeting" }; vmivr_menu_t sub_menu = { "std_record_greeting" };
char *tmp_filepath = generate_random_file_name(session, "voicemail_ivr", "wav" /* TODO make it configurable */); char *tmp_filepath = generate_random_file_name(session, "voicemail_ivr", "wav" /* TODO make it configurable */);
switch_status_t status; switch_status_t status;
/* Initialize Menu Configs */ /* Initialize Menu Configs */
populate_profile_menu_event(profile, &sub_menu); menu_init(profile, &sub_menu);
status = vmivr_menu_record(session, profile, sub_menu, tmp_filepath); status = vmivr_menu_record(session, profile, sub_menu, tmp_filepath);
@ -593,13 +574,13 @@ void vmivr_menu_record_greeting_with_slot(switch_core_session_t *session, vmivr_
char *cmd = switch_core_session_sprintf(session, "%s %s %s %d %s", profile->api_profile, profile->domain, profile->id, gnum, tmp_filepath); char *cmd = switch_core_session_sprintf(session, "%s %s %s %d %s", profile->api_profile, profile->domain, profile->id, gnum, tmp_filepath);
char *str_num = switch_core_session_sprintf(session, "%d", gnum); char *str_num = switch_core_session_sprintf(session, "%d", gnum);
vmivr_api_execute(session, profile->api_pref_greeting_set, cmd); vmivr_api_execute(session, profile->api_pref_greeting_set, cmd);
playbackBufferDTMF(session, switch_event_get_header(menu.event_phrases, "selected_slot"), str_num, NULL, NULL, 0); ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "selected_slot"), str_num, NULL, NULL, 0);
} }
free_profile_menu_event(&sub_menu); menu_free(&sub_menu);
} }
free_profile_menu_event(&menu); menu_free(&menu);
} }
@ -608,10 +589,10 @@ void vmivr_menu_preference(switch_core_session_t *session, vmivr_profile_t *prof
int retry; int retry;
vmivr_menu_profile_t menu = { "std_preference" }; vmivr_menu_t menu = { "std_preference" };
/* Initialize Menu Configs */ /* Initialize Menu Configs */
populate_profile_menu_event(profile, &menu); menu_init(profile, &menu);
if (!menu.event_keys_dtmf || !menu.event_phrases) { if (!menu.event_keys_dtmf || !menu.event_phrases) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing Menu Phrases and Keys\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing Menu Phrases and Keys\n");
@ -619,25 +600,19 @@ void vmivr_menu_preference(switch_core_session_t *session, vmivr_profile_t *prof
} }
for (retry = MAX_ATTEMPT; switch_channel_ready(channel) && retry > 0; retry--) { for (retry = MAX_ATTEMPT; switch_channel_ready(channel) && retry > 0; retry--) {
dtmf_ss_t loc;
char *dtmfa[16] = { 0 };
switch_event_t *phrase_params = NULL;
switch_event_create(&phrase_params, SWITCH_EVENT_REQUEST_PARAMS); menu_instance_init(&menu);
append_event_profile(phrase_params, profile, menu);
populate_dtmfa_from_event(phrase_params, profile, menu, dtmfa); ivre_init(&menu.ivre_d, menu.dtmfa);
captureMenuInitialize(&loc, dtmfa); ivre_playback(session, &menu.ivre_d, switch_event_get_header(menu.event_phrases, "menu_options"), NULL, menu.phrase_params, NULL, DEFAULT_IVR_TIMEOUT);
captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "menu_options"), NULL, phrase_params, NULL, DEFAULT_IVR_TIMEOUT); if (menu.ivre_d.result == RES_TIMEOUT) {
if (loc.result == RES_TIMEOUT) {
/* TODO Ask for the prompt Again IF retry != 0 */ /* TODO Ask for the prompt Again IF retry != 0 */
} else if (loc.result == RES_INVALID) { } else if (menu.ivre_d.result == RES_INVALID) {
/* TODO Say invalid option, and ask for the prompt again IF retry != 0 */ /* TODO Say invalid option, and ask for the prompt again IF retry != 0 */
} else if (loc.result == RES_FOUND) { /* Matching DTMF Key Pressed */ } else if (menu.ivre_d.result == RES_FOUND) { /* Matching DTMF Key Pressed */
const char *action = switch_event_get_header(menu.event_keys_dtmf, loc.dtmf_stored); const char *action = switch_event_get_header(menu.event_keys_dtmf, menu.ivre_d.dtmf_stored);
/* Reset the try count */ /* Reset the try count */
retry = MAX_ATTEMPT; retry = MAX_ATTEMPT;
@ -653,13 +628,13 @@ void vmivr_menu_preference(switch_core_session_t *session, vmivr_profile_t *prof
} }
} }
} }
switch_event_destroy(&phrase_params); menu_instance_free(&menu);
} }
free_profile_menu_event(&menu); menu_free(&menu);
} }
char *vmivr_menu_get_input_set(switch_core_session_t *session, vmivr_profile_t *profile, vmivr_menu_profile_t menu, const char *input_mask) { char *vmivr_menu_get_input_set(switch_core_session_t *session, vmivr_profile_t *profile, vmivr_menu_t menu, const char *input_mask) {
char *result = NULL; char *result = NULL;
int retry; int retry;
const char *terminate_key = NULL; const char *terminate_key = NULL;
@ -673,49 +648,43 @@ char *vmivr_menu_get_input_set(switch_core_session_t *session, vmivr_profile_t *
terminate_key = switch_event_get_header(menu.event_keys_action, "ivrengine:terminate_entry"); terminate_key = switch_event_get_header(menu.event_keys_action, "ivrengine:terminate_entry");
for (retry = MAX_ATTEMPT; switch_channel_ready(channel) && retry > 0; retry--) { for (retry = MAX_ATTEMPT; switch_channel_ready(channel) && retry > 0; retry--) {
dtmf_ss_t loc;
char *dtmfa[16] = { 0 };
int i; int i;
switch_event_t *phrase_params = NULL;
switch_event_create(&phrase_params, SWITCH_EVENT_REQUEST_PARAMS); menu_instance_init(&menu);
append_event_profile(phrase_params, profile, menu);
populate_dtmfa_from_event(phrase_params, profile, menu, dtmfa);
/* Find the last entry and append this one to it */ /* Find the last entry and append this one to it */
for (i=0; dtmfa[i] && i < 16; i++){ for (i=0; menu.dtmfa[i] && i < 16; i++){
} }
dtmfa[i] = (char *) input_mask; menu.dtmfa[i] = (char *) input_mask;
captureMenuInitialize(&loc, dtmfa); ivre_init(&menu.ivre_d, menu.dtmfa);
if (terminate_key) { if (terminate_key) {
loc.terminate_key = terminate_key[0]; menu.ivre_d.terminate_key = terminate_key[0];
} }
captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "instructions"), NULL, phrase_params, NULL, DEFAULT_IVR_TIMEOUT); ivre_playback(session, &menu.ivre_d, switch_event_get_header(menu.event_phrases, "instructions"), NULL, menu.phrase_params, NULL, DEFAULT_IVR_TIMEOUT);
if (loc.result == RES_TIMEOUT) { if (menu.ivre_d.result == RES_TIMEOUT) {
/* TODO Ask for the prompt Again IF retry != 0 */ /* TODO Ask for the prompt Again IF retry != 0 */
} else if (loc.result == RES_INVALID) { } else if (menu.ivre_d.result == RES_INVALID) {
/* TODO Say invalid option, and ask for the prompt again IF retry != 0 */ /* TODO Say invalid option, and ask for the prompt again IF retry != 0 */
} else if (loc.result == RES_FOUND) { /* Matching DTMF Key Pressed */ } else if (menu.ivre_d.result == RES_FOUND) { /* Matching DTMF Key Pressed */
/* Reset the try count */ /* Reset the try count */
retry = MAX_ATTEMPT; retry = MAX_ATTEMPT;
if (!strncasecmp(loc.completeMatch, input_mask, 1)) { if (!strncasecmp(menu.ivre_d.completeMatch, input_mask, 1)) {
result = switch_core_session_strdup(session, loc.dtmf_stored); result = switch_core_session_strdup(session, menu.ivre_d.dtmf_stored);
retry = -1; retry = -1;
} }
} }
switch_event_destroy(&phrase_params); menu_instance_free(&menu);
} }
return result; return result;
} }
switch_status_t vmivr_menu_record(switch_core_session_t *session, vmivr_profile_t *profile, vmivr_menu_profile_t menu, const char *file_name) { switch_status_t vmivr_menu_record(switch_core_session_t *session, vmivr_profile_t *profile, vmivr_menu_t menu, const char *file_name) {
switch_status_t status = SWITCH_STATUS_FALSE; switch_status_t status = SWITCH_STATUS_FALSE;
switch_channel_t *channel = switch_core_session_get_channel(session); switch_channel_t *channel = switch_core_session_get_channel(session);
int retry; int retry;
@ -730,10 +699,6 @@ switch_status_t vmivr_menu_record(switch_core_session_t *session, vmivr_profile_
} }
for (retry = MAX_ATTEMPT; switch_channel_ready(channel) && retry > 0; retry--) { for (retry = MAX_ATTEMPT; switch_channel_ready(channel) && retry > 0; retry--) {
dtmf_ss_t loc;
char *dtmfa[16] = { 0 };
switch_event_t *phrase_params = NULL;
switch_file_handle_t fh = { 0 }; switch_file_handle_t fh = { 0 };
/* TODO Make the following configurable */ /* TODO Make the following configurable */
@ -741,31 +706,27 @@ switch_status_t vmivr_menu_record(switch_core_session_t *session, vmivr_profile_
fh.silence_hits = 4; fh.silence_hits = 4;
//fh.samplerate = 8000; //fh.samplerate = 8000;
menu_instance_init(&menu);
switch_event_create(&phrase_params, SWITCH_EVENT_REQUEST_PARAMS); ivre_init(&menu.ivre_d, menu.dtmfa);
append_event_profile(phrase_params, profile, menu);
populate_dtmfa_from_event(phrase_params, profile, menu, dtmfa);
captureMenuInitialize(&loc, dtmfa);
if (record_prompt) { if (record_prompt) {
if (play_instruction) { if (play_instruction) {
captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "instructions"), NULL, phrase_params, NULL, 0); ivre_playback(session, &menu.ivre_d, switch_event_get_header(menu.event_phrases, "instructions"), NULL, menu.phrase_params, NULL, 0);
} }
play_instruction = SWITCH_TRUE; play_instruction = SWITCH_TRUE;
captureMenuRecord(session, &loc, phrase_params, file_name, &fh, 30 /* TODO Make max recording configurable */); ivre_record(session, &menu.ivre_d, menu.phrase_params, file_name, &fh, 30 /* TODO Make max recording configurable */);
} else { } else {
if (listen_recording) { if (listen_recording) {
switch_event_add_header(phrase_params, SWITCH_STACK_BOTTOM, "VM-Record-File-Path", "%s", file_name); switch_event_add_header(menu.phrase_params, SWITCH_STACK_BOTTOM, "VM-Record-File-Path", "%s", file_name);
captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "play_recording"), NULL, phrase_params, NULL, 0); ivre_playback(session, &menu.ivre_d, switch_event_get_header(menu.event_phrases, "play_recording"), NULL, menu.phrase_params, NULL, 0);
listen_recording = SWITCH_FALSE; listen_recording = SWITCH_FALSE;
} }
captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "menu_options"), NULL, phrase_params, NULL, DEFAULT_IVR_TIMEOUT); ivre_playback(session, &menu.ivre_d, switch_event_get_header(menu.event_phrases, "menu_options"), NULL, menu.phrase_params, NULL, DEFAULT_IVR_TIMEOUT);
} }
if (loc.recorded_audio) { if (menu.ivre_d.recorded_audio) {
/* Reset the try count */ /* Reset the try count */
retry = MAX_ATTEMPT; retry = MAX_ATTEMPT;
@ -773,12 +734,12 @@ switch_status_t vmivr_menu_record(switch_core_session_t *session, vmivr_profile_
record_prompt = SWITCH_FALSE; record_prompt = SWITCH_FALSE;
} else if (loc.result == RES_TIMEOUT) { } else if (menu.ivre_d.result == RES_TIMEOUT) {
/* TODO Ask for the prompt Again IF retry != 0 */ /* TODO Ask for the prompt Again IF retry != 0 */
} else if (loc.result == RES_INVALID) { } else if (menu.ivre_d.result == RES_INVALID) {
/* TODO Say invalid option, and ask for the prompt again IF retry != 0 */ /* TODO Say invalid option, and ask for the prompt again IF retry != 0 */
} else if (loc.result == RES_FOUND) { /* Matching DTMF Key Pressed */ } else if (menu.ivre_d.result == RES_FOUND) { /* Matching DTMF Key Pressed */
const char *action = switch_event_get_header(menu.event_keys_dtmf, loc.dtmf_stored); const char *action = switch_event_get_header(menu.event_keys_dtmf, menu.ivre_d.dtmf_stored);
/* Reset the try count */ /* Reset the try count */
retry = MAX_ATTEMPT; retry = MAX_ATTEMPT;
@ -808,7 +769,7 @@ switch_status_t vmivr_menu_record(switch_core_session_t *session, vmivr_profile_
} }
} }
} }
switch_event_destroy(&phrase_params); menu_instance_free(&menu);
} }
return status; return status;
} }

View File

@ -45,8 +45,8 @@ void vmivr_menu_record_greeting_with_slot(switch_core_session_t *session, vmivr_
void vmivr_menu_preference(switch_core_session_t *session, vmivr_profile_t *profile); void vmivr_menu_preference(switch_core_session_t *session, vmivr_profile_t *profile);
void vmivr_menu_forward(switch_core_session_t *session, vmivr_profile_t *profile); void vmivr_menu_forward(switch_core_session_t *session, vmivr_profile_t *profile);
switch_status_t vmivr_menu_record(switch_core_session_t *session, vmivr_profile_t *profile, vmivr_menu_profile_t menu, const char *file_name); switch_status_t vmivr_menu_record(switch_core_session_t *session, vmivr_profile_t *profile, vmivr_menu_t menu, const char *file_name);
char *vmivr_menu_get_input_set(switch_core_session_t *session, vmivr_profile_t *profile, vmivr_menu_profile_t menu, const char *input_mask); char *vmivr_menu_get_input_set(switch_core_session_t *session, vmivr_profile_t *profile, vmivr_menu_t menu, const char *input_mask);
struct vmivr_menu_function { struct vmivr_menu_function {

View File

@ -124,34 +124,6 @@ switch_status_t vmivr_api_execute(switch_core_session_t *session, const char *ap
return status; return status;
} }
void append_event_profile(switch_event_t *phrase_params, vmivr_profile_t *profile, vmivr_menu_profile_t menu) {
/* Used for some appending function */
if (profile->name && profile->id && profile->domain) {
switch_event_add_header(phrase_params, SWITCH_STACK_BOTTOM, "VM-Profile", "%s", profile->name);
switch_event_add_header(phrase_params, SWITCH_STACK_BOTTOM, "VM-Account-ID", "%s", profile->id);
switch_event_add_header(phrase_params, SWITCH_STACK_BOTTOM, "VM-Account-Domain", "%s", profile->domain);
}
}
void populate_dtmfa_from_event(switch_event_t *phrase_params, vmivr_profile_t *profile, vmivr_menu_profile_t menu, char **dtmfa) {
int i = 0;
if (menu.event_keys_dtmf) {
switch_event_header_t *hp;
for (hp = menu.event_keys_dtmf->headers; hp; hp = hp->next) {
if (strlen(hp->name) < 3 && hp->value) { /* TODO This is a hack to discard default FS Events ! */
const char *varphrasename = switch_event_get_header(menu.event_keys_varname, hp->value);
dtmfa[i++] = hp->name;
if (varphrasename && !zstr(varphrasename)) {
switch_event_add_header(phrase_params, SWITCH_STACK_BOTTOM, varphrasename, "%s", hp->name);
}
}
}
}
}
void append_event_message(switch_core_session_t *session, vmivr_profile_t *profile, switch_event_t *phrase_params, switch_event_t *msg_list_event, size_t current_msg) { void append_event_message(switch_core_session_t *session, vmivr_profile_t *profile, switch_event_t *phrase_params, switch_event_t *msg_list_event, size_t current_msg) {
char *varname; char *varname;

View File

@ -37,11 +37,9 @@
switch_status_t vmivr_merge_files(const char** inputs, const char *output); switch_status_t vmivr_merge_files(const char** inputs, const char *output);
void append_event_message(switch_core_session_t *session, vmivr_profile_t *profile, switch_event_t *phrase_params, switch_event_t *msg_list_event, size_t current_msg); void append_event_message(switch_core_session_t *session, vmivr_profile_t *profile, switch_event_t *phrase_params, switch_event_t *msg_list_event, size_t current_msg);
void append_event_profile(switch_event_t *phrase_params, vmivr_profile_t *profile, vmivr_menu_profile_t menu);
char *generate_random_file_name(switch_core_session_t *session, const char *mod_name, char *file_extension); char *generate_random_file_name(switch_core_session_t *session, const char *mod_name, char *file_extension);
switch_event_t *jsonapi2event(switch_core_session_t *session, switch_event_t *apply_event, const char *api, const char *data); switch_event_t *jsonapi2event(switch_core_session_t *session, switch_event_t *apply_event, const char *api, const char *data);
switch_status_t vmivr_merge_media_files(const char** inputs, const char *output); switch_status_t vmivr_merge_media_files(const char** inputs, const char *output);
switch_status_t vmivr_api_execute(switch_core_session_t *session, const char *apiname, const char *arguments); switch_status_t vmivr_api_execute(switch_core_session_t *session, const char *apiname, const char *arguments);
void populate_dtmfa_from_event(switch_event_t *phrase_params, vmivr_profile_t *profile, vmivr_menu_profile_t menu, char **dtmfa);
#endif /* _UTIL_H_ */ #endif /* _UTIL_H_ */