summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaksym Ked (GitHub) <41471947+mked-luxoft@users.noreply.github.com>2019-08-29 22:28:40 +0300
committerJacob Keeler <jacob.keeler@livioradio.com>2019-08-29 15:28:40 -0400
commite90b4aa4729ca9f64e7b6f4aa9fc746c29863f23 (patch)
tree75d35eac19de42817e387b91250faab94f7e4e70
parent5905717229c512e975ca95715736db795f3105d2 (diff)
downloadsdl_core-e90b4aa4729ca9f64e7b6f4aa9fc746c29863f23.tar.gz
Feature/service status update to hmi (#2921)
* Added OnServiceUpdate notification * Added handling of service status update - introduced ServiceStatusUpdateHandler and ServiceStatusUpdateHandlerListener interfaces - added lacking interface functions to corresponding entities - added notification of listeners - introduced ServiceStatusUpdateNotificationBuilder - replaced shared_ptr with unique_ptr - moved SERVICE_RECEIVED * Add UT's for service status update to HMI feature * Added ServiceStatusUpdateDocumentation * Added sending error on PTU retries exceed allowed count * Fix OnServiceUpdate for unsecure force protected service * Updates according to proposal changes Added new result codes for ServiceStatusUpdateReasonStructure
-rw-r--r--Doxyfile3
-rw-r--r--src/appMain/life_cycle_impl.cc7
-rw-r--r--src/components/application_manager/include/application_manager/application_manager_impl.h52
-rw-r--r--src/components/application_manager/include/application_manager/message_helper.h10
-rw-r--r--src/components/application_manager/include/application_manager/policies/policy_handler.h19
-rw-r--r--src/components/application_manager/include/application_manager/policies/regular/policy_handler_observer.h2
-rw-r--r--src/components/application_manager/include/application_manager/smart_object_keys.h3
-rw-r--r--src/components/application_manager/include/application_manager/system_time/system_time_handler_impl.h6
-rw-r--r--src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/on_service_update_notification.h82
-rw-r--r--src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/basic_communication_get_system_time_request.cc2
-rw-r--r--src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/on_service_update_notification.cc63
-rw-r--r--src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/on_system_request_notification.cc15
-rw-r--r--src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/hmi_command_factory.cc4
-rw-r--r--src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/hmi/basic_communication_get_system_time_request_test.cc2
-rw-r--r--src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/hmi/on_service_status_update_notification_test.cc96
-rw-r--r--src/components/application_manager/src/application_manager_impl.cc65
-rw-r--r--src/components/application_manager/src/hmi_interfaces_impl.cc2
-rw-r--r--src/components/application_manager/src/message_helper/message_helper.cc43
-rw-r--r--src/components/application_manager/src/policies/policy_handler.cc50
-rw-r--r--src/components/application_manager/src/smart_object_keys.cc3
-rw-r--r--src/components/application_manager/src/system_time/system_time_handler_impl.cc15
-rw-r--r--src/components/application_manager/test/application_manager_impl_test.cc91
-rw-r--r--src/components/application_manager/test/help_prompt_manager_test.cc2
-rw-r--r--src/components/application_manager/test/include/application_manager/mock_message_helper.h7
-rwxr-xr-x[-rw-r--r--]src/components/application_manager/test/mock_message_helper.cc11
-rw-r--r--src/components/application_manager/test/policy_handler_test.cc6
-rw-r--r--src/components/include/application_manager/policies/policy_handler_interface.h11
-rw-r--r--src/components/include/application_manager/policies/policy_handler_observer.h12
-rw-r--r--src/components/include/policy/policy_external/policy/policy_listener.h4
-rw-r--r--src/components/include/policy/policy_external/policy/policy_manager.h7
-rw-r--r--src/components/include/policy/policy_regular/policy/policy_listener.h11
-rw-r--r--src/components/include/policy/policy_regular/policy/policy_manager.h9
-rw-r--r--src/components/include/protocol_handler/protocol_handler.h12
-rw-r--r--src/components/include/security_manager/security_manager.h18
-rw-r--r--src/components/include/security_manager/security_manager_listener.h17
-rw-r--r--src/components/include/test/application_manager/policies/mock_policy_handler_interface.h6
-rw-r--r--src/components/include/test/policy/policy_external/policy/mock_policy_listener.h3
-rw-r--r--src/components/include/test/policy/policy_external/policy/mock_policy_manager.h8
-rw-r--r--src/components/include/test/policy/policy_external/policy/mock_ptu_retry_handler.h48
-rw-r--r--src/components/include/test/policy/policy_regular/policy/mock_policy_listener.h5
-rw-r--r--src/components/include/test/policy/policy_regular/policy/mock_policy_manager.h6
-rw-r--r--src/components/include/test/protocol_handler/mock_protocol_handler.h6
-rw-r--r--src/components/include/test/security_manager/mock_security_manager.h7
-rw-r--r--src/components/include/test/security_manager/mock_security_manager_listener.h6
-rw-r--r--src/components/include/test/utils/mock_system_time_handler.h1
-rw-r--r--src/components/interfaces/HMI_API.xml96
-rw-r--r--src/components/policy/policy_external/include/policy/policy_manager_impl.h38
-rw-r--r--src/components/policy/policy_external/include/policy/policy_types.h2
-rw-r--r--src/components/policy/policy_external/include/policy/ptu_retry_handler.h57
-rw-r--r--src/components/policy/policy_external/src/policy_manager_impl.cc96
-rw-r--r--src/components/policy/policy_external/src/status.cc4
-rw-r--r--src/components/policy/policy_external/src/update_status_manager.cc9
-rw-r--r--src/components/policy/policy_external/test/include/policy/policy_manager_impl_test_base.h3
-rw-r--r--src/components/policy/policy_external/test/policy_manager_impl_test.cc48
-rw-r--r--src/components/policy/policy_external/test/policy_manager_impl_test_base.cc4
-rw-r--r--src/components/policy/policy_external/test/update_status_manager_test.cc44
-rw-r--r--src/components/policy/policy_regular/include/policy/policy_manager_impl.h8
-rw-r--r--src/components/policy/policy_regular/include/policy/policy_types.h4
-rw-r--r--src/components/policy/policy_regular/src/policy_manager_impl.cc51
-rw-r--r--src/components/policy/policy_regular/src/status.cc4
-rw-r--r--src/components/policy/policy_regular/test/policy_manager_impl_test.cc2
-rw-r--r--src/components/protocol_handler/CMakeLists.txt1
-rw-r--r--src/components/protocol_handler/docs/SDL.SDD.ServiceStatusUpdate.dox116
-rw-r--r--src/components/protocol_handler/docs/assets/PTU_for_EXTERNAL_PROPRIETARY.pngbin0 -> 95754 bytes
-rw-r--r--src/components/protocol_handler/docs/assets/ServiceStatusUpdate_classes.pngbin0 -> 429855 bytes
-rw-r--r--src/components/protocol_handler/docs/assets/ServiceStatusUpdate_sequence.pngbin0 -> 79236 bytes
-rw-r--r--src/components/protocol_handler/docs/assets/invalid_cert.pngbin0 -> 57118 bytes
-rw-r--r--src/components/protocol_handler/docs/assets/invalid_time.pngbin0 -> 52580 bytes
-rw-r--r--src/components/protocol_handler/docs/assets/ptu_failed.pngbin0 -> 34454 bytes
-rw-r--r--src/components/protocol_handler/include/protocol_handler/handshake_handler.h36
-rw-r--r--src/components/protocol_handler/include/protocol_handler/protocol_handler_impl.h37
-rw-r--r--src/components/protocol_handler/include/protocol_handler/service_status_update_handler.h89
-rw-r--r--src/components/protocol_handler/include/protocol_handler/service_status_update_handler_listener.h77
-rw-r--r--src/components/protocol_handler/src/handshake_handler.cc97
-rw-r--r--src/components/protocol_handler/src/protocol_handler_impl.cc124
-rw-r--r--src/components/protocol_handler/src/service_status_update_handler.cc117
-rw-r--r--src/components/protocol_handler/test/include/protocol_handler/mock_service_status_update_handler_listener.h57
-rw-r--r--src/components/protocol_handler/test/protocol_handler_tm_test.cc18
-rw-r--r--src/components/protocol_handler/test/service_status_update_handler_test.cc225
-rw-r--r--src/components/security_manager/include/security_manager/security_manager_impl.h23
-rw-r--r--src/components/security_manager/src/security_manager_impl.cc79
-rw-r--r--src/components/utils/include/utils/system_time_handler.h11
82 files changed, 2230 insertions, 205 deletions
diff --git a/Doxyfile b/Doxyfile
index 36155e37a7..8674bd3114 100644
--- a/Doxyfile
+++ b/Doxyfile
@@ -899,7 +899,8 @@ EXAMPLE_RECURSIVE = NO
# \image command).
IMAGE_PATH = \
- src/components/security_manager/docs/assets
+ src/components/security_manager/docs/assets \
+ src/components/protocol_handler/docs/assets
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
diff --git a/src/appMain/life_cycle_impl.cc b/src/appMain/life_cycle_impl.cc
index 10f0fc0d52..c903fb1a8a 100644
--- a/src/appMain/life_cycle_impl.cc
+++ b/src/appMain/life_cycle_impl.cc
@@ -103,6 +103,13 @@ bool LifeCycleImpl::StartComponents() {
app_manager_ =
new application_manager::ApplicationManagerImpl(profile_, profile_);
+ auto service_status_update_handler =
+ std::unique_ptr<protocol_handler::ServiceStatusUpdateHandler>(
+ new protocol_handler::ServiceStatusUpdateHandler(app_manager_));
+
+ protocol_handler_->set_service_status_update_handler(
+ std::move(service_status_update_handler));
+
DCHECK(!hmi_handler_);
hmi_handler_ = new hmi_message_handler::HMIMessageHandlerImpl(profile_);
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 a224d51a33..702f7a9a4d 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
@@ -58,6 +58,8 @@
#include "application_manager/rpc_service.h"
#include "application_manager/state_controller_impl.h"
+#include "application_manager/rpc_handler.h"
+
#include "application_manager/policies/policy_handler_interface.h"
#include "application_manager/policies/policy_handler_observer.h"
#include "connection_handler/connection_handler.h"
@@ -69,6 +71,7 @@
#include "policies/policy_handler.h"
#include "protocol_handler/protocol_handler.h"
#include "protocol_handler/protocol_observer.h"
+#include "protocol_handler/service_status_update_handler_listener.h"
#include "interfaces/HMI_API.h"
#include "interfaces/HMI_API_schema.h"
@@ -132,7 +135,8 @@ typedef std::shared_ptr<timer::Timer> TimerSPtr;
class ApplicationManagerImpl
: public ApplicationManager,
public connection_handler::ConnectionHandlerObserver,
- public policy::PolicyHandlerObserver
+ public policy::PolicyHandlerObserver,
+ public protocol_handler::ServiceStatusUpdateHandlerListener
#ifdef ENABLE_SECURITY
,
public security_manager::SecurityManagerListener
@@ -538,6 +542,50 @@ class ApplicationManagerImpl
*/
void OnPTUFinished(const bool ptu_result) FINAL;
+#if defined(EXTERNAL_PROPRIETARY_MODE) && defined(ENABLE_SECURITY)
+ /**
+ * @brief OnCertDecryptFailed is called when certificate decryption fails in
+ * external flow
+ * @return since this callback is a part of SecurityManagerListener, bool
+ * return value is used to indicate whether listener instance can be deleted
+ * by calling entity. if true - listener can be deleted and removed from
+ * listeners by SecurityManager, false - listener retains its place within
+ * SecurityManager.
+ */
+ bool OnCertDecryptFailed() FINAL;
+
+ /**
+ * @brief OnCertDecryptFinished is called when certificate decryption is
+ * finished in the external flow
+ * @param decrypt_result bool value indicating whether decryption was
+ * successful
+ */
+ void OnCertDecryptFinished(const bool decrypt_result) FINAL;
+#endif
+
+ /**
+ * @brief OnPTUTimeoutExceeded is called on policy table update timed out
+ */
+ void OnPTUTimeoutExceeded() FINAL;
+
+ /**
+ *@brief ProcessServiceStatusUpdate callback that is invoked in case of
+ *service status update
+ *@param connection_key - connection key
+ *@param service_type enum value containing type of service.
+ *@param service_event enum value containing event that occured during service
+ *start.
+ *@param service_update_reason enum value containing reason why service_event
+ *occured.
+ **/
+ void ProcessServiceStatusUpdate(
+ const uint32_t connection_key,
+ hmi_apis::Common_ServiceType::eType service_type,
+ hmi_apis::Common_ServiceEvent::eType service_event,
+ utils::Optional<hmi_apis::Common_ServiceStatusUpdateReason::eType>
+ service_update_reason) FINAL;
+
+ bool OnPTUFailed() FINAL;
/*
* @brief Starts audio pass thru thread
*
@@ -657,7 +705,7 @@ class ApplicationManagerImpl
* @brief Notification about handshake failure
* @return true on success notification handling or false otherwise
*/
- bool OnHandshakeFailed() OVERRIDE;
+ bool OnGetSystemTimeFailed() OVERRIDE;
/**
* @brief Notification that certificate update is required.
diff --git a/src/components/application_manager/include/application_manager/message_helper.h b/src/components/application_manager/include/application_manager/message_helper.h
index 8f05b523b3..aff4659323 100644
--- a/src/components/application_manager/include/application_manager/message_helper.h
+++ b/src/components/application_manager/include/application_manager/message_helper.h
@@ -89,10 +89,18 @@ class MessageHelper {
static smart_objects::SmartObjectSPtr CreateHMINotification(
hmi_apis::FunctionID::eType function_id);
+ static smart_objects::SmartObjectSPtr CreateOnServiceUpdateNotification(
+ const hmi_apis::Common_ServiceType::eType type,
+ const hmi_apis::Common_ServiceEvent::eType event,
+ const hmi_apis::Common_ServiceStatusUpdateReason::eType reason =
+ hmi_apis::Common_ServiceStatusUpdateReason::INVALID_ENUM,
+ const uint32_t app_id = 0);
+
/**
* @brief Creates request for different interfaces(JSON)
* @param correlation_id unique ID
- * @param params Vector of arguments that we need in GetVehicleData request
+ * @param params Vector of arguments that we need in GetVehicleData
+ * request
* (e.g. gps, odometer, fuel_level)
*/
static void CreateGetVehicleDataRequest(
diff --git a/src/components/application_manager/include/application_manager/policies/policy_handler.h b/src/components/application_manager/include/application_manager/policies/policy_handler.h
index dddd1b333d..5ddac88dd9 100644
--- a/src/components/application_manager/include/application_manager/policies/policy_handler.h
+++ b/src/components/application_manager/include/application_manager/policies/policy_handler.h
@@ -103,8 +103,11 @@ class PolicyHandler : public PolicyHandlerInterface,
void OnSnapshotCreated(const BinaryMessage& pt_string,
const std::vector<int>& retry_delay_seconds,
uint32_t timeout_exchange) OVERRIDE;
+
+ PTURetryHandler& ptu_retry_handler() const OVERRIDE;
#else // EXTERNAL_PROPRIETARY_MODE
- void OnSnapshotCreated(const BinaryMessage& pt_string) OVERRIDE;
+ void OnSnapshotCreated(const BinaryMessage& pt_string,
+ const PTUIterationType iteration_type) OVERRIDE;
#endif // EXTERNAL_PROPRIETARY_MODE
virtual bool GetPriority(const std::string& policy_app_id,
std::string* priority) const OVERRIDE;
@@ -176,6 +179,9 @@ class PolicyHandler : public PolicyHandlerInterface,
const std::string& policy_app_id,
const std::string& hmi_level) OVERRIDE;
+#ifndef EXTERNAL_PROPRIETARY_MODE
+ void OnPTUTimeOut() OVERRIDE;
+#endif
/**
* Gets all allowed module types
* @param app_id unique identifier of application
@@ -456,9 +462,12 @@ class PolicyHandler : public PolicyHandlerInterface,
std::string& cloud_transport_type,
std::string& hybrid_app_preference) const OVERRIDE;
+ void OnAuthTokenUpdated(const std::string& policy_app_id,
+ const std::string& auth_token) OVERRIDE;
+
/**
- * @brief Callback for when a SetCloudAppProperties message is received from a
- * mobile app
+ * @brief Callback for when a SetCloudAppProperties message is received
+ * from a mobile app
* @param message The SetCloudAppProperties message
*/
void OnSetCloudAppProperties(
@@ -502,11 +511,11 @@ class PolicyHandler : public PolicyHandlerInterface,
virtual void OnCertificateUpdated(
const std::string& certificate_data) OVERRIDE;
+
#ifdef EXTERNAL_PROPRIETARY_MODE
void OnCertificateDecrypted(bool is_succeeded) OVERRIDE;
+ void ProcessCertDecryptFailed();
#endif // EXTERNAL_PROPRIETARY_MODE
- void OnAuthTokenUpdated(const std::string& policy_app_id,
- const std::string& auth_token);
virtual bool CanUpdate() OVERRIDE;
diff --git a/src/components/application_manager/include/application_manager/policies/regular/policy_handler_observer.h b/src/components/application_manager/include/application_manager/policies/regular/policy_handler_observer.h
index 3c4dce2fbc..fdfed698c4 100644
--- a/src/components/application_manager/include/application_manager/policies/regular/policy_handler_observer.h
+++ b/src/components/application_manager/include/application_manager/policies/regular/policy_handler_observer.h
@@ -53,6 +53,8 @@ class PolicyHandlerObserver {
virtual void OnPTUFinished(const bool ptu_result) {}
+ virtual void OnPTUTimeoutExceeded() {}
+
virtual ~PolicyHandlerObserver() {}
};
} // namespace policy
diff --git a/src/components/application_manager/include/application_manager/smart_object_keys.h b/src/components/application_manager/include/application_manager/smart_object_keys.h
index 1d13417fa1..b3ca00013a 100644
--- a/src/components/application_manager/include/application_manager/smart_object_keys.h
+++ b/src/components/application_manager/include/application_manager/smart_object_keys.h
@@ -616,6 +616,9 @@ extern const char* policyfile;
extern const char* is_active;
extern const char* is_deactivated;
extern const char* event_name;
+extern const char* service_type;
+extern const char* service_event;
+extern const char* reason;
} // namespace hmi_notification
diff --git a/src/components/application_manager/include/application_manager/system_time/system_time_handler_impl.h b/src/components/application_manager/include/application_manager/system_time/system_time_handler_impl.h
index 46aa98e6c1..a8ba796a1b 100644
--- a/src/components/application_manager/include/application_manager/system_time/system_time_handler_impl.h
+++ b/src/components/application_manager/include/application_manager/system_time/system_time_handler_impl.h
@@ -130,6 +130,12 @@ class SystemTimeHandlerImpl : public utils::SystemTimeHandler,
void ProcessSystemTimeReadyNotification();
/**
+ * @brief ResetPendingSystemTimeRequests resets waiting for system time
+ * requests flag
+ */
+ void ResetPendingSystemTimeRequests() OVERRIDE;
+
+ /**
* @brief Checks if UTC time is ready to provided by HMI
* and can be requested by GetSystemTime request
* @return True if HMI is ready to provide UTC time
diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/on_service_update_notification.h b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/on_service_update_notification.h
new file mode 100644
index 0000000000..bfa9b6e6ae
--- /dev/null
+++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/on_service_update_notification.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2019, 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_RPC_PLUGINS_SDL_RPC_PLUGIN_INCLUDE_SDL_RPC_PLUGIN_COMMANDS_HMI_ON_SERVICE_UPDATE_NOTIFICATION_H_
+#define SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_SDL_RPC_PLUGIN_INCLUDE_SDL_RPC_PLUGIN_COMMANDS_HMI_ON_SERVICE_UPDATE_NOTIFICATION_H_
+
+#include "application_manager/commands/notification_to_hmi.h"
+
+namespace sdl_rpc_plugin {
+namespace app_mngr = application_manager;
+
+namespace commands {
+namespace hmi {
+
+/**
+ * @brief OnServiceUpdateNotification command class
+ **/
+class OnServiceUpdateNotification
+ : public app_mngr::commands::NotificationToHMI {
+ public:
+ /**
+ * @brief OnServiceUpdateNotification class constructor
+ * @param application_manager ref to application manager
+ * @param rpc_service ref to rpc service
+ * @param hmi_capabilities ref to HMI capabilities
+ * @param policy_handle ref to policy handler
+ **/
+ OnServiceUpdateNotification(
+ const app_mngr::commands::MessageSharedPtr& message,
+ app_mngr::ApplicationManager& application_manager,
+ app_mngr::rpc_service::RPCService& rpc_service,
+ app_mngr::HMICapabilities& hmi_capabilities,
+ policy::PolicyHandlerInterface& policy_handler);
+
+ /**
+ * @brief OnServiceUpdateNotification class destructor
+ **/
+ virtual ~OnServiceUpdateNotification() OVERRIDE;
+
+ /**
+ * @brief Execute command
+ **/
+ void Run() OVERRIDE;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(OnServiceUpdateNotification);
+};
+
+} // namespace hmi
+} // namespace commands
+} // namespace sdl_rpc_plugin
+
+#endif // SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_SDL_RPC_PLUGIN_INCLUDE_SDL_RPC_PLUGIN_COMMANDS_HMI_ON_SERVICE_UPDATE_NOTIFICATION_H_
diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/basic_communication_get_system_time_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/basic_communication_get_system_time_request.cc
index fb87612e19..19c9fa91d8 100644
--- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/basic_communication_get_system_time_request.cc
+++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/basic_communication_get_system_time_request.cc
@@ -51,7 +51,7 @@ BasicCommunicationGetSystemTimeRequest::BasicCommunicationGetSystemTimeRequest(
void BasicCommunicationGetSystemTimeRequest::onTimeOut() {
LOG4CXX_AUTO_TRACE(logger_);
- application_manager_.protocol_handler().NotifyOnFailedHandshake();
+ application_manager_.protocol_handler().NotifyOnGetSystemTimeFailed();
}
} // namespace commands
diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/on_service_update_notification.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/on_service_update_notification.cc
new file mode 100644
index 0000000000..de03b75214
--- /dev/null
+++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/on_service_update_notification.cc
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2019, 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 "sdl_rpc_plugin/commands/hmi/on_service_update_notification.h"
+
+namespace sdl_rpc_plugin {
+using namespace application_manager;
+
+namespace commands {
+
+namespace hmi {
+
+OnServiceUpdateNotification::OnServiceUpdateNotification(
+ const application_manager::commands::MessageSharedPtr& message,
+ ApplicationManager& application_manager,
+ rpc_service::RPCService& rpc_service,
+ HMICapabilities& hmi_capabilities,
+ policy::PolicyHandlerInterface& policy_handler)
+ : NotificationToHMI(message,
+ application_manager,
+ rpc_service,
+ hmi_capabilities,
+ policy_handler) {}
+
+OnServiceUpdateNotification::~OnServiceUpdateNotification() {}
+
+void OnServiceUpdateNotification::Run() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ SendNotification();
+}
+
+} // namespace hmi
+} // namespace commands
+} // namespace sdl_rpc_plugin
diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/on_system_request_notification.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/on_system_request_notification.cc
index a9670681b2..6d95febe71 100644
--- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/on_system_request_notification.cc
+++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/on_system_request_notification.cc
@@ -37,6 +37,10 @@
#include "sdl_rpc_plugin/commands/hmi/on_system_request_notification.h"
#include "utils/macro.h"
+#ifdef EXTERNAL_PROPRIETARY_MODE
+#include "policy/ptu_retry_handler.h"
+#endif // EXTERNAL_PROPRIETARY_MODE
+
using policy::PolicyHandlerInterface;
namespace sdl_rpc_plugin {
@@ -116,6 +120,17 @@ void OnSystemRequestNotification::Run() {
"Sending request with application id " << app->policy_app_id());
params[strings::connection_key] = app->app_id();
+
+#ifdef EXTERNAL_PROPRIETARY_MODE
+ using namespace rpc::policy_table_interface_base;
+ const auto request_type =
+ static_cast<rpc::policy_table_interface_base::RequestType>(
+ (*message_)[strings::msg_params][strings::request_type].asUInt());
+
+ if (RequestType::RT_PROPRIETARY == request_type) {
+ policy_handler_.ptu_retry_handler().OnSystemRequestReceived();
+ }
+#endif
SendNotificationToMobile(message_);
}
diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/hmi_command_factory.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/hmi_command_factory.cc
index 27768e8a31..a0dee162dd 100644
--- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/hmi_command_factory.cc
+++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/hmi_command_factory.cc
@@ -247,6 +247,7 @@
#include "sdl_rpc_plugin/commands/hmi/bc_get_file_path_request.h"
#include "sdl_rpc_plugin/commands/hmi/bc_get_file_path_response.h"
+#include "sdl_rpc_plugin/commands/hmi/on_service_update_notification.h"
#include "sdl_rpc_plugin/commands/hmi/rc_get_capabilities_request.h"
#include "sdl_rpc_plugin/commands/hmi/rc_get_capabilities_response.h"
#include "sdl_rpc_plugin/commands/hmi/rc_is_ready_request.h"
@@ -866,6 +867,9 @@ CommandCreator& HMICommandFactory::get_creator_factory(
? factory.GetCreator<commands::hmi::DialNumberRequest>()
: factory.GetCreator<commands::hmi::DialNumberResponse>();
}
+ case hmi_apis::FunctionID::BasicCommunication_OnServiceUpdate: {
+ return factory.GetCreator<commands::hmi::OnServiceUpdateNotification>();
+ }
case hmi_apis::FunctionID::Navigation_OnWayPointChange: {
return factory.GetCreator<commands::OnNaviWayPointChangeNotification>();
}
diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/hmi/basic_communication_get_system_time_request_test.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/hmi/basic_communication_get_system_time_request_test.cc
index 0251c4873d..9cd87b053d 100644
--- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/hmi/basic_communication_get_system_time_request_test.cc
+++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/hmi/basic_communication_get_system_time_request_test.cc
@@ -60,7 +60,7 @@ TEST_F(BasicCommunicationGetSystemTimeRequestTest, OnTimeout) {
ON_CALL(app_mngr_, protocol_handler())
.WillByDefault(ReturnRef(mock_protocol_handler));
- EXPECT_CALL(mock_protocol_handler, NotifyOnFailedHandshake());
+ EXPECT_CALL(mock_protocol_handler, NotifyOnGetSystemTimeFailed());
command->onTimeOut();
}
diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/hmi/on_service_status_update_notification_test.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/hmi/on_service_status_update_notification_test.cc
new file mode 100644
index 0000000000..a9bc97f842
--- /dev/null
+++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/hmi/on_service_status_update_notification_test.cc
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2019, 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 <stdint.h>
+
+#include "application_manager/commands/commands_test.h"
+#include "application_manager/mock_application.h"
+#include "application_manager/mock_application_manager.h"
+#include "application_manager/smart_object_keys.h"
+#include "gtest/gtest.h"
+#include "hmi/on_service_update_notification.h"
+#include "smart_objects/smart_object.h"
+
+namespace test {
+namespace components {
+namespace commands_test {
+namespace hmi_commands_test {
+namespace on_service_update_notification {
+
+using namespace application_manager;
+using sdl_rpc_plugin::commands::hmi::OnServiceUpdateNotification;
+
+typedef std::shared_ptr<OnServiceUpdateNotification> NotificationPtr;
+typedef hmi_apis::Common_ServiceType::eType ServiceType;
+typedef hmi_apis::Common_ServiceEvent::eType ServiceEvent;
+
+namespace {
+const uint32_t kConnectionKey = 1232u;
+const uint32_t kHmi_app_id = 321u;
+} // namespace
+
+class OnServiceUpdateNotificationTest
+ : public CommandsTest<CommandsTestMocks::kIsNice> {
+ public:
+ OnServiceUpdateNotificationTest()
+ : message_(CreateMessage(smart_objects::SmartType_Map)) {}
+
+ public:
+ MessageSharedPtr message_;
+ NotificationPtr command_;
+};
+
+TEST_F(OnServiceUpdateNotificationTest, SendNotificationToHMI) {
+ (*message_)[strings::msg_params][hmi_notification::service_type] =
+ ServiceType::AUDIO;
+ (*message_)[strings::msg_params][hmi_notification::service_event] =
+ ServiceEvent::REQUEST_ACCEPTED;
+ (*message_)[strings::msg_params][strings::app_id] = kConnectionKey;
+ command_ = CreateCommand<OnServiceUpdateNotification>(message_);
+
+ EXPECT_CALL(mock_rpc_service_, SendMessageToHMI(message_)).Times(1);
+
+ auto mock_app = std::make_shared<NiceMock<MockApplication> >();
+
+ ON_CALL(app_mngr_, application(kConnectionKey))
+ .WillByDefault(Return(mock_app));
+
+ ON_CALL(*mock_app, hmi_app_id()).WillByDefault(Return(kHmi_app_id));
+
+ command_->Init();
+ command_->Run();
+}
+
+} // namespace on_service_update_notification
+} // namespace hmi_commands_test
+} // namespace commands_test
+} // namespace components
+} // namespace test
diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc
index 3829005047..94e67a0c80 100644
--- a/src/components/application_manager/src/application_manager_impl.cc
+++ b/src/components/application_manager/src/application_manager_impl.cc
@@ -1917,7 +1917,7 @@ void ApplicationManagerImpl::OnServiceStartedCallback(
"ServiceType = " << type << ". Session = " << std::hex << session_key);
std::vector<std::string> empty;
- if (type == kRpc) {
+ if (kRpc == type) {
LOG4CXX_DEBUG(logger_, "RPC service is about to be started.");
connection_handler().NotifyServiceStartedResult(session_key, true, empty);
return;
@@ -1944,6 +1944,7 @@ void ApplicationManagerImpl::OnServiceStartedCallback(
} else {
LOG4CXX_WARN(logger_, "Refuse unknown service");
}
+
connection_handler().NotifyServiceStartedResult(session_key, false, empty);
}
@@ -2026,6 +2027,34 @@ void ApplicationManagerImpl::OnServiceEndedCallback(
}
}
+void ApplicationManagerImpl::ProcessServiceStatusUpdate(
+ const uint32_t connection_key,
+ hmi_apis::Common_ServiceType::eType service_type,
+ hmi_apis::Common_ServiceEvent::eType service_event,
+ utils::Optional<hmi_apis::Common_ServiceStatusUpdateReason::eType>
+ service_update_reason) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ LOG4CXX_DEBUG(logger_,
+ "Processing status update with connection key: "
+ << connection_key << " service type: " << service_type
+ << " service_event " << service_event
+ << " service_update_reason " << service_update_reason);
+
+ const auto app = application(connection_key);
+
+ const uint32_t app_id = app ? app->app_id() : 0u;
+
+ auto reason = service_update_reason
+ ? *service_update_reason
+ : hmi_apis::Common_ServiceStatusUpdateReason::INVALID_ENUM;
+
+ auto notification = MessageHelper::CreateOnServiceUpdateNotification(
+ service_type, service_event, reason, app_id);
+
+ rpc_service_->ManageHMICommand(notification);
+}
+
void ApplicationManagerImpl::OnSecondaryTransportStartedCallback(
const connection_handler::DeviceHandle device_handle,
const int32_t session_key) {
@@ -2118,7 +2147,12 @@ bool ApplicationManagerImpl::OnHandshakeDone(
using namespace helpers;
ApplicationSharedPtr app = application(connection_key);
- DCHECK_OR_RETURN(app, false);
+ if (!app) {
+ LOG4CXX_WARN(logger_,
+ "Application for connection key: " << connection_key
+ << " was not found");
+ return false;
+ }
if (Compare<SSLContext::HandshakeResult, EQ, ONE>(
result,
SSLContext::Handshake_Result_CertExpired,
@@ -2131,7 +2165,12 @@ bool ApplicationManagerImpl::OnHandshakeDone(
return false;
}
-bool ApplicationManagerImpl::OnHandshakeFailed() {
+bool ApplicationManagerImpl::OnPTUFailed() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ return false;
+}
+
+bool ApplicationManagerImpl::OnGetSystemTimeFailed() {
LOG4CXX_AUTO_TRACE(logger_);
return false;
}
@@ -3889,6 +3928,7 @@ void ApplicationManagerImpl::ProcessReconnection(
void ApplicationManagerImpl::OnPTUFinished(const bool ptu_result) {
LOG4CXX_AUTO_TRACE(logger_);
if (!ptu_result) {
+ protocol_handler_->ProcessFailedPTU();
return;
}
@@ -3907,6 +3947,25 @@ void ApplicationManagerImpl::OnPTUFinished(const bool ptu_result) {
plugin_manager_->ForEachPlugin(on_app_policy_updated);
}
+#if defined(EXTERNAL_PROPRIETARY_MODE) && defined(ENABLE_SECURITY)
+void ApplicationManagerImpl::OnCertDecryptFinished(const bool decrypt_result) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (!decrypt_result) {
+ protocol_handler_->ProcessFailedCertDecrypt();
+ }
+}
+
+bool ApplicationManagerImpl::OnCertDecryptFailed() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ return false;
+}
+#endif
+
+void ApplicationManagerImpl::OnPTUTimeoutExceeded() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ protocol_handler_->ProcessFailedPTU();
+}
+
void ApplicationManagerImpl::SendDriverDistractionState(
ApplicationSharedPtr application) {
LOG4CXX_AUTO_TRACE(logger_);
diff --git a/src/components/application_manager/src/hmi_interfaces_impl.cc b/src/components/application_manager/src/hmi_interfaces_impl.cc
index f1f8660217..64ec2374a9 100644
--- a/src/components/application_manager/src/hmi_interfaces_impl.cc
+++ b/src/components/application_manager/src/hmi_interfaces_impl.cc
@@ -103,6 +103,8 @@ generate_function_to_interface_convert_map() {
HmiInterfaces::HMI_INTERFACE_BasicCommunication;
convert_map[BasicCommunication_OnEventChanged] =
HmiInterfaces::HMI_INTERFACE_BasicCommunication;
+ convert_map[BasicCommunication_OnServiceUpdate] =
+ HmiInterfaces::HMI_INTERFACE_BasicCommunication;
convert_map[BasicCommunication_GetFilePath] =
HmiInterfaces::HMI_INTERFACE_BasicCommunication;
convert_map[BasicCommunication_CloseApplication] =
diff --git a/src/components/application_manager/src/message_helper/message_helper.cc b/src/components/application_manager/src/message_helper/message_helper.cc
index e2ed3fa820..31eaa54e5d 100644
--- a/src/components/application_manager/src/message_helper/message_helper.cc
+++ b/src/components/application_manager/src/message_helper/message_helper.cc
@@ -2234,6 +2234,34 @@ smart_objects::SmartObjectSPtr MessageHelper::CreateNegativeResponse(
return std::make_shared<smart_objects::SmartObject>(response_data);
}
+smart_objects::SmartObjectSPtr MessageHelper::CreateOnServiceUpdateNotification(
+ const hmi_apis::Common_ServiceType::eType service_type,
+ const hmi_apis::Common_ServiceEvent::eType service_event,
+ const hmi_apis::Common_ServiceStatusUpdateReason::eType
+ service_update_reason,
+ const uint32_t app_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ auto notification = MessageHelper::CreateHMINotification(
+ hmi_apis::FunctionID::BasicCommunication_OnServiceUpdate);
+
+ (*notification)[strings::msg_params][hmi_notification::service_type] =
+ service_type;
+ (*notification)[strings::msg_params][hmi_notification::service_event] =
+ service_event;
+
+ if (0 != app_id) {
+ (*notification)[strings::msg_params][strings::app_id] = app_id;
+ }
+
+ if (hmi_apis::Common_ServiceStatusUpdateReason::INVALID_ENUM !=
+ service_update_reason) {
+ (*notification)[strings::msg_params][hmi_notification::reason] =
+ service_update_reason;
+ }
+
+ return notification;
+}
+
void MessageHelper::SendNaviSetVideoConfig(
int32_t app_id,
ApplicationManager& app_mngr,
@@ -2430,6 +2458,14 @@ void MessageHelper::SendPolicySnapshotNotification(
const std::string& url,
ApplicationManager& app_mngr) {
smart_objects::SmartObject content(smart_objects::SmartType_Map);
+ const auto request_type =
+#if defined(PROPRIETARY_MODE) || defined(EXTERNAL_PROPRIETARY_MODE)
+ mobile_apis::RequestType::PROPRIETARY;
+#else
+ mobile_apis::RequestType::HTTP;
+#endif // PROPRIETARY || EXTERNAL_PROPRIETARY_MODE
+
+ content[strings::msg_params][strings::request_type] = request_type;
if (!url.empty()) {
content[strings::msg_params][strings::url] =
@@ -2440,13 +2476,6 @@ void MessageHelper::SendPolicySnapshotNotification(
content[strings::params][strings::binary_data] =
smart_objects::SmartObject(policy_data);
-#if defined(PROPRIETARY_MODE) || defined(EXTERNAL_PROPRIETARY_MODE)
- content[strings::msg_params][strings::request_type] =
- mobile_apis::RequestType::PROPRIETARY;
-#else
- content[strings::msg_params][strings::request_type] =
- mobile_apis::RequestType::HTTP;
-#endif // PROPRIETARY || EXTERNAL_PROPRIETARY_MODE
SendSystemRequestNotification(connection_key, content, app_mngr);
}
diff --git a/src/components/application_manager/src/policies/policy_handler.cc b/src/components/application_manager/src/policies/policy_handler.cc
index 1bad50b34f..c3b4520613 100644
--- a/src/components/application_manager/src/policies/policy_handler.cc
+++ b/src/components/application_manager/src/policies/policy_handler.cc
@@ -58,6 +58,9 @@
#include "policy/policy_manager.h"
#include "utils/helpers.h"
+#ifdef EXTERNAL_PROPRIETARY_MODE
+#include "policy/ptu_retry_handler.h"
+#endif // EXTERNAL_PROPRIETARY_MODE
namespace policy {
@@ -443,6 +446,11 @@ uint32_t PolicyHandler::GetAppIdForSending() const {
}
#ifdef EXTERNAL_PROPRIETARY_MODE
+PTURetryHandler& PolicyHandler::ptu_retry_handler() const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ return *policy_manager_;
+}
+
void PolicyHandler::OnAppPermissionConsent(
const uint32_t connection_key,
const PermissionConsent& permissions,
@@ -1461,6 +1469,11 @@ void PolicyHandler::OnPermissionsUpdated(const std::string& device_id,
<< policy_app_id << " and connection_key "
<< app->app_id());
}
+#ifndef EXTERNAL_PROPRIETARY_MODE
+void PolicyHandler::OnPTUTimeOut() {
+ application_manager_.protocol_handler().ProcessFailedPTU();
+}
+#endif
bool PolicyHandler::SaveSnapshot(const BinaryMessage& pt_string,
std::string& snap_path) {
@@ -1497,7 +1510,8 @@ void PolicyHandler::OnSnapshotCreated(
}
}
#else // EXTERNAL_PROPRIETARY_MODE
-void PolicyHandler::OnSnapshotCreated(const BinaryMessage& pt_string) {
+void PolicyHandler::OnSnapshotCreated(const BinaryMessage& pt_string,
+ const PTUIterationType iteration_type) {
LOG4CXX_AUTO_TRACE(logger_);
POLICY_LIB_CHECK_VOID();
#ifdef PROPRIETARY_MODE
@@ -1506,10 +1520,17 @@ void PolicyHandler::OnSnapshotCreated(const BinaryMessage& pt_string) {
LOG4CXX_ERROR(logger_, "Snapshot processing skipped.");
return;
}
- MessageHelper::SendPolicyUpdate(policy_snapshot_full_path,
- TimeoutExchangeSec(),
- policy_manager_->RetrySequenceDelaysSeconds(),
- application_manager_);
+
+ if (PTUIterationType::RetryIteration == iteration_type) {
+ MessageHelper::SendPolicySnapshotNotification(
+ GetAppIdForSending(), pt_string, std::string(""), application_manager_);
+ } else {
+ MessageHelper::SendPolicyUpdate(
+ policy_snapshot_full_path,
+ TimeoutExchangeSec(),
+ policy_manager_->RetrySequenceDelaysSeconds(),
+ application_manager_);
+ }
#else // PROPRIETARY_MODE
LOG4CXX_ERROR(logger_, "HTTP policy");
EndpointUrls urls;
@@ -1629,7 +1650,13 @@ uint32_t PolicyHandler::TimeoutExchangeMSec() const {
}
void PolicyHandler::OnExceededTimeout() {
+ LOG4CXX_AUTO_TRACE(logger_);
POLICY_LIB_CHECK_VOID();
+
+ std::for_each(listeners_.begin(),
+ listeners_.end(),
+ std::mem_fn(&PolicyHandlerObserver::OnPTUTimeoutExceeded));
+
policy_manager_->OnExceededTimeout();
}
@@ -1787,6 +1814,7 @@ void PolicyHandler::OnCertificateDecrypted(bool is_succeeded) {
if (!is_succeeded) {
LOG4CXX_ERROR(logger_, "Couldn't delete file " << file_name);
+ ProcessCertDecryptFailed();
return;
}
@@ -1809,6 +1837,18 @@ void PolicyHandler::OnCertificateDecrypted(bool is_succeeded) {
std::bind2nd(std::mem_fun(&PolicyHandlerObserver::OnCertificateUpdated),
certificate_data));
}
+
+void PolicyHandler::ProcessCertDecryptFailed() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock lock(listeners_lock_);
+
+ std::for_each(
+ listeners_.begin(),
+ listeners_.end(),
+ std::bind2nd(std::mem_fn(&PolicyHandlerObserver::OnCertDecryptFinished),
+ false));
+}
+
#else // EXTERNAL_PROPRIETARY_MODE
void PolicyHandler::OnCertificateUpdated(const std::string& certificate_data) {
LOG4CXX_AUTO_TRACE(logger_);
diff --git a/src/components/application_manager/src/smart_object_keys.cc b/src/components/application_manager/src/smart_object_keys.cc
index 2efc04a767..e67c87a234 100644
--- a/src/components/application_manager/src/smart_object_keys.cc
+++ b/src/components/application_manager/src/smart_object_keys.cc
@@ -573,6 +573,9 @@ const char* policyfile = "policyfile";
const char* is_active = "isActive";
const char* is_deactivated = "isDeactivated";
const char* event_name = "eventName";
+const char* service_type = "serviceType";
+const char* service_event = "serviceEvent";
+const char* reason = "reason";
} // namespace hmi_notification
} // namespace application_manager
diff --git a/src/components/application_manager/src/system_time/system_time_handler_impl.cc b/src/components/application_manager/src/system_time/system_time_handler_impl.cc
index f5d08a8ebf..deb92d5d81 100644
--- a/src/components/application_manager/src/system_time/system_time_handler_impl.cc
+++ b/src/components/application_manager/src/system_time/system_time_handler_impl.cc
@@ -82,6 +82,13 @@ void SystemTimeHandlerImpl::DoSubscribe(utils::SystemTimeListener* listener) {
system_time_listener_ = listener;
}
+void SystemTimeHandlerImpl::ResetPendingSystemTimeRequests() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ unsubscribe_from_event(
+ hmi_apis::FunctionID::BasicCommunication_GetSystemTime);
+ awaiting_get_system_time_ = false;
+}
+
void SystemTimeHandlerImpl::DoUnsubscribe(utils::SystemTimeListener* listener) {
LOG4CXX_AUTO_TRACE(logger_);
sync_primitives::AutoLock lock(system_time_listener_lock_);
@@ -145,6 +152,14 @@ void SystemTimeHandlerImpl::ProcessSystemTimeResponse(
const application_manager::event_engine::Event& event) {
LOG4CXX_AUTO_TRACE(logger_);
const smart_objects::SmartObject& message = event.smart_object();
+
+ const auto result = static_cast<hmi_apis::Common_Result::eType>(
+ message[strings::params][hmi_response::code].asInt());
+
+ if (hmi_apis::Common_Result::SUCCESS != result) {
+ system_time_listener_->OnSystemTimeFailed();
+ }
+
const smart_objects::SmartObject& system_time_so =
message[strings::msg_params][hmi_response::system_time];
diff --git a/src/components/application_manager/test/application_manager_impl_test.cc b/src/components/application_manager/test/application_manager_impl_test.cc
index 1f0b705f41..bb87d71a48 100644
--- a/src/components/application_manager/test/application_manager_impl_test.cc
+++ b/src/components/application_manager/test/application_manager_impl_test.cc
@@ -105,6 +105,12 @@ const std::string kAppName = "appName";
const WindowID kDefaultWindowId =
mobile_apis::PredefinedWindows::DEFAULT_WINDOW;
+typedef hmi_apis::Common_ServiceStatusUpdateReason::eType
+ ServiceStatusUpdateReason;
+typedef hmi_apis::Common_ServiceType::eType ServiceType;
+typedef hmi_apis::Common_ServiceEvent::eType ServiceEvent;
+typedef utils::Optional<ServiceStatusUpdateReason> UpdateReasonOptional;
+
#if defined(CLOUD_APP_WEBSOCKET_TRANSPORT_SUPPORT)
// Cloud application params
const std::string kEndpoint = "endpoint";
@@ -119,7 +125,20 @@ const bool kEnabled = true;
#endif // CLOUD_APP_WEBSOCKET_TRANSPORT_SUPPORT
} // namespace
-class ApplicationManagerImplTest : public ::testing::Test {
+struct ServiceStatus {
+ ServiceType service_type_;
+ ServiceEvent service_event_;
+ UpdateReasonOptional reason_;
+
+ ServiceStatus(ServiceType type,
+ ServiceEvent event,
+ UpdateReasonOptional reason)
+ : service_type_(type), service_event_(event), reason_(reason) {}
+};
+
+class ApplicationManagerImplTest
+ : public ::testing::Test,
+ public ::testing::WithParamInterface<ServiceStatus> {
public:
ApplicationManagerImplTest()
: app_id_(0u)
@@ -149,10 +168,13 @@ class ApplicationManagerImplTest : public ::testing::Test {
CreateAppManager();
ON_CALL(*mock_app_ptr_, app_id()).WillByDefault(Return(kConnectionKey));
ON_CALL(*mock_app_ptr_, device()).WillByDefault(Return(kDeviceId));
+ ON_CALL(mock_session_observer_, GetDataOnSessionKey(_, _, _, _))
+ .WillByDefault(DoAll(SetArgPointee<3u>(kDeviceId), Return(0)));
ON_CALL(mock_connection_handler_, GetDataOnSessionKey(_, _, _, &kDeviceId))
.WillByDefault(DoAll(SetArgPointee<3u>(app_id_), Return(0)));
ON_CALL(mock_connection_handler_, get_session_observer())
.WillByDefault(ReturnRef(mock_session_observer_));
+
app_manager_impl_->SetMockRPCService(mock_rpc_service_);
app_manager_impl_->resume_controller().set_resumption_storage(
mock_storage_);
@@ -255,6 +277,72 @@ class ApplicationManagerImplTest : public ::testing::Test {
NiceMock<protocol_handler_test::MockProtocolHandler> mock_protocol_handler_;
};
+INSTANTIATE_TEST_CASE_P(
+ ProcessServiceStatusUpdate_REQUEST_ACCEPTED,
+ ApplicationManagerImplTest,
+ ::testing::Values(ServiceStatus(ServiceType::AUDIO,
+ ServiceEvent::REQUEST_ACCEPTED,
+ UpdateReasonOptional::EMPTY),
+ ServiceStatus(ServiceType::VIDEO,
+ ServiceEvent::REQUEST_ACCEPTED,
+ UpdateReasonOptional::EMPTY),
+ ServiceStatus(ServiceType::RPC,
+ ServiceEvent::REQUEST_ACCEPTED,
+ UpdateReasonOptional::EMPTY)));
+
+INSTANTIATE_TEST_CASE_P(
+ ProcessServiceStatusUpdate_REQUEST_RECEIVED,
+ ApplicationManagerImplTest,
+ ::testing::Values(ServiceStatus(ServiceType::AUDIO,
+ ServiceEvent::REQUEST_RECEIVED,
+ UpdateReasonOptional::EMPTY),
+ ServiceStatus(ServiceType::VIDEO,
+ ServiceEvent::REQUEST_RECEIVED,
+ UpdateReasonOptional::EMPTY),
+ ServiceStatus(ServiceType::RPC,
+ ServiceEvent::REQUEST_RECEIVED,
+ UpdateReasonOptional::EMPTY)));
+
+INSTANTIATE_TEST_CASE_P(
+ ProcessServiceStatusUpdate_REQUEST_REJECTED,
+ ApplicationManagerImplTest,
+ ::testing::Values(ServiceStatus(ServiceType::AUDIO,
+ ServiceEvent::REQUEST_REJECTED,
+ UpdateReasonOptional::EMPTY),
+ ServiceStatus(ServiceType::VIDEO,
+ ServiceEvent::REQUEST_REJECTED,
+ UpdateReasonOptional::EMPTY),
+ ServiceStatus(ServiceType::RPC,
+ ServiceEvent::REQUEST_REJECTED,
+ UpdateReasonOptional::EMPTY)));
+
+TEST_P(ApplicationManagerImplTest,
+ ProcessServiceStatusUpdate_SendMessageToHMI) {
+ smart_objects::SmartObjectSPtr notification_ =
+ std::make_shared<smart_objects::SmartObject>(
+ smart_objects::SmartType_Map);
+ (*notification_)[strings::msg_params][hmi_notification::service_type] =
+ GetParam().service_type_;
+ (*notification_)[strings::msg_params][hmi_notification::service_event] =
+ GetParam().service_event_;
+ (*notification_)[strings::msg_params][strings::app_id] = kConnectionKey;
+
+ AddMockApplication();
+
+ ON_CALL(*mock_app_ptr_, app_id()).WillByDefault(Return(kConnectionKey));
+
+ ON_CALL(*mock_message_helper_, CreateOnServiceUpdateNotification(_, _, _, _))
+ .WillByDefault(Return(notification_));
+
+ EXPECT_CALL(*mock_rpc_service_, ManageHMICommand(notification_, _))
+ .WillOnce(Return(true));
+
+ app_manager_impl_->ProcessServiceStatusUpdate(kConnectionKey,
+ GetParam().service_type_,
+ GetParam().service_event_,
+ GetParam().reason_);
+}
+
TEST_F(ApplicationManagerImplTest, ProcessQueryApp_ExpectSuccess) {
using namespace ns_smart_device_link::ns_smart_objects;
SmartObject app_data;
@@ -844,6 +932,7 @@ TEST_F(ApplicationManagerImplTest,
std::shared_ptr<MockApplication> nonswitching_app_ptr =
std::make_shared<MockApplication>();
+
const std::string nonswitching_device_id = "nonswitching";
const std::string nonswitching_device_id_hash =
encryption::MakeHash(nonswitching_device_id);
diff --git a/src/components/application_manager/test/help_prompt_manager_test.cc b/src/components/application_manager/test/help_prompt_manager_test.cc
index 502c1bdbbf..1a719012a8 100644
--- a/src/components/application_manager/test/help_prompt_manager_test.cc
+++ b/src/components/application_manager/test/help_prompt_manager_test.cc
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (c) 2018, Ford Motor Company
* All rights reserved.
*
diff --git a/src/components/application_manager/test/include/application_manager/mock_message_helper.h b/src/components/application_manager/test/include/application_manager/mock_message_helper.h
index 79718983ee..072199082e 100644
--- a/src/components/application_manager/test/include/application_manager/mock_message_helper.h
+++ b/src/components/application_manager/test/include/application_manager/mock_message_helper.h
@@ -341,6 +341,13 @@ class MockMessageHelper {
CreateDisplayCapabilityUpdateToMobile,
smart_objects::SmartObjectSPtr(const smart_objects::SmartObject&,
application_manager::Application&));
+ MOCK_METHOD4(CreateOnServiceUpdateNotification,
+ smart_objects::SmartObjectSPtr(
+ const hmi_apis::Common_ServiceType::eType service_type,
+ const hmi_apis::Common_ServiceEvent::eType service_event,
+ const hmi_apis::Common_ServiceStatusUpdateReason::eType
+ service_update_reason,
+ const uint32_t app_id));
static MockMessageHelper* message_helper_mock();
};
diff --git a/src/components/application_manager/test/mock_message_helper.cc b/src/components/application_manager/test/mock_message_helper.cc
index 7002bb0157..628fd97ae8 100644..100755
--- a/src/components/application_manager/test/mock_message_helper.cc
+++ b/src/components/application_manager/test/mock_message_helper.cc
@@ -627,4 +627,15 @@ MessageHelper::CreateDisplayCapabilityUpdateToMobile(
return MockMessageHelper::message_helper_mock()
->CreateDisplayCapabilityUpdateToMobile(system_capabilities, app);
}
+
+smart_objects::SmartObjectSPtr MessageHelper::CreateOnServiceUpdateNotification(
+ const hmi_apis::Common_ServiceType::eType service_type,
+ const hmi_apis::Common_ServiceEvent::eType service_event,
+ const hmi_apis::Common_ServiceStatusUpdateReason::eType
+ service_update_reason,
+ const uint32_t app_id) {
+ return MockMessageHelper::message_helper_mock()
+ ->CreateOnServiceUpdateNotification(
+ service_type, service_event, service_update_reason, app_id);
+}
} // namespace application_manager
diff --git a/src/components/application_manager/test/policy_handler_test.cc b/src/components/application_manager/test/policy_handler_test.cc
index 94567e893d..b7cdf9a4d2 100644
--- a/src/components/application_manager/test/policy_handler_test.cc
+++ b/src/components/application_manager/test/policy_handler_test.cc
@@ -1785,7 +1785,8 @@ TEST_F(PolicyHandlerTest, OnSnapshotCreated_UrlNotAdded) {
.WillRepeatedly(SetArgReferee<1>(test_data));
policy_handler_.OnSnapshotCreated(msg, retry_delay_seconds, timeout_exchange);
#else // EXTERNAL_PROPRIETARY_MODE
- policy_handler_.OnSnapshotCreated(msg);
+ policy_handler_.OnSnapshotCreated(msg,
+ policy::PTUIterationType::DefaultIteration);
#endif // EXTERNAL_PROPRIETARY_MODE
}
@@ -1863,7 +1864,8 @@ TEST_F(PolicyHandlerTest, DISABLED_OnSnapshotCreated_UrlAdded) {
#endif // PROPRIETARY_MODE
EXPECT_CALL(*mock_policy_manager_, OnUpdateStarted());
- policy_handler_.OnSnapshotCreated(msg);
+ policy_handler_.OnSnapshotCreated(msg,
+ policy::PTUIterationType::DefaultIteration);
}
#endif // EXTERNAL_PROPRIETARY_MODE
diff --git a/src/components/include/application_manager/policies/policy_handler_interface.h b/src/components/include/application_manager/policies/policy_handler_interface.h
index 8e450edd49..6c08dbcb0b 100644
--- a/src/components/include/application_manager/policies/policy_handler_interface.h
+++ b/src/components/include/application_manager/policies/policy_handler_interface.h
@@ -52,6 +52,10 @@
#include "smart_objects/smart_object.h"
#include "utils/callable.h"
#include "utils/custom_string.h"
+#include "utils/optional.h"
+#ifdef EXTERNAL_PROPRIETARY_MODE
+#include "policy/ptu_retry_handler.h"
+#endif // EXTERNAL_PROPRIETARY_MODE
using namespace ::rpc::policy_table_interface_base;
namespace policy {
@@ -59,6 +63,8 @@ typedef std::shared_ptr<utils::Callable> StatusNotifier;
typedef std::shared_ptr<PolicyEncryptionFlagGetterInterface>
PolicyEncryptionFlagGetterInterfaceSPtr;
+class PTURetryHandler;
+
class PolicyHandlerInterface {
public:
virtual ~PolicyHandlerInterface() {}
@@ -87,8 +93,11 @@ class PolicyHandlerInterface {
virtual void OnSnapshotCreated(const BinaryMessage& pt_string,
const std::vector<int>& retry_delay_seconds,
uint32_t timeout_exchange) = 0;
+
+ virtual PTURetryHandler& ptu_retry_handler() const = 0;
#else // EXTERNAL_PROPRIETARY_MODE
- virtual void OnSnapshotCreated(const BinaryMessage& pt_string) = 0;
+ virtual void OnSnapshotCreated(const BinaryMessage& pt_string,
+ const PTUIterationType iteration_type) = 0;
#endif // EXTERNAL_PROPRIETARY_MODE
virtual bool GetPriority(const std::string& policy_app_id,
diff --git a/src/components/include/application_manager/policies/policy_handler_observer.h b/src/components/include/application_manager/policies/policy_handler_observer.h
index 42348e7705..fc22d196df 100644
--- a/src/components/include/application_manager/policies/policy_handler_observer.h
+++ b/src/components/include/application_manager/policies/policy_handler_observer.h
@@ -55,6 +55,18 @@ class PolicyHandlerObserver {
virtual void OnPTInited() {}
+ virtual void OnPTUTimeoutExceeded() {}
+
+#ifdef EXTERNAL_PROPRIETARY_MODE
+ /**
+ * @brief OnCertDecryptFinished is called when certificate decryption is
+ * finished in the external flow
+ * @param decrypt_result bool value indicating whether decryption was
+ * successful
+ */
+ virtual void OnCertDecryptFinished(const bool decrypt_result) {}
+#endif
+
virtual ~PolicyHandlerObserver() {}
};
} // namespace policy
diff --git a/src/components/include/policy/policy_external/policy/policy_listener.h b/src/components/include/policy/policy_external/policy/policy_listener.h
index 8203f5c9b6..8220d05584 100644
--- a/src/components/include/policy/policy_external/policy/policy_listener.h
+++ b/src/components/include/policy/policy_external/policy/policy_listener.h
@@ -42,6 +42,8 @@ namespace policy {
namespace custom_str = utils::custom_string;
+class PTURetryHandler;
+
class PolicyListener {
public:
virtual ~PolicyListener() {}
@@ -187,6 +189,8 @@ class PolicyListener {
* LockScreenDismissal
*/
virtual void OnLockScreenDismissalStateChanged() = 0;
+
+ virtual PTURetryHandler& ptu_retry_handler() const = 0;
};
} // namespace policy
#endif // SRC_COMPONENTS_INCLUDE_POLICY_POLICY_EXTERNAL_POLICY_POLICY_LISTENER_H_
diff --git a/src/components/include/policy/policy_external/policy/policy_manager.h b/src/components/include/policy/policy_external/policy/policy_manager.h
index 1242c7a460..bf0e03b0b8 100644
--- a/src/components/include/policy/policy_external/policy/policy_manager.h
+++ b/src/components/include/policy/policy_external/policy/policy_manager.h
@@ -44,6 +44,7 @@
#include "policy/policy_listener.h"
#include "policy/policy_table/types.h"
#include "policy/policy_types.h"
+#include "policy/ptu_retry_handler.h"
#include "policy/usage_statistics/statistics_manager.h"
namespace policy {
@@ -51,7 +52,8 @@ class PolicySettings;
typedef std::shared_ptr<utils::Callable> StatusNotifier;
class PolicyManager : public usage_statistics::StatisticsManager,
- public PolicyEncryptionFlagGetterInterface {
+ public PolicyEncryptionFlagGetterInterface,
+ public PTURetryHandler {
public:
/**
* @brief The NotificationMode enum defines whether application will be
@@ -206,8 +208,9 @@ class PolicyManager : public usage_statistics::StatisticsManager,
/**
* @brief Resets retry sequence
+ * @param reset_type - reset retry count with sending OnStatusUpdate or not
*/
- virtual void ResetRetrySequence() = 0;
+ virtual void ResetRetrySequence(const ResetRetryCountType reset_type) = 0;
/**
* @brief Gets timeout to wait before next retry updating PT
diff --git a/src/components/include/policy/policy_regular/policy/policy_listener.h b/src/components/include/policy/policy_regular/policy/policy_listener.h
index d717822cac..bbe220060e 100644
--- a/src/components/include/policy/policy_regular/policy/policy_listener.h
+++ b/src/components/include/policy/policy_regular/policy/policy_listener.h
@@ -79,11 +79,13 @@ class PolicyListener {
*
* @param pt_string the snapshot
*
- * @param retry_seconds retry sequence timeouts.
+ * @param iteration_type flag indicating whether PTU was caused by retry
+ * sequence.
*
* @param timeout_exceed timeout.
*/
- virtual void OnSnapshotCreated(const BinaryMessage& pt_string) = 0;
+ virtual void OnSnapshotCreated(const BinaryMessage& pt_string,
+ const PTUIterationType iteration_type) = 0;
/**
* @brief Make appropriate changes for related applications permissions and
@@ -119,6 +121,11 @@ class PolicyListener {
virtual void OnCertificateUpdated(const std::string& certificate_data) = 0;
/**
+ * @brief OnPTUTimeOut the callback which signals if PTU timeout occured
+ */
+ virtual void OnPTUTimeOut() = 0;
+
+ /**
* @brief OnAuthTokenUpdated the callback which signals if an app's auth token
* field has been updated during a PTU
*
diff --git a/src/components/include/policy/policy_regular/policy/policy_manager.h b/src/components/include/policy/policy_regular/policy/policy_manager.h
index 65f4cb69ff..27ae18eca8 100644
--- a/src/components/include/policy/policy_regular/policy/policy_manager.h
+++ b/src/components/include/policy/policy_regular/policy/policy_manager.h
@@ -117,7 +117,7 @@ class PolicyManager : public usage_statistics::StatisticsManager,
/**
* @brief PTU is needed, for this PTS has to be formed and sent.
*/
- virtual bool RequestPTUpdate() = 0;
+ virtual bool RequestPTUpdate(const PTUIterationType iteration_type) = 0;
/**
* @brief Check if specified RPC for specified application
@@ -202,6 +202,13 @@ class PolicyManager : public usage_statistics::StatisticsManager,
virtual std::string ForcePTExchangeAtUserRequest() = 0;
/**
+ * @brief Resets retry sequence
+ * @param send_event - if true corresponding event is sent to
+ * UpdateStatusManager
+ */
+ virtual void ResetRetrySequence(const ResetRetryCountType reset_type) = 0;
+
+ /**
* @brief Gets timeout to wait before next retry updating PT
* If timeout is less or equal to zero then the retry sequence is not need.
* @return timeout in seconds
diff --git a/src/components/include/protocol_handler/protocol_handler.h b/src/components/include/protocol_handler/protocol_handler.h
index 619c47ac34..aacb31c260 100644
--- a/src/components/include/protocol_handler/protocol_handler.h
+++ b/src/components/include/protocol_handler/protocol_handler.h
@@ -118,7 +118,7 @@ class ProtocolHandler {
/**
* \brief Called to notify all handsheke handlers about handshake failure.
*/
- virtual void NotifyOnFailedHandshake() = 0;
+ virtual void NotifyOnGetSystemTimeFailed() = 0;
/**
* \brief Protocol handler settings getter
@@ -141,6 +141,16 @@ class ProtocolHandler {
virtual bool IsRPCServiceSecure(const uint32_t connection_key) const = 0;
+ virtual void ProcessFailedPTU() = 0;
+
+#ifdef EXTERNAL_PROPRIETARY_MODE
+ /**
+ * @brief ProcessFailedCertDecrypt is called to notify security manager that
+ * certificate decryption failed in the external flow
+ */
+ virtual void ProcessFailedCertDecrypt() = 0;
+#endif
+
protected:
/**
* \brief Destructor
diff --git a/src/components/include/security_manager/security_manager.h b/src/components/include/security_manager/security_manager.h
index e02a3a1cbe..358c4e5268 100644
--- a/src/components/include/security_manager/security_manager.h
+++ b/src/components/include/security_manager/security_manager.h
@@ -166,7 +166,17 @@ class SecurityManager : public protocol_handler::ProtocolObserver,
/**
* @brief Notify all listeners that handshake was failed
*/
- virtual void NotifyListenersOnHandshakeFailed() = 0;
+ virtual void NotifyListenersOnGetSystemTimeFailed() = 0;
+
+ virtual void ProcessFailedPTU() = 0;
+
+#ifdef EXTERNAL_PROPRIETARY_MODE
+ /**
+ * @brief ProcessFailedCertDecrypt is called to notify listeners that
+ * certificate decryption failed in the external flow
+ */
+ virtual void ProcessFailedCertDecrypt() = 0;
+#endif
/**
* @brief Check if policy certificate data is empty
@@ -175,6 +185,12 @@ class SecurityManager : public protocol_handler::ProtocolObserver,
virtual bool IsPolicyCertificateDataEmpty() = 0;
/**
+ * @brief ResetPendingSystemTimeRequests resets waiting for system time
+ * requests flag
+ */
+ virtual void ResetPendingSystemTimeRequests() = 0;
+
+ /**
* \brief Add/Remove for SecurityManagerListener
*/
virtual void AddListener(SecurityManagerListener* const listener) = 0;
diff --git a/src/components/include/security_manager/security_manager_listener.h b/src/components/include/security_manager/security_manager_listener.h
index 00a4c68134..0648ed0a11 100644
--- a/src/components/include/security_manager/security_manager_listener.h
+++ b/src/components/include/security_manager/security_manager_listener.h
@@ -52,13 +52,28 @@ class SecurityManagerListener {
* @brief Notification about handshake failure
* @return true on success notification handling or false otherwise
*/
- virtual bool OnHandshakeFailed() = 0;
+ virtual bool OnGetSystemTimeFailed() = 0;
/**
* @brief Notify listeners that certificate update is required.
*/
virtual void OnCertificateUpdateRequired() = 0;
+ virtual bool OnPTUFailed() = 0;
+
+#ifdef EXTERNAL_PROPRIETARY_MODE
+ /**
+ * @brief OnCertDecryptFailed is called when certificate decryption fails in
+ * external flow
+ * @return since this callback is a part of SecurityManagerListener, bool
+ * return value is used to indicate whether listener instance can be deleted
+ * by calling entity. if true - listener can be deleted and removed from
+ * listeners by SecurityManager, false - listener retains its place within
+ * SecurityManager.
+ */
+ virtual bool OnCertDecryptFailed() = 0;
+#endif
+
/**
* @brief Get certificate data from policy
* @param reference to string where to save certificate data
diff --git a/src/components/include/test/application_manager/policies/mock_policy_handler_interface.h b/src/components/include/test/application_manager/policies/mock_policy_handler_interface.h
index f5b6f28825..defdad38f7 100644
--- a/src/components/include/test/application_manager/policies/mock_policy_handler_interface.h
+++ b/src/components/include/test/application_manager/policies/mock_policy_handler_interface.h
@@ -76,7 +76,9 @@ class MockPolicyHandlerInterface : public policy::PolicyHandlerInterface {
const std::vector<int>& retry_delay_seconds,
uint32_t timeout_exchange));
#else // EXTERNAL_PROPRIETARY_MODE
- MOCK_METHOD1(OnSnapshotCreated, void(const policy::BinaryMessage& pt_string));
+ MOCK_METHOD2(OnSnapshotCreated,
+ void(const policy::BinaryMessage& pt_string,
+ const policy::PTUIterationType iteration_type));
#endif // EXTERNAL_PROPRIETARY_MODE
MOCK_CONST_METHOD2(GetPriority,
@@ -261,6 +263,8 @@ class MockPolicyHandlerInterface : public policy::PolicyHandlerInterface {
#ifdef EXTERNAL_PROPRIETARY_MODE
MOCK_CONST_METHOD0(GetMetaInfo, const policy::MetaInfo());
+ MOCK_METHOD0(IncrementRetryIndex, void());
+ MOCK_CONST_METHOD0(ptu_retry_handler, policy::PTURetryHandler&());
#endif // EXTERNAL_PROPRIETARY_MODE
MOCK_METHOD1(Increment, void(usage_statistics::GlobalCounterId type));
diff --git a/src/components/include/test/policy/policy_external/policy/mock_policy_listener.h b/src/components/include/test/policy/policy_external/policy/mock_policy_listener.h
index 16341ed4f4..2eb5b3300b 100644
--- a/src/components/include/test/policy/policy_external/policy/mock_policy_listener.h
+++ b/src/components/include/test/policy/policy_external/policy/mock_policy_listener.h
@@ -112,6 +112,9 @@ class MockPolicyListener : public ::policy::PolicyListener {
const std::string& policy_app_id,
const std::string& hmi_level));
MOCK_METHOD0(OnLockScreenDismissalStateChanged, void());
+ MOCK_METHOD1(OnCertDecryptFinished, void(bool));
+ MOCK_METHOD0(IncrementRetryIndex, void());
+ MOCK_CONST_METHOD0(ptu_retry_handler, policy::PTURetryHandler&());
};
} // namespace policy_test
diff --git a/src/components/include/test/policy/policy_external/policy/mock_policy_manager.h b/src/components/include/test/policy/policy_external/policy/mock_policy_manager.h
index 7c71643044..cfe5844757 100644
--- a/src/components/include/test/policy/policy_external/policy/mock_policy_manager.h
+++ b/src/components/include/test/policy/policy_external/policy/mock_policy_manager.h
@@ -102,7 +102,8 @@ class MockPolicyManager : public PolicyManager {
MOCK_METHOD0(IncrementIgnitionCycles, void());
MOCK_METHOD0(ForcePTExchange, std::string());
MOCK_METHOD0(ForcePTExchangeAtUserRequest, std::string());
- MOCK_METHOD0(ResetRetrySequence, void());
+ MOCK_METHOD1(ResetRetrySequence,
+ void(const policy::ResetRetryCountType send_event));
MOCK_METHOD0(NextRetryTimeout, int());
MOCK_METHOD0(TimeoutExchangeMSec, uint32_t());
MOCK_METHOD0(RetrySequenceDelaysSeconds, const std::vector<int>());
@@ -291,6 +292,11 @@ class MockPolicyManager : public PolicyManager {
RequestType::State(const std::string& policy_app_id));
MOCK_CONST_METHOD1(GetAppRequestSubTypesState,
RequestSubType::State(const std::string& policy_app_id));
+ MOCK_METHOD0(IncrementPTURetryIndex, void());
+ MOCK_CONST_METHOD0(IsAllowedPTURetryCountExceeded, bool());
+ MOCK_CONST_METHOD0(IsAllowedRetryCountExceeded, bool());
+ MOCK_METHOD0(OnSystemRequestReceived, void());
+ MOCK_METHOD0(RetrySequenceFailed, void());
};
} // namespace policy_manager_test
} // namespace components
diff --git a/src/components/include/test/policy/policy_external/policy/mock_ptu_retry_handler.h b/src/components/include/test/policy/policy_external/policy/mock_ptu_retry_handler.h
new file mode 100644
index 0000000000..d76c791b85
--- /dev/null
+++ b/src/components/include/test/policy/policy_external/policy/mock_ptu_retry_handler.h
@@ -0,0 +1,48 @@
+/*
+ Copyright (c) 2019, 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_POLICY_POLICY_EXTERNAL_INCLUDE_POLICY_MOCK_PTU_RETRY_HANDLER_H_
+#define SRC_COMPONENTS_POLICY_POLICY_EXTERNAL_INCLUDE_POLICY_MOCK_PTU_RETRY_HANDLER_H_
+
+#include "policy/ptu_retry_handler.h"
+
+namespace policy {
+
+class MockPTURetryHandler : public PTURetryHandler {
+ public:
+ MOCK_CONST_METHOD0(IsAllowedRetryCountExceeded, bool());
+ MOCK_METHOD0(OnSystemRequestReceived, void());
+ MOCK_METHOD0(RetrySequenceFailed, void());
+};
+} // namespace policy
+
+#endif // SRC_COMPONENTS_POLICY_POLICY_EXTERNAL_INCLUDE_POLICY_MOCK_PTU_RETRY_HANDLER_H_ \ No newline at end of file
diff --git a/src/components/include/test/policy/policy_regular/policy/mock_policy_listener.h b/src/components/include/test/policy/policy_regular/policy/mock_policy_listener.h
index d0d85409a2..48c549e91b 100644
--- a/src/components/include/test/policy/policy_regular/policy/mock_policy_listener.h
+++ b/src/components/include/test/policy/policy_regular/policy/mock_policy_listener.h
@@ -77,7 +77,9 @@ class MockPolicyListener : public ::policy::PolicyListener {
MOCK_METHOD1(OnUpdateHMIAppType,
void(std::map<std::string, policy::StringArray>));
MOCK_METHOD1(GetAvailableApps, void(std::queue<std::string>&));
- MOCK_METHOD1(OnSnapshotCreated, void(const policy::BinaryMessage& pt_string));
+ MOCK_METHOD2(OnSnapshotCreated,
+ void(const policy::BinaryMessage& pt_string,
+ const policy::PTUIterationType iteration_type));
MOCK_METHOD0(CanUpdate, bool());
MOCK_METHOD1(OnCertificateUpdated, void(const std::string&));
MOCK_METHOD2(OnAuthTokenUpdated,
@@ -105,6 +107,7 @@ class MockPolicyListener : public ::policy::PolicyListener {
const std::string& policy_app_id,
const std::string& hmi_level));
MOCK_METHOD0(OnLockScreenDismissalStateChanged, void());
+ MOCK_METHOD0(OnPTUTimeOut, void());
};
} // namespace policy_test
diff --git a/src/components/include/test/policy/policy_regular/policy/mock_policy_manager.h b/src/components/include/test/policy/policy_regular/policy/mock_policy_manager.h
index 4ddd8cb309..d23674c060 100644
--- a/src/components/include/test/policy/policy_regular/policy/mock_policy_manager.h
+++ b/src/components/include/test/policy/policy_regular/policy/mock_policy_manager.h
@@ -85,7 +85,8 @@ class MockPolicyManager : public PolicyManager {
MOCK_METHOD2(GetUpdateUrls,
void(const std::string& service_type,
EndpointUrls& out_end_points));
- MOCK_METHOD0(RequestPTUpdate, bool());
+ MOCK_METHOD1(RequestPTUpdate,
+ bool(const policy::PTUIterationType iteration_type));
MOCK_METHOD5(CheckPermissions,
void(const PTString& app_id,
const PTString& hmi_level,
@@ -102,7 +103,8 @@ class MockPolicyManager : public PolicyManager {
MOCK_METHOD0(IncrementIgnitionCycles, void());
MOCK_METHOD0(ForcePTExchange, std::string());
MOCK_METHOD0(ForcePTExchangeAtUserRequest, std::string());
- MOCK_METHOD0(ResetRetrySequence, void());
+ MOCK_METHOD1(ResetRetrySequence,
+ void(const policy::ResetRetryCountType send_event));
MOCK_METHOD0(NextRetryTimeout, uint32_t());
MOCK_METHOD0(TimeoutExchangeMSec, uint32_t());
MOCK_METHOD0(RetrySequenceDelaysSeconds, const std::vector<int>());
diff --git a/src/components/include/test/protocol_handler/mock_protocol_handler.h b/src/components/include/test/protocol_handler/mock_protocol_handler.h
index 772b63b582..354c797c24 100644
--- a/src/components/include/test/protocol_handler/mock_protocol_handler.h
+++ b/src/components/include/test/protocol_handler/mock_protocol_handler.h
@@ -67,8 +67,12 @@ class MockProtocolHandler : public ::protocol_handler::ProtocolHandler {
MOCK_METHOD2(NotifySessionStarted,
void(const ::protocol_handler::SessionContext& context,
std::vector<std::string>& rejected_params));
- MOCK_METHOD0(NotifyOnFailedHandshake, void());
+ MOCK_METHOD0(NotifyOnGetSystemTimeFailed, void());
MOCK_CONST_METHOD1(IsRPCServiceSecure, bool(const uint32_t connection_key));
+ MOCK_METHOD0(ProcessFailedPTU, void());
+#ifdef EXTERNAL_PROPRIETARY_MODE
+ MOCK_METHOD0(ProcessFailedCertDecrypt, void());
+#endif
};
} // namespace protocol_handler_test
} // namespace components
diff --git a/src/components/include/test/security_manager/mock_security_manager.h b/src/components/include/test/security_manager/mock_security_manager.h
index 2b5d99c156..e44d6207c1 100644
--- a/src/components/include/test/security_manager/mock_security_manager.h
+++ b/src/components/include/test/security_manager/mock_security_manager.h
@@ -68,11 +68,16 @@ class MockSecurityManager : public ::security_manager::SecurityManager {
void(const ::protocol_handler::RawMessagePtr));
MOCK_METHOD1(IsCertificateUpdateRequired, bool(const uint32_t));
MOCK_METHOD0(NotifyOnCertificateUpdateRequired, void());
- MOCK_METHOD0(NotifyListenersOnHandshakeFailed, void());
+ MOCK_METHOD0(NotifyListenersOnGetSystemTimeFailed, void());
MOCK_METHOD0(IsPolicyCertificateDataEmpty, bool());
+ MOCK_METHOD0(ProcessFailedPTU, void());
MOCK_METHOD1(OnCertificateUpdated, bool(const std::string&));
MOCK_METHOD1(PostponeHandshake, void(const uint32_t));
MOCK_CONST_METHOD0(IsSystemTimeProviderReady, bool());
+ MOCK_METHOD0(ResetPendingSystemTimeRequests, void());
+#ifdef EXTERNAL_PROPRIETARY_MODE
+ MOCK_METHOD0(ProcessFailedCertDecrypt, void());
+#endif
};
/*
diff --git a/src/components/include/test/security_manager/mock_security_manager_listener.h b/src/components/include/test/security_manager/mock_security_manager_listener.h
index 7a7714d299..81790d1830 100644
--- a/src/components/include/test/security_manager/mock_security_manager_listener.h
+++ b/src/components/include/test/security_manager/mock_security_manager_listener.h
@@ -49,7 +49,11 @@ class MockSecurityManagerListener
::security_manager::SSLContext::HandshakeResult result));
MOCK_METHOD0(OnCertificateUpdateRequired, void());
MOCK_CONST_METHOD1(GetPolicyCertificateData, bool(std::string& data));
- MOCK_METHOD0(OnHandshakeFailed, bool());
+ MOCK_METHOD0(OnGetSystemTimeFailed, bool());
+ MOCK_METHOD0(OnPTUFailed, bool());
+#ifdef EXTERNAL_PROPRIETARY_MODE
+ MOCK_METHOD0(OnCertDecryptFailed, bool());
+#endif
};
} // namespace security_manager_test
} // namespace components
diff --git a/src/components/include/test/utils/mock_system_time_handler.h b/src/components/include/test/utils/mock_system_time_handler.h
index 7bb2a7f0a5..5d82c0a8c7 100644
--- a/src/components/include/test/utils/mock_system_time_handler.h
+++ b/src/components/include/test/utils/mock_system_time_handler.h
@@ -50,6 +50,7 @@ class MockSystemTimeHandler : public ::utils::SystemTimeHandler {
void(utils::SystemTimeListener* listener));
MOCK_METHOD0(GetUTCTime, time_t());
MOCK_CONST_METHOD0(system_time_can_be_received, bool());
+ MOCK_METHOD0(ResetPendingSystemTimeRequests, void());
~MockSystemTimeHandler() {}
private:
diff --git a/src/components/interfaces/HMI_API.xml b/src/components/interfaces/HMI_API.xml
index df7fbbfbad..ff4947e7a8 100644
--- a/src/components/interfaces/HMI_API.xml
+++ b/src/components/interfaces/HMI_API.xml
@@ -402,7 +402,7 @@
<element name="STOP">
<description>Indicates that a button press of the Play/Pause button would stop the current playback.</description>
</element>
-</enum>
+</enum>
<enum name="SystemContext">
<description>Enumeration that describes possible contexts the application might be in on HU.</description>
@@ -3486,7 +3486,6 @@
</param>
</struct>
-
<struct name="RemoteControlCapabilities">
<param name="climateControlCapabilities" type="ClimateControlCapabilities" mandatory="false" minsize="1" maxsize="100" array="true">
<description>If included, the platform supports RC climate controls. For this baseline version, maxsize=1. i.e. only one climate control module is supported.</description >
@@ -3537,10 +3536,10 @@
<description>The position of the haptic rectangle to be highlighted. The center of this rectangle will be "touched" when a press occurs.</description>
</param>
</struct>
-
- <struct name="SyncMsgVersion">
+
+ <struct name="SyncMsgVersion">
<description>Specifies the version number of the SmartDeviceLink protocol that is supported by the mobile application or app service</description>
-
+
<param name="majorVersion" type="Integer" minvalue="1" maxvalue="10" mandatory="true">
<description>The major version indicates versions that is not-compatible to previous versions.</description>
</param>
@@ -3552,6 +3551,48 @@
</param>
</struct>
+ <enum name="ServiceType">
+ <element name="VIDEO" >
+ <description>Refers to the Video service.</description>
+ </element>
+ <element name="AUDIO" >
+ <description>Refers to the Audio service.</description>
+ </element>
+ <element name="RPC" >
+ <description>Refers to the RPC service.</description>
+ </element>
+ </enum>
+
+ <enum name="ServiceEvent">
+ <element name="REQUEST_RECEIVED" >
+ <description>When a request for a Service is received.</description>
+ </element>
+ <element name="REQUEST_ACCEPTED" >
+ <description>When a request for a Service is Accepted.</description>
+ </element>
+ <element name="REQUEST_REJECTED" >
+ <description>When a request for a Service is Rejected.</description>
+ </element>
+ </enum>
+
+ <enum name="ServiceStatusUpdateReason">
+ <element name="PTU_FAILED" >
+ <description>When a Service is rejected because the system was unable to get a required Policy Table Update.</description>
+ </element>
+ <element name="INVALID_CERT" >
+ <description>When a Service is rejected because the security certificate is invalid/expired.</description>
+ </element>
+ <element name="INVALID_TIME" >
+ <description>When a Service is rejected because the system was unable to get a valid SystemTime from HMI, which is required for certificate authentication.</description>
+ </element>
+ <element name="PROTECTION_ENFORCED" >
+ <description>When a Service is rejected because the system configuration ini file requires the service must be protected, but the app asks for an unprotected service.</description>
+ </element>
+ <element name="PROTECTION_DISABLED" >
+ <description>When a mobile app requests a protected service, but the system starts an unprotected service instead.</description>
+ </element>
+ </enum>
+
<!-- App Services -->
<enum name="AppServiceType">
@@ -3694,7 +3735,7 @@
<param name="apparentTemperature" type="Common.Temperature" mandatory="false"/>
<param name="apparentTemperatureHigh" type="Common.Temperature" mandatory="false"/>
<param name="apparentTemperatureLow" type="Common.Temperature" mandatory="false"/>
-
+
<param name="weatherSummary" type="String" mandatory="false"/>
<param name="time" type="Common.DateTime" mandatory="false"/>
<param name="humidity" type="Float" minvalue="0" maxvalue="1" mandatory="false">
@@ -3765,7 +3806,7 @@
<description> Using this action plus a supplied direction can give the type of turn. </description>
</element>
<element name="EXIT"/>
- <element name="STAY"/>
+ <element name="STAY"/>
<element name="MERGE"/>
<element name="FERRY"/>
<element name="CAR_SHUTTLE_TRAIN"/>
@@ -4086,6 +4127,26 @@
</interface>
<interface name="BasicCommunication" version="2.1.0" date="2019-03-18">
+<function name="OnServiceUpdate" messagetype="notification">
+ <description>
+ Must be sent by SDL to HMI when there is an update on status of certain services.
+ Services supported with current version: Video
+ </description>
+ <param name="serviceType" type="Common.ServiceType" mandatory="true">
+ <description>Specifies the service which has been updated.</description>
+ </param>
+ <param name="serviceEvent" type="Common.ServiceEvent" mandatory="false">
+ <description>Specifies service update event.</description>
+ </param>
+ <param name="reason" type="Common.ServiceStatusUpdateReason" mandatory="false">
+ <description>
+ The reason for a service event. Certain events may not have a reason, such as when a service is ACCEPTED (which is the normal expected behavior).
+ </description>
+ </param>
+ <param name="appID" type="Integer" mandatory="false">
+ <description>ID of the application which triggered the update.</description>
+ </param>
+</function>
<function name="GetSystemTime" messagetype="request">
<description>Request from SDL to HMI to obtain current UTC time.</description>
</function>
@@ -4436,7 +4497,7 @@
<description>Selected file type.</description>
</param>
</function>
-
+
<!-- Policies -->
<function name="GetSystemInfo" messagetype="request">
<description>Request from SDL to HMI to obtain information about head unit system.</description>
@@ -5282,7 +5343,6 @@
</function>
<function name="SetAppIcon" messagetype="response">
</function>
-
<function name="ShowCustomForm" messagetype="request">
<description>Used to show a custom form; it can be a parent or child screen. If no parent screen is designated, it is set as a parent screen.</description>
<param name="customFormID" type="String" maxlength="500" mandatory="true">
@@ -6767,18 +6827,18 @@
<function name="GetAppServiceData" messagetype="request">
<description> This request asks the module for current data related to the specific service. It also includes an option to subscribe to that service for future updates</description>
-
+
<param name="serviceType" type="String" mandatory="true">
<description>The type of service that is to be offered by this app. See AppServiceType for known enum equivalent types. Parameter is a string to allow for new service types to be used by apps on older versions of SDL Core.</description>
</param>
-
+
<param name="subscribe" type="Boolean" mandatory="false">
<description> If true, the consumer is requesting to subscribe to all future updates from the service publisher. If false, the consumer doesn't wish to subscribe and should be unsubscribed if it was previously subscribed.</description>
- </param>
+ </param>
</function>
<function name="GetAppServiceData" messagetype="response">
- <description> This response includes the data that was requested from the specific service</description>
+ <description> This response includes the data that was requested from the specific service</description>
<param name="serviceData" type="Common.AppServiceData" mandatory="false"/>
</function>
@@ -6786,15 +6846,15 @@
<param name="serviceUri" type="String" mandatory="true">
<description>Fully qualified URI based on a predetermined scheme provided by the app service. SDL makes no guarantee that this URI is correct.</description>
</param>
-
+
<param name="serviceID" type="String" mandatory="true">
<description>The service ID that the app consumer wishes to send this URI.</description>
</param>
-
+
<param name="originApp" type="String" mandatory="false">
<description>This string is the appID of the app requesting the app service provider take the specific action. This will automatically be set by SDL Core in requests originating from the HMI</description>
</param>
-
+
<param name="requestServiceActive" type="Boolean" mandatory="false">
<description>This flag signals the requesting consumer would like this service to become the active primary service of the destination's type.</description>
</param>
@@ -6839,7 +6899,7 @@
</param>
<param name="setAsDefault" type="Boolean" mandatory="false">
<description>True if the service was set to the default service of this type. False if the app was not to be the default</description>
- </param>
+ </param>
</function>
<function name="GetActiveServiceConsent" messagetype="request">
@@ -6850,7 +6910,7 @@
<description>The ID of the service to be activated</description>
</param>
</function>
-
+
<function name="GetActiveServiceConsent" messagetype="response">
<param name="activate" type="Boolean" mandatory="true">
<description>
diff --git a/src/components/policy/policy_external/include/policy/policy_manager_impl.h b/src/components/policy/policy_external/include/policy/policy_manager_impl.h
index cb06a65e41..1524e949ef 100644
--- a/src/components/policy/policy_external/include/policy/policy_manager_impl.h
+++ b/src/components/policy/policy_external/include/policy/policy_manager_impl.h
@@ -44,6 +44,7 @@
#include "policy/update_status_manager.h"
#include "policy/usage_statistics/statistics_manager.h"
#include "utils/lock.h"
+#include "utils/timer.h"
namespace policy_table = rpc::policy_table_interface_base;
@@ -220,8 +221,10 @@ class PolicyManagerImpl : public PolicyManager {
/**
* @brief Resets retry sequence
+ * @param send_event - if true corresponding event is sent to
+ * UpdateStatusManager
*/
- void ResetRetrySequence() OVERRIDE;
+ void ResetRetrySequence(const ResetRetryCountType reset_type) OVERRIDE;
/**
* @brief Gets timeout to wait before next retry updating PT
@@ -885,8 +888,28 @@ class PolicyManagerImpl : public PolicyManager {
void Add(const std::string& app_id,
usage_statistics::AppStopwatchId type,
int32_t timespan_seconds) OVERRIDE;
+
// Interface StatisticsManager (end)
+ /**
+ * @brief Check whether allowed retry sequence count is exceeded
+ * @return bool value - true is allowed count is exceeded, otherwise - false
+ */
+ bool IsAllowedRetryCountExceeded() const OVERRIDE;
+
+ /**
+ * @brief Finish PTU retry requence
+ */
+ void RetrySequenceFailed() OVERRIDE;
+
+ /**
+ * @brief In EXTERNAL_PROPRIETARY_MODE PTU sequence is driven by HMI and
+ * begins with OnSystemRequest from HMI. Following function is called when
+ * this notification is received to track number of PTU retries and react
+ * accordingly once allowed retry count is exceeded
+ */
+ void OnSystemRequestReceived() OVERRIDE;
+
protected:
/**
* @brief Parse policy table content and convert to PT object
@@ -898,6 +921,11 @@ class PolicyManagerImpl : public PolicyManager {
private:
/**
+ * @brief Increments PTU retry index for external flow
+ */
+ void IncrementRetryIndex();
+
+ /**
* @brief Checks if PT update should be started and schedules it if needed
*/
void CheckTriggers();
@@ -1263,7 +1291,7 @@ class PolicyManagerImpl : public PolicyManager {
/**
* @brief Lock for guarding retry sequence
*/
- sync_primitives::Lock retry_sequence_lock_;
+ mutable sync_primitives::Lock retry_sequence_lock_;
/**
* @brief Device id, which is used during PTU handling for specific
@@ -1303,6 +1331,12 @@ class PolicyManagerImpl : public PolicyManager {
* @brief Flag for notifying that invalid PTU should be triggered
*/
bool trigger_ptu_;
+
+ /**
+ * @brief Flag that indicates whether a PTU sequence (including retries) is in
+ * progress
+ */
+ bool is_ptu_in_progress_;
};
} // namespace policy
diff --git a/src/components/policy/policy_external/include/policy/policy_types.h b/src/components/policy/policy_external/include/policy/policy_types.h
index fcf6c33c1b..fe63ae3479 100644
--- a/src/components/policy/policy_external/include/policy/policy_types.h
+++ b/src/components/policy/policy_external/include/policy/policy_types.h
@@ -122,6 +122,8 @@ typedef std::vector<std::string> StringArray;
enum PermitResult { kRpcAllowed = 0, kRpcDisallowed, kRpcUserDisallowed };
+enum class ResetRetryCountType { kResetWithStatusUpdate = 0, kResetInternally };
+
/**
* @struct Stores result of check:
* if HMI Level was allowed for RPC to work in
diff --git a/src/components/policy/policy_external/include/policy/ptu_retry_handler.h b/src/components/policy/policy_external/include/policy/ptu_retry_handler.h
new file mode 100644
index 0000000000..79623124e3
--- /dev/null
+++ b/src/components/policy/policy_external/include/policy/ptu_retry_handler.h
@@ -0,0 +1,57 @@
+/*
+ Copyright (c) 2019, 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_POLICIES_PTU_RETRY_HANDLER_H_
+#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_POLICIES_PTU_RETRY_HANDLER_H_
+
+namespace policy {
+
+class PTURetryHandler {
+ public:
+ /**
+ * @brief Check whether allowed retry sequence count is exceeded
+ * @return bool value - true is allowed count is exceeded, otherwise - false
+ */
+ virtual bool IsAllowedRetryCountExceeded() const = 0;
+
+ /**
+ * @brief Begins new retry sequence
+ */
+ virtual void OnSystemRequestReceived() = 0;
+
+ /**
+ * @brief Handle OnSystemRequest from HMI timeout
+ */
+ virtual void RetrySequenceFailed() = 0;
+};
+} // namespace policy
+
+#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_POLICIES_PTU_RETRY_HANDLER_H_
diff --git a/src/components/policy/policy_external/src/policy_manager_impl.cc b/src/components/policy/policy_external/src/policy_manager_impl.cc
index 255f6050a6..0629fea022 100644
--- a/src/components/policy/policy_external/src/policy_manager_impl.cc
+++ b/src/components/policy/policy_external/src/policy_manager_impl.cc
@@ -52,6 +52,7 @@
#include "policy/access_remote.h"
#include "policy/access_remote_impl.h"
+#include "utils/timer_task_impl.h"
__attribute__((visibility("default"))) policy::PolicyManager* CreateManager() {
return new policy::PolicyManagerImpl();
@@ -220,7 +221,8 @@ PolicyManagerImpl::PolicyManagerImpl()
, retry_sequence_timeout_(60)
, retry_sequence_index_(0)
, ignition_check(true)
- , retry_sequence_url_(0, 0, "") {}
+ , retry_sequence_url_(0, 0, "")
+ , is_ptu_in_progress_(false) {}
PolicyManagerImpl::PolicyManagerImpl(bool in_memory)
: PolicyManager()
@@ -234,7 +236,8 @@ PolicyManagerImpl::PolicyManagerImpl(bool in_memory)
, retry_sequence_url_(0, 0, "")
, wrong_ptu_update_received_(false)
, send_on_update_sent_out_(false)
- , trigger_ptu_(false) {}
+ , trigger_ptu_(false)
+ , is_ptu_in_progress_(false) {}
void PolicyManagerImpl::set_listener(PolicyListener* listener) {
listener_ = listener;
@@ -832,6 +835,7 @@ void PolicyManagerImpl::CheckPermissions(const PTString& device_id,
LOG4CXX_INFO(logger_,
"CheckPermissions for " << app_id << " and rpc " << rpc
<< " for " << hmi_level << " level.");
+
Permissions rpc_permissions;
// Check, if there are calculated permission present in cache
@@ -1108,7 +1112,7 @@ bool PolicyManagerImpl::ReactOnUserDevConsentForApp(
}
if (permissions.requestTypeChanged || (!permissions.priority.empty())) {
- auto device_id = GetCurrentDeviceId(device_handle, app_id);
+ const auto& device_id = GetCurrentDeviceId(device_handle, app_id);
listener_->SendOnAppPermissionsChanged(permissions, device_id, app_id);
}
return result;
@@ -1287,6 +1291,42 @@ void PolicyManagerImpl::SetUserConsentForApp(
updated_app_group_permissons);
}
+bool PolicyManagerImpl::IsAllowedRetryCountExceeded() const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock auto_lock(retry_sequence_lock_);
+
+ return retry_sequence_index_ > retry_sequence_seconds_.size();
+}
+
+void PolicyManagerImpl::IncrementRetryIndex() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock auto_lock(retry_sequence_lock_);
+
+ if (!is_ptu_in_progress_) {
+ LOG4CXX_TRACE(logger_,
+ "First PTU iteration, skipping incrementing retry index");
+ is_ptu_in_progress_ = true;
+ return;
+ }
+
+ ++retry_sequence_index_;
+ LOG4CXX_DEBUG(logger_,
+ "current retry_sequence_index_ is: " << retry_sequence_index_);
+}
+
+void PolicyManagerImpl::RetrySequenceFailed() {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ listener_->OnPTUFinished(false);
+ ResetRetrySequence(ResetRetryCountType::kResetWithStatusUpdate);
+}
+
+void PolicyManagerImpl::OnSystemRequestReceived() {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ IncrementRetryIndex();
+}
+
bool PolicyManagerImpl::GetDefaultHmi(const std::string& device_id,
const std::string& policy_app_id,
std::string* default_hmi) const {
@@ -1395,11 +1435,13 @@ void PolicyManagerImpl::GetPermissionsForApp(
}
bool allowed_by_default = false;
- if (cache_->IsDefaultPolicy(policy_app_id)) {
+ const auto device_consent = GetUserConsentForDevice(device_id);
+ if ((policy::kDeviceAllowed == device_consent) &&
+ cache_->IsDefaultPolicy(policy_app_id)) {
app_id_to_check = kDefaultId;
allowed_by_default = true;
} else if (cache_->IsPredataPolicy(policy_app_id) ||
- policy::kDeviceDisallowed == GetUserConsentForDevice(device_id)) {
+ policy::kDeviceAllowed != device_consent) {
app_id_to_check = kPreDataConsentId;
allowed_by_default = true;
}
@@ -1592,7 +1634,7 @@ void PolicyManagerImpl::UpdateAppConsentWithExternalConsent(
void PolicyManagerImpl::NotifySystem(
const std::string& device_id,
- const AppPoliciesValueType& app_policy) const {
+ const PolicyManagerImpl::AppPoliciesValueType& app_policy) const {
listener()->OnPendingPermissionChange(device_id, app_policy.first);
}
@@ -1767,12 +1809,14 @@ void PolicyManagerImpl::KmsChanged(int kilometers) {
const boost::optional<bool> PolicyManagerImpl::LockScreenDismissalEnabledState()
const {
+ LOG4CXX_AUTO_TRACE(logger_);
return cache_->LockScreenDismissalEnabledState();
}
const boost::optional<std::string>
PolicyManagerImpl::LockScreenDismissalWarningMessage(
const std::string& language) const {
+ LOG4CXX_AUTO_TRACE(logger_);
return cache_->LockScreenDismissalWarningMessage(language);
}
@@ -1801,10 +1845,11 @@ int PolicyManagerImpl::NextRetryTimeout() {
sync_primitives::AutoLock auto_lock(retry_sequence_lock_);
LOG4CXX_DEBUG(logger_, "Index: " << retry_sequence_index_);
int next = 0;
+
if (!retry_sequence_seconds_.empty() &&
retry_sequence_index_ < retry_sequence_seconds_.size()) {
- next = retry_sequence_seconds_[retry_sequence_index_];
- ++retry_sequence_index_;
+ next = retry_sequence_seconds_[retry_sequence_index_] *
+ date_time::MILLISECONDS_IN_SECOND;
}
return next;
}
@@ -1816,10 +1861,15 @@ void PolicyManagerImpl::RefreshRetrySequence() {
cache_->SecondsBetweenRetries(retry_sequence_seconds_);
}
-void PolicyManagerImpl::ResetRetrySequence() {
+void PolicyManagerImpl::ResetRetrySequence(
+ const ResetRetryCountType reset_type) {
+ LOG4CXX_AUTO_TRACE(logger_);
sync_primitives::AutoLock auto_lock(retry_sequence_lock_);
retry_sequence_index_ = 0;
- update_status_manager_.OnResetRetrySequence();
+ is_ptu_in_progress_ = false;
+ if (ResetRetryCountType::kResetWithStatusUpdate == reset_type) {
+ update_status_manager_.OnResetRetrySequence();
+ }
}
uint32_t PolicyManagerImpl::TimeoutExchangeMSec() {
@@ -1832,6 +1882,8 @@ const std::vector<int> PolicyManagerImpl::RetrySequenceDelaysSeconds() {
}
void PolicyManagerImpl::OnExceededTimeout() {
+ LOG4CXX_AUTO_TRACE(logger_);
+
update_status_manager_.OnUpdateTimeoutOccurs();
}
@@ -1885,7 +1937,7 @@ bool PolicyManagerImpl::IsApplicationRevoked(const std::string& app_id) const {
bool PolicyManagerImpl::IsConsentNeeded(const std::string& device_id,
const std::string& app_id) {
LOG4CXX_AUTO_TRACE(logger_);
- int count = cache_->CountUnconsentedGroups(app_id, device_id);
+ const int count = cache_->CountUnconsentedGroups(app_id, device_id);
LOG4CXX_DEBUG(logger_, "There are: " << count << " unconsented groups.");
return count != 0;
}
@@ -2029,7 +2081,10 @@ StatusNotifier PolicyManagerImpl::AddApplication(
const std::string& application_id,
const rpc::policy_table_interface_base::AppHmiTypes& hmi_types) {
LOG4CXX_AUTO_TRACE(logger_);
- DeviceConsent device_consent = GetUserConsentForDevice(device_id);
+ auto device_consent = GetUserConsentForDevice(device_id);
+ LOG4CXX_DEBUG(logger_,
+ "check_device_id: " << device_id << " check_device_consent: "
+ << device_consent);
sync_primitives::AutoLock lock(apps_registration_lock_);
if (IsNewApplication(application_id)) {
LOG4CXX_DEBUG(logger_, "Adding new application");
@@ -2067,6 +2122,7 @@ void PolicyManagerImpl::ProcessExternalConsentStatusForApp(
CalculateGroupsConsentFromExternalConsent(
groups_by_status, allowed_groups, disallowed_groups);
+ LOG4CXX_DEBUG(logger_, "check device_id: " << device_id);
UpdateAppConsentWithExternalConsent(device_id,
application_id,
allowed_groups,
@@ -2106,8 +2162,16 @@ void PolicyManagerImpl::PromoteExistedApplication(
DeviceConsent device_consent) {
// If device consent changed to allowed during application being
// disconnected, app permissions should be changed also
+ LOG4CXX_DEBUG(logger_,
+ "kDeviceAllowed == device_consent: "
+ << (kDeviceAllowed == device_consent)
+ << " device_consent: " << device_consent);
if (kDeviceAllowed == device_consent &&
cache_->IsPredataPolicy(application_id)) {
+ LOG4CXX_INFO(logger_,
+ "Setting "
+ << policy::kDefaultId
+ << " permissions for application id: " << application_id);
cache_->SetDefaultPolicy(application_id);
}
ProcessExternalConsentStatusForApp(
@@ -2173,6 +2237,11 @@ uint32_t PolicyManagerImpl::HeartBeatTimeout(const std::string& app_id) const {
}
void PolicyManagerImpl::SaveUpdateStatusRequired(bool is_update_needed) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ if (!is_update_needed) {
+ ResetRetrySequence(ResetRetryCountType::kResetInternally);
+ }
cache_->SaveUpdateRequired(is_update_needed);
}
@@ -2196,8 +2265,7 @@ void PolicyManagerImpl::SetDefaultHmiTypes(
const std::string& application_id,
const std::vector<int>& hmi_types) {
LOG4CXX_INFO(logger_, "SetDefaultHmiTypes");
- const std::string device_id =
- GetCurrentDeviceId(device_handle, application_id);
+ const auto device_id = GetCurrentDeviceId(device_handle, application_id);
ApplicationOnDevice who = {device_id, application_id};
access_remote_->SetDefaultHmiTypes(who, hmi_types);
}
diff --git a/src/components/policy/policy_external/src/status.cc b/src/components/policy/policy_external/src/status.cc
index c2ee4e4bbc..3d1cae3eba 100644
--- a/src/components/policy/policy_external/src/status.cc
+++ b/src/components/policy/policy_external/src/status.cc
@@ -99,9 +99,11 @@ void policy::UpdatingStatus::ProcessEvent(policy::UpdateStatusManager* manager,
break;
case kScheduleUpdate:
case kScheduleManualUpdate:
- case kOnResetRetrySequence:
manager->SetPostponedStatus(std::make_shared<UpdateNeededStatus>());
break;
+ case kOnResetRetrySequence:
+ manager->SetNextStatus(std::make_shared<UpdateNeededStatus>());
+ break;
default:
break;
}
diff --git a/src/components/policy/policy_external/src/update_status_manager.cc b/src/components/policy/policy_external/src/update_status_manager.cc
index b352b5ea39..050908f3a0 100644
--- a/src/components/policy/policy_external/src/update_status_manager.cc
+++ b/src/components/policy/policy_external/src/update_status_manager.cc
@@ -32,6 +32,7 @@
#include "policy/update_status_manager.h"
#include "policy/policy_listener.h"
+#include "policy/ptu_retry_handler.h"
#include "utils/logger.h"
namespace policy {
@@ -87,6 +88,14 @@ void UpdateStatusManager::OnUpdateSentOut(uint32_t update_timeout) {
void UpdateStatusManager::OnUpdateTimeoutOccurs() {
LOG4CXX_AUTO_TRACE(logger_);
+
+ auto& ptu_retry_handler = listener_->ptu_retry_handler();
+
+ if (ptu_retry_handler.IsAllowedRetryCountExceeded()) {
+ ptu_retry_handler.RetrySequenceFailed();
+ return;
+ }
+
ProcessEvent(kOnUpdateTimeout);
DCHECK(update_status_thread_delegate_);
update_status_thread_delegate_->updateTimeOut(0); // Stop Timer
diff --git a/src/components/policy/policy_external/test/include/policy/policy_manager_impl_test_base.h b/src/components/policy/policy_external/test/include/policy/policy_manager_impl_test_base.h
index 65972e0a82..2ab6caf15d 100644
--- a/src/components/policy/policy_external/test/include/policy/policy_manager_impl_test_base.h
+++ b/src/components/policy/policy_external/test/include/policy/policy_manager_impl_test_base.h
@@ -42,6 +42,7 @@
#include "policy/mock_cache_manager.h"
#include "policy/mock_policy_listener.h"
#include "policy/mock_policy_settings.h"
+#include "policy/mock_ptu_retry_handler.h"
#include "policy/mock_update_status_manager.h"
namespace test {
@@ -115,6 +116,7 @@ class PolicyManagerImplTest : public ::testing::Test {
MockCacheManagerInterface* cache_manager_;
MockUpdateStatusManager update_manager_;
NiceMock<MockPolicyListener> listener_;
+ NiceMock<MockPTURetryHandler> ptu_retry_handler_;
void SetUp() OVERRIDE;
@@ -140,6 +142,7 @@ class PolicyManagerImplTest2 : public ::testing::Test {
PolicyManagerImpl* policy_manager_;
NiceMock<MockPolicyListener> listener_;
+ NiceMock<MockPTURetryHandler> ptu_retry_handler_;
::policy::StringArray hmi_level_;
::policy::StringArray pt_request_types_;
size_t ptu_request_types_size_;
diff --git a/src/components/policy/policy_external/test/policy_manager_impl_test.cc b/src/components/policy/policy_external/test/policy_manager_impl_test.cc
index b809c83d75..1a7500c954 100644
--- a/src/components/policy/policy_external/test/policy_manager_impl_test.cc
+++ b/src/components/policy/policy_external/test/policy_manager_impl_test.cc
@@ -37,6 +37,7 @@
#include "json/reader.h"
#include "policy/policy_manager_impl_test_base.h"
+#include "utils/date_time.h"
using ::testing::_;
using ::testing::AtLeast;
@@ -47,30 +48,6 @@ namespace test {
namespace components {
namespace policy_test {
-TEST_F(
- PolicyManagerImplTest,
- RefreshRetrySequence_SetSecondsBetweenRetries_ExpectRetryTimeoutSequenceWithSameSeconds) {
- // Arrange
- std::vector<int> seconds;
- seconds.push_back(50);
- seconds.push_back(100);
- seconds.push_back(200);
-
- // Assert
- EXPECT_CALL(*cache_manager_, TimeoutResponse()).WillOnce(Return(60));
- EXPECT_CALL(*cache_manager_, SecondsBetweenRetries(_))
- .WillOnce(DoAll(SetArgReferee<0>(seconds), Return(true)));
-
- // Act
- policy_manager_->RefreshRetrySequence();
-
- // Assert
- EXPECT_EQ(50, policy_manager_->NextRetryTimeout());
- EXPECT_EQ(100, policy_manager_->NextRetryTimeout());
- EXPECT_EQ(200, policy_manager_->NextRetryTimeout());
- EXPECT_EQ(0, policy_manager_->NextRetryTimeout());
-}
-
TEST_F(PolicyManagerImplTest, GetNotificationsNumber) {
std::string priority = "EMERGENCY";
uint32_t notif_number = 100;
@@ -199,31 +176,14 @@ TEST_F(PolicyManagerImplTest2, OnSystemReady) {
TEST_F(PolicyManagerImplTest2, ResetRetrySequence) {
// Arrange
CreateLocalPT(preloaded_pt_filename_);
- policy_manager_->ResetRetrySequence();
+ policy_manager_->ResetRetrySequence(
+ policy::ResetRetryCountType::kResetWithStatusUpdate);
EXPECT_EQ("UPDATE_NEEDED", policy_manager_->GetPolicyTableStatus());
policy_manager_->SetSendOnUpdateFlags(false, false);
policy_manager_->OnUpdateStarted();
EXPECT_EQ("UPDATING", policy_manager_->GetPolicyTableStatus());
}
-TEST_F(PolicyManagerImplTest2, NextRetryTimeout_ExpectTimeoutsFromPT) {
- // Arrange
- std::ifstream ifile(preloaded_pt_filename_);
- Json::Reader reader;
- Json::Value root(Json::objectValue);
- if (ifile.is_open() && reader.parse(ifile, root, true)) {
- Json::Value seconds_between_retries = Json::Value(Json::arrayValue);
- seconds_between_retries =
- root["policy_table"]["module_config"]["seconds_between_retries"];
- uint32_t size = seconds_between_retries.size();
- CreateLocalPT(preloaded_pt_filename_);
- for (uint32_t i = 0; i < size; ++i) {
- EXPECT_EQ(seconds_between_retries[i],
- policy_manager_->NextRetryTimeout());
- }
- }
-}
-
TEST_F(PolicyManagerImplTest2, TimeOutExchange) {
// Arrange
CreateLocalPT(preloaded_pt_filename_);
@@ -319,6 +279,8 @@ TEST_F(PolicyManagerImplTest2,
OnExceededTimeout_GetPolicyTableStatus_ExpectUpdateNeeded) {
// Arrange
CreateLocalPT(preloaded_pt_filename_);
+ ON_CALL(ptu_retry_handler_, IsAllowedRetryCountExceeded())
+ .WillByDefault(Return(false));
policy_manager_->ForcePTExchange();
policy_manager_->OnExceededTimeout();
// Check
diff --git a/src/components/policy/policy_external/test/policy_manager_impl_test_base.cc b/src/components/policy/policy_external/test/policy_manager_impl_test_base.cc
index 8a62772992..be7f25dabb 100644
--- a/src/components/policy/policy_external/test/policy_manager_impl_test_base.cc
+++ b/src/components/policy/policy_external/test/policy_manager_impl_test_base.cc
@@ -218,6 +218,8 @@ void PolicyManagerImplTest::SetUp() {
ON_CALL(*cache_manager_, GetKnownLinksFromPT())
.WillByDefault(Return(std::map<std::string, std::string>()));
ON_CALL(listener_, GetRegisteredLinks(_)).WillByDefault(Return());
+ ON_CALL(listener_, ptu_retry_handler())
+ .WillByDefault(ReturnRef(ptu_retry_handler_));
}
void PolicyManagerImplTest::TearDown() {
@@ -253,6 +255,8 @@ PolicyManagerImplTest2::PolicyManagerImplTest2()
void PolicyManagerImplTest2::SetUp() {
ON_CALL(listener_, GetRegisteredLinks(_)).WillByDefault(Return());
+ ON_CALL(listener_, ptu_retry_handler())
+ .WillByDefault(ReturnRef(ptu_retry_handler_));
file_system::CreateDirectory(app_storage_folder_);
diff --git a/src/components/policy/policy_external/test/update_status_manager_test.cc b/src/components/policy/policy_external/test/update_status_manager_test.cc
index f5192471cc..9f68456750 100644
--- a/src/components/policy/policy_external/test/update_status_manager_test.cc
+++ b/src/components/policy/policy_external/test/update_status_manager_test.cc
@@ -33,6 +33,7 @@
#include "policy/update_status_manager.h"
#include "gtest/gtest.h"
#include "policy/mock_policy_listener.h"
+#include "policy/mock_ptu_retry_handler.h"
#include "policy/policy_manager_impl.h"
#include "utils/conditional_variable.h"
@@ -52,6 +53,7 @@ class UpdateStatusManagerTest : public ::testing::Test {
PolicyTableStatus status_;
const uint32_t k_timeout_;
NiceMock<MockPolicyListener> listener_;
+ NiceMock<MockPTURetryHandler> mock_ptu_retry_handler_;
const std::string up_to_date_status_;
const std::string update_needed_status_;
const std::string updating_status_;
@@ -61,6 +63,7 @@ class UpdateStatusManagerTest : public ::testing::Test {
: manager_(std::make_shared<UpdateStatusManager>())
, k_timeout_(1000)
, listener_()
+ , mock_ptu_retry_handler_()
, up_to_date_status_("UP_TO_DATE")
, update_needed_status_("UPDATE_NEEDED")
, updating_status_("UPDATING") {}
@@ -68,6 +71,8 @@ class UpdateStatusManagerTest : public ::testing::Test {
void SetUp() OVERRIDE {
manager_->set_listener(&listener_);
ON_CALL(listener_, OnUpdateStatusChanged(_)).WillByDefault(Return());
+ ON_CALL(listener_, ptu_retry_handler())
+ .WillByDefault(ReturnRef(mock_ptu_retry_handler_));
}
void TearDown() OVERRIDE {}
@@ -111,6 +116,11 @@ ACTION_P(NotifyAsync, waiter) {
waiter->Notify();
}
+ACTION_P2(RetryFailed, manager, listener) {
+ manager->OnResetRetrySequence();
+ listener->OnPTUFinished(false);
+}
+
TEST_F(UpdateStatusManagerTest,
OnUpdateSentOut_WaitForTimeoutExpired_ExpectStatusUpdateNeeded) {
// Arrange
@@ -131,6 +141,38 @@ TEST_F(UpdateStatusManagerTest,
EXPECT_EQ(StatusUpdateRequired, status_);
}
+TEST_F(
+ UpdateStatusManagerTest,
+ OnUpdateSentOut_WaitForTimeoutExpired_ExpectStatusUpdateNeeded_RetryExceeded) {
+ sync_primitives::Lock lock;
+ sync_primitives::AutoLock auto_lock(lock);
+ const uint32_t count = 3u;
+ const uint32_t timeout = 2u * k_timeout_;
+ WaitAsync waiter(count, timeout);
+ EXPECT_CALL(listener_, OnUpdateStatusChanged(_))
+ .WillRepeatedly(NotifyAsync(&waiter));
+ EXPECT_CALL(mock_ptu_retry_handler_, RetrySequenceFailed())
+ .WillOnce(RetryFailed(manager_, &listener_));
+ manager_->ScheduleUpdate();
+ manager_->OnUpdateSentOut(k_timeout_);
+ status_ = manager_->GetLastUpdateStatus();
+ {
+ ::testing::InSequence s;
+ EXPECT_CALL(mock_ptu_retry_handler_, IsAllowedRetryCountExceeded())
+ .WillRepeatedly(Return(false));
+ EXPECT_CALL(mock_ptu_retry_handler_, IsAllowedRetryCountExceeded())
+ .WillRepeatedly(Return(false));
+ EXPECT_CALL(mock_ptu_retry_handler_, IsAllowedRetryCountExceeded())
+ .WillRepeatedly(Return(true));
+ EXPECT_CALL(listener_, OnPTUFinished(false));
+ }
+ EXPECT_EQ(StatusUpdatePending, status_);
+ EXPECT_TRUE(waiter.Wait(auto_lock));
+ status_ = manager_->GetLastUpdateStatus();
+ // Check
+ EXPECT_EQ(StatusUpdateRequired, status_);
+}
+
TEST_F(UpdateStatusManagerTest,
OnUpdateTimeOutOccurs_ExpectStatusUpdateNeeded) {
// Arrange
@@ -245,7 +287,7 @@ TEST_F(UpdateStatusManagerTest, OnResetRetrySequence_ExpectStatusUpToDate) {
manager_->OnResetRetrySequence();
status_ = manager_->GetLastUpdateStatus();
// Check
- EXPECT_EQ(StatusUpdatePending, status_);
+ EXPECT_EQ(StatusUpdateRequired, status_);
}
TEST_F(UpdateStatusManagerTest,
diff --git a/src/components/policy/policy_regular/include/policy/policy_manager_impl.h b/src/components/policy/policy_regular/include/policy/policy_manager_impl.h
index d8ab079cf0..92ef67176a 100644
--- a/src/components/policy/policy_regular/include/policy/policy_manager_impl.h
+++ b/src/components/policy/policy_regular/include/policy/policy_manager_impl.h
@@ -183,7 +183,7 @@ class PolicyManagerImpl : public PolicyManager {
/**
* @brief PTU is needed, for this PTS has to be formed and sent.
*/
- bool RequestPTUpdate() OVERRIDE;
+ bool RequestPTUpdate(const PTUIterationType iteration_type) OVERRIDE;
/**
* @brief Check if specified RPC for specified application
@@ -247,8 +247,10 @@ class PolicyManagerImpl : public PolicyManager {
/**
* @brief Resets retry sequence
+ * @param send_event - if true corresponding event is sent to
+ * UpdateStatusManager
*/
- void ResetRetrySequence();
+ void ResetRetrySequence(const ResetRetryCountType reset_type) OVERRIDE;
/**
* @brief Gets timeout to wait before next retry updating PT
@@ -1019,7 +1021,7 @@ class PolicyManagerImpl : public PolicyManager {
/**
* @brief Starts new retry sequence
*/
- void RetrySequence();
+ void OnPTUIterationTimeout();
private:
/**
diff --git a/src/components/policy/policy_regular/include/policy/policy_types.h b/src/components/policy/policy_regular/include/policy/policy_types.h
index 2794615cb4..08ff9b4285 100644
--- a/src/components/policy/policy_regular/include/policy/policy_types.h
+++ b/src/components/policy/policy_regular/include/policy/policy_types.h
@@ -78,6 +78,10 @@ enum PolicyTableStatus {
StatusUnknown
};
+enum class PTUIterationType { DefaultIteration = 0, RetryIteration };
+
+enum class ResetRetryCountType { kResetWithStatusUpdate = 0, kResetInternally };
+
typedef rpc::Optional<rpc::Boolean> EncryptionRequired;
// Code generator uses String class name, so this typedef was renamed to PTSring
diff --git a/src/components/policy/policy_regular/src/policy_manager_impl.cc b/src/components/policy/policy_regular/src/policy_manager_impl.cc
index e3d2c1780c..ee4c991183 100644
--- a/src/components/policy/policy_regular/src/policy_manager_impl.cc
+++ b/src/components/policy/policy_regular/src/policy_manager_impl.cc
@@ -79,9 +79,10 @@ PolicyManagerImpl::PolicyManagerImpl()
new AccessRemoteImpl(std::static_pointer_cast<CacheManager>(cache_)))
, retry_sequence_timeout_(kDefaultRetryTimeoutInMSec)
, retry_sequence_index_(0)
- , timer_retry_sequence_("Retry sequence timer",
- new timer::TimerTaskImpl<PolicyManagerImpl>(
- this, &PolicyManagerImpl::RetrySequence))
+ , timer_retry_sequence_(
+ "Retry sequence timer",
+ new timer::TimerTaskImpl<PolicyManagerImpl>(
+ this, &PolicyManagerImpl::OnPTUIterationTimeout))
, ignition_check(true)
, retry_sequence_url_(0, 0, "")
, wrong_ptu_update_received_(false)
@@ -316,6 +317,7 @@ bool PolicyManagerImpl::LoadPT(const std::string& file,
FilterPolicyTable(pt_update->policy_table);
if (!IsPTValid(pt_update, policy_table::PT_UPDATE)) {
wrong_ptu_update_received_ = true;
+ ResetRetrySequence(ResetRetryCountType::kResetInternally);
update_status_manager_.OnWrongUpdateReceived();
return false;
}
@@ -519,7 +521,7 @@ void PolicyManagerImpl::GetUpdateUrls(const uint32_t service_type,
cache_->GetUpdateUrls(service_type, out_end_points);
}
-bool PolicyManagerImpl::RequestPTUpdate() {
+bool PolicyManagerImpl::RequestPTUpdate(const PTUIterationType iteration_type) {
LOG4CXX_AUTO_TRACE(logger_);
std::shared_ptr<policy_table::Table> policy_table_snapshot =
cache_->GenerateSnapshot();
@@ -538,7 +540,7 @@ bool PolicyManagerImpl::RequestPTUpdate() {
BinaryMessage update(message_string.begin(), message_string.end());
- listener_->OnSnapshotCreated(update);
+ listener_->OnSnapshotCreated(update, iteration_type);
return true;
}
@@ -580,7 +582,8 @@ void PolicyManagerImpl::StartPTExchange() {
}
if (update_status_manager_.IsUpdateRequired()) {
- if (RequestPTUpdate() && !timer_retry_sequence_.is_running()) {
+ if (RequestPTUpdate(PTUIterationType::DefaultIteration) &&
+ !timer_retry_sequence_.is_running()) {
// Start retry sequency
const uint32_t timeout_msec = NextRetryTimeout();
@@ -1192,6 +1195,7 @@ std::string PolicyManagerImpl::GetPolicyTableStatus() const {
}
uint32_t PolicyManagerImpl::NextRetryTimeout() {
+ LOG4CXX_AUTO_TRACE(logger_);
sync_primitives::AutoLock auto_lock(retry_sequence_lock_);
LOG4CXX_DEBUG(logger_, "Index: " << retry_sequence_index_);
uint32_t next = 0u;
@@ -1217,16 +1221,21 @@ uint32_t PolicyManagerImpl::NextRetryTimeout() {
}
void PolicyManagerImpl::RefreshRetrySequence() {
+ LOG4CXX_AUTO_TRACE(logger_);
sync_primitives::AutoLock auto_lock(retry_sequence_lock_);
retry_sequence_timeout_ = cache_->TimeoutResponse();
retry_sequence_seconds_.clear();
cache_->SecondsBetweenRetries(retry_sequence_seconds_);
}
-void PolicyManagerImpl::ResetRetrySequence() {
+void PolicyManagerImpl::ResetRetrySequence(
+ const ResetRetryCountType reset_type) {
+ LOG4CXX_AUTO_TRACE(logger_);
sync_primitives::AutoLock auto_lock(retry_sequence_lock_);
retry_sequence_index_ = 0;
- update_status_manager_.OnResetRetrySequence();
+ if (ResetRetryCountType::kResetWithStatusUpdate == reset_type) {
+ update_status_manager_.OnResetRetrySequence();
+ }
}
uint32_t PolicyManagerImpl::TimeoutExchangeMSec() {
@@ -1438,6 +1447,7 @@ bool PolicyManagerImpl::IsNewApplication(
}
bool PolicyManagerImpl::ResetPT(const std::string& file_name) {
+ LOG4CXX_AUTO_TRACE(logger_);
cache_->ResetCalculatedPermissions();
const bool result = cache_->ResetPT(file_name);
if (result) {
@@ -1494,6 +1504,11 @@ uint32_t PolicyManagerImpl::HeartBeatTimeout(const std::string& app_id) const {
}
void PolicyManagerImpl::SaveUpdateStatusRequired(bool is_update_needed) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ if (!is_update_needed) {
+ ResetRetrySequence(ResetRetryCountType::kResetInternally);
+ }
cache_->SaveUpdateRequired(is_update_needed);
}
@@ -1502,8 +1517,22 @@ void PolicyManagerImpl::set_cache_manager(
cache_ = std::shared_ptr<CacheManagerInterface>(cache_manager);
}
-void PolicyManagerImpl::RetrySequence() {
- LOG4CXX_INFO(logger_, "Start new retry sequence");
+void PolicyManagerImpl::OnPTUIterationTimeout() {
+ LOG4CXX_DEBUG(logger_, "Start new retry sequence");
+
+ const bool is_exceeded_retries_count =
+ (retry_sequence_seconds_.size() < retry_sequence_index_);
+
+ if (is_exceeded_retries_count) {
+ LOG4CXX_WARN(logger_, "Exceeded allowed PTU retry count");
+ listener_->OnPTUTimeOut();
+ ResetRetrySequence(ResetRetryCountType::kResetWithStatusUpdate);
+ if (timer_retry_sequence_.is_running()) {
+ timer_retry_sequence_.Stop();
+ }
+ return;
+ }
+
update_status_manager_.OnUpdateTimeoutOccurs();
const uint32_t timeout_msec = NextRetryTimeout();
@@ -1515,7 +1544,7 @@ void PolicyManagerImpl::RetrySequence() {
return;
}
- RequestPTUpdate();
+ RequestPTUpdate(PTUIterationType::RetryIteration);
timer_retry_sequence_.Start(timeout_msec, timer::kPeriodic);
}
diff --git a/src/components/policy/policy_regular/src/status.cc b/src/components/policy/policy_regular/src/status.cc
index 00a6a95af3..114ecb9f97 100644
--- a/src/components/policy/policy_regular/src/status.cc
+++ b/src/components/policy/policy_regular/src/status.cc
@@ -101,9 +101,11 @@ void policy::UpdatingStatus::ProcessEvent(
manager->SetPostponedStatus(std::make_shared<UpdateNeededStatus>());
break;
case kScheduleUpdate:
- case kOnResetRetrySequence:
manager->SetPostponedStatus(std::make_shared<UpdateNeededStatus>());
break;
+ case kOnResetRetrySequence:
+ manager->SetNextStatus(std::make_shared<UpdateNeededStatus>());
+ break;
default:
break;
}
diff --git a/src/components/policy/policy_regular/test/policy_manager_impl_test.cc b/src/components/policy/policy_regular/test/policy_manager_impl_test.cc
index eb06856eae..ed80e904b4 100644
--- a/src/components/policy/policy_regular/test/policy_manager_impl_test.cc
+++ b/src/components/policy/policy_regular/test/policy_manager_impl_test.cc
@@ -1083,7 +1083,7 @@ TEST_F(PolicyManagerImplTest2, OnSystemReady) {
TEST_F(PolicyManagerImplTest2, ResetRetrySequence) {
// Arrange
CreateLocalPT("sdl_preloaded_pt.json");
- manager->ResetRetrySequence();
+ manager->ResetRetrySequence(ResetRetryCountType::kResetWithStatusUpdate);
EXPECT_EQ("UPDATE_NEEDED", manager->GetPolicyTableStatus());
manager->SetSendOnUpdateSentOut(false);
manager->OnUpdateStarted();
diff --git a/src/components/protocol_handler/CMakeLists.txt b/src/components/protocol_handler/CMakeLists.txt
index d18c13337c..b4123aaf06 100644
--- a/src/components/protocol_handler/CMakeLists.txt
+++ b/src/components/protocol_handler/CMakeLists.txt
@@ -35,6 +35,7 @@ include_directories(
${COMPONENTS_DIR}/protocol_handler/include/
${COMPONENTS_DIR}/connection_handler/include/
${COMPONENTS_DIR}/application_manager/include
+ ${CMAKE_BINARY_DIR}/src/components/
${LOG4CXX_INCLUDE_DIRECTORY}
${BSON_INCLUDE_DIRECTORY}
)
diff --git a/src/components/protocol_handler/docs/SDL.SDD.ServiceStatusUpdate.dox b/src/components/protocol_handler/docs/SDL.SDD.ServiceStatusUpdate.dox
new file mode 100644
index 0000000000..dea9ae5d0b
--- /dev/null
+++ b/src/components/protocol_handler/docs/SDL.SDD.ServiceStatusUpdate.dox
@@ -0,0 +1,116 @@
+/**
+\page service_status_update Service Status Update Detailed Design
+## Table of contents
+- \subpage service_status_update_intoduction
+ + \ref service_status_update_rationale "1.1 Rationale"
+ + \ref service_status_update_scope "1.2 Scope"
+- \subpage service_status_update_detail_design
+ + \ref service_status_update_design_solutions "2.1 Design solutions"
+ + \ref service_status_update_class_structure "2.2 Class Structure"
+ + \ref service_status_update_sequence_diagram "2.3 Sequence diagram"
+- \subpage service_status_update_data_structures
+ + \ref service_status_update_data_structure "3.1 Data structures"
+- \subpage service_status_update_references_and_history
+ + \ref service_status_update_history "4.1 References"
+*/
+//-----------------------------------------------------------
+/**
+\page service_status_update_intoduction 1 Introduction
+The document is intended to support software developers,
+maintenance and integration engineers with sufficient,
+detailed information concerning the design, development and
+deployment concepts, to accomplish their respective tasks without reliance on the authors.
+
+\anchor service_status_update_rationale
+## 1.1 Rationale
+ServiceStatusUpdateHandler and ServiceStatusUpdateHandlerListener classes are
+implemented to provide adequate levels of abstraction when passing data between ProtocolHandler,
+SecurityManager, ApplicationManager and PolicyHandler
+
+\anchor service_status_update_scope
+## 1.2 Scope
+ServiceStatusUpdateHandler is a part of protocol_handler namespace
+
+*/
+//-----------------------------------------------------------
+/**
+\page service_status_update_detail_design 2 Component detail design
+\anchor service_status_update_design_solutions
+### 2.1 Design solutions
+The following design approaches and patterns was used for ServiceStatusUpdateHandler:
+- Introducing extra layer to process data relevant only for ProtocolHandler or ApplicationManager
+ + ServiceStatusUpdateHandler converts ServiceStatus value relevant only for ProtocolHandler to
+ HMI API values relevant only for ApplicationManager
+- [Builder design pattern](https://sourcemaking.com/design_patterns/builder)
+ used for construction of OnServiceUpdate notification object
+- [Observer design pattern]
+ used for notifying ApplicationManager of service update occured
+
+
+#### Design description
+protocol_handler::ServiceStatusUpdateHandler is an entity to establish data transfer between
+ProtocolHandler and ApplicationManager about occuring service updates
+protocol_handler::ServiceStatusUpdateHandlerListener is an interface used
+to provide adequate level of abstraction between broadcasting and listening entity
+MessageHelper::ServiceStatusUpdateNotificationBuilder is an entity used
+for flexible construction of OnServiceUpdate notification object
+
+\anchor service_status_update_class_structure
+### 2.2 Class Structure
+The following UML class diagram shows the component structure.
+![Service Status Update class diagram](ServiceStatusUpdate_classes.png)
+For more information about class diagram follow:
+- http://www.uml-diagrams.org/class-diagrams-overview.htqml
+- https://sourcemaking.com/uml/modeling-it-systems/structural-view/class-diagram
+
+\anchor service_status_update_sequence_diagram
+### 2.3 Sequence diagram
+The following UML sequence diagram shows the component dynamic behavior.
+For more information about sequence diagram follow:
+- http://www.uml-diagrams.org/sequence-diagrams.html
+- https://sourcemaking.com/uml/modeling-it-systems/external-view/use-case-sequence-diagram
+
+Service Status Update basic flow:
+![Basic flow](ServiceStatusUpdate_sequence.png)
+
+Service Status Update invalid certificate:
+![Invalid Cert](invalid_cert.png)
+
+Service Status Update PTU failed:
+![PTU Failed](ptu_failed.png)
+
+Service Status Update PTU failed (EXTERNAL_PROPRIETARY):
+![PTU Failed EXTERNAL_PROPRIETARY](PTU_for_EXTERNAL_PROPRIETARY.png)
+
+Service Status Update GetSystemTime failed:
+![GetSystemTime failed](invalid_time.png)
+*/
+
+//-----------------------------------------------------------
+/**
+\page service_status_update_data_structures 3 Component data and resources
+\anchor service_status_update_data_structure
+### 3.1 Element Data Structure
+The following data types are used by the ServiceStatusUpdateHandler:
+ - protocol_handler::ServiceStatus
+
+//-----------------------------------------------------------
+/**
+\page service_status_update_references_and_history 4 References and history
+\anchor service_status_update_history
+### 4.1 Document history
+Document change history
+
+| Version | Date | Author/Editor | Change description |
+|-------------|------------|----------------------------------------|---------------------|
+| 0.1 | 02/21/2019 | [MKed](https://github.com/mked-luxoft) | Initial version from the previous [SDL SDD](https://adc.luxoft.com/confluence/pages/viewpage.action?pageId=279677125) |
+
+Document approve history
+
+| Version | Date | Author/Editor | Change description |
+|-------------|------------|-----------------------------|---------------------|
+| | | | |
+
+For more precise document change history follow github history -
+- https://github.com/smartdevicelink/sdl_core/commits/develop/src/components/protocol_handler/docs/SDL.SDD.ServiceStatusUpdate.dox
+*/ \ No newline at end of file
diff --git a/src/components/protocol_handler/docs/assets/PTU_for_EXTERNAL_PROPRIETARY.png b/src/components/protocol_handler/docs/assets/PTU_for_EXTERNAL_PROPRIETARY.png
new file mode 100644
index 0000000000..5962a1f08b
--- /dev/null
+++ b/src/components/protocol_handler/docs/assets/PTU_for_EXTERNAL_PROPRIETARY.png
Binary files differ
diff --git a/src/components/protocol_handler/docs/assets/ServiceStatusUpdate_classes.png b/src/components/protocol_handler/docs/assets/ServiceStatusUpdate_classes.png
new file mode 100644
index 0000000000..f604a80aa9
--- /dev/null
+++ b/src/components/protocol_handler/docs/assets/ServiceStatusUpdate_classes.png
Binary files differ
diff --git a/src/components/protocol_handler/docs/assets/ServiceStatusUpdate_sequence.png b/src/components/protocol_handler/docs/assets/ServiceStatusUpdate_sequence.png
new file mode 100644
index 0000000000..ac58aa9c48
--- /dev/null
+++ b/src/components/protocol_handler/docs/assets/ServiceStatusUpdate_sequence.png
Binary files differ
diff --git a/src/components/protocol_handler/docs/assets/invalid_cert.png b/src/components/protocol_handler/docs/assets/invalid_cert.png
new file mode 100644
index 0000000000..e208e27a52
--- /dev/null
+++ b/src/components/protocol_handler/docs/assets/invalid_cert.png
Binary files differ
diff --git a/src/components/protocol_handler/docs/assets/invalid_time.png b/src/components/protocol_handler/docs/assets/invalid_time.png
new file mode 100644
index 0000000000..c9c88a5ed3
--- /dev/null
+++ b/src/components/protocol_handler/docs/assets/invalid_time.png
Binary files differ
diff --git a/src/components/protocol_handler/docs/assets/ptu_failed.png b/src/components/protocol_handler/docs/assets/ptu_failed.png
new file mode 100644
index 0000000000..f9f5a6d144
--- /dev/null
+++ b/src/components/protocol_handler/docs/assets/ptu_failed.png
Binary files differ
diff --git a/src/components/protocol_handler/include/protocol_handler/handshake_handler.h b/src/components/protocol_handler/include/protocol_handler/handshake_handler.h
index cb52c9d375..5be513049d 100644
--- a/src/components/protocol_handler/include/protocol_handler/handshake_handler.h
+++ b/src/components/protocol_handler/include/protocol_handler/handshake_handler.h
@@ -57,7 +57,8 @@ class HandshakeHandler : public security_manager::SecurityManagerListener {
utils::SemanticVersion& full_version,
const SessionContext& context,
const uint8_t protocol_version,
- std::shared_ptr<BsonObject> payload);
+ std::shared_ptr<BsonObject> payload,
+ ServiceStatusUpdateHandler& service_status_update_handler);
~HandshakeHandler();
@@ -82,13 +83,28 @@ class HandshakeHandler : public security_manager::SecurityManagerListener {
* @brief Notification about handshake failure
* @return true on success notification handling or false otherwise
*/
- bool OnHandshakeFailed() OVERRIDE;
+ bool OnGetSystemTimeFailed() OVERRIDE;
/**
* @brief Notification that certificate update is required.
*/
void OnCertificateUpdateRequired() OVERRIDE;
+ bool OnPTUFailed() OVERRIDE;
+
+#ifdef EXTERNAL_PROPRIETARY_MODE
+ /**
+ * @brief OnCertDecryptFailed is called when certificate decryption fails in
+ * external flow
+ * @return since this callback is a part of SecurityManagerListener, bool
+ * return value is used to indicate whether listener instance can be deleted
+ * by calling entity. if true - listener can be deleted and removed from
+ * listeners by SecurityManager, false - listener retains its place within
+ * SecurityManager.
+ */
+ bool OnCertDecryptFailed() OVERRIDE;
+#endif
+
/**
* @brief Get connection key of this handler
* @return connection key
@@ -107,8 +123,21 @@ class HandshakeHandler : public security_manager::SecurityManagerListener {
/**
* @brief Performs related actions if handshake was failed
* @param params set of params used in bson part of message
+ * @param service_status - service status to be sent to HMI
+ */
+ void ProcessFailedHandshake(BsonObject& params, ServiceStatus service_status);
+
+ /**
+ * @brief Determines whether service can be protected
+ * @return true is service can be protected, otherwise - false
+ */
+ bool CanBeProtected() const;
+
+ /**
+ * @brief Determines whether service is already protected
+ * @return true is service is already protected, otherwise - false
*/
- void ProcessFailedHandshake(BsonObject& params);
+ bool IsAlreadyProtected() const;
ProtocolHandlerImpl& protocol_handler_;
SessionObserver& session_observer_;
@@ -116,6 +145,7 @@ class HandshakeHandler : public security_manager::SecurityManagerListener {
utils::SemanticVersion full_version_;
const uint8_t protocol_version_;
std::shared_ptr<BsonObject> payload_;
+ ServiceStatusUpdateHandler& service_status_update_handler_;
};
} // namespace protocol_handler
diff --git a/src/components/protocol_handler/include/protocol_handler/protocol_handler_impl.h b/src/components/protocol_handler/include/protocol_handler/protocol_handler_impl.h
index 9d6243e274..8dbfc4ed4d 100644
--- a/src/components/protocol_handler/include/protocol_handler/protocol_handler_impl.h
+++ b/src/components/protocol_handler/include/protocol_handler/protocol_handler_impl.h
@@ -55,6 +55,7 @@
#include "protocol_handler/protocol_handler_settings.h"
#include "protocol_handler/protocol_observer.h"
#include "protocol_handler/protocol_packet.h"
+#include "protocol_handler/service_status_update_handler.h"
#include "protocol_handler/session_observer.h"
#include "transport_manager/common.h"
#include "transport_manager/transport_adapter/transport_adapter.h"
@@ -210,6 +211,16 @@ class ProtocolHandlerImpl
void RemoveProtocolObserver(ProtocolObserver* observer) OVERRIDE;
+ void ProcessFailedPTU() OVERRIDE;
+
+#ifdef EXTERNAL_PROPRIETARY_MODE
+ /**
+ * @brief ProcessFailedCertDecrypt is called to notify security manager that
+ * certificate decryption failed in the external flow
+ */
+ void ProcessFailedCertDecrypt() OVERRIDE;
+#endif
+
#ifdef ENABLE_SECURITY
/**
* \brief Sets pointer for SecurityManager layer for managing protection
@@ -220,6 +231,9 @@ class ProtocolHandlerImpl
security_manager::SecurityManager* security_manager);
#endif // ENABLE_SECURITY
+ void set_service_status_update_handler(
+ std::unique_ptr<ServiceStatusUpdateHandler> handler);
+
/**
* \brief Stop all handling activity
*/
@@ -278,7 +292,7 @@ class ProtocolHandlerImpl
uint8_t session_id,
uint8_t service_type);
- void NotifyOnFailedHandshake() OVERRIDE;
+ void NotifyOnGetSystemTimeFailed() OVERRIDE;
// TODO(Ezamakhov): move Ack/Nack as interface for StartSessionHandler
/**
@@ -436,9 +450,6 @@ class ProtocolHandlerImpl
void NotifySessionStarted(const SessionContext& context,
std::vector<std::string>& rejected_params) OVERRIDE;
- void OnAuthTokenUpdated(const std::string& policy_app_id,
- const std::string& auth_token) OVERRIDE;
-
#ifdef BUILD_TESTS
const impl::FromMobileQueue& get_from_mobile_queue() const {
return raw_ford_messages_from_mobile_;
@@ -457,6 +468,8 @@ class ProtocolHandlerImpl
}
#endif
+ void OnAuthTokenUpdated(const std::string&, const std::string&) OVERRIDE;
+
private:
void SendEndServicePrivate(int32_t primary_connection_id,
int32_t connection_id,
@@ -523,10 +536,6 @@ class ProtocolHandlerImpl
void OnTMMessageSendFailed(const transport_manager::DataSendError& error,
const RawMessagePtr message) OVERRIDE;
- void OnConnectionPending(
- const transport_manager::DeviceInfo& device_info,
- const transport_manager::ConnectionUID connection_id) OVERRIDE;
-
void OnConnectionEstablished(
const transport_manager::DeviceInfo& device_info,
const transport_manager::ConnectionUID connection_id) OVERRIDE;
@@ -538,6 +547,10 @@ class ProtocolHandlerImpl
const transport_manager::ConnectionUID connection_id,
const transport_manager::CommunicationError& error) OVERRIDE;
+ void OnConnectionPending(
+ const transport_manager::DeviceInfo& device_info,
+ const transport_manager::ConnectionUID connection_id) OVERRIDE;
+
/**
* @brief Notifies that configuration of a transport has been updated.
*
@@ -704,6 +717,12 @@ class ProtocolHandlerImpl
const std::string TransportTypeFromTransport(
const utils::custom_string::CustomString& transport) const;
+ const ServiceStatus ServiceDisallowedBySettings(
+ const ServiceType service_type,
+ const ConnectionID connection_id,
+ const uint8_t session_id,
+ const bool protection) const;
+
const ProtocolHandlerSettings& settings_;
/**
@@ -790,6 +809,8 @@ class ProtocolHandlerImpl
sync_primitives::Lock start_session_frame_map_lock_;
StartSessionFrameMap start_session_frame_map_;
+ std::unique_ptr<ServiceStatusUpdateHandler> service_status_update_handler_;
+
// Map policy app id -> auth token
sync_primitives::Lock auth_token_map_lock_;
std::map<std::string, std::string> auth_token_map_;
diff --git a/src/components/protocol_handler/include/protocol_handler/service_status_update_handler.h b/src/components/protocol_handler/include/protocol_handler/service_status_update_handler.h
new file mode 100644
index 0000000000..c94ddb91e4
--- /dev/null
+++ b/src/components/protocol_handler/include/protocol_handler/service_status_update_handler.h
@@ -0,0 +1,89 @@
+/*
+ Copyright (c) 2019, 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_PROTOCOL_HANDLER_INCLUDE_PROTOCOL_HANDLER_SERVICE_STATUS_UPDATE_HANDLER_H_
+#define SRC_COMPONENTS_PROTOCOL_HANDLER_INCLUDE_PROTOCOL_HANDLER_SERVICE_STATUS_UPDATE_HANDLER_H_
+
+#include "protocol_handler/service_status_update_handler_listener.h"
+
+namespace protocol_handler {
+
+/**
+ * @brief ServiceStatus helper enum containing reasons for
+ * service
+ * status to be updated
+ */
+enum class ServiceStatus {
+ INVALID_ENUM = -1,
+ SERVICE_RECEIVED,
+ SERVICE_ACCEPTED,
+ SERVICE_START_FAILED,
+ PTU_FAILED,
+ CERT_INVALID,
+ INVALID_TIME,
+ PROTECTION_ENFORCED,
+ PROTECTION_DISABLED,
+ UNSECURE_START_FAILED
+};
+
+/**
+ * @brief ServiceStatusUpdateHandler class is used to notify listeners about
+ * occured events during service start
+ */
+class ServiceStatusUpdateHandler {
+ public:
+ /**
+ * @brief ServiceStatusUpdateHandler class constructor
+ * @param listener pointer to ServiceStatusUpdateHandlerListener instance
+ */
+ ServiceStatusUpdateHandler(ServiceStatusUpdateHandlerListener* listener)
+ : listener_(listener) {}
+
+ /**
+ * @brief OnServiceUpdate callback that is invoked in case of
+ * service status update needed
+ * @param connection_key - connection key
+ * @param service_type enum value containing type of service.
+ * @param service_status enum value containing status of service.
+ * received
+ */
+ void OnServiceUpdate(const uint32_t connection_key,
+ const protocol_handler::ServiceType service_type,
+ const ServiceStatus service_status);
+
+ private:
+ ServiceStatusUpdateHandlerListener* listener_;
+};
+
+} // namespace protocol_handler
+
+#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_SERVICE_STATUS_UPDATE_HANDLER_H_
diff --git a/src/components/protocol_handler/include/protocol_handler/service_status_update_handler_listener.h b/src/components/protocol_handler/include/protocol_handler/service_status_update_handler_listener.h
new file mode 100644
index 0000000000..3c782f72f8
--- /dev/null
+++ b/src/components/protocol_handler/include/protocol_handler/service_status_update_handler_listener.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2019, 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_PROTOCOL_HANDLER_INCLUDE_PROTOCOL_HANDLER_SERVICE_STATUS_UPDATE_HANDLER_LISTENER_H_
+#define SRC_COMPONENTS_PROTOCOL_HANDLER_INCLUDE_PROTOCOL_HANDLER_SERVICE_STATUS_UPDATE_HANDLER_LISTENER_H_
+
+#include "interfaces/HMI_API.h"
+#include "protocol_handler/protocol_handler.h"
+#include "transport_manager/transport_manager.h"
+#include "utils/optional.h"
+
+namespace protocol_handler {
+/**
+ * @brief Converts service type enum value from protocol_handler to hmi_apis.
+ * @param service_type protocol_handler enum value.
+ */
+hmi_apis::Common_ServiceType::eType GetHMIServiceType(
+ protocol_handler::ServiceType service_type);
+
+/**
+ * @brief ServiceStatusUpdateHandlerListener provides callbacks interface with
+ * a purpose to notify HMI on successful or failed state updates of different
+ * services
+ */
+class ServiceStatusUpdateHandlerListener {
+ public:
+ /**
+ * @brief ProcessServiceStatusUpdate callback that is invoked in case of
+ * service
+ * status update
+ * @param connection_key - connection key
+ * @param service_type enum value containing type of service.
+ * @param service_event enum value containing event that occured during
+ * service start.
+ * @param service_update_reason enum value containing reason why service_event
+ * occured.
+ */
+ virtual void ProcessServiceStatusUpdate(
+ const uint32_t connection_key,
+ hmi_apis::Common_ServiceType::eType service_type,
+ hmi_apis::Common_ServiceEvent::eType service_event,
+ utils::Optional<hmi_apis::Common_ServiceStatusUpdateReason::eType>
+ service_update_reason) = 0;
+};
+
+} // namespace protocol_handler
+
+#endif
diff --git a/src/components/protocol_handler/src/handshake_handler.cc b/src/components/protocol_handler/src/handshake_handler.cc
index fa0b375018..669b73c18b 100644
--- a/src/components/protocol_handler/src/handshake_handler.cc
+++ b/src/components/protocol_handler/src/handshake_handler.cc
@@ -38,23 +38,27 @@
#include "protocol_handler/protocol_packet.h"
#include "protocol_handler/session_observer.h"
#include "security_manager/security_manager.h"
+#include "utils/helpers.h"
namespace protocol_handler {
CREATE_LOGGERPTR_GLOBAL(logger_, "ProtocolHandler")
-HandshakeHandler::HandshakeHandler(ProtocolHandlerImpl& protocol_handler,
- SessionObserver& session_observer,
- utils::SemanticVersion& full_version,
- const SessionContext& context,
- const uint8_t protocol_version,
- std::shared_ptr<BsonObject> payload)
+HandshakeHandler::HandshakeHandler(
+ ProtocolHandlerImpl& protocol_handler,
+ SessionObserver& session_observer,
+ utils::SemanticVersion& full_version,
+ const SessionContext& context,
+ const uint8_t protocol_version,
+ std::shared_ptr<BsonObject> payload,
+ ServiceStatusUpdateHandler& service_status_update_handler)
: protocol_handler_(protocol_handler)
, session_observer_(session_observer)
, context_(context)
, full_version_(full_version)
, protocol_version_(protocol_version)
- , payload_(payload) {}
+ , payload_(payload)
+ , service_status_update_handler_(service_status_update_handler) {}
HandshakeHandler::~HandshakeHandler() {
LOG4CXX_DEBUG(logger_, "Destroying of HandshakeHandler: " << this);
@@ -69,26 +73,53 @@ bool HandshakeHandler::GetPolicyCertificateData(std::string& data) const {
return false;
}
-void HandshakeHandler::OnCertificateUpdateRequired() {}
+void HandshakeHandler::OnCertificateUpdateRequired() {
+ LOG4CXX_AUTO_TRACE(logger_);
+}
+
+#if defined(EXTERNAL_PROPRIETARY_MODE) && defined(ENABLE_SECURITY)
+bool HandshakeHandler::OnCertDecryptFailed() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (payload_) {
+ ProcessFailedHandshake(*payload_, ServiceStatus::CERT_INVALID);
+ }
+
+ return true;
+}
+#endif
+
+bool HandshakeHandler::OnGetSystemTimeFailed() {
+ LOG4CXX_AUTO_TRACE(logger_);
-bool HandshakeHandler::OnHandshakeFailed() {
if (payload_) {
- ProcessFailedHandshake(*payload_);
+ ProcessFailedHandshake(*payload_, ServiceStatus::INVALID_TIME);
} else {
BsonObject params;
bson_object_initialize_default(&params);
- ProcessFailedHandshake(params);
+ ProcessFailedHandshake(params, ServiceStatus::INVALID_TIME);
bson_object_deinitialize(&params);
}
return true;
}
+bool HandshakeHandler::OnPTUFailed() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (payload_) {
+ ProcessFailedHandshake(*payload_, ServiceStatus::PTU_FAILED);
+ }
+
+ return true;
+}
+
bool HandshakeHandler::OnHandshakeDone(
uint32_t connection_key,
security_manager::SSLContext::HandshakeResult result) {
LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(logger_,
+ "OnHandshakeDone for service : " << context_.service_type_);
+
if (connection_key != this->connection_key()) {
LOG4CXX_DEBUG(logger_,
"Listener " << this
@@ -106,7 +137,7 @@ bool HandshakeHandler::OnHandshakeDone(
if (success) {
ProcessSuccessfulHandshake(connection_key, *payload_);
} else {
- ProcessFailedHandshake(*payload_);
+ ProcessFailedHandshake(*payload_, ServiceStatus::CERT_INVALID);
}
} else {
BsonObject params;
@@ -114,7 +145,7 @@ bool HandshakeHandler::OnHandshakeDone(
if (success) {
ProcessSuccessfulHandshake(connection_key, params);
} else {
- ProcessFailedHandshake(params);
+ ProcessFailedHandshake(params, ServiceStatus::CERT_INVALID);
}
bson_object_deinitialize(&params);
}
@@ -122,20 +153,25 @@ bool HandshakeHandler::OnHandshakeDone(
return true;
}
+bool HandshakeHandler::CanBeProtected() const {
+ const auto& force_unprotected =
+ protocol_handler_.get_settings().force_unprotected_service();
+
+ return !(helpers::in_range(force_unprotected, context_.service_type_));
+}
+
+bool HandshakeHandler::IsAlreadyProtected() const {
+ return (session_observer_.GetSSLContext(this->connection_key(),
+ context_.service_type_) != NULL);
+}
+
void HandshakeHandler::ProcessSuccessfulHandshake(const uint32_t connection_key,
BsonObject& params) {
LOG4CXX_AUTO_TRACE(logger_);
- const std::vector<int>& force_unprotected =
- protocol_handler_.get_settings().force_unprotected_service();
- const bool can_be_protected =
- std::find(force_unprotected.begin(),
- force_unprotected.end(),
- context_.service_type_) == force_unprotected.end();
+ const bool is_service_already_protected = IsAlreadyProtected();
- const bool is_service_already_protected =
- session_observer_.GetSSLContext(connection_key, context_.service_type_) !=
- NULL;
+ const bool can_be_protected = CanBeProtected();
LOG4CXX_DEBUG(logger_,
"Service can be protected: " << can_be_protected
@@ -144,6 +180,10 @@ void HandshakeHandler::ProcessSuccessfulHandshake(const uint32_t connection_key,
if (can_be_protected && !is_service_already_protected) {
session_observer_.SetProtectionFlag(connection_key, context_.service_type_);
+ service_status_update_handler_.OnServiceUpdate(
+ this->connection_key(),
+ context_.service_type_,
+ ServiceStatus::SERVICE_ACCEPTED);
protocol_handler_.SendStartSessionAck(context_.connection_id_,
context_.new_session_id_,
protocol_version_,
@@ -153,6 +193,10 @@ void HandshakeHandler::ProcessSuccessfulHandshake(const uint32_t connection_key,
full_version_,
params);
} else {
+ service_status_update_handler_.OnServiceUpdate(
+ this->connection_key(),
+ context_.service_type_,
+ ServiceStatus::SERVICE_START_FAILED);
protocol_handler_.SendStartSessionNAck(context_.connection_id_,
context_.new_session_id_,
protocol_version_,
@@ -160,7 +204,8 @@ void HandshakeHandler::ProcessSuccessfulHandshake(const uint32_t connection_key,
}
}
-void HandshakeHandler::ProcessFailedHandshake(BsonObject& params) {
+void HandshakeHandler::ProcessFailedHandshake(BsonObject& params,
+ ServiceStatus service_status) {
LOG4CXX_AUTO_TRACE(logger_);
LOG4CXX_DEBUG(logger_, "Handshake failed");
const std::vector<int>& force_protected =
@@ -177,6 +222,10 @@ void HandshakeHandler::ProcessFailedHandshake(BsonObject& params) {
<< context_.is_new_service_);
if (can_be_unprotected && context_.is_new_service_) {
+ service_status_update_handler_.OnServiceUpdate(
+ this->connection_key(),
+ context_.service_type_,
+ ServiceStatus::PROTECTION_DISABLED);
protocol_handler_.SendStartSessionAck(context_.connection_id_,
context_.new_session_id_,
protocol_version_,
@@ -186,6 +235,8 @@ void HandshakeHandler::ProcessFailedHandshake(BsonObject& params) {
full_version_,
params);
} else {
+ service_status_update_handler_.OnServiceUpdate(
+ this->connection_key(), context_.service_type_, service_status);
protocol_handler_.SendStartSessionNAck(context_.connection_id_,
context_.new_session_id_,
protocol_version_,
diff --git a/src/components/protocol_handler/src/protocol_handler_impl.cc b/src/components/protocol_handler/src/protocol_handler_impl.cc
index d95c57f0cc..268af48fdc 100644
--- a/src/components/protocol_handler/src/protocol_handler_impl.cc
+++ b/src/components/protocol_handler/src/protocol_handler_impl.cc
@@ -1129,13 +1129,25 @@ void ProtocolHandlerImpl::OnUnexpectedDisconnect(
OnConnectionClosed(connection_id);
}
-void ProtocolHandlerImpl::NotifyOnFailedHandshake() {
+void ProtocolHandlerImpl::NotifyOnGetSystemTimeFailed() {
LOG4CXX_AUTO_TRACE(logger_);
+ security_manager_->ResetPendingSystemTimeRequests();
#ifdef ENABLE_SECURITY
- security_manager_->NotifyListenersOnHandshakeFailed();
+ security_manager_->NotifyListenersOnGetSystemTimeFailed();
#endif // ENABLE_SECURITY
}
+void ProtocolHandlerImpl::ProcessFailedPTU() {
+ security_manager_->ProcessFailedPTU();
+}
+
+#ifdef EXTERNAL_PROPRIETARY_MODE
+void ProtocolHandlerImpl::ProcessFailedCertDecrypt() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ security_manager_->ProcessFailedCertDecrypt();
+}
+#endif
+
void ProtocolHandlerImpl::OnTransportConfigUpdated(
const transport_manager::transport_adapter::TransportConfig& configs) {
LOG4CXX_AUTO_TRACE(logger_);
@@ -1584,6 +1596,57 @@ RESULT_CODE ProtocolHandlerImpl::HandleControlMessageEndSession(
return RESULT_OK;
}
+const ServiceStatus ProtocolHandlerImpl::ServiceDisallowedBySettings(
+ const ServiceType service_type,
+ const ConnectionID connection_id,
+ const uint8_t session_id,
+ const bool protection) const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ const std::string& transport =
+ session_observer_.TransportTypeProfileStringFromConnHandle(connection_id);
+
+ const auto video_transports = settings_.video_service_transports();
+ const bool is_video_allowed =
+ video_transports.empty() ||
+ std::find(video_transports.begin(), video_transports.end(), transport) !=
+ video_transports.end();
+
+ const auto audio_transports = settings_.audio_service_transports();
+ const bool is_audio_allowed =
+ audio_transports.empty() ||
+ std::find(audio_transports.begin(), audio_transports.end(), transport) !=
+ audio_transports.end();
+
+ const auto& force_protected = get_settings().force_protected_service();
+
+ const auto& force_unprotected = get_settings().force_unprotected_service();
+
+ const bool is_force_protected =
+ (helpers::in_range(force_protected, service_type));
+
+ const bool is_force_unprotected =
+ (helpers::in_range(force_unprotected, service_type));
+
+ const bool can_start_protected = is_force_protected && protection;
+
+ const bool can_start_unprotected = is_force_unprotected && !protection;
+
+ if ((ServiceType::kMobileNav == service_type && !is_video_allowed) ||
+ (ServiceType::kAudio == service_type && !is_audio_allowed)) {
+ return ServiceStatus::SERVICE_START_FAILED;
+ }
+
+ if (is_force_protected && !can_start_protected) {
+ return ServiceStatus::PROTECTION_ENFORCED;
+ }
+
+ if (is_force_unprotected && !can_start_unprotected) {
+ return ServiceStatus::UNSECURE_START_FAILED;
+ }
+
+ return ServiceStatus::INVALID_ENUM;
+}
+
RESULT_CODE ProtocolHandlerImpl::HandleControlMessageEndServiceACK(
const ProtocolPacket& packet) {
LOG4CXX_AUTO_TRACE(logger_);
@@ -1624,27 +1687,21 @@ RESULT_CODE ProtocolHandlerImpl::HandleControlMessageStartSession(
const ConnectionID connection_id = packet->connection_id();
const uint8_t session_id = packet->session_id();
- const std::string& transport =
- session_observer_.TransportTypeProfileStringFromConnHandle(connection_id);
+ const uint32_t connection_key =
+ session_observer_.KeyFromPair(connection_id, session_id);
- const auto video_transports = settings_.video_service_transports();
- const bool is_video_allowed =
- video_transports.empty() ||
- std::find(video_transports.begin(), video_transports.end(), transport) !=
- video_transports.end();
+ service_status_update_handler_->OnServiceUpdate(
+ connection_key, service_type, ServiceStatus::SERVICE_RECEIVED);
- const auto audio_transports = settings_.audio_service_transports();
- const bool is_audio_allowed =
- audio_transports.empty() ||
- std::find(audio_transports.begin(), audio_transports.end(), transport) !=
- audio_transports.end();
+ const auto settings_check = ServiceDisallowedBySettings(
+ service_type, connection_id, session_id, protection);
- if ((ServiceType::kMobileNav == service_type && !is_video_allowed) ||
- (ServiceType::kAudio == service_type && !is_audio_allowed)) {
+ if (ServiceStatus::INVALID_ENUM != settings_check) {
LOG4CXX_DEBUG(logger_,
"Rejecting StartService for service:"
- << service_type << ", over transport: " << transport
- << ", disallowed by settings.");
+ << service_type << ", disallowed by settings.");
+ service_status_update_handler_->OnServiceUpdate(
+ connection_key, service_type, settings_check);
SendStartSessionNAck(
connection_id, session_id, protocol_version, service_type);
return RESULT_OK;
@@ -1836,12 +1893,14 @@ void ProtocolHandlerImpl::NotifySessionStarted(
context.connection_id_, context.new_session_id_);
std::shared_ptr<HandshakeHandler> handler =
- std::make_shared<HandshakeHandler>(*this,
- session_observer_,
- *fullVersion,
- context,
- packet->protocol_version(),
- start_session_ack_params);
+ std::make_shared<HandshakeHandler>(
+ *this,
+ session_observer_,
+ *fullVersion,
+ context,
+ packet->protocol_version(),
+ start_session_ack_params,
+ *(service_status_update_handler_.get()));
security_manager::SSLContext* ssl_context =
security_manager_->CreateSSLContext(
@@ -1872,6 +1931,10 @@ void ProtocolHandlerImpl::NotifySessionStarted(
// mark service as protected
session_observer_.SetProtectionFlag(connection_key, service_type);
// Start service as protected with current SSLContext
+ service_status_update_handler_->OnServiceUpdate(
+ connection_key,
+ context.service_type_,
+ ServiceStatus::SERVICE_ACCEPTED);
SendStartSessionAck(context.connection_id_,
context.new_session_id_,
packet->protocol_version(),
@@ -1908,7 +1971,11 @@ void ProtocolHandlerImpl::NotifySessionStarted(
return;
}
#endif // ENABLE_SECURITY
+ const uint32_t connection_key = session_observer_.KeyFromPair(
+ context.connection_id_, context.new_session_id_);
if (rejected_params.empty()) {
+ service_status_update_handler_->OnServiceUpdate(
+ connection_key, context.service_type_, ServiceStatus::SERVICE_ACCEPTED);
SendStartSessionAck(context.connection_id_,
context.new_session_id_,
packet->protocol_version(),
@@ -1918,6 +1985,10 @@ void ProtocolHandlerImpl::NotifySessionStarted(
*fullVersion,
*start_session_ack_params);
} else {
+ service_status_update_handler_->OnServiceUpdate(
+ connection_key,
+ context.service_type_,
+ ServiceStatus::SERVICE_START_FAILED);
SendStartSessionNAck(context.connection_id_,
packet->session_id(),
protocol_version,
@@ -2099,6 +2170,11 @@ void ProtocolHandlerImpl::Stop() {
start_session_frame_map_.clear();
}
+void ProtocolHandlerImpl::set_service_status_update_handler(
+ std::unique_ptr<ServiceStatusUpdateHandler> handler) {
+ service_status_update_handler_ = std::move(handler);
+}
+
#ifdef ENABLE_SECURITY
void ProtocolHandlerImpl::set_security_manager(
security_manager::SecurityManager* security_manager) {
diff --git a/src/components/protocol_handler/src/service_status_update_handler.cc b/src/components/protocol_handler/src/service_status_update_handler.cc
new file mode 100644
index 0000000000..7b2c67ea23
--- /dev/null
+++ b/src/components/protocol_handler/src/service_status_update_handler.cc
@@ -0,0 +1,117 @@
+#include "protocol_handler/service_status_update_handler.h"
+#include "interfaces/HMI_API.h"
+
+namespace protocol_handler {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "ServiceStatusUpdateHandler")
+
+hmi_apis::Common_ServiceType::eType GetHMIServiceType(
+ protocol_handler::ServiceType service_type) {
+ using namespace hmi_apis;
+ using namespace protocol_handler;
+ switch (service_type) {
+ case SERVICE_TYPE_RPC: {
+ return Common_ServiceType::RPC;
+ }
+ case SERVICE_TYPE_AUDIO: {
+ return Common_ServiceType::AUDIO;
+ }
+ case SERVICE_TYPE_NAVI: {
+ return Common_ServiceType::VIDEO;
+ }
+ default: { return Common_ServiceType::INVALID_ENUM; }
+ }
+}
+
+void ServiceStatusUpdateHandler::OnServiceUpdate(
+ const uint32_t connection_key,
+ const protocol_handler::ServiceType service_type,
+ ServiceStatus service_status) {
+ using namespace hmi_apis;
+ typedef utils::Optional<Common_ServiceStatusUpdateReason::eType>
+ UpdateReasonOptional;
+ LOG4CXX_AUTO_TRACE(logger_);
+ auto hmi_service_type = GetHMIServiceType(service_type);
+
+ switch (service_status) {
+ case ServiceStatus::SERVICE_RECEIVED: {
+ return listener_->ProcessServiceStatusUpdate(
+ connection_key,
+ hmi_service_type,
+ Common_ServiceEvent::REQUEST_RECEIVED,
+ UpdateReasonOptional(UpdateReasonOptional::EMPTY));
+ }
+ case ServiceStatus::SERVICE_ACCEPTED: {
+ return listener_->ProcessServiceStatusUpdate(
+ connection_key,
+ hmi_service_type,
+ Common_ServiceEvent::REQUEST_ACCEPTED,
+ UpdateReasonOptional(UpdateReasonOptional::EMPTY));
+ }
+ case ServiceStatus::SERVICE_START_FAILED: {
+ return listener_->ProcessServiceStatusUpdate(
+ connection_key,
+ hmi_service_type,
+ Common_ServiceEvent::REQUEST_REJECTED,
+ UpdateReasonOptional(UpdateReasonOptional::EMPTY));
+ }
+ case ServiceStatus::PTU_FAILED: {
+ auto update_reason = Common_ServiceStatusUpdateReason::PTU_FAILED;
+ return listener_->ProcessServiceStatusUpdate(
+ connection_key,
+ hmi_service_type,
+ Common_ServiceEvent::REQUEST_REJECTED,
+ update_reason);
+ }
+ case ServiceStatus::CERT_INVALID: {
+ auto update_reason = Common_ServiceStatusUpdateReason::INVALID_CERT;
+ return listener_->ProcessServiceStatusUpdate(
+ connection_key,
+ hmi_service_type,
+ Common_ServiceEvent::REQUEST_REJECTED,
+ update_reason);
+ }
+ case ServiceStatus::INVALID_TIME: {
+ auto update_reason = Common_ServiceStatusUpdateReason::INVALID_TIME;
+ return listener_->ProcessServiceStatusUpdate(
+ connection_key,
+ hmi_service_type,
+ Common_ServiceEvent::REQUEST_REJECTED,
+ update_reason);
+ }
+ case ServiceStatus::PROTECTION_ENFORCED: {
+ auto update_reason =
+ Common_ServiceStatusUpdateReason::PROTECTION_ENFORCED;
+ return listener_->ProcessServiceStatusUpdate(
+ connection_key,
+ hmi_service_type,
+ Common_ServiceEvent::REQUEST_REJECTED,
+ update_reason);
+ }
+ case ServiceStatus::PROTECTION_DISABLED: {
+ auto update_reason =
+ Common_ServiceStatusUpdateReason::PROTECTION_DISABLED;
+ return listener_->ProcessServiceStatusUpdate(
+ connection_key,
+ hmi_service_type,
+ Common_ServiceEvent::REQUEST_ACCEPTED,
+ update_reason);
+ }
+ case ServiceStatus::UNSECURE_START_FAILED: {
+ auto update_reason =
+ Common_ServiceStatusUpdateReason::PROTECTION_DISABLED;
+ return listener_->ProcessServiceStatusUpdate(
+ connection_key,
+ hmi_service_type,
+ Common_ServiceEvent::REQUEST_REJECTED,
+ update_reason);
+ }
+ default: {
+ LOG4CXX_WARN(logger_,
+ "Received unknown ServiceStatus: "
+ << static_cast<int32_t>(service_status));
+ return;
+ }
+ }
+}
+} // namespace protocol_handler
diff --git a/src/components/protocol_handler/test/include/protocol_handler/mock_service_status_update_handler_listener.h b/src/components/protocol_handler/test/include/protocol_handler/mock_service_status_update_handler_listener.h
new file mode 100644
index 0000000000..ccbfeb8438
--- /dev/null
+++ b/src/components/protocol_handler/test/include/protocol_handler/mock_service_status_update_handler_listener.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2019, 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_PROTOCOL_HANDLER_TEST_INCLUDE_MOCK_SERVICE_STATUS_UPDATE_HANDLER_LISTENER_H
+#define SRC_COMPONENTS_PROTOCOL_HANDLER_TEST_INCLUDE_MOCK_SERVICE_STATUS_UPDATE_HANDLER_LISTENER_H
+
+#include "gmock/gmock.h"
+#include "protocol_handler/service_status_update_handler_listener.h"
+
+namespace test {
+namespace components {
+namespace protocol_handler_test {
+
+class MockServiceStatusUpdateHandlerListener
+ : public protocol_handler::ServiceStatusUpdateHandlerListener {
+ public:
+ MOCK_METHOD4(
+ ProcessServiceStatusUpdate,
+ void(const uint32_t,
+ hmi_apis::Common_ServiceType::eType,
+ hmi_apis::Common_ServiceEvent::eType,
+ utils::Optional<hmi_apis::Common_ServiceStatusUpdateReason::eType>));
+};
+} // namespace protocol_handler_test
+} // namespace components
+} // namespace test
+
+#endif // SRC_COMPONENTS_PROTOCOL_HANDLER_TEST_INCLUDE_MOCK_SERVICE_STATUS_UPDATE_HANDLER_LISTENER_H
diff --git a/src/components/protocol_handler/test/protocol_handler_tm_test.cc b/src/components/protocol_handler/test/protocol_handler_tm_test.cc
index 692b1a7134..1bea53b075 100644
--- a/src/components/protocol_handler/test/protocol_handler_tm_test.cc
+++ b/src/components/protocol_handler/test/protocol_handler_tm_test.cc
@@ -39,6 +39,7 @@
#include "protocol_handler/mock_protocol_handler.h"
#include "protocol_handler/mock_protocol_handler_settings.h"
#include "protocol_handler/mock_protocol_observer.h"
+#include "protocol_handler/mock_service_status_update_handler_listener.h"
#include "protocol_handler/mock_session_observer.h"
#include "protocol_handler/protocol_handler.h"
#include "protocol_handler/protocol_handler_impl.h"
@@ -108,6 +109,7 @@ using protocol_handler::PROTOCOL_VERSION_MAX;
using protocol_handler::ProtocolHandlerImpl;
using protocol_handler::RawMessage;
using protocol_handler::RawMessagePtr;
+using protocol_handler::ServiceStatusUpdateHandler;
using protocol_handler::ServiceType;
// For TM states
using test::components::security_manager_test::MockSystemTimeHandler;
@@ -139,6 +141,9 @@ using ::testing::SetArgPointee;
using ::testing::SetArgReferee;
typedef std::vector<uint8_t> UCharDataVector;
+typedef std::shared_ptr<
+ testing::NiceMock<MockServiceStatusUpdateHandlerListener> >
+ MockServiceStatusUpdateHandlerListenerPtr;
// custom action to call a member function with 6 arguments
ACTION_P4(InvokeMemberFuncWithArg2, ptr, memberFunc, a, b) {
@@ -186,10 +191,17 @@ class ProtocolHandlerImplTest : public ::testing::Test {
session_observer_mock,
connection_handler_mock,
transport_manager_mock));
+ std::unique_ptr<ServiceStatusUpdateHandler> service_status_update_handler_(
+ new ServiceStatusUpdateHandler(
+ &(*mock_service_status_update_handler_listener_)));
+ protocol_handler_impl->set_service_status_update_handler(
+ std::move(service_status_update_handler_));
tm_listener = protocol_handler_impl.get();
}
void SetUp() OVERRIDE {
+ mock_service_status_update_handler_listener_ = std::make_shared<
+ testing::NiceMock<MockServiceStatusUpdateHandlerListener> >();
InitProtocolHandlerImpl(0u, 0u);
connection_id = 0xAu;
session_id = 0xFFu;
@@ -390,6 +402,8 @@ class ProtocolHandlerImplTest : public ::testing::Test {
testing::NiceMock<MockProtocolHandlerSettings> protocol_handler_settings_mock;
std::shared_ptr<ProtocolHandlerImpl> protocol_handler_impl;
+ MockServiceStatusUpdateHandlerListenerPtr
+ mock_service_status_update_handler_listener_;
TransportManagerListener* tm_listener;
// Uniq connection
::transport_manager::ConnectionUID connection_id;
@@ -737,7 +751,7 @@ TEST_F(ProtocolHandlerImplTest,
AddSecurityManager();
EXPECT_CALL(session_observer_mock, KeyFromPair(connection_id2, session_id2))
- .WillOnce(Return(connection_key));
+ .WillRepeatedly(Return(connection_key));
EXPECT_CALL(session_observer_mock,
GetSSLContext(connection_key, start_service))
@@ -1416,7 +1430,7 @@ TEST_F(ProtocolHandlerImplTest,
services.push_back(0x0A);
services.push_back(0x0B);
EXPECT_CALL(protocol_handler_settings_mock, force_protected_service())
- .WillOnce(ReturnRefOfCopy(services));
+ .WillRepeatedly(ReturnRefOfCopy(services));
// call new SSLContext creation
EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key, _))
diff --git a/src/components/protocol_handler/test/service_status_update_handler_test.cc b/src/components/protocol_handler/test/service_status_update_handler_test.cc
new file mode 100644
index 0000000000..7d4516a7ff
--- /dev/null
+++ b/src/components/protocol_handler/test/service_status_update_handler_test.cc
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2019, 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 "protocol_handler/service_status_update_handler.h"
+#include "gtest/gtest.h"
+#include "protocol_handler/mock_service_status_update_handler_listener.h"
+
+namespace test {
+namespace components {
+namespace protocol_handler_test {
+
+namespace {
+const uint32_t kConnectionKey = 123u;
+}
+
+using namespace protocol_handler;
+using ::testing::_;
+using ::testing::Return;
+using namespace hmi_apis;
+typedef utils::Optional<Common_ServiceStatusUpdateReason::eType>
+ UpdateReasonOptional;
+typedef std::shared_ptr<ServiceStatusUpdateHandler>
+ ServiceStatusUpdateHandlerPtr;
+typedef std::shared_ptr<MockServiceStatusUpdateHandlerListener>
+ MockServiceStatusUpdateHandlerListenerPtr;
+
+struct ServiceUpdate {
+ ServiceType service_type_;
+ ServiceStatus service_status_;
+ ServiceUpdate(ServiceType type, ServiceStatus status)
+ : service_type_(type), service_status_(status) {}
+};
+
+class ServiceStatusUpdateHandlerTest
+ : public ::testing::TestWithParam<ServiceUpdate> {
+ public:
+ ServiceStatusUpdateHandlerTest() {
+ mock_service_status_update_handler_listener_.reset(
+ new MockServiceStatusUpdateHandlerListener);
+ service_status_update_handler_ =
+ std::make_shared<ServiceStatusUpdateHandler>(
+ &(*mock_service_status_update_handler_listener_));
+ }
+
+ Common_ServiceEvent::eType GetServiceEvent(ServiceStatus status) {
+ switch (status) {
+ case ServiceStatus::SERVICE_ACCEPTED:
+ case ServiceStatus::PROTECTION_DISABLED: {
+ return Common_ServiceEvent::REQUEST_ACCEPTED;
+ }
+ case ServiceStatus::SERVICE_RECEIVED: {
+ return Common_ServiceEvent::REQUEST_RECEIVED;
+ }
+ case ServiceStatus::SERVICE_START_FAILED:
+ case ServiceStatus::PTU_FAILED:
+ case ServiceStatus::CERT_INVALID:
+ case ServiceStatus::INVALID_TIME:
+ case ServiceStatus::PROTECTION_ENFORCED: {
+ return Common_ServiceEvent::REQUEST_REJECTED;
+ }
+ default: { return Common_ServiceEvent::INVALID_ENUM; }
+ }
+ }
+
+ UpdateReasonOptional GetUpdateReason(ServiceStatus status) {
+ switch (status) {
+ case ServiceStatus::SERVICE_START_FAILED:
+ case ServiceStatus::SERVICE_ACCEPTED:
+ case ServiceStatus::SERVICE_RECEIVED: {
+ return UpdateReasonOptional::EMPTY;
+ }
+ case ServiceStatus::PTU_FAILED: {
+ auto reason = Common_ServiceStatusUpdateReason::PTU_FAILED;
+ return reason;
+ }
+ case ServiceStatus::CERT_INVALID: {
+ auto reason = Common_ServiceStatusUpdateReason::INVALID_CERT;
+ return reason;
+ }
+ case ServiceStatus::INVALID_TIME: {
+ auto reason = Common_ServiceStatusUpdateReason::INVALID_TIME;
+ return reason;
+ }
+ case ServiceStatus::PROTECTION_ENFORCED: {
+ auto reason = Common_ServiceStatusUpdateReason::PROTECTION_ENFORCED;
+ return reason;
+ }
+ case ServiceStatus::PROTECTION_DISABLED: {
+ auto reason = Common_ServiceStatusUpdateReason::PROTECTION_DISABLED;
+ return reason;
+ }
+ default: {
+ auto reason = Common_ServiceStatusUpdateReason::INVALID_ENUM;
+ return reason;
+ }
+ }
+ }
+
+ public:
+ MockServiceStatusUpdateHandlerListenerPtr
+ mock_service_status_update_handler_listener_;
+ ServiceStatusUpdateHandlerPtr service_status_update_handler_;
+};
+
+INSTANTIATE_TEST_CASE_P(
+ OnServiceUpdate_SERVICE_ACCEPTED,
+ ServiceStatusUpdateHandlerTest,
+ ::testing::Values(
+ ServiceUpdate(ServiceType::kAudio, ServiceStatus::SERVICE_ACCEPTED),
+ ServiceUpdate(ServiceType::kMobileNav, ServiceStatus::SERVICE_ACCEPTED),
+ ServiceUpdate(ServiceType::kRpc, ServiceStatus::SERVICE_ACCEPTED)));
+
+INSTANTIATE_TEST_CASE_P(
+ OnServiceUpdate_SERVICE_RECEIVED,
+ ServiceStatusUpdateHandlerTest,
+ ::testing::Values(
+ ServiceUpdate(ServiceType::kAudio, ServiceStatus::SERVICE_RECEIVED),
+ ServiceUpdate(ServiceType::kMobileNav, ServiceStatus::SERVICE_RECEIVED),
+ ServiceUpdate(ServiceType::kRpc, ServiceStatus::SERVICE_RECEIVED)));
+
+INSTANTIATE_TEST_CASE_P(
+ OnServiceUpdate_SERVICE_START_FAILED,
+ ServiceStatusUpdateHandlerTest,
+ ::testing::Values(
+ ServiceUpdate(ServiceType::kAudio, ServiceStatus::SERVICE_START_FAILED),
+ ServiceUpdate(ServiceType::kMobileNav,
+ ServiceStatus::SERVICE_START_FAILED),
+ ServiceUpdate(ServiceType::kRpc, ServiceStatus::SERVICE_START_FAILED)));
+
+INSTANTIATE_TEST_CASE_P(
+ OnServiceUpdate_CERT_INVALID,
+ ServiceStatusUpdateHandlerTest,
+ ::testing::Values(
+ ServiceUpdate(ServiceType::kAudio, ServiceStatus::CERT_INVALID),
+ ServiceUpdate(ServiceType::kMobileNav, ServiceStatus::CERT_INVALID),
+ ServiceUpdate(ServiceType::kRpc, ServiceStatus::CERT_INVALID)));
+
+INSTANTIATE_TEST_CASE_P(
+ OnServiceUpdate_INVALID_TIME,
+ ServiceStatusUpdateHandlerTest,
+ ::testing::Values(
+ ServiceUpdate(ServiceType::kAudio, ServiceStatus::INVALID_TIME),
+ ServiceUpdate(ServiceType::kMobileNav, ServiceStatus::INVALID_TIME),
+ ServiceUpdate(ServiceType::kRpc, ServiceStatus::INVALID_TIME)));
+
+INSTANTIATE_TEST_CASE_P(
+ OnServiceUpdate_PTU_FAILED,
+ ServiceStatusUpdateHandlerTest,
+ ::testing::Values(
+ ServiceUpdate(ServiceType::kAudio, ServiceStatus::PTU_FAILED),
+ ServiceUpdate(ServiceType::kMobileNav, ServiceStatus::PTU_FAILED),
+ ServiceUpdate(ServiceType::kRpc, ServiceStatus::PTU_FAILED)));
+
+INSTANTIATE_TEST_CASE_P(
+ OnServiceUpdate_PROTECTION_ENFRORCED,
+ ServiceStatusUpdateHandlerTest,
+ ::testing::Values(
+ ServiceUpdate(ServiceType::kAudio, ServiceStatus::PROTECTION_ENFORCED),
+ ServiceUpdate(ServiceType::kMobileNav,
+ ServiceStatus::PROTECTION_ENFORCED),
+ ServiceUpdate(ServiceType::kRpc, ServiceStatus::PROTECTION_ENFORCED)));
+
+INSTANTIATE_TEST_CASE_P(
+ OnServiceUpdate_PROTECTION_DISABLED,
+ ServiceStatusUpdateHandlerTest,
+ ::testing::Values(
+ ServiceUpdate(ServiceType::kAudio, ServiceStatus::PROTECTION_DISABLED),
+ ServiceUpdate(ServiceType::kMobileNav,
+ ServiceStatus::PROTECTION_DISABLED),
+ ServiceUpdate(ServiceType::kRpc, ServiceStatus::PROTECTION_DISABLED)));
+
+TEST_P(ServiceStatusUpdateHandlerTest, OnServiceUpdate) {
+ auto service_event_ = GetServiceEvent(GetParam().service_status_);
+ auto reason_ = GetUpdateReason(GetParam().service_status_);
+
+ EXPECT_CALL(
+ *mock_service_status_update_handler_listener_,
+ ProcessServiceStatusUpdate(kConnectionKey, _, service_event_, reason_))
+ .Times(1);
+
+ service_status_update_handler_->OnServiceUpdate(
+ kConnectionKey, GetParam().service_type_, GetParam().service_status_);
+}
+
+TEST_F(ServiceStatusUpdateHandlerTest, GetHMIServiceType) {
+ EXPECT_EQ(Common_ServiceType::RPC, GetHMIServiceType(ServiceType::kRpc));
+ EXPECT_EQ(Common_ServiceType::AUDIO, GetHMIServiceType(ServiceType::kAudio));
+ EXPECT_EQ(Common_ServiceType::VIDEO,
+ GetHMIServiceType(ServiceType::kMobileNav));
+ EXPECT_EQ(Common_ServiceType::INVALID_ENUM,
+ GetHMIServiceType(ServiceType::kInvalidServiceType));
+}
+
+} // namespace protocol_handler_test
+} // namespace components
+} // namespace test
diff --git a/src/components/security_manager/include/security_manager/security_manager_impl.h b/src/components/security_manager/include/security_manager/security_manager_impl.h
index f2a417a43d..ee00e0774a 100644
--- a/src/components/security_manager/include/security_manager/security_manager_impl.h
+++ b/src/components/security_manager/include/security_manager/security_manager_impl.h
@@ -200,7 +200,7 @@ class SecurityManagerImpl : public SecurityManager,
/**
* @brief Notify all listeners that handshake was failed
*/
- void NotifyListenersOnHandshakeFailed() OVERRIDE;
+ void NotifyListenersOnGetSystemTimeFailed() OVERRIDE;
/**
* @brief Check is policy certificate data is empty
@@ -214,6 +214,16 @@ class SecurityManagerImpl : public SecurityManager,
*/
static const char* ConfigSection();
+ void ProcessFailedPTU() OVERRIDE;
+
+#ifdef EXTERNAL_PROPRIETARY_MODE
+ /**
+ * @brief ProcessFailedCertDecrypt is called to notify listeners that
+ * certificate decryption failed in the external flow
+ */
+ void ProcessFailedCertDecrypt() OVERRIDE;
+#endif
+
private:
/**
* \brief Sends Handshake binary data to mobile application
@@ -280,6 +290,17 @@ class SecurityManagerImpl : public SecurityManager,
*/
void OnSystemTimeArrived(const time_t utc_time) OVERRIDE;
+ /**
+ * @brief OnSystemTimeFailed Notify about system request failure
+ */
+ void OnSystemTimeFailed() OVERRIDE;
+
+ /**
+ * @brief ResetPendingSystemTimeRequests resets waiting for system time
+ * requests flag
+ */
+ void ResetPendingSystemTimeRequests();
+
// Thread that pumps handshake data
SecurityMessageLoop security_messages_;
diff --git a/src/components/security_manager/src/security_manager_impl.cc b/src/components/security_manager/src/security_manager_impl.cc
index 19c2ee2b11..41e2b07a03 100644
--- a/src/components/security_manager/src/security_manager_impl.cc
+++ b/src/components/security_manager/src/security_manager_impl.cc
@@ -213,6 +213,13 @@ void SecurityManagerImpl::ResumeHandshake(uint32_t connection_key) {
return;
}
+ LOG4CXX_DEBUG(logger_,
+ "Connection key : "
+ << connection_key
+ << " is waiting for certificate: " << std::boolalpha
+ << waiting_for_certificate_ << " and has certificate: "
+ << ssl_context->HasCertificate());
+
ssl_context->ResetConnection();
if (!waiting_for_certificate_ && !ssl_context->HasCertificate()) {
NotifyListenersOnHandshakeDone(connection_key,
@@ -228,6 +235,7 @@ void SecurityManagerImpl::StartHandshake(uint32_t connection_key) {
LOG4CXX_INFO(logger_, "StartHandshake: connection_key " << connection_key);
security_manager::SSLContext* ssl_context = session_observer_->GetSSLContext(
connection_key, protocol_handler::kControl);
+
if (!ssl_context) {
const std::string error_text(
"StartHandshake failed, "
@@ -277,6 +285,7 @@ void SecurityManagerImpl::ProceedHandshake(
time_t cert_due_date;
if (!ssl_context->GetCertificateDueDate(cert_due_date)) {
LOG4CXX_ERROR(logger_, "Failed to get certificate due date!");
+ PostponeHandshake(connection_key);
return;
}
@@ -388,6 +397,68 @@ void SecurityManagerImpl::OnSystemTimeArrived(const time_t utc_time) {
awaiting_time_connections_.clear();
}
+void SecurityManagerImpl::OnSystemTimeFailed() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ {
+ sync_primitives::AutoLock lock(waiters_lock_);
+ waiting_for_time_ = false;
+ }
+
+ NotifyListenersOnGetSystemTimeFailed();
+
+ awaiting_time_connections_.clear();
+}
+
+void SecurityManagerImpl::ProcessFailedPTU() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (listeners_.empty()) {
+ LOG4CXX_DEBUG(logger_, "listeners arrays IS EMPTY!");
+ return;
+ }
+
+ std::list<SecurityManagerListener*> listeners_to_remove;
+ for (auto listener : listeners_) {
+ if (listener->OnPTUFailed()) {
+ listeners_to_remove.push_back(listener);
+ }
+ }
+
+ for (auto& listener : listeners_to_remove) {
+ auto it = std::find(listeners_.begin(), listeners_.end(), listener);
+ DCHECK(it != listeners_.end());
+ LOG4CXX_DEBUG(logger_, "Destroying listener: " << *it);
+ delete (*it);
+ listeners_.erase(it);
+ }
+}
+
+#ifdef EXTERNAL_PROPRIETARY_MODE
+void SecurityManagerImpl::ProcessFailedCertDecrypt() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ {
+ sync_primitives::AutoLock lock(waiters_lock_);
+ waiting_for_certificate_ = false;
+ }
+
+ std::list<SecurityManagerListener*> listeners_to_remove;
+ for (auto listener : listeners_) {
+ if (listener->OnCertDecryptFailed()) {
+ listeners_to_remove.push_back(listener);
+ }
+ }
+
+ for (auto& listener : listeners_to_remove) {
+ auto it = std::find(listeners_.begin(), listeners_.end(), listener);
+ DCHECK(it != listeners_.end());
+ LOG4CXX_DEBUG(logger_, "Destroying listener: " << *it);
+ delete (*it);
+ listeners_.erase(it);
+ }
+
+ awaiting_certificate_connections_.clear();
+}
+#endif
+
void SecurityManagerImpl::NotifyListenersOnHandshakeDone(
const uint32_t& connection_key, SSLContext::HandshakeResult error) {
LOG4CXX_AUTO_TRACE(logger_);
@@ -412,11 +483,15 @@ void SecurityManagerImpl::NotifyOnCertificateUpdateRequired() {
}
}
-void SecurityManagerImpl::NotifyListenersOnHandshakeFailed() {
+void SecurityManagerImpl::ResetPendingSystemTimeRequests() {
+ system_time_handler_->ResetPendingSystemTimeRequests();
+}
+
+void SecurityManagerImpl::NotifyListenersOnGetSystemTimeFailed() {
LOG4CXX_AUTO_TRACE(logger_);
std::list<SecurityManagerListener*>::iterator it = listeners_.begin();
while (it != listeners_.end()) {
- if ((*it)->OnHandshakeFailed()) {
+ if ((*it)->OnGetSystemTimeFailed()) {
LOG4CXX_DEBUG(logger_, "Destroying listener: " << *it);
delete (*it);
it = listeners_.erase(it);
diff --git a/src/components/utils/include/utils/system_time_handler.h b/src/components/utils/include/utils/system_time_handler.h
index 15b2dd0cca..2013622f30 100644
--- a/src/components/utils/include/utils/system_time_handler.h
+++ b/src/components/utils/include/utils/system_time_handler.h
@@ -50,6 +50,11 @@ class SystemTimeListener {
* @param utc_time current system time.
*/
virtual void OnSystemTimeArrived(const time_t utc_time) = 0;
+
+ /**
+ * @brief OnSystemTimeFailed Notify about system request failure
+ */
+ virtual void OnSystemTimeFailed() = 0;
};
/**
@@ -97,6 +102,12 @@ class SystemTimeHandler {
time_t GetUTCTime();
/**
+ * @brief ResetPendingSystemTimeRequests resets waiting for system time
+ * requests flag
+ */
+ virtual void ResetPendingSystemTimeRequests() = 0;
+
+ /**
* @brief Checks if system time is ready
* and can be requested by GetSystemTime request
* @return True if HMI is ready to provide UTC time