summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShobhit Adlakha <ShobhitAd@users.noreply.github.com>2019-03-07 21:43:31 -0500
committerGitHub <noreply@github.com>2019-03-07 21:43:31 -0500
commit3be4d6a8384f5422a040121c11b448a7dd6901fc (patch)
treeeef53c493b759056158ac39b261fcd4e0519b7b3
parent5cc1ad073dd9a05a3bd65499acf0c6b079287a29 (diff)
downloadsdl_core-3be4d6a8384f5422a040121c11b448a7dd6901fc.tar.gz
RPC Passing and Handling unknown RPC parameters (#2821)
* Initial app service app extension * Add GetAppServiceData rpc templates. * Add request to mobile, and fix HMI GASD naming * Add Core->Mobile Requests and Responses * HMI GetAppService Request/Response to hmi and from hmi. * Add mobile on event handling * Fix GASD Response From Mobile * Add PerformAppServiceInteraction RPC * Fixes for GetAppServiceData subscribe, and OnAppServiceData Fixes allow for multiple consumers on a single app service type. Consumer/provider can be any combination of an ios app(s), android app(s), or an ivi HMI app(s). * Update AppServicetype to string and fix unit tests * Implemented RpcPassThroughTimeout param and IncreaseForwardedRequestTimeout function * Address review comments * Fixed build tests * Fix style * Address comments * Address comments * Pass info from provider in GASD response * Implemented boolean paramter to keep/remove unknown RPC paramaters * Added plugin keys * Implemented allowing unknown rpc params if function is handled by AS plugin or is related to SystemCapability * Implemented handling unknown params for OSCU notifications * Fixed build tests * Implemented handling unknown params for RPC Passing * Initial implementation of RPC Passing * fixed UNSUPPORTED_REQUEST case * Moved RPCPassing implementation into seperate class * Implemented passthrough request timeout * Addressed style and formatting comments * Put RPCPassingHandler in seperate file * Removed unused request/response file (based on review comment r263121367) * Fixed timeout implementation * Created functions for handling forwarding requests/responses to core and mobile * Moved Populating request queue functionality to seperate function * Changed implementation to use one map with the original request and a queue of app service information * Fixed timeout implementation * Seperated RPCPassing checks from IsAppServiceRPC checks * Added locks for request and timeout queues * Addressed review comments * Fixed rpc_passing_handler_ initializer and added comments * Reduced scope of locks for rpc_passing_queue
-rw-r--r--src/appMain/smartDeviceLink.ini10
-rw-r--r--src/components/application_manager/include/application_manager/app_service_manager.h6
-rw-r--r--src/components/application_manager/include/application_manager/application_manager_impl.h3
-rw-r--r--src/components/application_manager/include/application_manager/plugin_manager/plugin_keys.h48
-rw-r--r--src/components/application_manager/include/application_manager/rpc_handler_impl.h3
-rw-r--r--src/components/application_manager/include/application_manager/rpc_passing_handler.h113
-rw-r--r--src/components/application_manager/include/application_manager/rpc_service_impl.h6
-rw-r--r--src/components/application_manager/rpc_plugins/app_service_rpc_plugin/src/app_service_rpc_plugin.cc4
-rw-r--r--src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/rc_rpc_plugin.cc4
-rw-r--r--src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/sdl_rpc_plugin.cc3
-rw-r--r--src/components/application_manager/rpc_plugins/vehicle_info_plugin/src/vehicle_info_plugin.cc4
-rw-r--r--src/components/application_manager/src/app_service_manager.cc22
-rw-r--r--src/components/application_manager/src/application_manager_impl.cc15
-rw-r--r--src/components/application_manager/src/plugin_manager/plugin_keys.cc14
-rw-r--r--src/components/application_manager/src/rpc_handler_impl.cc71
-rw-r--r--src/components/application_manager/src/rpc_passing_handler.cc331
-rw-r--r--src/components/application_manager/src/rpc_service_impl.cc94
-rw-r--r--src/components/formatters/include/formatters/CFormatterJsonSDLRPCv1.h10
-rw-r--r--src/components/formatters/include/formatters/CFormatterJsonSDLRPCv2.h10
-rw-r--r--src/components/formatters/include/formatters/CSmartFactory.h8
-rw-r--r--src/components/formatters/include/formatters/formatter_json_rpc.h6
-rw-r--r--src/components/formatters/src/CFormatterJsonSDLRPCv1.cc12
-rw-r--r--src/components/formatters/src/CFormatterJsonSDLRPCv2.cc12
-rw-r--r--src/components/formatters/src/formatter_json_rpc.cc6
-rw-r--r--src/components/include/application_manager/rpc_service.h11
-rw-r--r--src/components/include/test/application_manager/mock_rpc_service.h4
-rw-r--r--src/components/smart_objects/include/smart_objects/array_schema_item.h11
-rw-r--r--src/components/smart_objects/include/smart_objects/enum_schema_item.h15
-rw-r--r--src/components/smart_objects/include/smart_objects/object_schema_item.h10
-rw-r--r--src/components/smart_objects/include/smart_objects/schema_item.h10
-rw-r--r--src/components/smart_objects/include/smart_objects/smart_schema.h10
-rw-r--r--src/components/smart_objects/src/array_schema_item.cc9
-rw-r--r--src/components/smart_objects/src/object_schema_item.cc15
-rw-r--r--src/components/smart_objects/src/schema_item.cc5
-rw-r--r--src/components/smart_objects/src/smart_schema.cc9
35 files changed, 835 insertions, 89 deletions
diff --git a/src/appMain/smartDeviceLink.ini b/src/appMain/smartDeviceLink.ini
index 54c2395c47..2b2c784746 100644
--- a/src/appMain/smartDeviceLink.ini
+++ b/src/appMain/smartDeviceLink.ini
@@ -359,6 +359,16 @@ EnableAppLaunchIOS = true
;SecondaryTransportForUSB =
;SecondaryTransportForWiFi =
+[AppServices]
+; The ID to pass to app service publishers when sending a PerformAppServiceInteraction request
+;CoresOriginId = "sdl_core"
+
+; Services that exist on the module. Values are of AppServiceType in RPC Spec. These services will be used as default and app services will only become primary service publisher with direct user interaction. These services will also be a fallback if no app service publisher is registered with the system of that type.
+;EmbeddedServices = MEDIA, WEATHER, NAVIGATION, VOICE_ASSISTANT, COMMUNICATION_VOIP, MESSAGING, TTS
+
+; Additional time added to RPC timeout when passing through to App service
+RpcPassThroughTimeout = 10000
+
[ServicesMap]
; A matrix to specify which service is allowed on which transports. The transports are listed
; in preferred order. If a transport is not listed, then the service is not allowed
diff --git a/src/components/application_manager/include/application_manager/app_service_manager.h b/src/components/application_manager/include/application_manager/app_service_manager.h
index d6d13a209a..f7c46178c5 100644
--- a/src/components/application_manager/include/application_manager/app_service_manager.h
+++ b/src/components/application_manager/include/application_manager/app_service_manager.h
@@ -37,6 +37,7 @@
#include "interfaces/MOBILE_API.h"
#include "smart_objects/smart_object.h"
#include "application_manager/application.h"
+#include "application_manager/rpc_passing_handler.h"
namespace resumption {
class LastState;
@@ -52,7 +53,6 @@ struct AppService {
};
class ApplicationManager;
-
/**
* @brief The AppServiceManager is TODO.
*/
@@ -124,6 +124,7 @@ class AppServiceManager {
* @param manifest
*/
std::vector<smart_objects::SmartObject> GetAllServices();
+ std::vector<std::pair<std::string, AppService> > GetActiveServices();
void GetProviderByType(const std::string& service_type,
bool mobile_consumer,
@@ -159,12 +160,15 @@ class AppServiceManager {
*/
bool UpdateNavigationCapabilities(smart_objects::SmartObject& out_params);
+ RPCPassingHandler& GetRPCPassingHandler();
+
private:
ApplicationManager& app_manager_;
resumption::LastState& last_state_;
sync_primitives::RecursiveLock published_services_lock_;
std::map<std::string, AppService> published_services_;
+ RPCPassingHandler rpc_passing_handler_;
void AppServiceUpdated(
const smart_objects::SmartObject& service_record,
diff --git a/src/components/application_manager/include/application_manager/application_manager_impl.h b/src/components/application_manager/include/application_manager/application_manager_impl.h
index 6161d6bbbf..12f2310d36 100644
--- a/src/components/application_manager/include/application_manager/application_manager_impl.h
+++ b/src/components/application_manager/include/application_manager/application_manager_impl.h
@@ -1118,7 +1118,8 @@ class ApplicationManagerImpl
mobile_apis::MOBILE_API& mobile_so_factory();
bool ConvertSOtoMessage(const smart_objects::SmartObject& message,
- Message& output);
+ Message& output,
+ const bool remove_unknown_parameters = true);
template <typename ApplicationList>
void PrepareApplicationListSO(ApplicationList app_list,
diff --git a/src/components/application_manager/include/application_manager/plugin_manager/plugin_keys.h b/src/components/application_manager/include/application_manager/plugin_manager/plugin_keys.h
new file mode 100644
index 0000000000..11a7d353f6
--- /dev/null
+++ b/src/components/application_manager/include/application_manager/plugin_manager/plugin_keys.h
@@ -0,0 +1,48 @@
+/*
+ Copyright (c) 2019, Ford Motor Company, Livio
+ 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 the copyright holders nor the names of their
+ 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.
+ */
+
+#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_PLUGIN_MANAGER_PLUGIN_KEYS_H
+#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_PLUGIN_MANAGER_PLUGIN_KEYS_H
+
+namespace application_manager {
+namespace plugin_manager {
+
+namespace plugin_names {
+extern const char* vehicle_info_rpc_plugin;
+extern const char* app_service_rpc_plugin;
+extern const char* rc_rpc_plugin;
+extern const char* sdl_rpc_plugin;
+}
+
+} // namespace plugin_manager
+} // namespace application_manager
+#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_PLUGIN_MANAGER_PLUGIN_KEYS_H
diff --git a/src/components/application_manager/include/application_manager/rpc_handler_impl.h b/src/components/application_manager/include/application_manager/rpc_handler_impl.h
index cc93e4213c..b7e74c5ab3 100644
--- a/src/components/application_manager/include/application_manager/rpc_handler_impl.h
+++ b/src/components/application_manager/include/application_manager/rpc_handler_impl.h
@@ -158,7 +158,8 @@ class RPCHandlerImpl : public RPCHandler,
void ProcessMessageFromMobile(const std::shared_ptr<Message> message);
void ProcessMessageFromHMI(const std::shared_ptr<Message> message);
bool ConvertMessageToSO(const Message& message,
- smart_objects::SmartObject& output);
+ smart_objects::SmartObject& output,
+ const bool remove_unknown_parameters = true);
std::shared_ptr<Message> ConvertRawMsgToMessage(
const ::protocol_handler::RawMessagePtr message);
hmi_apis::HMI_API& hmi_so_factory();
diff --git a/src/components/application_manager/include/application_manager/rpc_passing_handler.h b/src/components/application_manager/include/application_manager/rpc_passing_handler.h
new file mode 100644
index 0000000000..3ed10ff1e6
--- /dev/null
+++ b/src/components/application_manager/include/application_manager/rpc_passing_handler.h
@@ -0,0 +1,113 @@
+/*
+ * 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.
+ */
+
+#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_RPC_PASSING_HANDLER_H_
+#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_RPC_PASSING_HANDLER_H_
+
+#include "application_manager/application.h"
+#include "interfaces/MOBILE_API.h"
+#include "smart_objects/smart_object.h"
+#include "application_manager/app_service_manager.h"
+#include <deque>
+#include "utils/timer.h"
+
+namespace application_manager {
+
+struct ServiceInfo {
+ std::string service_id;
+ uint32_t connection_key;
+};
+
+typedef std::shared_ptr<timer::Timer> TimerSPtr;
+
+class AppServiceManager;
+
+class RPCPassingHandler {
+ public:
+ RPCPassingHandler(AppServiceManager& asm_ref, ApplicationManager& am_ref);
+
+ /**
+ * @brief Class destructor
+ */
+ ~RPCPassingHandler();
+
+ /**
+ * @brief Check if function id is in the handled_rpcs list of an active app
+ * service
+ * @param function_id RPC function id
+ * @return true if function id exists in handled_rpcs list of an active app
+ * service
+ */
+ bool CanHandleFunctionID(int32_t function_id);
+
+ /**
+ * @brief Check if app services or core is being used to handle the RPC
+ * @param correlation_id correlation id of RPC response
+ * @return true if an app service was used to handle the RPC
+ */
+ bool IsPassThroughMessage(uint32_t correlation_id,
+ commands::Command::CommandSource source,
+ int32_t message_type);
+
+ /**
+ * @brief Function to handle sending and receiving RPC Passing
+ * requests/responses
+ * @param rpc_message RPC message SmartObject
+ * @return true if the request was forwarded, false otherwise
+ */
+ bool RPCPassThrough(smart_objects::SmartObject rpc_message);
+
+ private:
+ bool PerformNextRequest(uint32_t correlation_id);
+ void OnPassThroughRequestTimeout();
+ void AddRequestTimer(uint32_t correlation_id);
+ void RemoveRequestTimer(uint32_t correlation_id);
+ void ClearCompletedTimers();
+ void ForwardRequestToMobile(uint32_t correlation_id);
+ void ForwardRequestToCore(uint32_t correlation_id);
+ void ForwardResponseToMobile(uint32_t correlation_id,
+ smart_objects::SmartObject response_message);
+ void PopulateRPCRequestQueue(smart_objects::SmartObject request_message);
+
+ AppServiceManager& app_service_manager_;
+ ApplicationManager& app_manager_;
+ sync_primitives::RecursiveLock rpc_request_queue_lock_;
+ std::map<uint32_t,
+ std::pair<smart_objects::SmartObject, std::deque<ServiceInfo> > >
+ rpc_request_queue;
+ sync_primitives::RecursiveLock timeout_queue_lock_;
+ std::vector<std::pair<TimerSPtr, uint32_t> > timeout_queue_;
+};
+
+} // namespace application_manager
+
+#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_RPC_PASSING_HANDLER_H_
diff --git a/src/components/application_manager/include/application_manager/rpc_service_impl.h b/src/components/application_manager/include/application_manager/rpc_service_impl.h
index 98767672ca..848e9645e7 100644
--- a/src/components/application_manager/include/application_manager/rpc_service_impl.h
+++ b/src/components/application_manager/include/application_manager/rpc_service_impl.h
@@ -121,6 +121,9 @@ class RPCServiceImpl : public RPCService,
bool final_message = false) OVERRIDE;
void SendMessageToHMI(const commands::MessageSharedPtr message) OVERRIDE;
+ bool IsAppServiceRPC(int32_t function_id,
+ commands::Command::CommandSource source);
+
void set_protocol_handler(
protocol_handler::ProtocolHandler* handler) OVERRIDE;
void set_hmi_message_handler(
@@ -128,7 +131,8 @@ class RPCServiceImpl : public RPCService,
private:
bool ConvertSOtoMessage(const smart_objects::SmartObject& message,
- Message& output);
+ Message& output,
+ const bool remove_unknown_parameters = true);
hmi_apis::HMI_API& hmi_so_factory();
mobile_apis::MOBILE_API& mobile_so_factory();
diff --git a/src/components/application_manager/rpc_plugins/app_service_rpc_plugin/src/app_service_rpc_plugin.cc b/src/components/application_manager/rpc_plugins/app_service_rpc_plugin/src/app_service_rpc_plugin.cc
index 971e3cc5e0..b96e5c199d 100644
--- a/src/components/application_manager/rpc_plugins/app_service_rpc_plugin/src/app_service_rpc_plugin.cc
+++ b/src/components/application_manager/rpc_plugins/app_service_rpc_plugin/src/app_service_rpc_plugin.cc
@@ -35,11 +35,13 @@
#include "app_service_rpc_plugin/app_service_app_extension.h"
#include "app_service_rpc_plugin/app_service_command_factory.h"
#include "app_service_rpc_plugin/app_service_rpc_plugin.h"
+#include "application_manager/plugin_manager/plugin_keys.h"
namespace app_service_rpc_plugin {
CREATE_LOGGERPTR_GLOBAL(logger_, "AppServiceRpcPlugin")
namespace strings = application_manager::strings;
+namespace plugins = application_manager::plugin_manager;
AppServiceRpcPlugin::AppServiceRpcPlugin() : application_manager_(nullptr) {}
@@ -60,7 +62,7 @@ bool AppServiceRpcPlugin::IsAbleToProcess(
}
std::string AppServiceRpcPlugin::PluginName() {
- return "App Service RPC Plugin";
+ return plugins::plugin_names::app_service_rpc_plugin;
}
app_mngr::CommandFactory& AppServiceRpcPlugin::GetCommandFactory() {
diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/rc_rpc_plugin.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/rc_rpc_plugin.cc
index fd6b4e86ac..3bc1106573 100644
--- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/rc_rpc_plugin.cc
+++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/rc_rpc_plugin.cc
@@ -29,7 +29,7 @@
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
-
+#include "application_manager/plugin_manager/plugin_keys.h"
#include "rc_rpc_plugin/rc_rpc_plugin.h"
#include "rc_rpc_plugin/rc_command_factory.h"
#include "rc_rpc_plugin/rc_app_extension.h"
@@ -77,7 +77,7 @@ bool RCRPCPlugin::IsAbleToProcess(
}
std::string RCRPCPlugin::PluginName() {
- return "RC RPC Plugin";
+ return plugins::plugin_names::rc_rpc_plugin;
}
application_manager::CommandFactory& RCRPCPlugin::GetCommandFactory() {
diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/sdl_rpc_plugin.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/sdl_rpc_plugin.cc
index aa82c74098..c448b41ff1 100644
--- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/sdl_rpc_plugin.cc
+++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/sdl_rpc_plugin.cc
@@ -30,6 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
*/
+#include "application_manager/plugin_manager/plugin_keys.h"
#include "sdl_rpc_plugin/sdl_rpc_plugin.h"
#include "sdl_rpc_plugin/sdl_command_factory.h"
#include "sdl_rpc_plugin/extensions/system_capability_app_extension.h"
@@ -56,7 +57,7 @@ bool SDLRPCPlugin::IsAbleToProcess(
}
std::string SDLRPCPlugin::PluginName() {
- return "SDL RPC Plugin";
+ return plugins::plugin_names::sdl_rpc_plugin;
}
app_mngr::CommandFactory& SDLRPCPlugin::GetCommandFactory() {
diff --git a/src/components/application_manager/rpc_plugins/vehicle_info_plugin/src/vehicle_info_plugin.cc b/src/components/application_manager/rpc_plugins/vehicle_info_plugin/src/vehicle_info_plugin.cc
index d0bcc36ab4..c9e9839929 100644
--- a/src/components/application_manager/rpc_plugins/vehicle_info_plugin/src/vehicle_info_plugin.cc
+++ b/src/components/application_manager/rpc_plugins/vehicle_info_plugin/src/vehicle_info_plugin.cc
@@ -33,6 +33,7 @@
#include "vehicle_info_plugin/vehicle_info_plugin.h"
#include "vehicle_info_plugin/vehicle_info_command_factory.h"
#include "vehicle_info_plugin/vehicle_info_app_extension.h"
+#include "application_manager/plugin_manager/plugin_keys.h"
#include "application_manager/smart_object_keys.h"
#include "application_manager/message_helper.h"
#include "application_manager/message_helper.h"
@@ -41,6 +42,7 @@ namespace vehicle_info_plugin {
CREATE_LOGGERPTR_GLOBAL(logger_, "VehicleInfoPlugin")
namespace strings = application_manager::strings;
+namespace plugins = application_manager::plugin_manager;
VehicleInfoPlugin::VehicleInfoPlugin() : application_manager_(nullptr) {}
@@ -61,7 +63,7 @@ bool VehicleInfoPlugin::IsAbleToProcess(
}
std::string VehicleInfoPlugin::PluginName() {
- return "Vehicle Info Plugin";
+ return plugins::plugin_names::vehicle_info_rpc_plugin;
}
app_mngr::CommandFactory& VehicleInfoPlugin::GetCommandFactory() {
diff --git a/src/components/application_manager/src/app_service_manager.cc b/src/components/application_manager/src/app_service_manager.cc
index 24c21dc201..d148e4ef61 100644
--- a/src/components/application_manager/src/app_service_manager.cc
+++ b/src/components/application_manager/src/app_service_manager.cc
@@ -45,8 +45,6 @@
#include "smart_objects/enum_schema_item.h"
#include "utils/logger.h"
-#include "smart_objects/enum_schema_item.h"
-
CREATE_LOGGERPTR_GLOBAL(logger_, "AppServiceManager")
namespace application_manager {
@@ -56,7 +54,9 @@ const char* kDefaults = "defaults";
AppServiceManager::AppServiceManager(ApplicationManager& app_manager,
resumption::LastState& last_state)
- : app_manager_(app_manager), last_state_(last_state) {}
+ : app_manager_(app_manager)
+ , last_state_(last_state)
+ , rpc_passing_handler_(*this, app_manager_) {}
AppServiceManager::~AppServiceManager() {
LOG4CXX_AUTO_TRACE(logger_);
@@ -544,4 +544,20 @@ void AppServiceManager::AppServiceUpdated(
services[-1] = service;
}
+std::vector<std::pair<std::string, AppService> >
+AppServiceManager::GetActiveServices() {
+ std::vector<std::pair<std::string, AppService> > active_services;
+ for (auto it = published_services_.begin(); it != published_services_.end();
+ ++it) {
+ if (it->second.record[strings::service_active].asBool()) {
+ active_services.push_back(*it);
+ }
+ }
+ return active_services;
+}
+
+RPCPassingHandler& AppServiceManager::GetRPCPassingHandler() {
+ return rpc_passing_handler_;
+}
+
} // namespace application_manager
diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc
index 2c8f5e06b2..f9da143720 100644
--- a/src/components/application_manager/src/application_manager_impl.cc
+++ b/src/components/application_manager/src/application_manager_impl.cc
@@ -2052,7 +2052,9 @@ bool ApplicationManagerImpl::Stop() {
}
bool ApplicationManagerImpl::ConvertSOtoMessage(
- const smart_objects::SmartObject& message, Message& output) {
+ const smart_objects::SmartObject& message,
+ Message& output,
+ const bool remove_unknown_parameters) {
LOG4CXX_AUTO_TRACE(logger_);
if (smart_objects::SmartType_Null == message.getType() ||
@@ -2077,16 +2079,16 @@ bool ApplicationManagerImpl::ConvertSOtoMessage(
switch (protocol_type) {
case 0: {
if (protocol_version == 1) {
- if (!formatters::CFormatterJsonSDLRPCv1::toString(message,
- output_string)) {
+ if (!formatters::CFormatterJsonSDLRPCv1::toString(
+ message, output_string, remove_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, remove_unknown_parameters)) {
LOG4CXX_WARN(logger_, "Failed to serialize smart object");
return false;
}
@@ -2098,7 +2100,8 @@ bool ApplicationManagerImpl::ConvertSOtoMessage(
break;
}
case 1: {
- if (!formatters::FormatterJsonRpc::ToString(message, output_string)) {
+ if (!formatters::FormatterJsonRpc::ToString(
+ message, output_string, remove_unknown_parameters)) {
LOG4CXX_WARN(logger_, "Failed to serialize smart object");
return false;
}
diff --git a/src/components/application_manager/src/plugin_manager/plugin_keys.cc b/src/components/application_manager/src/plugin_manager/plugin_keys.cc
new file mode 100644
index 0000000000..9eabc67c09
--- /dev/null
+++ b/src/components/application_manager/src/plugin_manager/plugin_keys.cc
@@ -0,0 +1,14 @@
+#include "application_manager/plugin_manager/plugin_keys.h"
+
+namespace application_manager {
+namespace plugin_manager {
+
+namespace plugin_names {
+const char* vehicle_info_rpc_plugin = "Vehicle Info RPC Plugin";
+const char* app_service_rpc_plugin = "App Service RPC Plugin";
+const char* rc_rpc_plugin = "RC RPC Plugin";
+const char* sdl_rpc_plugin = "SDL RPC Plugin";
+}
+
+} // namespace plugin_manager
+} // namespace application_manager \ No newline at end of file
diff --git a/src/components/application_manager/src/rpc_handler_impl.cc b/src/components/application_manager/src/rpc_handler_impl.cc
index 40f2e90115..6374e2a955 100644
--- a/src/components/application_manager/src/rpc_handler_impl.cc
+++ b/src/components/application_manager/src/rpc_handler_impl.cc
@@ -31,6 +31,7 @@
*/
#include "application_manager/rpc_handler_impl.h"
+#include "application_manager/plugin_manager/plugin_keys.h"
namespace application_manager {
namespace rpc_handler {
@@ -38,6 +39,7 @@ namespace rpc_handler {
CREATE_LOGGERPTR_LOCAL(logger_, "RPCHandlerImpl")
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;
RPCHandlerImpl::RPCHandlerImpl(ApplicationManager& app_manager)
: app_manager_(app_manager)
@@ -63,17 +65,54 @@ void RPCHandlerImpl::ProcessMessageFromMobile(
#endif // TELEMETRY_MONITOR
smart_objects::SmartObjectSPtr so_from_mobile =
std::make_shared<smart_objects::SmartObject>();
-
+ bool remove_unknown_parameters = true;
DCHECK_OR_RETURN_VOID(so_from_mobile);
if (!so_from_mobile) {
LOG4CXX_ERROR(logger_, "Null pointer");
return;
}
- if (!ConvertMessageToSO(*message, *so_from_mobile)) {
+ bool rpc_passing = app_manager_.GetAppServiceManager()
+ .GetRPCPassingHandler()
+ .CanHandleFunctionID(message->function_id());
+ if (app_manager_.GetRPCService().IsAppServiceRPC(
+ message->function_id(), commands::Command::SOURCE_MOBILE) ||
+ rpc_passing) {
+ LOG4CXX_DEBUG(logger_,
+ "Allowing unknown parameters for request function "
+ << message->function_id());
+ remove_unknown_parameters = false;
+ }
+
+ if (!ConvertMessageToSO(
+ *message, *so_from_mobile, remove_unknown_parameters)) {
LOG4CXX_ERROR(logger_, "Cannot create smart object from message");
return;
}
+
+ if (rpc_passing) {
+ uint32_t correlation_id =
+ (*so_from_mobile)[strings::params][strings::correlation_id].asUInt();
+ int32_t message_type =
+ (*so_from_mobile)[strings::params][strings::message_type].asInt();
+ if (app_manager_.GetAppServiceManager()
+ .GetRPCPassingHandler()
+ .RPCPassThrough(*so_from_mobile)) {
+ // RPC was forwarded. Skip handling by Core
+ return;
+ } else if (!app_manager_.GetAppServiceManager()
+ .GetRPCPassingHandler()
+ .IsPassThroughMessage(correlation_id,
+ commands::Command::SOURCE_MOBILE,
+ message_type)) {
+ // Since PassThrough failed, refiltering the message
+ if (!ConvertMessageToSO(*message, *so_from_mobile, true)) {
+ LOG4CXX_ERROR(logger_, "Cannot create smart object from message");
+ return;
+ }
+ }
+ }
+
#ifdef TELEMETRY_MONITOR
metric->message = so_from_mobile;
#endif // TELEMETRY_MONITOR
@@ -95,13 +134,28 @@ void RPCHandlerImpl::ProcessMessageFromHMI(
LOG4CXX_AUTO_TRACE(logger_);
smart_objects::SmartObjectSPtr smart_object =
std::make_shared<smart_objects::SmartObject>();
-
+ bool remove_unknown_parameters = true;
if (!smart_object) {
LOG4CXX_ERROR(logger_, "Null pointer");
return;
}
- if (!ConvertMessageToSO(*message, *smart_object)) {
+ smart_objects::SmartObject converted_result;
+ formatters::FormatterJsonRpc::FromString<hmi_apis::FunctionID::eType,
+ hmi_apis::messageType::eType>(
+ message->json_message(), converted_result);
+
+ if (app_manager_.GetRPCService().IsAppServiceRPC(
+ converted_result[jhs::S_PARAMS][jhs::S_FUNCTION_ID].asInt(),
+ commands::Command::SOURCE_HMI)) {
+ LOG4CXX_DEBUG(
+ logger_,
+ "Allowing unknown parameters for request function "
+ << converted_result[jhs::S_PARAMS][jhs::S_FUNCTION_ID].asInt());
+ remove_unknown_parameters = false;
+ }
+
+ if (!ConvertMessageToSO(*message, *smart_object, remove_unknown_parameters)) {
if (application_manager::MessageType::kResponse ==
(*smart_object)[strings::params][strings::message_type].asInt()) {
(*smart_object).erase(strings::msg_params);
@@ -228,7 +282,8 @@ void RPCHandlerImpl::GetMessageVersion(
bool RPCHandlerImpl::ConvertMessageToSO(
const Message& message,
- ns_smart_device_link::ns_smart_objects::SmartObject& output) {
+ ns_smart_device_link::ns_smart_objects::SmartObject& output,
+ const bool remove_unknown_parameters) {
LOG4CXX_AUTO_TRACE(logger_);
LOG4CXX_DEBUG(logger_,
"\t\t\tMessage to convert: protocol "
@@ -262,9 +317,11 @@ bool RPCHandlerImpl::ConvertMessageToSO(
}
if (!conversion_result ||
- !mobile_so_factory().attachSchema(output, true, msg_version) ||
+ !mobile_so_factory().attachSchema(
+ output, remove_unknown_parameters, msg_version) ||
((output.validate(&report, msg_version) !=
- smart_objects::errors::OK))) {
+ smart_objects::errors::OK &&
+ remove_unknown_parameters))) {
LOG4CXX_WARN(logger_,
"Failed to parse string to smart object with API version "
<< msg_version.toString() << " : "
diff --git a/src/components/application_manager/src/rpc_passing_handler.cc b/src/components/application_manager/src/rpc_passing_handler.cc
new file mode 100644
index 0000000000..560418e910
--- /dev/null
+++ b/src/components/application_manager/src/rpc_passing_handler.cc
@@ -0,0 +1,331 @@
+/*
+ * 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/help_prompt_manager_impl.h"
+
+#include <algorithm>
+#include <iterator>
+
+#include "application_manager/application.h"
+#include "application_manager/application_manager.h"
+#include "application_manager/rpc_passing_handler.h"
+#include "application_manager/commands/command_impl.h"
+#include "application_manager/message_helper.h"
+#include "application_manager/smart_object_keys.h"
+#include "encryption/hashing.h"
+#include "resumption/last_state.h"
+#include "smart_objects/enum_schema_item.h"
+#include "utils/logger.h"
+
+#include "smart_objects/enum_schema_item.h"
+#include "utils/timer_task_impl.h"
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "RPCPassingHandler")
+
+namespace application_manager {
+
+RPCPassingHandler::RPCPassingHandler(AppServiceManager& asm_ref,
+ ApplicationManager& am_ref)
+ : app_service_manager_(asm_ref), app_manager_(am_ref) {}
+
+RPCPassingHandler::~RPCPassingHandler() {}
+
+bool RPCPassingHandler::IsPassThroughMessage(
+ uint32_t correlation_id,
+ commands::Command::CommandSource source,
+ int32_t message_type) {
+ sync_primitives::AutoLock lock(rpc_request_queue_lock_);
+
+ if (rpc_request_queue.find(correlation_id) != rpc_request_queue.end()) {
+ if (message_type == MessageType::kResponse &&
+ source == commands::Command::CommandSource::SOURCE_SDL) {
+ // Checks if response is being sent to mobile then removes the correlation
+ // id from the map
+ rpc_request_queue.erase(correlation_id);
+ }
+ return true;
+ }
+ return false;
+}
+
+bool RPCPassingHandler::CanHandleFunctionID(int32_t function_id) {
+ auto services = app_service_manager_.GetActiveServices();
+ for (auto it = services.begin(); it != services.end(); ++it) {
+ auto handled_rpcs =
+ it->second.record[strings::service_manifest][strings::handled_rpcs];
+ for (size_t i = 0; i < handled_rpcs.length(); i++) {
+ if (handled_rpcs[i].asInt() == function_id) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool RPCPassingHandler::RPCPassThrough(smart_objects::SmartObject rpc_message) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ uint32_t correlation_id =
+ rpc_message[strings::params][strings::correlation_id].asUInt();
+ int32_t message_type =
+ rpc_message[strings::params][strings::message_type].asInt();
+
+ LOG4CXX_DEBUG(logger_, "RPC_PASSING: ");
+ MessageHelper::PrintSmartObject(rpc_message);
+
+ // Clear timers for timed out requests
+ ClearCompletedTimers();
+ switch (message_type) {
+ case MessageType::kRequest: {
+ LOG4CXX_DEBUG(logger_, "Handle request");
+ rpc_request_queue_lock_.Acquire();
+ if (rpc_request_queue.find(correlation_id) == rpc_request_queue.end()) {
+ rpc_request_queue_lock_.Release();
+ LOG4CXX_DEBUG(
+ logger_,
+ "Correlation id DOES NOT exist in map. Constructing request queue");
+ PopulateRPCRequestQueue(rpc_message);
+ } else {
+ rpc_request_queue_lock_.Release();
+ LOG4CXX_DEBUG(logger_, "Correlation id DOES exist in map. Continuing");
+ return false;
+ }
+
+ rpc_request_queue_lock_.Acquire();
+ if (rpc_request_queue[correlation_id].second.empty()) {
+ LOG4CXX_DEBUG(logger_,
+ "No services left in map. Using core to handle request");
+ rpc_request_queue.erase(correlation_id);
+ rpc_request_queue_lock_.Release();
+ return false;
+ } else {
+ rpc_request_queue_lock_.Release();
+ ForwardRequestToMobile(correlation_id);
+ return true;
+ }
+
+ break;
+ }
+
+ case MessageType::kResponse: {
+ LOG4CXX_DEBUG(logger_, "Handle response");
+ rpc_request_queue_lock_.Acquire();
+ if (rpc_request_queue.find(correlation_id) == rpc_request_queue.end()) {
+ rpc_request_queue_lock_.Release();
+ return false;
+ }
+ rpc_request_queue_lock_.Release();
+ RemoveRequestTimer(correlation_id);
+ auto result_code = static_cast<mobile_apis::Result::eType>(
+ rpc_message[strings::msg_params][strings::result_code].asInt());
+
+ if (result_code == mobile_apis::Result::UNSUPPORTED_REQUEST) {
+ LOG4CXX_DEBUG(logger_, "Service sent UNSUPPORTED_REQUEST");
+ PerformNextRequest(correlation_id);
+ return true;
+ } else {
+ LOG4CXX_DEBUG(logger_, "Valid RPC passing response");
+ ForwardResponseToMobile(correlation_id, rpc_message);
+ return true;
+ }
+
+ break;
+ }
+ }
+
+ return false;
+}
+
+void RPCPassingHandler::PopulateRPCRequestQueue(
+ smart_objects::SmartObject request_message) {
+ uint32_t origin_connection_key =
+ request_message[strings::params][strings::connection_key].asUInt();
+ uint32_t correlation_id =
+ request_message[strings::params][strings::correlation_id].asUInt();
+ int32_t function_id =
+ request_message[strings::params][strings::function_id].asInt();
+
+ // Construct list of pass through services
+ auto entry = std::make_pair(request_message, std::deque<ServiceInfo>());
+ auto services = app_service_manager_.GetActiveServices();
+
+ for (auto services_it = services.begin(); services_it != services.end();
+ ++services_it) {
+ auto handled_rpcs =
+ services_it->second
+ .record[strings::service_manifest][strings::handled_rpcs];
+ for (size_t i = 0; i < handled_rpcs.length(); i++) {
+ if (handled_rpcs[i].asInt() == function_id) {
+ // Add requests to queue
+ ServiceInfo service_info{services_it->first,
+ services_it->second.connection_key};
+ entry.second.push_back(service_info);
+ app_manager_.IncreaseForwardedRequestTimeout(origin_connection_key,
+ correlation_id);
+ break;
+ }
+ }
+ }
+
+ sync_primitives::AutoLock lock(rpc_request_queue_lock_);
+ rpc_request_queue[correlation_id] = entry;
+
+ LOG4CXX_DEBUG(logger_,
+ "Added " << rpc_request_queue[correlation_id].second.size()
+ << " requests to the queue");
+}
+void RPCPassingHandler::ForwardRequestToMobile(uint32_t correlation_id) {
+ rpc_request_queue_lock_.Acquire();
+ uint32_t connection_key =
+ rpc_request_queue[correlation_id].second.front().connection_key;
+ LOG4CXX_DEBUG(logger_,
+ "Forwarding request to service with app id " << connection_key);
+
+ smart_objects::SmartObject message(rpc_request_queue[correlation_id].first);
+ message[strings::params][strings::connection_key] = connection_key;
+ smart_objects::SmartObjectSPtr result =
+ std::make_shared<smart_objects::SmartObject>(message);
+ rpc_request_queue_lock_.Release();
+ AddRequestTimer(correlation_id);
+ app_manager_.GetRPCService().SendMessageToMobile(result);
+}
+
+void RPCPassingHandler::ForwardRequestToCore(uint32_t correlation_id) {
+ LOG4CXX_DEBUG(logger_,
+ "No services left in map. using core to handle request");
+ rpc_request_queue_lock_.Acquire();
+ smart_objects::SmartObject message(rpc_request_queue[correlation_id].first);
+ smart_objects::SmartObjectSPtr result =
+ std::make_shared<smart_objects::SmartObject>(message);
+ rpc_request_queue.erase(correlation_id);
+ rpc_request_queue_lock_.Release();
+ app_manager_.GetRPCService().ManageMobileCommand(
+ result, commands::Command::SOURCE_MOBILE);
+}
+
+void RPCPassingHandler::ForwardResponseToMobile(
+ uint32_t correlation_id, smart_objects::SmartObject response_message) {
+ rpc_request_queue_lock_.Acquire();
+ uint32_t origin_connection_key =
+ rpc_request_queue[correlation_id]
+ .first[strings::params][strings::connection_key]
+ .asUInt();
+ rpc_request_queue_lock_.Release();
+
+ LOG4CXX_DEBUG(logger_,
+ "Forwarding response to mobile app " << origin_connection_key);
+ smart_objects::SmartObject message(response_message);
+ message[strings::params][strings::connection_key] = origin_connection_key;
+ smart_objects::SmartObjectSPtr result =
+ std::make_shared<smart_objects::SmartObject>(message);
+ app_manager_.GetRPCService().SendMessageToMobile(result);
+}
+
+bool RPCPassingHandler::PerformNextRequest(uint32_t correlation_id) {
+ LOG4CXX_DEBUG(logger_, "Performing next request in queue");
+ rpc_request_queue_lock_.Acquire();
+ if (rpc_request_queue.find(correlation_id) == rpc_request_queue.end()) {
+ LOG4CXX_ERROR(logger_, "Correlation id does NOT exist in map");
+ rpc_request_queue_lock_.Release();
+ return false;
+ }
+ rpc_request_queue[correlation_id].second.pop_front();
+ bool empty = rpc_request_queue[correlation_id].second.empty();
+ rpc_request_queue_lock_.Release();
+
+ if (empty) {
+ ForwardRequestToCore(correlation_id);
+ } else {
+ ForwardRequestToMobile(correlation_id);
+ }
+
+ return true;
+}
+
+void RPCPassingHandler::OnPassThroughRequestTimeout() {
+ timeout_queue_lock_.Acquire();
+ LOG4CXX_DEBUG(logger_, "Request Timed out");
+ auto timeout_entry = timeout_queue_.front();
+ uint32_t correlation_id = timeout_entry.second;
+ timeout_queue_lock_.Release();
+ PerformNextRequest(correlation_id);
+}
+
+void RPCPassingHandler::ClearCompletedTimers() {
+ sync_primitives::AutoLock lock(timeout_queue_lock_);
+
+ LOG4CXX_DEBUG(logger_, "Clearing Completed Timers");
+ for (auto it = timeout_queue_.begin(); it != timeout_queue_.end();) {
+ TimerSPtr timer = it->first;
+ uint32_t cid = it->second;
+ if (timer->is_completed()) {
+ LOG4CXX_DEBUG(logger_,
+ "Removing completed timer for correlation id " << cid);
+ it = timeout_queue_.erase(it);
+ } else {
+ ++it;
+ }
+ }
+}
+
+void RPCPassingHandler::AddRequestTimer(uint32_t correlation_id) {
+ TimerSPtr rpc_passing_timer(std::make_shared<timer::Timer>(
+ "RPCPassingTimeoutTimer_" + std::to_string(correlation_id),
+ new timer::TimerTaskImpl<RPCPassingHandler>(
+ this, &RPCPassingHandler::OnPassThroughRequestTimeout)));
+ const uint32_t timeout_ms =
+ app_manager_.get_settings().rpc_pass_through_timeout();
+ rpc_passing_timer->Start(timeout_ms, timer::kSingleShot);
+ LOG4CXX_DEBUG(logger_,
+ "Adding and starting timer for correlation id "
+ << correlation_id);
+ sync_primitives::AutoLock lock(timeout_queue_lock_);
+ timeout_queue_.push_back(std::make_pair(rpc_passing_timer, correlation_id));
+}
+
+void RPCPassingHandler::RemoveRequestTimer(uint32_t correlation_id) {
+ sync_primitives::AutoLock lock(timeout_queue_lock_);
+
+ for (auto it = timeout_queue_.begin(); it != timeout_queue_.end();) {
+ TimerSPtr timer = it->first;
+ uint32_t cid = it->second;
+ if (cid == correlation_id) {
+ LOG4CXX_DEBUG(logger_,
+ "Removing timer for correlation id " << correlation_id);
+ it = timeout_queue_.erase(it);
+ } else {
+ ++it;
+ }
+ }
+}
+
+} // namespace application_manager
diff --git a/src/components/application_manager/src/rpc_service_impl.cc b/src/components/application_manager/src/rpc_service_impl.cc
index 99d0bf0cfe..d8329ba8cf 100644
--- a/src/components/application_manager/src/rpc_service_impl.cc
+++ b/src/components/application_manager/src/rpc_service_impl.cc
@@ -31,6 +31,7 @@
*/
#include "application_manager/rpc_service_impl.h"
+#include "application_manager/plugin_manager/plugin_keys.h"
namespace application_manager {
namespace rpc_service {
@@ -38,6 +39,7 @@ 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,
@@ -386,6 +388,7 @@ void RPCServiceImpl::SendMessageToMobile(
const bool is_result_code_exists =
(*message)[strings::msg_params].keyExists(strings::result_code);
+ bool remove_unknown_parameters = true;
if (!app) {
LOG4CXX_ERROR(logger_, "No application associated with connection key");
@@ -417,7 +420,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);
+ remove_unknown_parameters = false;
+ }
+
+ 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())) {
+ remove_unknown_parameters = true;
+ }
+ if (!ConvertSOtoMessage(
+ (*message), (*message_to_send), remove_unknown_parameters)) {
LOG4CXX_WARN(logger_, "Can't send msg to Mobile: failed to create string");
return;
}
@@ -496,6 +523,7 @@ void RPCServiceImpl::SendMessageToHMI(
return;
}
+ bool remove_unknown_parameters = true;
// SmartObject |message| has no way to declare priority for now
std::shared_ptr<Message> message_to_send(
new Message(protocol_handler::MessagePriority::kDefault));
@@ -509,7 +537,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());
+
+ remove_unknown_parameters = false;
+ }
+
+ if (!ConvertSOtoMessage(
+ *message, *message_to_send, remove_unknown_parameters)) {
LOG4CXX_WARN(logger_,
"Cannot send message to HMI: failed to create string");
return;
@@ -518,6 +556,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;
@@ -530,7 +604,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 remove_unknown_parameters) {
LOG4CXX_AUTO_TRACE(logger_);
if (smart_objects::SmartType_Null == message.getType() ||
@@ -555,16 +630,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, remove_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, remove_unknown_parameters)) {
LOG4CXX_WARN(logger_, "Failed to serialize smart object");
return false;
}
@@ -576,7 +651,8 @@ bool RPCServiceImpl::ConvertSOtoMessage(
break;
}
case 1: {
- if (!formatters::FormatterJsonRpc::ToString(message, output_string)) {
+ if (!formatters::FormatterJsonRpc::ToString(
+ message, output_string, remove_unknown_parameters)) {
LOG4CXX_WARN(logger_, "Failed to serialize smart object");
return false;
}
@@ -589,7 +665,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)
diff --git a/src/components/formatters/include/formatters/CFormatterJsonSDLRPCv1.h b/src/components/formatters/include/formatters/CFormatterJsonSDLRPCv1.h
index d2fdf87957..cd3e50212a 100644
--- a/src/components/formatters/include/formatters/CFormatterJsonSDLRPCv1.h
+++ b/src/components/formatters/include/formatters/CFormatterJsonSDLRPCv1.h
@@ -126,11 +126,14 @@ class CFormatterJsonSDLRPCv1 : public CFormatterJsonBase {
*
* @param obj input SmartObject
* @param outStr resulting JSON string
+ * @param remove_unknown_parameters contains true if need to remove unknown
+ *parameters
* @return true if success, false otherwise
*/
static bool toString(
const ns_smart_device_link::ns_smart_objects::SmartObject& obj,
- std::string& outStr);
+ std::string& outStr,
+ const bool remove_unknown_parameters = true);
/**
* @brief Creates a SmartObject from a JSON string.
@@ -151,12 +154,15 @@ class CFormatterJsonSDLRPCv1 : public CFormatterJsonBase {
* @param schema Smart schema which describes 'fake' smart object to be
*formatted
* @param outStr Resulting JSON string
+ * @param remove_unknown_parameters contains true if need to remove unknown
+ *parameters
* @return formatting error code
*/
static tMetaFormatterErrorCode MetaFormatToString(
const ns_smart_device_link::ns_smart_objects::SmartObject& object,
const ns_smart_device_link::ns_smart_objects::CSmartSchema& schema,
- std::string& outStr);
+ std::string& outStr,
+ const bool remove_unknown_parameters = true);
};
// ----------------------------------------------------------------------------
diff --git a/src/components/formatters/include/formatters/CFormatterJsonSDLRPCv2.h b/src/components/formatters/include/formatters/CFormatterJsonSDLRPCv2.h
index e248954552..f86e4e51cb 100644
--- a/src/components/formatters/include/formatters/CFormatterJsonSDLRPCv2.h
+++ b/src/components/formatters/include/formatters/CFormatterJsonSDLRPCv2.h
@@ -73,11 +73,14 @@ class CFormatterJsonSDLRPCv2 : public CFormatterJsonBase {
*
* @param obj input SmartObject
* @param outStr resulting JSON string
+ * @param remove_unknown_parameters contains true if need to remove unknown
+ *parameters
* @return true if success, false otherwise
*/
static bool toString(
const ns_smart_device_link::ns_smart_objects::SmartObject& obj,
- std::string& outStr);
+ std::string& outStr,
+ const bool remove_unknown_parameters = true);
/**
* @brief Creates a SmartObject from a JSON string.
@@ -128,12 +131,15 @@ class CFormatterJsonSDLRPCv2 : public CFormatterJsonBase {
* @param schema Smart schema which describes 'fake' smart object to be
*formatted
* @param outStr Resulting JSON string
+ * @param remove_unknown_parameters contains true if need to remove unknown
+ *parameters
* @return formatting error code
*/
static tMetaFormatterErrorCode MetaFormatToString(
const ns_smart_device_link::ns_smart_objects::SmartObject& object,
const ns_smart_device_link::ns_smart_objects::CSmartSchema& schema,
- std::string& outStr);
+ std::string& outStr,
+ const bool remove_unknown_parameters = true);
};
template <typename FunctionId, typename MessageType>
diff --git a/src/components/formatters/include/formatters/CSmartFactory.h b/src/components/formatters/include/formatters/CSmartFactory.h
index a48eab2a6b..f3c3fbe207 100644
--- a/src/components/formatters/include/formatters/CSmartFactory.h
+++ b/src/components/formatters/include/formatters/CSmartFactory.h
@@ -148,14 +148,14 @@ class CSmartFactory {
*
* @param object SmartObject to attach schema for.
*
- * @param RemoveFakeParameters contains true if need
+ * @param remove_unknown_parameters contains true if need
* to remove fake parameters from smart object otherwise contains false.
*
* @return True if operation was successful or false otherwise.
*/
bool attachSchema(
ns_smart_device_link::ns_smart_objects::SmartObject& object,
- const bool RemoveFakeParameters,
+ const bool remove_unknown_parameters,
const utils::SemanticVersion& MessageVersion = utils::SemanticVersion());
/**
@@ -276,7 +276,7 @@ CSmartFactory<FunctionIdEnum, MessageTypeEnum, StructIdEnum>::CSmartFactory(
template <class FunctionIdEnum, class MessageTypeEnum, class StructIdEnum>
bool CSmartFactory<FunctionIdEnum, MessageTypeEnum, StructIdEnum>::attachSchema(
ns_smart_device_link::ns_smart_objects::SmartObject& object,
- const bool RemoveFakeParameters,
+ const bool remove_unknown_parameters,
const utils::SemanticVersion& MessageVersion) {
if (false == object.keyExists(strings::S_PARAMS))
return false;
@@ -305,7 +305,7 @@ bool CSmartFactory<FunctionIdEnum, MessageTypeEnum, StructIdEnum>::attachSchema(
object.setSchema(schemaIterator->second);
schemaIterator->second.applySchema(
- object, RemoveFakeParameters, MessageVersion);
+ object, remove_unknown_parameters, MessageVersion);
return true;
}
diff --git a/src/components/formatters/include/formatters/formatter_json_rpc.h b/src/components/formatters/include/formatters/formatter_json_rpc.h
index 842e176976..3503767988 100644
--- a/src/components/formatters/include/formatters/formatter_json_rpc.h
+++ b/src/components/formatters/include/formatters/formatter_json_rpc.h
@@ -105,11 +105,13 @@ class FormatterJsonRpc : public CFormatterJsonBase {
*
* @param obj Input SmartObject.
* @param out_str Resulting JSON string.
- *
+ * @param remove_unknown_parameters contains true if need to remove unknown
+ *parameters
* @return true if success, false otherwise.
*/
static bool ToString(const ns_smart_objects::SmartObject& obj,
- std::string& out_str);
+ std::string& out_str,
+ const bool remove_unknown_parameters = true);
/**
* @brief Creates a SmartObject from a JSON string.
diff --git a/src/components/formatters/src/CFormatterJsonSDLRPCv1.cc b/src/components/formatters/src/CFormatterJsonSDLRPCv1.cc
index 121fd43131..a5c3d1a103 100644
--- a/src/components/formatters/src/CFormatterJsonSDLRPCv1.cc
+++ b/src/components/formatters/src/CFormatterJsonSDLRPCv1.cc
@@ -85,7 +85,8 @@ const std::string CFormatterJsonSDLRPCv1::getMessageType(
// ----------------------------------------------------------------------------
bool CFormatterJsonSDLRPCv1::toString(const smart_objects_ns::SmartObject& obj,
- std::string& outStr) {
+ std::string& outStr,
+ const bool remove_unknown_parameters) {
bool result = false;
try {
Json::Value root(Json::objectValue);
@@ -93,7 +94,8 @@ bool CFormatterJsonSDLRPCv1::toString(const smart_objects_ns::SmartObject& obj,
smart_objects_ns::SmartObject formattedObj(obj);
formattedObj.getSchema().unapplySchema(
- formattedObj); // converts enums(as int32_t) to strings
+ formattedObj,
+ remove_unknown_parameters); // converts enums(as int32_t) to strings
objToJsonValue(formattedObj.getElement(strings::S_MSG_PARAMS), params);
@@ -125,7 +127,8 @@ CFormatterJsonSDLRPCv1::tMetaFormatterErrorCode
CFormatterJsonSDLRPCv1::MetaFormatToString(
const smart_objects_ns::SmartObject& object,
const smart_objects_ns::CSmartSchema& schema,
- std::string& outStr) {
+ std::string& outStr,
+ const bool remove_unknown_parameters) {
meta_formatter_error_code::tMetaFormatterErrorCode result_code =
meta_formatter_error_code::kErrorOk;
@@ -156,7 +159,8 @@ CFormatterJsonSDLRPCv1::MetaFormatToString(
result_code |= meta_formatter_error_code::kErrorSchemaIsNotFunction;
}
- CFormatterJsonSDLRPCv1::toString(tmp_object, outStr);
+ CFormatterJsonSDLRPCv1::toString(
+ tmp_object, outStr, remove_unknown_parameters);
return result_code;
}
diff --git a/src/components/formatters/src/CFormatterJsonSDLRPCv2.cc b/src/components/formatters/src/CFormatterJsonSDLRPCv2.cc
index ffbb644cc6..a582b52462 100644
--- a/src/components/formatters/src/CFormatterJsonSDLRPCv2.cc
+++ b/src/components/formatters/src/CFormatterJsonSDLRPCv2.cc
@@ -41,14 +41,16 @@ namespace formatters {
// ----------------------------------------------------------------------------
bool CFormatterJsonSDLRPCv2::toString(const smart_objects_ns::SmartObject& obj,
- std::string& outStr) {
+ std::string& outStr,
+ const bool remove_unknown_parameters) {
bool result = true;
try {
Json::Value root(Json::objectValue);
smart_objects_ns::SmartObject formattedObj(obj);
formattedObj.getSchema().unapplySchema(
- formattedObj); // converts enums(as int32_t) to strings
+ formattedObj,
+ remove_unknown_parameters); // converts enums(as int32_t) to strings
objToJsonValue(formattedObj.getElement(strings::S_MSG_PARAMS), root);
@@ -68,7 +70,8 @@ CFormatterJsonSDLRPCv2::tMetaFormatterErrorCode
CFormatterJsonSDLRPCv2::MetaFormatToString(
const smart_objects_ns::SmartObject& object,
const smart_objects_ns::CSmartSchema& schema,
- std::string& outStr) {
+ std::string& outStr,
+ const bool remove_unknown_parameters) {
meta_formatter_error_code::tMetaFormatterErrorCode result_code =
meta_formatter_error_code::kErrorOk;
@@ -99,7 +102,8 @@ CFormatterJsonSDLRPCv2::MetaFormatToString(
result_code |= meta_formatter_error_code::kErrorSchemaIsNotFunction;
}
- CFormatterJsonSDLRPCv2::toString(tmp_object, outStr);
+ CFormatterJsonSDLRPCv2::toString(
+ tmp_object, outStr, remove_unknown_parameters);
return result_code;
}
diff --git a/src/components/formatters/src/formatter_json_rpc.cc b/src/components/formatters/src/formatter_json_rpc.cc
index d50d04d0e9..07d45d5855 100644
--- a/src/components/formatters/src/formatter_json_rpc.cc
+++ b/src/components/formatters/src/formatter_json_rpc.cc
@@ -57,7 +57,8 @@ const char* FormatterJsonRpc::kData = "data";
const char* FormatterJsonRpc::kMessage = "message";
bool FormatterJsonRpc::ToString(const ns_smart_objects::SmartObject& obj,
- std::string& out_str) {
+ std::string& out_str,
+ const bool remove_unknown_parameters) {
bool result = true;
try {
Json::Value root(Json::objectValue);
@@ -66,7 +67,8 @@ bool FormatterJsonRpc::ToString(const ns_smart_objects::SmartObject& obj,
ns_smart_objects::SmartObject formatted_object(obj);
Json::Value msg_params_json(Json::objectValue);
- formatted_object.getSchema().unapplySchema(formatted_object);
+ formatted_object.getSchema().unapplySchema(formatted_object,
+ remove_unknown_parameters);
bool is_message_params = formatted_object.keyExists(strings::S_MSG_PARAMS);
bool empty_message_params = true;
diff --git a/src/components/include/application_manager/rpc_service.h b/src/components/include/application_manager/rpc_service.h
index d892b12422..e0127eac80 100644
--- a/src/components/include/application_manager/rpc_service.h
+++ b/src/components/include/application_manager/rpc_service.h
@@ -77,6 +77,17 @@ class RPCService {
virtual void SendMessageToHMI(const commands::MessageSharedPtr message) = 0;
/**
+ * @brief Check if RPC with function_id can be handled by app services(related
+ * to app services or handled by app services plugin)
+ * @param function_id RPC function id
+ * @param source RPC command source
+ * @param rpc_passing Reference to bool. Set to true to enable rpc pasing
+ * @return true if App Services can handle RPC
+ */
+ virtual bool IsAppServiceRPC(int32_t function_id,
+ commands::Command::CommandSource source) = 0;
+
+ /**
* @brief set_protocol_handler
* @param handler
* set protocol handler
diff --git a/src/components/include/test/application_manager/mock_rpc_service.h b/src/components/include/test/application_manager/mock_rpc_service.h
index 3503f8bad1..aacb48a5ab 100644
--- a/src/components/include/test/application_manager/mock_rpc_service.h
+++ b/src/components/include/test/application_manager/mock_rpc_service.h
@@ -27,6 +27,10 @@ class MockRPCService : public application_manager::rpc_service::RPCService {
void(protocol_handler::ProtocolHandler* handler));
MOCK_METHOD1(set_hmi_message_handler,
void(hmi_message_handler::HMIMessageHandler* handler));
+ MOCK_METHOD2(
+ IsAppServiceRPC,
+ bool(int32_t function_id,
+ application_manager::commands::Command::CommandSource source));
};
}
}
diff --git a/src/components/smart_objects/include/smart_objects/array_schema_item.h b/src/components/smart_objects/include/smart_objects/array_schema_item.h
index a81fdd637e..b365a48638 100644
--- a/src/components/smart_objects/include/smart_objects/array_schema_item.h
+++ b/src/components/smart_objects/include/smart_objects/array_schema_item.h
@@ -79,12 +79,12 @@ class CArraySchemaItem : public ISchemaItem {
* @brief Apply schema.
*
* @param Object Object to apply schema.
- *
- * @param RemoveFakeParameters contains true if need to remove fake parameters
+ * @param remove_unknown_parameters contains true if need to remove unknown
+ *parameters
* from smart object otherwise contains false.
**/
void applySchema(SmartObject& Object,
- const bool RemoveFakeParameters,
+ const bool remove_unknown_parameters,
const utils::SemanticVersion& MessageVersion =
utils::SemanticVersion()) OVERRIDE;
@@ -92,8 +92,11 @@ class CArraySchemaItem : public ISchemaItem {
* @brief Unapply schema.
*
* @param Object Object to unapply schema.
+ * @param remove_unknown_parameters contains true if need to remove unknown
+ *parameters
**/
- void unapplySchema(SmartObject& Object) OVERRIDE;
+ void unapplySchema(SmartObject& Object,
+ const bool remove_unknown_parameters) OVERRIDE;
/**
* @brief Build smart object by smart schema having copied matched
diff --git a/src/components/smart_objects/include/smart_objects/enum_schema_item.h b/src/components/smart_objects/include/smart_objects/enum_schema_item.h
index 942b491927..dfa0a4baeb 100644
--- a/src/components/smart_objects/include/smart_objects/enum_schema_item.h
+++ b/src/components/smart_objects/include/smart_objects/enum_schema_item.h
@@ -129,18 +129,22 @@ class TEnumSchemaItem : public CDefaultSchemaItem<EnumType> {
* and tries to convert it to integer according to element-to-string
* map.
* @param Object Object to apply schema.
- * @param RemoveFakeParameters contains true if need to remove fake parameters
+ * @param remove_unknown_parameters contains true if need to remove unknown
+ *parameters
* from smart object otherwise contains false.
**/
void applySchema(SmartObject& Object,
- const bool RemoveFakeParameters,
+ const bool remove_unknown_parameters,
const utils::SemanticVersion& MessageVersion =
utils::SemanticVersion()) OVERRIDE;
/**
* @brief Unapply schema.
* @param Object Object to unapply schema.
+ * @param remove_unknown_parameters contains true if need to remove unknown
+ *parameters
**/
- void unapplySchema(SmartObject& Object) OVERRIDE;
+ void unapplySchema(SmartObject& Object,
+ const bool remove_unknown_parameters) OVERRIDE;
private:
/**
@@ -365,7 +369,7 @@ errors::eType TEnumSchemaItem<EnumType>::validate(
template <typename EnumType>
void TEnumSchemaItem<EnumType>::applySchema(
SmartObject& Object,
- const bool RemoveFakeParameters,
+ const bool remove_unknown_parameters,
const utils::SemanticVersion& MessageVersion) {
if (SmartType_String == Object.getType()) {
EnumType enum_val = static_cast<EnumType>(-1);
@@ -376,7 +380,8 @@ void TEnumSchemaItem<EnumType>::applySchema(
}
template <typename EnumType>
-void TEnumSchemaItem<EnumType>::unapplySchema(SmartObject& Object) {
+void TEnumSchemaItem<EnumType>::unapplySchema(
+ SmartObject& Object, const bool remove_unknown_parameters) {
if (SmartType_Integer == Object.getType()) {
const char* str;
if (ConversionHelper::EnumToCString(static_cast<EnumType>(Object.asInt()),
diff --git a/src/components/smart_objects/include/smart_objects/object_schema_item.h b/src/components/smart_objects/include/smart_objects/object_schema_item.h
index 45d161320b..27937ee17c 100644
--- a/src/components/smart_objects/include/smart_objects/object_schema_item.h
+++ b/src/components/smart_objects/include/smart_objects/object_schema_item.h
@@ -118,18 +118,22 @@ class CObjectSchemaItem : public ISchemaItem {
/**
* @brief Apply schema.
* @param Object Object to apply schema.
- * @param RemoveFakeParameters contains true if need to remove fake parameters
+ * @param remove_unknown_parameters contains true if need to remove unknown
+ *parameters
* from smart object otherwise contains false.
**/
void applySchema(SmartObject& Object,
- const bool RemoveFakeParameters,
+ const bool remove_unknown_parameters,
const utils::SemanticVersion& MessageVersion =
utils::SemanticVersion()) OVERRIDE;
/**
* @brief Unapply schema.
* @param Object Object to unapply schema.
+ * @param remove_unknown_parameters contains true if need to remove unknown
+ *parameters
**/
- void unapplySchema(SmartObject& Object) OVERRIDE;
+ void unapplySchema(SmartObject& Object,
+ const bool remove_unknown_parameters) OVERRIDE;
/**
* @brief Build smart object by smart schema having copied matched
* parameters from pattern smart object
diff --git a/src/components/smart_objects/include/smart_objects/schema_item.h b/src/components/smart_objects/include/smart_objects/schema_item.h
index 24c642c0ba..0c1b3f75b8 100644
--- a/src/components/smart_objects/include/smart_objects/schema_item.h
+++ b/src/components/smart_objects/include/smart_objects/schema_item.h
@@ -88,21 +88,25 @@ class ISchemaItem {
* @brief Apply schema.
*
* @param Object Object to apply schema.
- * @param RemoveFakeParameters contains true if need to remove fake parameters
+ * @param remove_unknown_parameters contains true if need to remove unknown
+ *parameters
* from smart object otherwise contains false.
**/
virtual void applySchema(
ns_smart_device_link::ns_smart_objects::SmartObject& Object,
- const bool RemoveFakeParameters,
+ const bool remove_unknown_parameters,
const utils::SemanticVersion& MessageVersion = utils::SemanticVersion());
/**
* @brief Unapply schema.
*
* @param Object Object to unapply schema.
+ * @param remove_unknown_parameters contains true if need to remove unknown
+ *parameters
**/
virtual void unapplySchema(
- ns_smart_device_link::ns_smart_objects::SmartObject& Object);
+ ns_smart_device_link::ns_smart_objects::SmartObject& Object,
+ const bool remove_unknown_parameters = true);
/**
* @brief Build smart object by smart schema having copied matched
diff --git a/src/components/smart_objects/include/smart_objects/smart_schema.h b/src/components/smart_objects/include/smart_objects/smart_schema.h
index 5e1497fdde..41737fed25 100644
--- a/src/components/smart_objects/include/smart_objects/smart_schema.h
+++ b/src/components/smart_objects/include/smart_objects/smart_schema.h
@@ -85,22 +85,26 @@ class CSmartSchema FINAL {
*
* @param Object Object to apply schema.
*
- * @param RemoveFakeParameters contains true if need to remove fake parameters
+ * @param remove_unknown_parameters contains true if need to remove unknown
+ *parameters
* from smart object otherwise contains false.
**/
void applySchema(
SmartObject& Object,
- const bool RemoveFakeParameters,
+ const bool remove_unknown_parameters,
const utils::SemanticVersion& MessageVersion = utils::SemanticVersion());
/**
* @brief The reverse SmartObject conversion using schema.
*
* @param object Object to convert.
+ * @param remove_unknown_parameters contains true if need to remove unknown
+ *parameters
*/
// TODO(cpplint): Is this a non-const reference?
// If so, make const or use a pointer.
- void unapplySchema(SmartObject& object);
+ void unapplySchema(SmartObject& object,
+ const bool remove_unknown_parameters = true);
/**
* @brief Build smart object by smart schema having copied matched
diff --git a/src/components/smart_objects/src/array_schema_item.cc b/src/components/smart_objects/src/array_schema_item.cc
index 7d5f8bcf84..be5fc2b83a 100644
--- a/src/components/smart_objects/src/array_schema_item.cc
+++ b/src/components/smart_objects/src/array_schema_item.cc
@@ -90,20 +90,21 @@ errors::eType CArraySchemaItem::validate(
void CArraySchemaItem::applySchema(
SmartObject& Object,
- const bool RemoveFakeParameters,
+ const bool remove_unknown_parameters,
const utils::SemanticVersion& MessageVersion) {
if (SmartType_Array == Object.getType()) {
for (size_t i = 0U; i < Object.length(); ++i) {
mElementSchemaItem->applySchema(
- Object[i], RemoveFakeParameters, MessageVersion);
+ Object[i], remove_unknown_parameters, MessageVersion);
}
}
}
-void CArraySchemaItem::unapplySchema(SmartObject& Object) {
+void CArraySchemaItem::unapplySchema(SmartObject& Object,
+ const bool remove_unknown_parameters) {
if (SmartType_Array == Object.getType()) {
for (size_t i = 0U; i < Object.length(); ++i) {
- mElementSchemaItem->unapplySchema(Object[i]);
+ mElementSchemaItem->unapplySchema(Object[i], remove_unknown_parameters);
}
}
}
diff --git a/src/components/smart_objects/src/object_schema_item.cc b/src/components/smart_objects/src/object_schema_item.cc
index 742c2ec353..b32757db7a 100644
--- a/src/components/smart_objects/src/object_schema_item.cc
+++ b/src/components/smart_objects/src/object_schema_item.cc
@@ -154,13 +154,13 @@ errors::eType CObjectSchemaItem::validate(
void CObjectSchemaItem::applySchema(
SmartObject& Object,
- const bool RemoveFakeParameters,
+ const bool remove_unknown_parameters,
const utils::SemanticVersion& MessageVersion) {
if (SmartType_Map != Object.getType()) {
return;
}
- if (RemoveFakeParameters) {
+ if (remove_unknown_parameters) {
RemoveFakeParams(Object, MessageVersion);
}
@@ -173,16 +173,17 @@ void CObjectSchemaItem::applySchema(
if (member.mSchemaItem->setDefaultValue(default_value)) {
Object[key] = default_value;
member.mSchemaItem->applySchema(
- Object[key], RemoveFakeParameters, MessageVersion);
+ Object[key], remove_unknown_parameters, MessageVersion);
}
} else {
member.mSchemaItem->applySchema(
- Object[key], RemoveFakeParameters, MessageVersion);
+ Object[key], remove_unknown_parameters, MessageVersion);
}
}
}
-void CObjectSchemaItem::unapplySchema(SmartObject& Object) {
+void CObjectSchemaItem::unapplySchema(SmartObject& Object,
+ const bool remove_unknown_parameters) {
if (SmartType_Map != Object.getType()) {
return;
}
@@ -191,7 +192,7 @@ void CObjectSchemaItem::unapplySchema(SmartObject& Object) {
const std::string& key = it->first;
// move next to avoid wrong iterator on erase
++it;
- if (mMembers.end() == mMembers.find(key)) {
+ if (mMembers.end() == mMembers.find(key) && remove_unknown_parameters) {
// remove fake params
Object.erase(key);
}
@@ -202,7 +203,7 @@ void CObjectSchemaItem::unapplySchema(SmartObject& Object) {
const std::string& key = it->first;
const SMember& member = it->second;
if (Object.keyExists(key)) {
- member.mSchemaItem->unapplySchema(Object[key]);
+ member.mSchemaItem->unapplySchema(Object[key], remove_unknown_parameters);
}
}
}
diff --git a/src/components/smart_objects/src/schema_item.cc b/src/components/smart_objects/src/schema_item.cc
index 5e9358092a..fbab17f32d 100644
--- a/src/components/smart_objects/src/schema_item.cc
+++ b/src/components/smart_objects/src/schema_item.cc
@@ -51,10 +51,11 @@ bool ISchemaItem::hasDefaultValue(SmartObject& Object) {
}
void ISchemaItem::applySchema(SmartObject& Object,
- const bool RemoveFakeParameters,
+ const bool remove_unknown_parameters,
const utils::SemanticVersion& MessageVersion) {}
-void ISchemaItem::unapplySchema(SmartObject& Object) {}
+void ISchemaItem::unapplySchema(SmartObject& Object,
+ const bool remove_unknown_parameters) {}
void ISchemaItem::BuildObjectBySchema(const SmartObject& pattern_object,
SmartObject& result_object) {}
diff --git a/src/components/smart_objects/src/smart_schema.cc b/src/components/smart_objects/src/smart_schema.cc
index f7cd22c4bc..dc0f1cbe31 100644
--- a/src/components/smart_objects/src/smart_schema.cc
+++ b/src/components/smart_objects/src/smart_schema.cc
@@ -52,13 +52,14 @@ void CSmartSchema::setSchemaItem(const ISchemaItemPtr schemaItem) {
}
void CSmartSchema::applySchema(SmartObject& Object,
- const bool RemoveFakeParameters,
+ const bool remove_unknown_parameters,
const utils::SemanticVersion& MessageVersion) {
- mSchemaItem->applySchema(Object, RemoveFakeParameters, MessageVersion);
+ mSchemaItem->applySchema(Object, remove_unknown_parameters, MessageVersion);
}
-void CSmartSchema::unapplySchema(SmartObject& Object) {
- mSchemaItem->unapplySchema(Object);
+void CSmartSchema::unapplySchema(SmartObject& Object,
+ const bool remove_unknown_parameters) {
+ mSchemaItem->unapplySchema(Object, remove_unknown_parameters);
}
void CSmartSchema::BuildObjectBySchema(const SmartObject& pattern_object,