summaryrefslogtreecommitdiff
path: root/src/components/application_manager/src/rpc_service_impl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/application_manager/src/rpc_service_impl.cc')
-rw-r--r--src/components/application_manager/src/rpc_service_impl.cc160
1 files changed, 144 insertions, 16 deletions
diff --git a/src/components/application_manager/src/rpc_service_impl.cc b/src/components/application_manager/src/rpc_service_impl.cc
index 7a68ae5779..b5cae1c126 100644
--- a/src/components/application_manager/src/rpc_service_impl.cc
+++ b/src/components/application_manager/src/rpc_service_impl.cc
@@ -32,12 +32,16 @@
#include "application_manager/rpc_service_impl.h"
+#include "application_manager/app_service_manager.h"
+#include "application_manager/plugin_manager/plugin_keys.h"
+
namespace application_manager {
namespace rpc_service {
CREATE_LOGGERPTR_LOCAL(logger_, "RPCServiceImpl")
namespace formatters = ns_smart_device_link::ns_json_handler::formatters;
namespace jhs = ns_smart_device_link::ns_json_handler::strings;
+namespace plugin_names = application_manager::plugin_manager::plugin_names;
RPCServiceImpl::RPCServiceImpl(
ApplicationManager& app_manager,
@@ -122,7 +126,8 @@ bool RPCServiceImpl::ManageMobileCommand(
auto plugin =
app_manager_.GetPluginManager().FindPluginToProcess(function_id, source);
if (!plugin) {
- LOG4CXX_WARN(logger_, "Filed to find plugin : " << plugin.error());
+ LOG4CXX_WARN(logger_, "Failed to find plugin : " << plugin.error());
+ CheckSourceForUnsupportedRequest(message, source);
return false;
}
application_manager::CommandFactory& factory = (*plugin).GetCommandFactory();
@@ -154,7 +159,19 @@ bool RPCServiceImpl::ManageMobileCommand(
return true;
}
- if (message_type == mobile_apis::messageType::request) {
+ if (message_type == mobile_apis::messageType::request &&
+ source == commands::Command::CommandSource::SOURCE_SDL) {
+ if (command->Init()) {
+ command->Run();
+ command->CleanUp();
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ if (message_type == mobile_apis::messageType::request &&
+ source == commands::Command::CommandSource::SOURCE_MOBILE) {
// commands will be launched from requesr_ctrl
mobile_apis::HMILevel::eType app_hmi_level =
mobile_apis::HMILevel::INVALID_ENUM;
@@ -241,8 +258,8 @@ bool RPCServiceImpl::ManageMobileCommand(
return false;
}
-bool RPCServiceImpl::ManageHMICommand(
- const commands::MessageSharedPtr message) {
+bool RPCServiceImpl::ManageHMICommand(const commands::MessageSharedPtr message,
+ commands::Command::CommandSource source) {
LOG4CXX_AUTO_TRACE(logger_);
if (!message) {
@@ -258,15 +275,15 @@ bool RPCServiceImpl::ManageHMICommand(
MessageHelper::PrintSmartObject(*message);
const int32_t function_id =
(*(message.get()))[strings::params][strings::function_id].asInt();
- auto plugin = app_manager_.GetPluginManager().FindPluginToProcess(
- function_id, commands::Command::SOURCE_HMI);
+ auto plugin =
+ app_manager_.GetPluginManager().FindPluginToProcess(function_id, source);
if (!plugin) {
LOG4CXX_WARN(logger_, "Filed to find plugin : " << plugin.error());
return false;
}
application_manager::CommandFactory& factory = (*plugin).GetCommandFactory();
- auto command = factory.CreateCommand(message, commands::Command::SOURCE_HMI);
+ auto command = factory.CreateCommand(message, source);
if (!command) {
LOG4CXX_WARN(logger_, "Failed to create command from smart object");
@@ -374,6 +391,7 @@ void RPCServiceImpl::SendMessageToMobile(
const bool is_result_code_exists =
(*message)[strings::msg_params].keyExists(strings::result_code);
+ bool allow_unknown_parameters = false;
if (!app) {
LOG4CXX_ERROR(logger_, "No application associated with connection key");
@@ -405,7 +423,31 @@ void RPCServiceImpl::SendMessageToMobile(
// Messages to mobile are not yet prioritized so use default priority value
std::shared_ptr<Message> message_to_send(
new Message(protocol_handler::MessagePriority::kDefault));
- if (!ConvertSOtoMessage((*message), (*message_to_send))) {
+
+ int32_t function_id = (*message)[jhs::S_PARAMS][jhs::S_FUNCTION_ID].asInt();
+ bool rpc_passing = app_manager_.GetAppServiceManager()
+ .GetRPCPassingHandler()
+ .CanHandleFunctionID(function_id);
+ if (IsAppServiceRPC(function_id,
+ commands::Command::CommandSource::SOURCE_SDL) ||
+ rpc_passing) {
+ LOG4CXX_DEBUG(
+ logger_,
+ "Allowing unknown parameters for response function " << function_id);
+ allow_unknown_parameters = true;
+ }
+
+ if (rpc_passing &&
+ !app_manager_.GetAppServiceManager()
+ .GetRPCPassingHandler()
+ .IsPassThroughMessage(
+ (*message)[jhs::S_PARAMS][jhs::S_CORRELATION_ID].asUInt(),
+ commands::Command::CommandSource::SOURCE_SDL,
+ (*message)[jhs::S_PARAMS][jhs::S_MESSAGE_TYPE].asInt())) {
+ allow_unknown_parameters = false;
+ }
+ if (!ConvertSOtoMessage(
+ (*message), (*message_to_send), allow_unknown_parameters)) {
LOG4CXX_WARN(logger_, "Can't send msg to Mobile: failed to create string");
return;
}
@@ -484,6 +526,7 @@ void RPCServiceImpl::SendMessageToHMI(
return;
}
+ bool allow_unknown_parameters = false;
// SmartObject |message| has no way to declare priority for now
std::shared_ptr<Message> message_to_send(
new Message(protocol_handler::MessagePriority::kDefault));
@@ -497,7 +540,17 @@ void RPCServiceImpl::SendMessageToHMI(
logger_,
"Attached schema to message, result if valid: " << message->isValid());
- if (!ConvertSOtoMessage(*message, *message_to_send)) {
+ if (IsAppServiceRPC((*message)[jhs::S_PARAMS][jhs::S_FUNCTION_ID].asInt(),
+ commands::Command::CommandSource::SOURCE_SDL_TO_HMI)) {
+ LOG4CXX_DEBUG(logger_,
+ "Allowing unknown parameters for response function "
+ << (*message)[jhs::S_PARAMS][jhs::S_FUNCTION_ID].asInt());
+
+ allow_unknown_parameters = true;
+ }
+
+ if (!ConvertSOtoMessage(
+ *message, *message_to_send, allow_unknown_parameters)) {
LOG4CXX_WARN(logger_,
"Cannot send message to HMI: failed to create string");
return;
@@ -506,6 +559,42 @@ void RPCServiceImpl::SendMessageToHMI(
messages_to_hmi_.PostMessage(impl::MessageToHmi(message_to_send));
}
+bool RPCServiceImpl::IsAppServiceRPC(int32_t function_id,
+ commands::Command::CommandSource source) {
+ // General RPCs related to App Services
+ if ((source == commands::Command::CommandSource::SOURCE_MOBILE) ||
+ (source ==
+ commands::Command::CommandSource::SOURCE_SDL)) { // MOBILE COMMANDS
+ switch (function_id) {
+ case mobile_apis::FunctionID::GetSystemCapabilityID:
+ case mobile_apis::FunctionID::OnSystemCapabilityUpdatedID:
+ return true;
+ break;
+ }
+ } else if ((source == commands::Command::CommandSource::SOURCE_HMI) ||
+ (source == commands::Command::CommandSource::
+ SOURCE_SDL_TO_HMI)) { // HMI COMMANDS
+ switch (function_id) {
+ case hmi_apis::FunctionID::BasicCommunication_OnSystemCapabilityUpdated:
+ return true;
+ break;
+ }
+ }
+
+ // RPCs handled by app services plugin
+ auto plugin =
+ app_manager_.GetPluginManager().FindPluginToProcess(function_id, source);
+ if (!plugin) {
+ return false;
+ }
+ if ((*plugin).PluginName() != plugin_names::app_service_rpc_plugin) {
+ return false;
+ }
+ application_manager::CommandFactory& factory = (*plugin).GetCommandFactory();
+
+ return factory.IsAbleToProcess(function_id, source);
+}
+
void RPCServiceImpl::set_protocol_handler(
protocol_handler::ProtocolHandler* handler) {
protocol_handler_ = handler;
@@ -518,7 +607,8 @@ void RPCServiceImpl::set_hmi_message_handler(
bool RPCServiceImpl::ConvertSOtoMessage(
const ns_smart_device_link::ns_smart_objects::SmartObject& message,
- Message& output) {
+ Message& output,
+ const bool allow_unknown_parameters) {
LOG4CXX_AUTO_TRACE(logger_);
if (smart_objects::SmartType_Null == message.getType() ||
@@ -543,16 +633,16 @@ bool RPCServiceImpl::ConvertSOtoMessage(
switch (protocol_type) {
case 0: {
if (protocol_version == 1) {
- if (!formatters::CFormatterJsonSDLRPCv1::toString(message,
- output_string)) {
+ if (!formatters::CFormatterJsonSDLRPCv1::toString(
+ message, output_string, !allow_unknown_parameters)) {
LOG4CXX_WARN(logger_, "Failed to serialize smart object");
return false;
}
output.set_protocol_version(
protocol_handler::MajorProtocolVersion::PROTOCOL_VERSION_1);
} else {
- if (!formatters::CFormatterJsonSDLRPCv2::toString(message,
- output_string)) {
+ if (!formatters::CFormatterJsonSDLRPCv2::toString(
+ message, output_string, !allow_unknown_parameters)) {
LOG4CXX_WARN(logger_, "Failed to serialize smart object");
return false;
}
@@ -564,7 +654,8 @@ bool RPCServiceImpl::ConvertSOtoMessage(
break;
}
case 1: {
- if (!formatters::FormatterJsonRpc::ToString(message, output_string)) {
+ if (!formatters::FormatterJsonRpc::ToString(
+ message, output_string, !allow_unknown_parameters)) {
LOG4CXX_WARN(logger_, "Failed to serialize smart object");
return false;
}
@@ -577,7 +668,7 @@ bool RPCServiceImpl::ConvertSOtoMessage(
return false;
}
- LOG4CXX_DEBUG(logger_, "Convertion result: " << output_string);
+ LOG4CXX_DEBUG(logger_, "Conversion result: " << output_string);
output.set_connection_key(message.getElement(jhs::S_PARAMS)
.getElement(strings::connection_key)
@@ -624,6 +715,43 @@ mobile_apis::MOBILE_API& RPCServiceImpl::mobile_so_factory() {
return mobile_so_factory_;
}
+void RPCServiceImpl::CheckSourceForUnsupportedRequest(
+ const commands::MessageSharedPtr message,
+ commands::Command::CommandSource source) {
+ int32_t message_type =
+ (*(message.get()))[strings::params][strings::message_type].asInt();
+ uint32_t correlation_id =
+ (*message)[strings::params].keyExists(strings::correlation_id)
+ ? (*message)[strings::params][strings::correlation_id].asUInt()
+ : 0;
+ const uint32_t connection_key = static_cast<uint32_t>(
+ (*message)[strings::params][strings::connection_key].asUInt());
+ mobile_apis::FunctionID::eType function_id =
+ static_cast<mobile_apis::FunctionID::eType>(
+ (*message)[strings::params][strings::function_id].asInt());
+ if ((source == commands::Command::CommandSource::SOURCE_MOBILE &&
+ kRequest == message_type) ||
+ (source == commands::Command::CommandSource::SOURCE_SDL &&
+ kResponse == message_type)) {
+ smart_objects::SmartObjectSPtr response =
+ MessageHelper::CreateNegativeResponse(connection_key,
+ static_cast<int32_t>(function_id),
+ correlation_id,
+ 0);
+
+ // Since we are dealing with an unknown RPC, there is no schema attached
+ // to the message, so we have to convert the result to string directly
+ std::string result_code;
+ smart_objects::EnumConversionHelper<mobile_apis::Result::eType>::
+ EnumToString(mobile_apis::Result::UNSUPPORTED_REQUEST, &result_code);
+ (*response)[strings::msg_params][strings::result_code] = result_code;
+ (*response)[strings::msg_params][strings::info] =
+ "Module does not recognize this function id";
+
+ SendMessageToMobile(response);
+ }
+}
+
} // namespace rpc_service
} // namespace application_manager