diff options
author | Ira Lytvynenko <ILytvynenko@luxoft.com> | 2018-02-02 18:49:10 +0200 |
---|---|---|
committer | Ira Lytvynenko (GitHub) <ILytvynenko@luxoft.com> | 2018-06-26 12:01:42 +0300 |
commit | d7c0131acbf1af7b8d1d13029c8dadbd4ebe4f63 (patch) | |
tree | 423b05b67a66a9a7d27bd9f6a5e97748390c078a /src/components/application_manager/src | |
parent | f83d4759add793398b24cca0ae1dd157d03f648c (diff) | |
download | sdl_core-d7c0131acbf1af7b8d1d13029c8dadbd4ebe4f63.tar.gz |
RPCHandler implementation
Fix tests
Fix due to rebase
Fix unit tests in mobile commands
Fixed unit tests in next commands:
- delete_command_request_test.cc
- delete_sub_menu_test.cc
- perform_audio_pass_thru_test.cc
- reset_global_properties_test.cc
- send_location_request_test.cc
- set_global_properties_test.cc
Diffstat (limited to 'src/components/application_manager/src')
3 files changed, 427 insertions, 340 deletions
diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc index e68e2e4b62..f23600f46b 100644 --- a/src/components/application_manager/src/application_manager_impl.cc +++ b/src/components/application_manager/src/application_manager_impl.cc @@ -44,6 +44,7 @@ #include "application_manager/commands/command_notification_impl.h" #include "application_manager/message_helper.h" #include "application_manager/rpc_service_impl.h" +#include "application_manager/rpc_handler_impl.h" #include "application_manager/mobile_message_handler.h" #include "application_manager/policies/policy_handler.h" #include "application_manager/hmi_capabilities_impl.h" @@ -158,8 +159,6 @@ ApplicationManagerImpl::ApplicationManagerImpl( , request_ctrl_(am_settings) , hmi_so_factory_(NULL) , mobile_so_factory_(NULL) - , messages_from_mobile_("AM FromMobile", this) - , messages_from_hmi_("AM FromHMI", this) , audio_pass_thru_messages_("AudioPassThru", this) , hmi_capabilities_(new HMICapabilitiesImpl(*this)) , unregister_reason_( @@ -198,6 +197,7 @@ ApplicationManagerImpl::ApplicationManagerImpl( const uint32_t timeout_ms = 10000u; clearing_timer->Start(timeout_ms, timer::kSingleShot); timer_pool_.push_back(clearing_timer); + rpc_handler_.reset(new rpc_handler::RPCHandlerImpl(*this)); commands_holder_.reset(new CommandHolderImpl(*this)); } @@ -941,43 +941,6 @@ ApplicationManagerImpl::GetDeviceTransportType( return result; } -void ApplicationManagerImpl::OnMessageReceived( - const ::protocol_handler::RawMessagePtr message) { - LOG4CXX_AUTO_TRACE(logger_); - - if (!message) { - LOG4CXX_ERROR(logger_, "Null-pointer message received."); - NOTREACHED(); - return; - } - - utils::SharedPtr<Message> outgoing_message = ConvertRawMsgToMessage(message); - - if (outgoing_message) { - LOG4CXX_DEBUG(logger_, "Posting new Message"); - messages_from_mobile_.PostMessage( - impl::MessageFromMobile(outgoing_message)); - } -} - -void ApplicationManagerImpl::OnMobileMessageSent( - const ::protocol_handler::RawMessagePtr message) { - LOG4CXX_AUTO_TRACE(logger_); -} - -void ApplicationManagerImpl::OnMessageReceived( - hmi_message_handler::MessageSharedPointer message) { - LOG4CXX_AUTO_TRACE(logger_); - - if (!message) { - LOG4CXX_ERROR(logger_, "Null-pointer message received."); - NOTREACHED(); - return; - } - - messages_from_hmi_.PostMessage(impl::MessageFromHmi(message)); -} - ApplicationConstSharedPtr ApplicationManagerImpl::WaitingApplicationByID( const uint32_t hmi_id) const { AppsWaitRegistrationSet app_list = AppsWaitingForRegistration().GetData(); @@ -1751,8 +1714,11 @@ protocol_handler::ProtocolHandler& ApplicationManagerImpl::protocol_handler() void ApplicationManagerImpl::set_protocol_handler( protocol_handler::ProtocolHandler* handler) { protocol_handler_ = handler; - rpc_service_.reset(new rpc_service::RPCServiceImpl( - *this, request_ctrl_, protocol_handler_, hmi_handler_)); + rpc_service_.reset(new rpc_service::RPCServiceImpl(*this, + request_ctrl_, + protocol_handler_, + hmi_handler_, + *commands_holder_)); } void ApplicationManagerImpl::StartDevicesDiscovery() { @@ -1878,156 +1844,6 @@ bool ApplicationManagerImpl::Stop() { return true; } -bool ApplicationManagerImpl::ConvertMessageToSO( - const Message& message, smart_objects::SmartObject& output) { - LOG4CXX_AUTO_TRACE(logger_); - LOG4CXX_DEBUG(logger_, - "\t\t\tMessage to convert: protocol " - << message.protocol_version() << "; json " - << message.json_message()); - - switch (message.protocol_version()) { - case protocol_handler::MajorProtocolVersion::PROTOCOL_VERSION_5: - case protocol_handler::MajorProtocolVersion::PROTOCOL_VERSION_4: - case protocol_handler::MajorProtocolVersion::PROTOCOL_VERSION_3: - case protocol_handler::MajorProtocolVersion::PROTOCOL_VERSION_2: { - const bool conversion_result = - formatters::CFormatterJsonSDLRPCv2::fromString( - message.json_message(), - output, - message.function_id(), - message.type(), - message.correlation_id()); - - rpc::ValidationReport report("RPC"); - - if (!conversion_result || - !mobile_so_factory().attachSchema(output, true) || - ((output.validate(&report) != smart_objects::Errors::OK))) { - LOG4CXX_WARN(logger_, - "Failed to parse string to smart object :" - << message.json_message()); - utils::SharedPtr<smart_objects::SmartObject> response( - MessageHelper::CreateNegativeResponse( - message.connection_key(), - message.function_id(), - message.correlation_id(), - mobile_apis::Result::INVALID_DATA)); - - (*response)[strings::msg_params][strings::info] = - rpc::PrettyFormat(report); - rpc_service_->ManageMobileCommand(response, commands::Command::ORIGIN_SDL); - return false; - } - LOG4CXX_DEBUG(logger_, - "Convertion result for sdl object is true function_id " - << output[jhs::S_PARAMS][jhs::S_FUNCTION_ID].asInt()); - - output[strings::params][strings::connection_key] = - message.connection_key(); - output[strings::params][strings::protocol_version] = - message.protocol_version(); - if (message.binary_data()) { - if (message.payload_size() < message.data_size()) { - LOG4CXX_ERROR(logger_, - "Incomplete binary" - << " binary size should be " << message.data_size() - << " payload data size is " - << message.payload_size()); - utils::SharedPtr<smart_objects::SmartObject> response( - MessageHelper::CreateNegativeResponse( - message.connection_key(), - message.function_id(), - message.correlation_id(), - mobile_apis::Result::INVALID_DATA)); - rpc_service_->ManageMobileCommand(response, - commands::Command::ORIGIN_SDL); - return false; - } - output[strings::params][strings::binary_data] = - *(message.binary_data()); - } - break; - } - case protocol_handler::MajorProtocolVersion::PROTOCOL_VERSION_HMI: { -#ifdef ENABLE_LOG - int32_t result = -#endif - formatters::FormatterJsonRpc::FromString< - hmi_apis::FunctionID::eType, - hmi_apis::messageType::eType>(message.json_message(), output); - LOG4CXX_DEBUG(logger_, - "Convertion result: " - << result << " function id " - << output[jhs::S_PARAMS][jhs::S_FUNCTION_ID].asInt()); - if (!hmi_so_factory().attachSchema(output, false)) { - LOG4CXX_WARN(logger_, "Failed to attach schema to object."); - return false; - } - - rpc::ValidationReport report("RPC"); - - if (output.validate(&report) != smart_objects::Errors::OK) { - LOG4CXX_ERROR(logger_, - "Incorrect parameter from HMI" - << rpc::PrettyFormat(report)); - - output.erase(strings::msg_params); - output[strings::params][hmi_response::code] = - hmi_apis::Common_Result::INVALID_DATA; - output[strings::msg_params][strings::info] = rpc::PrettyFormat(report); - return false; - } - break; - } - case protocol_handler::MajorProtocolVersion::PROTOCOL_VERSION_1: { - static NsSmartDeviceLinkRPC::V1::v4_protocol_v1_2_no_extra v1_shema; - - if (message.function_id() == 0 || message.type() == kUnknownType) { - LOG4CXX_ERROR(logger_, "Message received: UNSUPPORTED_VERSION"); - - int32_t conversation_result = - formatters::CFormatterJsonSDLRPCv1::fromString< - NsSmartDeviceLinkRPC::V1::FunctionID::eType, - NsSmartDeviceLinkRPC::V1::messageType::eType>( - message.json_message(), output); - - if (formatters::CFormatterJsonSDLRPCv1::kSuccess == - conversation_result) { - smart_objects::SmartObject params = smart_objects::SmartObject( - smart_objects::SmartType::SmartType_Map); - - output[strings::params][strings::message_type] = - NsSmartDeviceLinkRPC::V1::messageType::response; - output[strings::params][strings::connection_key] = - message.connection_key(); - - output[strings::msg_params] = smart_objects::SmartObject( - smart_objects::SmartType::SmartType_Map); - output[strings::msg_params][strings::success] = false; - output[strings::msg_params][strings::result_code] = - NsSmartDeviceLinkRPC::V1::Result::UNSUPPORTED_VERSION; - - smart_objects::SmartObjectSPtr msg_to_send = - new smart_objects::SmartObject(output); - v1_shema.attachSchema(*msg_to_send, false); - rpc_service_->SendMessageToMobile(msg_to_send); - return false; - } - } - break; - } - default: - LOG4CXX_WARN(logger_, - "Application used unsupported protocol :" - << message.protocol_version() << "."); - return false; - } - - LOG4CXX_DEBUG(logger_, "Successfully parsed message into smart object"); - return true; -} - bool ApplicationManagerImpl::ConvertSOtoMessage( const smart_objects::SmartObject& message, Message& output) { LOG4CXX_AUTO_TRACE(logger_); @@ -2188,102 +2004,6 @@ MessageValidationResult ApplicationManagerImpl::ValidateMessageBySchema( return SUCCESS; } -utils::SharedPtr<Message> ApplicationManagerImpl::ConvertRawMsgToMessage( - const ::protocol_handler::RawMessagePtr message) { - LOG4CXX_AUTO_TRACE(logger_); - DCHECK(message); - utils::SharedPtr<Message> outgoing_message; - - LOG4CXX_DEBUG(logger_, "Service type." << message->service_type()); - if (message->service_type() != protocol_handler::kRpc && - message->service_type() != protocol_handler::kBulk) { - // skip this message, not under handling of ApplicationManager - LOG4CXX_TRACE(logger_, "Skipping message; not the under AM handling."); - return outgoing_message; - } - - Message* convertion_result = - MobileMessageHandler::HandleIncomingMessageProtocol(message); - - if (convertion_result) { - outgoing_message = convertion_result; - } else { - LOG4CXX_ERROR(logger_, "Received invalid message"); - } - return outgoing_message; -} - -void ApplicationManagerImpl::ProcessMessageFromMobile( - const utils::SharedPtr<Message> message) { - LOG4CXX_AUTO_TRACE(logger_); -#ifdef TELEMETRY_MONITOR - AMTelemetryObserver::MessageMetricSharedPtr metric( - new AMTelemetryObserver::MessageMetric()); - metric->begin = date_time::DateTime::getCurrentTime(); -#endif // TELEMETRY_MONITOR - smart_objects::SmartObjectSPtr so_from_mobile = - utils::MakeShared<smart_objects::SmartObject>(); - - DCHECK_OR_RETURN_VOID(so_from_mobile); - if (!so_from_mobile) { - LOG4CXX_ERROR(logger_, "Null pointer"); - return; - } - - if (!ConvertMessageToSO(*message, *so_from_mobile)) { - LOG4CXX_ERROR(logger_, "Cannot create smart object from message"); - return; - } -#ifdef TELEMETRY_MONITOR - metric->message = so_from_mobile; -#endif // TELEMETRY_MONITOR - - if (!rpc_service_->ManageMobileCommand(so_from_mobile, - commands::Command::ORIGIN_MOBILE)) { - LOG4CXX_ERROR(logger_, "Received command didn't run successfully"); - } -#ifdef TELEMETRY_MONITOR - metric->end = date_time::DateTime::getCurrentTime(); - if (metric_observer_) { - metric_observer_->OnMessage(metric); - } -#endif // TELEMETRY_MONITOR -} - -void ApplicationManagerImpl::ProcessMessageFromHMI( - const utils::SharedPtr<Message> message) { - LOG4CXX_AUTO_TRACE(logger_); - smart_objects::SmartObjectSPtr smart_object(new smart_objects::SmartObject); - - if (!smart_object) { - LOG4CXX_ERROR(logger_, "Null pointer"); - return; - } - -#ifdef HMI_DBUS_API - *smart_object = message->smart_object(); -#else - if (!ConvertMessageToSO(*message, *smart_object)) { - if (application_manager::MessageType::kResponse == - (*smart_object)[strings::params][strings::message_type].asInt()) { - (*smart_object).erase(strings::msg_params); - (*smart_object)[strings::params][hmi_response::code] = - hmi_apis::Common_Result::INVALID_DATA; - (*smart_object)[strings::msg_params][strings::info] = - std::string("Received invalid data on HMI response"); - } else { - LOG4CXX_ERROR(logger_, "Cannot create smart object from message"); - return; - } - } -#endif // HMI_DBUS_API - - LOG4CXX_DEBUG(logger_, "Converted message, trying to create hmi command"); - if (!rpc_service_->ManageHMICommand(smart_object)) { - LOG4CXX_ERROR(logger_, "Received command didn't run successfully"); - } -} - hmi_apis::HMI_API& ApplicationManagerImpl::hmi_so_factory() { if (!hmi_so_factory_) { hmi_so_factory_ = new hmi_apis::HMI_API; @@ -2509,7 +2229,7 @@ bool ApplicationManagerImpl::is_attenuated_supported() const { #ifdef TELEMETRY_MONITOR void ApplicationManagerImpl::SetTelemetryObserver( AMTelemetryObserver* observer) { - metric_observer_ = observer; + rpc_handler_->SetTelemetryObserver(observer); } #endif // TELEMETRY_MONITOR @@ -2878,54 +2598,6 @@ void ApplicationManagerImpl::OnAppUnauthorized(const uint32_t& app_id) { connection_handler::kUnauthorizedApp); } -void ApplicationManagerImpl::Handle(const impl::MessageFromMobile message) { - LOG4CXX_AUTO_TRACE(logger_); - - if (!message) { - LOG4CXX_ERROR(logger_, "Null-pointer message received."); - return; - } - sync_primitives::AutoLock lock(stopping_application_mng_lock_); - if (is_stopping_) { - LOG4CXX_INFO(logger_, "Application manager is stopping"); - return; - } -#ifdef SDL_REMOTE_CONTROL - if (plugin_manager_.IsMessageForPlugin(message)) { - if (functional_modules::ProcessResult::PROCESSED == - plugin_manager_.ProcessMessage(message)) { - LOG4CXX_INFO(logger_, "Message is processed by plugin."); - return; - } - } -#endif - ProcessMessageFromMobile(message); -} - - -void ApplicationManagerImpl::Handle(const impl::MessageFromHmi message) { - LOG4CXX_AUTO_TRACE(logger_); - - if (!message) { - LOG4CXX_ERROR(logger_, "Null-pointer message received."); - return; - } - -#ifdef SDL_REMOTE_CONTROL - if (plugin_manager_.IsHMIMessageForPlugin(message)) { - functional_modules::ProcessResult result = - plugin_manager_.ProcessHMIMessage(message); - if (functional_modules::ProcessResult::PROCESSED == result || - functional_modules::ProcessResult::FAILED == result) { - LOG4CXX_INFO(logger_, "Message is processed by plugin."); - return; - } - } -#endif - - ProcessMessageFromHMI(message); -} - void ApplicationManagerImpl::Handle(const impl::AudioData message) { LOG4CXX_AUTO_TRACE(logger_); smart_objects::SmartObjectSPtr on_audio_pass = @@ -3019,6 +2691,11 @@ mobile_apis::Result::eType ApplicationManagerImpl::CheckPolicyPermissions( return mobile_api::Result::SUCCESS; } +bool ApplicationManagerImpl::is_stopping() const { + sync_primitives::AutoLock lock(stopping_application_mng_lock_); + return is_stopping_; +} + void ApplicationManagerImpl::OnLowVoltage() { LOG4CXX_AUTO_TRACE(logger_); is_low_voltage_ = true; diff --git a/src/components/application_manager/src/rpc_handler_impl.cc b/src/components/application_manager/src/rpc_handler_impl.cc new file mode 100644 index 0000000000..af03e704eb --- /dev/null +++ b/src/components/application_manager/src/rpc_handler_impl.cc @@ -0,0 +1,389 @@ +/* + * Copyright (c) 2018, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "application_manager/rpc_handler_impl.h" + +namespace application_manager { +namespace rpc_handler { + +CREATE_LOGGERPTR_LOCAL(logger_, "RPCHandlerImpl") +namespace formatters = NsSmartDeviceLink::NsJSONHandler::Formatters; +namespace jhs = NsSmartDeviceLink::NsJSONHandler::strings; + +RPCHandlerImpl::RPCHandlerImpl(ApplicationManager& app_manager) + : app_manager_(app_manager) + , messages_from_mobile_("AM FromMobile", this) + , messages_from_hmi_("AM FromHMI", this) + , hmi_so_factory_(hmi_apis::HMI_API()) + , mobile_so_factory_(mobile_apis::MOBILE_API()) +#ifdef TELEMETRY_MONITOR + , metric_observer_(NULL) +#endif // TELEMETRY_MONITOR +{ +} + +RPCHandlerImpl::~RPCHandlerImpl() {} + +void RPCHandlerImpl::ProcessMessageFromMobile( + const utils::SharedPtr<Message> message) { + LOG4CXX_AUTO_TRACE(logger_); +#ifdef TELEMETRY_MONITOR + AMTelemetryObserver::MessageMetricSharedPtr metric( + new AMTelemetryObserver::MessageMetric()); + metric->begin = date_time::DateTime::getCurrentTime(); +#endif // TELEMETRY_MONITOR + smart_objects::SmartObjectSPtr so_from_mobile = + utils::MakeShared<smart_objects::SmartObject>(); + + DCHECK_OR_RETURN_VOID(so_from_mobile); + if (!so_from_mobile) { + LOG4CXX_ERROR(logger_, "Null pointer"); + return; + } + + if (!ConvertMessageToSO(*message, *so_from_mobile)) { + LOG4CXX_ERROR(logger_, "Cannot create smart object from message"); + return; + } +#ifdef TELEMETRY_MONITOR + metric->message = so_from_mobile; +#endif // TELEMETRY_MONITOR + + if (!app_manager_.GetRPCService().ManageMobileCommand( + so_from_mobile, commands::Command::ORIGIN_MOBILE)) { + LOG4CXX_ERROR(logger_, "Received command didn't run successfully"); + } +#ifdef TELEMETRY_MONITOR + metric->end = date_time::DateTime::getCurrentTime(); + if (metric_observer_) { + metric_observer_->OnMessage(metric); + } +#endif // TELEMETRY_MONITOR +} + +void RPCHandlerImpl::ProcessMessageFromHMI( + const utils::SharedPtr<Message> message) { + LOG4CXX_AUTO_TRACE(logger_); + smart_objects::SmartObjectSPtr smart_object(new smart_objects::SmartObject); + + if (!smart_object) { + LOG4CXX_ERROR(logger_, "Null pointer"); + return; + } + +#ifdef HMI_DBUS_API + *smart_object = message->smart_object(); +#else + if (!ConvertMessageToSO(*message, *smart_object)) { + if (application_manager::MessageType::kResponse == + (*smart_object)[strings::params][strings::message_type].asInt()) { + (*smart_object).erase(strings::msg_params); + (*smart_object)[strings::params][hmi_response::code] = + hmi_apis::Common_Result::INVALID_DATA; + (*smart_object)[strings::msg_params][strings::info] = + std::string("Received invalid data on HMI response"); + } else { + LOG4CXX_ERROR(logger_, "Cannot create smart object from message"); + return; + } + } +#endif // HMI_DBUS_API + + LOG4CXX_DEBUG(logger_, "Converted message, trying to create hmi command"); + if (!app_manager_.GetRPCService().ManageHMICommand(smart_object)) { + LOG4CXX_ERROR(logger_, "Received command didn't run successfully"); + } +} +void RPCHandlerImpl::Handle(const impl::MessageFromMobile message) { + LOG4CXX_AUTO_TRACE(logger_); + + if (!message) { + LOG4CXX_ERROR(logger_, "Null-pointer message received."); + return; + } + if (app_manager_.is_stopping()) { + LOG4CXX_INFO(logger_, "Application manager is stopping"); + return; + } +#ifdef SDL_REMOTE_CONTROL + if (app_manager_.GetPluginManager().IsMessageForPlugin(message)) { + if (functional_modules::ProcessResult::PROCESSED == + app_manager_.GetPluginManager().ProcessMessage(message)) { + LOG4CXX_INFO(logger_, "Message is processed by plugin."); + return; + } + } +#endif + ProcessMessageFromMobile(message); +} + +void RPCHandlerImpl::Handle(const impl::MessageFromHmi message) { + LOG4CXX_AUTO_TRACE(logger_); + + if (!message) { + LOG4CXX_ERROR(logger_, "Null-pointer message received."); + return; + } + +#ifdef SDL_REMOTE_CONTROL + if (app_manager_.GetPluginManager().IsHMIMessageForPlugin(message)) { + functional_modules::ProcessResult result = + app_manager_.GetPluginManager().ProcessHMIMessage(message); + if (functional_modules::ProcessResult::PROCESSED == result || + functional_modules::ProcessResult::FAILED == result) { + LOG4CXX_INFO(logger_, "Message is processed by plugin."); + return; + } + } +#endif + + ProcessMessageFromHMI(message); +} + +void RPCHandlerImpl::OnMessageReceived( + const protocol_handler::RawMessagePtr message) { + LOG4CXX_AUTO_TRACE(logger_); + + if (!message) { + LOG4CXX_ERROR(logger_, "Null-pointer message received."); + NOTREACHED(); + return; + } + + utils::SharedPtr<Message> outgoing_message = ConvertRawMsgToMessage(message); + + if (outgoing_message) { + LOG4CXX_DEBUG(logger_, "Posting new Message"); + messages_from_mobile_.PostMessage( + impl::MessageFromMobile(outgoing_message)); + } +} + +void RPCHandlerImpl::OnMobileMessageSent( + const protocol_handler::RawMessagePtr message) { + LOG4CXX_AUTO_TRACE(logger_); +} + +void RPCHandlerImpl::OnMessageReceived( + hmi_message_handler::MessageSharedPointer message) { + LOG4CXX_AUTO_TRACE(logger_); + + if (!message) { + LOG4CXX_ERROR(logger_, "Null-pointer message received."); + NOTREACHED(); + return; + } + + messages_from_hmi_.PostMessage(impl::MessageFromHmi(message)); +} + +void RPCHandlerImpl::OnErrorSending( + hmi_message_handler::MessageSharedPointer message) { + return; +} + +#ifdef TELEMETRY_MONITOR +void RPCHandlerImpl::SetTelemetryObserver(AMTelemetryObserver* observer) { + metric_observer_ = observer; +} +#endif // TELEMETRY_MONITOR + +bool RPCHandlerImpl::ConvertMessageToSO( + const Message& message, + NsSmartDeviceLink::NsSmartObjects::SmartObject& output) { + LOG4CXX_AUTO_TRACE(logger_); + LOG4CXX_DEBUG(logger_, + "\t\t\tMessage to convert: protocol " + << message.protocol_version() << "; json " + << message.json_message()); + + switch (message.protocol_version()) { + case protocol_handler::MajorProtocolVersion::PROTOCOL_VERSION_5: + case protocol_handler::MajorProtocolVersion::PROTOCOL_VERSION_4: + case protocol_handler::MajorProtocolVersion::PROTOCOL_VERSION_3: + case protocol_handler::MajorProtocolVersion::PROTOCOL_VERSION_2: { + const bool conversion_result = + formatters::CFormatterJsonSDLRPCv2::fromString( + message.json_message(), + output, + message.function_id(), + message.type(), + message.correlation_id()); + if (!conversion_result || + !mobile_so_factory().attachSchema(output, true) || + ((output.validate() != smart_objects::Errors::OK))) { + LOG4CXX_WARN(logger_, + "Failed to parse string to smart object :" + << message.json_message()); + utils::SharedPtr<smart_objects::SmartObject> response( + MessageHelper::CreateNegativeResponse( + message.connection_key(), + message.function_id(), + message.correlation_id(), + mobile_apis::Result::INVALID_DATA)); + app_manager_.GetRPCService().ManageMobileCommand( + response, commands::Command::ORIGIN_SDL); + return false; + } + LOG4CXX_DEBUG(logger_, + "Convertion result for sdl object is true function_id " + << output[jhs::S_PARAMS][jhs::S_FUNCTION_ID].asInt()); + + output[strings::params][strings::connection_key] = + message.connection_key(); + output[strings::params][strings::protocol_version] = + message.protocol_version(); + if (message.binary_data()) { + if (message.payload_size() < message.data_size()) { + LOG4CXX_ERROR(logger_, + "Incomplete binary" + << " binary size should be " << message.data_size() + << " payload data size is " + << message.payload_size()); + utils::SharedPtr<smart_objects::SmartObject> response( + MessageHelper::CreateNegativeResponse( + message.connection_key(), + message.function_id(), + message.correlation_id(), + mobile_apis::Result::INVALID_DATA)); + app_manager_.GetRPCService().ManageMobileCommand( + response, commands::Command::ORIGIN_SDL); + return false; + } + output[strings::params][strings::binary_data] = + *(message.binary_data()); + } + break; + } + case protocol_handler::MajorProtocolVersion::PROTOCOL_VERSION_HMI: { +#ifdef ENABLE_LOG + int32_t result = +#endif + formatters::FormatterJsonRpc::FromString< + hmi_apis::FunctionID::eType, + hmi_apis::messageType::eType>(message.json_message(), output); + LOG4CXX_DEBUG(logger_, + "Convertion result: " + << result << " function id " + << output[jhs::S_PARAMS][jhs::S_FUNCTION_ID].asInt()); + if (!hmi_so_factory().attachSchema(output, false)) { + LOG4CXX_WARN(logger_, "Failed to attach schema to object."); + return false; + } + if (output.validate() != smart_objects::Errors::OK) { + LOG4CXX_ERROR(logger_, "Incorrect parameter from HMI"); + return false; + } + break; + } + case protocol_handler::MajorProtocolVersion::PROTOCOL_VERSION_1: { + static NsSmartDeviceLinkRPC::V1::v4_protocol_v1_2_no_extra v1_shema; + + if (message.function_id() == 0 || message.type() == kUnknownType) { + LOG4CXX_ERROR(logger_, "Message received: UNSUPPORTED_VERSION"); + + int32_t conversation_result = + formatters::CFormatterJsonSDLRPCv1::fromString< + NsSmartDeviceLinkRPC::V1::FunctionID::eType, + NsSmartDeviceLinkRPC::V1::messageType::eType>( + message.json_message(), output); + + if (formatters::CFormatterJsonSDLRPCv1::kSuccess == + conversation_result) { + smart_objects::SmartObject params = smart_objects::SmartObject( + smart_objects::SmartType::SmartType_Map); + + output[strings::params][strings::message_type] = + NsSmartDeviceLinkRPC::V1::messageType::response; + output[strings::params][strings::connection_key] = + message.connection_key(); + + output[strings::msg_params] = smart_objects::SmartObject( + smart_objects::SmartType::SmartType_Map); + output[strings::msg_params][strings::success] = false; + output[strings::msg_params][strings::result_code] = + NsSmartDeviceLinkRPC::V1::Result::UNSUPPORTED_VERSION; + + smart_objects::SmartObjectSPtr msg_to_send = + new smart_objects::SmartObject(output); + v1_shema.attachSchema(*msg_to_send, false); + app_manager_.GetRPCService().SendMessageToMobile(msg_to_send); + return false; + } + } + break; + } + default: + LOG4CXX_WARN(logger_, + "Application used unsupported protocol :" + << message.protocol_version() << "."); + return false; + } + + LOG4CXX_DEBUG(logger_, "Successfully parsed message into smart object"); + return true; +} + +utils::SharedPtr<Message> RPCHandlerImpl::ConvertRawMsgToMessage( + const protocol_handler::RawMessagePtr message) { + LOG4CXX_AUTO_TRACE(logger_); + DCHECK(message); + utils::SharedPtr<Message> outgoing_message; + + LOG4CXX_DEBUG(logger_, "Service type." << message->service_type()); + if (message->service_type() != protocol_handler::kRpc && + message->service_type() != protocol_handler::kBulk) { + // skip this message, not under handling of ApplicationManager + LOG4CXX_TRACE(logger_, "Skipping message; not the under AM handling."); + return outgoing_message; + } + + Message* convertion_result = + MobileMessageHandler::HandleIncomingMessageProtocol(message); + + if (convertion_result) { + outgoing_message = convertion_result; + } else { + LOG4CXX_ERROR(logger_, "Received invalid message"); + } + return outgoing_message; +} + +hmi_apis::HMI_API& RPCHandlerImpl::hmi_so_factory() { + return hmi_so_factory_; +} + +mobile_apis::MOBILE_API& RPCHandlerImpl::mobile_so_factory() { + return mobile_so_factory_; +} +} +} diff --git a/src/components/application_manager/src/rpc_service_impl.cc b/src/components/application_manager/src/rpc_service_impl.cc index a6c99c08ba..3be10a75f8 100644 --- a/src/components/application_manager/src/rpc_service_impl.cc +++ b/src/components/application_manager/src/rpc_service_impl.cc @@ -43,11 +43,13 @@ RPCServiceImpl::RPCServiceImpl( ApplicationManager& app_manager, request_controller::RequestController& request_ctrl, protocol_handler::ProtocolHandler* protocol_handler, - hmi_message_handler::HMIMessageHandler* hmi_handler) + hmi_message_handler::HMIMessageHandler* hmi_handler, + CommandHolder& commands_holder) : app_manager_(app_manager) , request_ctrl_(request_ctrl) , protocol_handler_(protocol_handler) , hmi_handler_(hmi_handler) + , commands_holder_(commands_holder) , messages_to_mobile_("AM ToMobile", this) , messages_to_hmi_("AM ToHMI", this) , hmi_so_factory_(hmi_apis::HMI_API()) @@ -83,6 +85,15 @@ bool RPCServiceImpl::ManageMobileCommand( return false; } + const uint32_t connection_key = static_cast<uint32_t>( + (*message)[strings::params][strings::connection_key].asUInt()); + + auto app_ptr = app_manager_.application(connection_key); + if (app_ptr && app_manager_.IsAppInReconnectMode(app_ptr->policy_app_id())) { + commands_holder_.Suspend( + app_ptr, CommandHolder::CommandType::kMobileCommand, message); + return true; + } mobile_apis::FunctionID::eType function_id = static_cast<mobile_apis::FunctionID::eType>( (*message)[strings::params][strings::function_id].asInt()); @@ -93,9 +104,6 @@ bool RPCServiceImpl::ManageMobileCommand( ? (*message)[strings::params][strings::correlation_id].asUInt() : 0; - uint32_t connection_key = - (*message)[strings::params][strings::connection_key].asUInt(); - int32_t protocol_type = (*message)[strings::params][strings::protocol_type].asInt(); @@ -253,6 +261,19 @@ bool RPCServiceImpl::ManageHMICommand( return false; } + if ((*message).keyExists(strings::msg_params) && + (*message)[strings::msg_params].keyExists(strings::app_id)) { + const auto connection_key = + (*message)[strings::msg_params][strings::app_id].asUInt(); + + auto app = app_manager_.application(static_cast<uint32_t>(connection_key)); + if (app && app_manager_.IsAppInReconnectMode(app->policy_app_id())) { + commands_holder_.Suspend( + app, CommandHolder::CommandType::kHmiCommand, message); + return true; + } + } + int32_t message_type = (*(message.get()))[strings::params][strings::message_type].asInt(); |