From eb9379b5f0152f5b312d8e58dc0960f4655efc95 Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Tue, 17 Feb 2015 09:52:49 -0500 Subject: [PATCH] FS-7164 [mod_rayo] support input grammar URL for MRCP only. Mixing URL and embedded grammars in same input request (but in different grammar elements) should work --- src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c | 5 +- .../mod_rayo/rayo_input_component.c | 105 +++++++++++------- 2 files changed, 70 insertions(+), 40 deletions(-) diff --git a/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c b/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c index 7f65bd406a..133618632f 100644 --- a/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c +++ b/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2009-2014, Anthony Minessale II + * Copyright (C) 2009-2015, Anthony Minessale II * * Version: MPL 1.1 * @@ -212,6 +212,7 @@ static int get_next_speech_channel_number(void); #define BUILTIN_ID "builtin:" #define SESSION_ID "session:" #define HTTP_ID "http://" +#define HTTPS_ID "https://" #define FILE_ID "file://" #define INLINE_ID "inline:" static int text_starts_with(const char *text, const char *match); @@ -3207,7 +3208,7 @@ static switch_status_t recog_asr_load_grammar(switch_asr_handle_t *ah, const cha } /* figure out what type of grammar this is */ - if (text_starts_with(grammar, HTTP_ID) || text_starts_with(grammar, FILE_ID) || text_starts_with(grammar, SESSION_ID) + if (text_starts_with(grammar, HTTP_ID) || text_starts_with(grammar, HTTPS_ID) || text_starts_with(grammar, FILE_ID) || text_starts_with(grammar, SESSION_ID) || text_starts_with(grammar, BUILTIN_ID)) { switch_log_printf(SWITCH_CHANNEL_UUID_LOG(schannel->session_uuid), SWITCH_LOG_DEBUG, "(%s) Grammar is URI\n", schannel->name); type = GRAMMAR_TYPE_URI; diff --git a/src/mod/event_handlers/mod_rayo/rayo_input_component.c b/src/mod/event_handlers/mod_rayo/rayo_input_component.c index 0eaabae613..a32cdf8602 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_input_component.c +++ b/src/mod/event_handlers/mod_rayo/rayo_input_component.c @@ -1,6 +1,6 @@ /* * mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2013-2014, Grasshopper + * Copyright (C) 2013-2015, Grasshopper * * Version: MPL 1.1 * @@ -383,6 +383,8 @@ static int validate_call_input(iks *input, const char **error) { iks *grammar; const char *content_type; + int has_grammar = 0; + int use_mrcp = 0; /* validate input attributes */ if (!VALIDATE_RAYO_INPUT(input)) { @@ -390,26 +392,48 @@ static int validate_call_input(iks *input, const char **error) return 0; } - /* missing grammar */ - grammar = iks_find(input, "grammar"); - if (!grammar) { + use_mrcp = !strncmp("unimrcp", iks_find_attrib(input, "recognizer") ? iks_find_attrib(input, "recognizer") : globals.default_recognizer, 7); + + /* validate grammar elements */ + for (grammar = iks_find(input, "grammar"); grammar; grammar = iks_next_tag(grammar)) { + /* is this a grammar? */ + if (strcmp("grammar", iks_name(grammar))) { + continue; + } + content_type = iks_find_attrib(grammar, "content-type"); + if (zstr(content_type)) { + /* grammar URL */ + if (zstr(iks_find_attrib(grammar, "url"))) { + *error = "url or content-type must be set"; + return 0; + } else if (!use_mrcp) { + *error = "url only supported with unimrcp recognizer"; + return 0; + } + } else { + /* inline grammar / only support srgs */ + if (!zstr(iks_find_attrib(grammar, "url"))) { + *error = "url not allowed with content-type"; + return 0; + } else if (strcmp("application/srgs+xml", content_type)) { + *error = "Unsupported content type"; + return 0; + } + + /* missing inline grammar body */ + if (zstr(iks_find_cdata(input, "grammar"))) { + *error = "Grammar content is missing"; + return 0; + } + } + has_grammar = 1; + } + + if (!has_grammar) { *error = "Missing "; return 0; } - /* only support srgs */ - content_type = iks_find_attrib(grammar, "content-type"); - if (!zstr(content_type) && strcmp("application/srgs+xml", content_type)) { - *error = "Unsupported content type"; - return 0; - } - - /* missing grammar body */ - if (zstr(iks_find_cdata(input, "grammar"))) { - *error = "Grammar content is missing"; - return 0; - } - return 1; } @@ -512,30 +536,35 @@ static char *setup_grammars_unimrcp(struct input_component *component, switch_co continue; } - /* get the srgs contained in this grammar */ - if (!(grammar_cdata = iks_child(grammar_tag)) || iks_type(grammar_cdata) != IKS_CDATA) { - *stanza_error = STANZA_ERROR_BAD_REQUEST; - *error_detail = "Missing grammar"; - switch_safe_free(grammar_uri_list.data); - return NULL; - } + if (!zstr(iks_find_attrib_soft(grammar_tag, "content-type"))) { + /* get the srgs contained in this grammar */ + if (!(grammar_cdata = iks_child(grammar_tag)) || iks_type(grammar_cdata) != IKS_CDATA) { + *stanza_error = STANZA_ERROR_BAD_REQUEST; + *error_detail = "Missing grammar"; + switch_safe_free(grammar_uri_list.data); + return NULL; + } - /* load the grammar */ - grammar = switch_core_sprintf(RAYO_POOL(component), "inline:%s", iks_cdata(grammar_cdata)); - grammar_name = switch_core_sprintf(RAYO_POOL(component), "grammar-%d", rayo_actor_seq_next(RAYO_ACTOR(component))); - /* unlock handler mutex, otherwise deadlock will happen if switch_ivr_detect_speech_load_grammar removes the media bug */ - switch_mutex_unlock(component->handler->mutex); - if (switch_ivr_detect_speech_load_grammar(session, grammar, grammar_name) != SWITCH_STATUS_SUCCESS) { + /* load the grammar */ + grammar = switch_core_sprintf(RAYO_POOL(component), "inline:%s", iks_cdata(grammar_cdata)); + grammar_name = switch_core_sprintf(RAYO_POOL(component), "grammar-%d", rayo_actor_seq_next(RAYO_ACTOR(component))); + /* unlock handler mutex, otherwise deadlock will happen if switch_ivr_detect_speech_load_grammar removes the media bug */ + switch_mutex_unlock(component->handler->mutex); + if (switch_ivr_detect_speech_load_grammar(session, grammar, grammar_name) != SWITCH_STATUS_SUCCESS) { + switch_mutex_lock(component->handler->mutex); + *stanza_error = STANZA_ERROR_INTERNAL_SERVER_ERROR; + *error_detail = "Failed to load grammar"; + switch_safe_free(grammar_uri_list.data); + return NULL; + } switch_mutex_lock(component->handler->mutex); - *stanza_error = STANZA_ERROR_INTERNAL_SERVER_ERROR; - *error_detail = "Failed to load grammar"; - switch_safe_free(grammar_uri_list.data); - return NULL; - } - switch_mutex_lock(component->handler->mutex); - /* add grammar to uri-list */ - grammar_uri_list.write_function(&grammar_uri_list, "session:%s\r\n", grammar_name); + /* add grammar to uri-list */ + grammar_uri_list.write_function(&grammar_uri_list, "session:%s\r\n", grammar_name); + } else { + /* add URI to uri-list */ + grammar_uri_list.write_function(&grammar_uri_list, "%s\r\n", iks_find_attrib_soft(grammar_tag, "url")); + } } switch_core_asr_text_param(ah, "start-recognize", "true");