summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrii Kalinich <AKalinich@luxoft.com>2021-01-12 14:06:28 -0500
committerLitvinenkoIra <ilytvynenko@luxoft.com>2021-01-21 10:03:44 +0200
commit500fa2d826f2d05a124ebda205ce9575c174e514 (patch)
treec977814c943f97abd8568f5e950b04e9c22ddfb3
parent98c4ff9811260a939e7892a0aa49d98914ad3b06 (diff)
downloadsdl_core-500fa2d826f2d05a124ebda205ce9575c174e514.tar.gz
Add vehicle data params to StartSessionAck
Also added some unit tests to cover happy path Additionally, implemented new waiter-function for blocking threads until HMI readiness and release them once all data became available.
-rw-r--r--src/components/application_manager/include/application_manager/application_manager_impl.h13
-rw-r--r--src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/update_device_list_request.h19
-rw-r--r--src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/register_app_interface_request.h6
-rw-r--r--src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/update_device_list_request.cc40
-rw-r--r--src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/register_app_interface_request.cc18
-rw-r--r--src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/hmi/update_device_list_request_test.cc41
-rw-r--r--src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/register_app_interface_request_test.cc21
-rw-r--r--src/components/application_manager/src/application_manager_impl.cc68
-rw-r--r--src/components/connection_handler/include/connection_handler/connection_handler_impl.h2
-rw-r--r--src/components/connection_handler/src/connection_handler_impl.cc9
-rw-r--r--src/components/include/application_manager/application_manager.h6
-rw-r--r--src/components/include/connection_handler/connection_handler.h20
-rw-r--r--src/components/include/connection_handler/connection_handler_observer.h8
-rw-r--r--src/components/include/protocol/bson_object_keys.h6
-rw-r--r--src/components/include/test/application_manager/mock_application_manager.h1
-rw-r--r--src/components/include/test/connection_handler/mock_connection_handler.h2
-rw-r--r--src/components/include/test/connection_handler/mock_connection_handler_observer.h2
-rw-r--r--src/components/protocol/src/bson_object_keys.cc6
-rw-r--r--src/components/protocol_handler/include/protocol_handler/protocol_handler_impl.h8
-rw-r--r--src/components/protocol_handler/src/protocol_handler_impl.cc39
-rw-r--r--src/components/protocol_handler/test/protocol_handler_tm_test.cc103
21 files changed, 318 insertions, 120 deletions
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 5bcea1eac9..af2b44180c 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
@@ -700,6 +700,9 @@ class ApplicationManagerImpl
void RemoveDevice(
const connection_handler::DeviceHandle& device_handle) OVERRIDE;
+ bool GetProtocolVehicleData(
+ connection_handler::ProtocolVehicleData& data) OVERRIDE;
+
/**
* @brief OnDeviceSwitchingStart is invoked on device transport switching
* start (e.g. from Bluetooth to USB) and creates waiting list of applications
@@ -1144,6 +1147,8 @@ class ApplicationManagerImpl
return is_stopping_;
}
+ bool WaitForHmiIsReady() OVERRIDE;
+
/**
* @brief ProcessReconnection handles reconnection flow for application on
* transport switch
@@ -1186,6 +1191,11 @@ class ApplicationManagerImpl
private:
/**
+ * @brief Sets is_stopping flag to true
+ */
+ void InitiateStopping();
+
+ /**
* @brief Adds application to registered applications list and marks it as
* registered
* @param application Application that should be added to registered
@@ -1642,6 +1652,9 @@ class ApplicationManagerImpl
sync_primitives::Lock close_app_timer_pool_lock_;
sync_primitives::Lock end_stream_timer_pool_lock_;
+ mutable sync_primitives::Lock wait_for_hmi_lock_;
+ sync_primitives::ConditionalVariable wait_for_hmi_condvar_;
+
StateControllerImpl state_ctrl_;
std::unique_ptr<app_launch::AppLaunchData> app_launch_dto_;
std::unique_ptr<app_launch::AppLaunchCtrl> app_launch_ctrl_;
diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/update_device_list_request.h b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/update_device_list_request.h
index db4f265a9f..ed89bc73ec 100644
--- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/update_device_list_request.h
+++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/update_device_list_request.h
@@ -46,8 +46,7 @@ namespace commands {
/**
* @brief UpdateDeviceListRequest command class
**/
-class UpdateDeviceListRequest : public app_mngr::commands::RequestToHMI,
- public app_mngr::event_engine::EventObserver {
+class UpdateDeviceListRequest : public app_mngr::commands::RequestToHMI {
public:
/**
* @brief UpdateDeviceListRequest class constructor
@@ -70,23 +69,7 @@ class UpdateDeviceListRequest : public app_mngr::commands::RequestToHMI,
**/
virtual void Run();
- /**
- * @brief Interface method that is called whenever new event received
- * Need to observe OnHMIReady event, to send UpdateDeviceListRequest
- * when HMI will be ready
- * @param event The received event
- */
- virtual void on_event(const app_mngr::event_engine::Event& event);
-
- /**
- * @brief Need to stop execution StopMethod if HMI did not started
- */
- virtual bool CleanUp();
-
private:
- sync_primitives::Lock wait_hmi_lock;
- sync_primitives::ConditionalVariable termination_condition_;
-
DISALLOW_COPY_AND_ASSIGN(UpdateDeviceListRequest);
};
diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/register_app_interface_request.h b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/register_app_interface_request.h
index fae8f5eeb7..ae52caf0f7 100644
--- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/register_app_interface_request.h
+++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/register_app_interface_request.h
@@ -261,12 +261,6 @@ class RegisterAppInterfaceRequest
const smart_objects::SmartObject& message);
/**
- * @brief WaitForHMIIsReady blocking function. Waits for HMI be ready for
- * requests processing
- */
- void WaitForHMIIsReady();
-
- /**
* @brief FillApplicationParams set app application attributes from the RAI
* request
* @param application applicaiton to fill params
diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/update_device_list_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/update_device_list_request.cc
index c8aa295645..4d055564de 100644
--- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/update_device_list_request.cc
+++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/update_device_list_request.cc
@@ -53,51 +53,27 @@ UpdateDeviceListRequest::UpdateDeviceListRequest(
application_manager,
rpc_service,
hmi_capabilities,
- policy_handle)
- , EventObserver(application_manager_.event_dispatcher()) {}
+ policy_handle) {}
UpdateDeviceListRequest::~UpdateDeviceListRequest() {}
void UpdateDeviceListRequest::Run() {
SDL_LOG_AUTO_TRACE();
- sync_primitives::AutoLock auto_lock(wait_hmi_lock);
// Fix problem with SDL and HMI HTML. This problem is not actual for HMI PASA.
// Flag conditional compilation for specific customer is used in order to
// exclude
// hit code to RTC
- if (true == application_manager_.get_settings().launch_hmi()) {
- if (!application_manager_.IsHMICooperating()) {
- SDL_LOG_INFO("Wait for HMI Cooperation");
- subscribe_on_event(hmi_apis::FunctionID::BasicCommunication_OnReady);
- termination_condition_.Wait(auto_lock);
- SDL_LOG_DEBUG("HMI Cooperation OK");
+ if (application_manager_.get_settings().launch_hmi()) {
+ SDL_LOG_INFO("Wait for HMI Cooperation");
+ if (!application_manager_.WaitForHmiIsReady()) {
+ SDL_LOG_ERROR("HMI is not ready");
+ return;
}
- }
-
- SendRequest();
-}
-void UpdateDeviceListRequest::on_event(const event_engine::Event& event) {
- SDL_LOG_AUTO_TRACE();
- sync_primitives::AutoLock auto_lock(wait_hmi_lock);
- switch (event.id()) {
- case hmi_apis::FunctionID::BasicCommunication_OnReady: {
- SDL_LOG_INFO("received OnReady");
- unsubscribe_from_event(hmi_apis::FunctionID::BasicCommunication_OnReady);
- termination_condition_.Broadcast();
- break;
- };
- default: {
- SDL_LOG_ERROR("Unknown event " << event.id());
- break;
- };
+ SDL_LOG_DEBUG("HMI Cooperation is OK");
}
-}
-bool UpdateDeviceListRequest::CleanUp() {
- sync_primitives::AutoLock auto_lock(wait_hmi_lock);
- termination_condition_.Broadcast();
- return true;
+ SendRequest();
}
} // namespace commands
diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/register_app_interface_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/register_app_interface_request.cc
index 6ac830c378..920805be7c 100644
--- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/register_app_interface_request.cc
+++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/register_app_interface_request.cc
@@ -159,18 +159,6 @@ uint32_t RegisterAppInterfaceRequest::default_timeout() const {
return 0;
}
-void RegisterAppInterfaceRequest::WaitForHMIIsReady() {
- while (!application_manager_.IsStopping() &&
- !application_manager_.IsHMICooperating()) {
- SDL_LOG_DEBUG("Waiting for the HMI... conn_key="
- << connection_key() << ", correlation_id=" << correlation_id()
- << ", default_timeout=" << default_timeout()
- << ", thread=" << pthread_self());
- sleep(1);
- // TODO(DK): timer_->StartWait(1);
- }
-}
-
void RegisterAppInterfaceRequest::FillApplicationParams(
ApplicationSharedPtr application) {
SDL_LOG_AUTO_TRACE();
@@ -488,10 +476,8 @@ void RegisterAppInterfaceRequest::Run() {
SDL_LOG_AUTO_TRACE();
SDL_LOG_DEBUG("Connection key is " << connection_key());
- WaitForHMIIsReady();
-
- if (application_manager_.IsStopping()) {
- SDL_LOG_WARN("The ApplicationManager is stopping!");
+ if (!application_manager_.WaitForHmiIsReady()) {
+ SDL_LOG_WARN("Failed to wait for HMI readiness");
return;
}
diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/hmi/update_device_list_request_test.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/hmi/update_device_list_request_test.cc
index 31c03a7ed5..9760462d05 100644
--- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/hmi/update_device_list_request_test.cc
+++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/hmi/update_device_list_request_test.cc
@@ -92,10 +92,6 @@ class UpdateDeviceListRequestTest
TEST_F(UpdateDeviceListRequestTest, RUN_LaunchHMIReturnsFalse) {
MessageSharedPtr command_msg = CreateCommandMsg();
- EXPECT_CALL(app_mngr_, event_dispatcher())
- .WillOnce(ReturnRef(mock_event_dispatcher_));
- EXPECT_CALL(mock_event_dispatcher_, remove_observer(_));
-
UpdateDeviceListRequestPtr command(
CreateCommand<UpdateDeviceListRequest>(command_msg));
@@ -103,7 +99,7 @@ TEST_F(UpdateDeviceListRequestTest, RUN_LaunchHMIReturnsFalse) {
EXPECT_CALL(settings_, launch_hmi()).WillOnce(Return(false));
- EXPECT_CALL(app_mngr_, IsHMICooperating()).Times(0);
+ EXPECT_CALL(app_mngr_, WaitForHmiIsReady()).Times(0);
EXPECT_CALL(mock_rpc_service_, SendMessageToHMI(command_msg));
command->Run();
@@ -114,13 +110,9 @@ TEST_F(UpdateDeviceListRequestTest, RUN_LaunchHMIReturnsFalse) {
CommandImpl::protocol_version_);
}
-TEST_F(UpdateDeviceListRequestTest, RUN_HMICooperatingReturnsTrue_SUCCESSS) {
+TEST_F(UpdateDeviceListRequestTest, RUN_HMICooperatingReturnsTrue_SUCCESS) {
MessageSharedPtr command_msg = CreateCommandMsg();
- EXPECT_CALL(app_mngr_, event_dispatcher())
- .WillOnce(ReturnRef(mock_event_dispatcher_));
- EXPECT_CALL(mock_event_dispatcher_, remove_observer(_));
-
UpdateDeviceListRequestPtr command(
CreateCommand<UpdateDeviceListRequest>(command_msg));
@@ -128,7 +120,7 @@ TEST_F(UpdateDeviceListRequestTest, RUN_HMICooperatingReturnsTrue_SUCCESSS) {
EXPECT_CALL(settings_, launch_hmi()).WillOnce(Return(true));
- EXPECT_CALL(app_mngr_, IsHMICooperating()).WillOnce(Return(true));
+ EXPECT_CALL(app_mngr_, WaitForHmiIsReady()).WillOnce(Return(true));
EXPECT_CALL(mock_rpc_service_, SendMessageToHMI(command_msg));
command->Run();
@@ -139,29 +131,20 @@ TEST_F(UpdateDeviceListRequestTest, RUN_HMICooperatingReturnsTrue_SUCCESSS) {
CommandImpl::protocol_version_);
}
-TEST_F(UpdateDeviceListRequestTest, OnEvent_WrongEventId_UNSUCCESS) {
- Event event(Event::EventID::INVALID_ENUM);
-
- EXPECT_CALL(app_mngr_, event_dispatcher())
- .WillOnce(ReturnRef(mock_event_dispatcher_));
- EXPECT_CALL(mock_event_dispatcher_, remove_observer(_));
-
- UpdateDeviceListRequestPtr command(CreateCommand<UpdateDeviceListRequest>());
+TEST_F(UpdateDeviceListRequestTest, RUN_HMICooperatingReturnsFalse_UNSUCCESS) {
+ MessageSharedPtr command_msg = CreateCommandMsg();
- command->on_event(event);
-}
+ UpdateDeviceListRequestPtr command(
+ CreateCommand<UpdateDeviceListRequest>(command_msg));
-TEST_F(UpdateDeviceListRequestTest, OnEvent_SUCCESS) {
- Event event(Event::EventID::BasicCommunication_OnReady);
+ EXPECT_CALL(app_mngr_, get_settings()).WillOnce(ReturnRef(settings_));
- EXPECT_CALL(app_mngr_, event_dispatcher())
- .WillOnce(ReturnRef(mock_event_dispatcher_));
- EXPECT_CALL(mock_event_dispatcher_, remove_observer(_, _));
- EXPECT_CALL(mock_event_dispatcher_, remove_observer(_));
+ EXPECT_CALL(settings_, launch_hmi()).WillOnce(Return(true));
- UpdateDeviceListRequestPtr command(CreateCommand<UpdateDeviceListRequest>());
+ EXPECT_CALL(app_mngr_, WaitForHmiIsReady()).WillOnce(Return(false));
+ EXPECT_CALL(mock_rpc_service_, SendMessageToHMI(_)).Times(0);
- command->on_event(event);
+ command->Run();
}
} // namespace update_device_list_request
diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/register_app_interface_request_test.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/register_app_interface_request_test.cc
index fab648fc95..4572a6d907 100644
--- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/register_app_interface_request_test.cc
+++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/register_app_interface_request_test.cc
@@ -198,7 +198,7 @@ class RegisterAppInterfaceRequestTest
void InitGetters() {
ON_CALL(app_mngr_, GetCorrectMobileIDFromMessage(msg_))
.WillByDefault(Return(kAppId1));
- ON_CALL(app_mngr_, IsHMICooperating()).WillByDefault(Return(true));
+ ON_CALL(app_mngr_, WaitForHmiIsReady()).WillByDefault(Return(true));
ON_CALL(app_mngr_, resume_controller())
.WillByDefault(ReturnRef(mock_resume_crt_));
ON_CALL(app_mngr_, connection_handler())
@@ -416,11 +416,7 @@ TEST_F(RegisterAppInterfaceRequestTest, DefaultTimeout_CheckIfZero_SUCCESS) {
TEST_F(RegisterAppInterfaceRequestTest, Run_MinimalData_SUCCESS) {
InitBasicMessage();
(*msg_)[am::strings::msg_params][am::strings::hash_id] = kAppId1;
- EXPECT_CALL(app_mngr_, IsStopping())
- .WillOnce(Return(false))
- .WillOnce(Return(true))
- .WillOnce(Return(false));
- ON_CALL(app_mngr_, IsHMICooperating()).WillByDefault(Return(false));
+ EXPECT_CALL(app_mngr_, WaitForHmiIsReady()).WillOnce(Return(true));
EXPECT_CALL(app_mngr_, IsApplicationForbidden(_, _)).WillOnce(Return(false));
ON_CALL(mock_connection_handler_,
@@ -504,11 +500,7 @@ TEST_F(RegisterAppInterfaceRequestTest,
Run_HmiInterfacesStateAvailable_SUCCESS) {
InitBasicMessage();
- EXPECT_CALL(app_mngr_, IsStopping())
- .WillOnce(Return(false))
- .WillOnce(Return(true))
- .WillOnce(Return(false));
- ON_CALL(app_mngr_, IsHMICooperating()).WillByDefault(Return(false));
+ ON_CALL(app_mngr_, WaitForHmiIsReady()).WillByDefault(Return(true));
EXPECT_CALL(app_mngr_, IsApplicationForbidden(_, _)).WillOnce(Return(false));
ON_CALL(mock_connection_handler_,
@@ -808,11 +800,8 @@ TEST_F(RegisterAppInterfaceRequestTest,
InitBasicMessage();
(*msg_)[am::strings::params][am::strings::connection_key] = kConnectionKey2;
- EXPECT_CALL(app_mngr_, IsStopping())
- .WillOnce(Return(false))
- .WillOnce(Return(true))
- .WillOnce(Return(false));
- ON_CALL(app_mngr_, IsHMICooperating()).WillByDefault(Return(false));
+
+ ON_CALL(app_mngr_, WaitForHmiIsReady()).WillByDefault(Return(true));
EXPECT_CALL(app_mngr_, IsApplicationForbidden(kConnectionKey2, kAppId1))
.WillOnce(Return(false));
diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc
index fcaa7c0536..2313ce5693 100644
--- a/src/components/application_manager/src/application_manager_impl.cc
+++ b/src/components/application_manager/src/application_manager_impl.cc
@@ -228,7 +228,7 @@ ApplicationManagerImpl::ApplicationManagerImpl(
ApplicationManagerImpl::~ApplicationManagerImpl() {
SDL_LOG_AUTO_TRACE();
- is_stopping_.store(true);
+ InitiateStopping();
SendOnSDLClose();
media_manager_ = NULL;
hmi_handler_ = NULL;
@@ -1598,6 +1598,58 @@ void ApplicationManagerImpl::OnDeviceListUpdated(
RefreshCloudAppInformation();
}
+bool ApplicationManagerImpl::WaitForHmiIsReady() {
+ sync_primitives::AutoLock lock(wait_for_hmi_lock_);
+ if (!IsStopping() && !IsHMICooperating()) {
+ SDL_LOG_DEBUG("Waiting for the HMI cooperation...");
+ wait_for_hmi_condvar_.Wait(lock);
+ }
+
+ if (IsStopping()) {
+ SDL_LOG_WARN("System is terminating...");
+ return false;
+ }
+
+ return IsHMICooperating();
+}
+
+bool ApplicationManagerImpl::GetProtocolVehicleData(
+ connection_handler::ProtocolVehicleData& data) {
+ SDL_LOG_AUTO_TRACE();
+ using namespace protocol_handler::strings;
+
+ if (!WaitForHmiIsReady()) {
+ SDL_LOG_ERROR("Failed to wait for HMI readiness");
+ return false;
+ }
+
+ const auto vehicle_type_ptr = hmi_capabilities_->vehicle_type();
+ if (vehicle_type_ptr) {
+ if (vehicle_type_ptr->keyExists(vehicle_make)) {
+ data.vehicle_make = vehicle_type_ptr->getElement(vehicle_make).asString();
+ }
+
+ if (vehicle_type_ptr->keyExists(vehicle_model)) {
+ data.vehicle_model =
+ vehicle_type_ptr->getElement(vehicle_model).asString();
+ }
+
+ if (vehicle_type_ptr->keyExists(vehicle_model_year)) {
+ data.vehicle_year =
+ vehicle_type_ptr->getElement(vehicle_model_year).asString();
+ }
+
+ if (vehicle_type_ptr->keyExists(vehicle_trim)) {
+ data.vehicle_trim = vehicle_type_ptr->getElement(vehicle_trim).asString();
+ }
+ }
+
+ data.vehicle_system_software_version = hmi_capabilities_->ccpu_version();
+ data.vehicle_system_hardware_version = hmi_capabilities_->hardware_version();
+
+ return true;
+}
+
void ApplicationManagerImpl::OnFindNewApplicationsRequest() {
connection_handler().ConnectToAllDevices();
SDL_LOG_DEBUG("Starting application list update timer");
@@ -2537,7 +2589,7 @@ bool ApplicationManagerImpl::Init(
bool ApplicationManagerImpl::Stop() {
SDL_LOG_AUTO_TRACE();
- is_stopping_.store(true);
+ InitiateStopping();
application_list_update_timer_.Stop();
try {
if (unregister_reason_ ==
@@ -2952,7 +3004,7 @@ void ApplicationManagerImpl::SetUnregisterAllApplicationsReason(
void ApplicationManagerImpl::HeadUnitReset(
mobile_api::AppInterfaceUnregisteredReason::eType reason) {
SDL_LOG_AUTO_TRACE();
- is_stopping_.store(true);
+ InitiateStopping();
switch (reason) {
case mobile_api::AppInterfaceUnregisteredReason::MASTER_RESET: {
SDL_LOG_TRACE("Performing MASTER_RESET");
@@ -4105,7 +4157,17 @@ bool ApplicationManagerImpl::IsHMICooperating() const {
}
void ApplicationManagerImpl::SetHMICooperating(const bool hmi_cooperating) {
+ SDL_LOG_AUTO_TRACE();
+ sync_primitives::AutoLock lock(wait_for_hmi_lock_);
hmi_cooperating_ = hmi_cooperating;
+ wait_for_hmi_condvar_.Broadcast();
+}
+
+void ApplicationManagerImpl::InitiateStopping() {
+ SDL_LOG_AUTO_TRACE();
+ sync_primitives::AutoLock lock(wait_for_hmi_lock_);
+ is_stopping_.store(true);
+ wait_for_hmi_condvar_.Broadcast();
}
void ApplicationManagerImpl::OnApplicationListUpdateTimer() {
diff --git a/src/components/connection_handler/include/connection_handler/connection_handler_impl.h b/src/components/connection_handler/include/connection_handler/connection_handler_impl.h
index a7dfd29b31..25a89ea4b3 100644
--- a/src/components/connection_handler/include/connection_handler/connection_handler_impl.h
+++ b/src/components/connection_handler/include/connection_handler/connection_handler_impl.h
@@ -648,6 +648,8 @@ class ConnectionHandlerImpl
void CreateWebEngineDevice() OVERRIDE;
+ bool GetProtocolVehicleData(ProtocolVehicleData& data) OVERRIDE;
+
private:
/**
* \brief Disconnect application.
diff --git a/src/components/connection_handler/src/connection_handler_impl.cc b/src/components/connection_handler/src/connection_handler_impl.cc
index a771f0a104..da269721eb 100644
--- a/src/components/connection_handler/src/connection_handler_impl.cc
+++ b/src/components/connection_handler/src/connection_handler_impl.cc
@@ -919,6 +919,15 @@ void ConnectionHandlerImpl::CreateWebEngineDevice() {
transport_manager_.CreateWebEngineDevice();
}
+bool ConnectionHandlerImpl::GetProtocolVehicleData(ProtocolVehicleData& data) {
+ sync_primitives::AutoReadLock read_lock(connection_handler_observer_lock_);
+ if (connection_handler_observer_) {
+ return connection_handler_observer_->GetProtocolVehicleData(data);
+ }
+
+ return false;
+}
+
const std::string
ConnectionHandlerImpl::TransportTypeProfileStringFromConnHandle(
transport_manager::ConnectionUID connection_handle) const {
diff --git a/src/components/include/application_manager/application_manager.h b/src/components/include/application_manager/application_manager.h
index dfc8314530..dc4d1e8ffe 100644
--- a/src/components/include/application_manager/application_manager.h
+++ b/src/components/include/application_manager/application_manager.h
@@ -623,6 +623,12 @@ class ApplicationManager {
virtual bool IsStopping() const = 0;
+ /**
+ * @brief Waits for HMI readiness and blocks thread if it's not ready yet
+ * @return true if HMI is ready and cooperating, otherwise returns false
+ */
+ virtual bool WaitForHmiIsReady() = 0;
+
virtual void RemoveAppFromTTSGlobalPropertiesList(const uint32_t app_id) = 0;
/**
diff --git a/src/components/include/connection_handler/connection_handler.h b/src/components/include/connection_handler/connection_handler.h
index cb83bec564..7cb1448a37 100644
--- a/src/components/include/connection_handler/connection_handler.h
+++ b/src/components/include/connection_handler/connection_handler.h
@@ -58,6 +58,18 @@ enum CloseSessionReason {
class ConnectionHandlerObserver;
+/**
+ * @brief Helper structure to collect all required vehicle data
+ */
+struct ProtocolVehicleData {
+ std::string vehicle_make;
+ std::string vehicle_model;
+ std::string vehicle_year;
+ std::string vehicle_trim;
+ std::string vehicle_system_software_version;
+ std::string vehicle_system_hardware_version;
+};
+
// The SessionConnectionMap keeps track of the primary and secondary transports
// associated with a session ID
typedef struct {
@@ -345,6 +357,14 @@ class ConnectionHandler {
const = 0;
/**
+ * @brief Collects all vehicle data required by a protocol layer
+ * @param data output structure to store received vehicle data
+ * @return true if data has been received successfully, otherwise returns
+ * false
+ */
+ virtual bool GetProtocolVehicleData(ProtocolVehicleData& data) = 0;
+
+ /**
* @brief Called when HMI cooperation is started,
* creates WebSocketDevice for WebEngine
*/
diff --git a/src/components/include/connection_handler/connection_handler_observer.h b/src/components/include/connection_handler/connection_handler_observer.h
index 7d6664a009..cfbbefefd4 100644
--- a/src/components/include/connection_handler/connection_handler_observer.h
+++ b/src/components/include/connection_handler/connection_handler_observer.h
@@ -177,6 +177,14 @@ class ConnectionHandlerObserver {
*/
virtual void OnWebEngineDeviceCreated() = 0;
+ /**
+ * @brief Collects all vehicle data required by a protocol layer
+ * @param data output structure to store received vehicle data
+ * @return true if data has been received successfully, otherwise returns
+ * false
+ */
+ virtual bool GetProtocolVehicleData(ProtocolVehicleData& data) = 0;
+
protected:
/**
* \brief Destructor
diff --git a/src/components/include/protocol/bson_object_keys.h b/src/components/include/protocol/bson_object_keys.h
index f81de4cc81..830c33b3eb 100644
--- a/src/components/include/protocol/bson_object_keys.h
+++ b/src/components/include/protocol/bson_object_keys.h
@@ -49,6 +49,12 @@ extern const char* tcp_ip_address;
extern const char* tcp_port;
extern const char* reason;
extern const char* auth_token;
+extern const char* vehicle_make;
+extern const char* vehicle_model;
+extern const char* vehicle_model_year;
+extern const char* vehicle_trim;
+extern const char* vehicle_system_software_version;
+extern const char* vehicle_system_hardware_version;
} // namespace strings
diff --git a/src/components/include/test/application_manager/mock_application_manager.h b/src/components/include/test/application_manager/mock_application_manager.h
index 70fdb4c4f3..57d3b8f7ad 100644
--- a/src/components/include/test/application_manager/mock_application_manager.h
+++ b/src/components/include/test/application_manager/mock_application_manager.h
@@ -232,6 +232,7 @@ class MockApplicationManager : public application_manager::ApplicationManager {
MOCK_CONST_METHOD1(IsAppsQueriedFrom,
bool(const connection_handler::DeviceHandle handle));
MOCK_CONST_METHOD0(IsStopping, bool());
+ MOCK_METHOD0(WaitForHmiIsReady, bool());
MOCK_METHOD1(RemoveAppFromTTSGlobalPropertiesList,
void(const uint32_t app_id));
MOCK_METHOD2(ResetGlobalProperties,
diff --git a/src/components/include/test/connection_handler/mock_connection_handler.h b/src/components/include/test/connection_handler/mock_connection_handler.h
index 78083b0abf..bdfcf55e34 100644
--- a/src/components/include/test/connection_handler/mock_connection_handler.h
+++ b/src/components/include/test/connection_handler/mock_connection_handler.h
@@ -139,6 +139,8 @@ class MockConnectionHandler : public connection_handler::ConnectionHandler {
OnSecondaryTransportEnded,
void(const transport_manager::ConnectionUID primary_connection_handle,
const transport_manager::ConnectionUID secondary_connection_handle));
+ MOCK_METHOD1(GetProtocolVehicleData,
+ bool(connection_handler::ProtocolVehicleData& data));
MOCK_METHOD0(CreateWebEngineDevice, void());
MOCK_CONST_METHOD0(GetWebEngineDeviceInfo, transport_manager::DeviceInfo&());
};
diff --git a/src/components/include/test/connection_handler/mock_connection_handler_observer.h b/src/components/include/test/connection_handler/mock_connection_handler_observer.h
index 61877daa23..90174017c3 100644
--- a/src/components/include/test/connection_handler/mock_connection_handler_observer.h
+++ b/src/components/include/test/connection_handler/mock_connection_handler_observer.h
@@ -83,6 +83,8 @@ class MockConnectionHandlerObserver
MOCK_METHOD2(SetPendingApplicationState,
void(const transport_manager::ConnectionUID connection_id,
const transport_manager::DeviceInfo& device_info));
+ MOCK_METHOD1(GetProtocolVehicleData,
+ bool(connection_handler::ProtocolVehicleData& data));
};
} // namespace connection_handler_test
diff --git a/src/components/protocol/src/bson_object_keys.cc b/src/components/protocol/src/bson_object_keys.cc
index acafd3dbd2..7e1656955f 100644
--- a/src/components/protocol/src/bson_object_keys.cc
+++ b/src/components/protocol/src/bson_object_keys.cc
@@ -19,6 +19,12 @@ const char* tcp_ip_address = "tcpIpAddress";
const char* tcp_port = "tcpPort";
const char* reason = "reason";
const char* auth_token = "authToken";
+const char* vehicle_make = "make";
+const char* vehicle_model = "model";
+const char* vehicle_model_year = "modelYear";
+const char* vehicle_trim = "trim";
+const char* vehicle_system_software_version = "systemSoftwareVersion";
+const char* vehicle_system_hardware_version = "systemHardwareVersion";
} // namespace strings
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 c79dbfcac3..3ea77c19cb 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
@@ -733,6 +733,14 @@ class ProtocolHandlerImpl
const uint8_t session_id,
const bool protection) const;
+ /**
+ * @brief Writes available protocol vehicle data into structured bson
+ * @param params bson params to write into
+ * @param data data to write
+ */
+ void WriteProtocolVehicleData(
+ BsonObject& params, const connection_handler::ProtocolVehicleData& data);
+
const ProtocolHandlerSettings& settings_;
/**
diff --git a/src/components/protocol_handler/src/protocol_handler_impl.cc b/src/components/protocol_handler/src/protocol_handler_impl.cc
index df499cd593..3393a74461 100644
--- a/src/components/protocol_handler/src/protocol_handler_impl.cc
+++ b/src/components/protocol_handler/src/protocol_handler_impl.cc
@@ -226,6 +226,39 @@ void ProtocolHandlerImpl::SendStartSessionAck(
bson_object_deinitialize(&empty_param);
}
+void ProtocolHandlerImpl::WriteProtocolVehicleData(
+ BsonObject& params, const connection_handler::ProtocolVehicleData& data) {
+ auto write_string_to_bson = [&params](const std::string& param_name,
+ const std::string& param_value) {
+ if (param_value.empty()) {
+ return;
+ }
+
+ const uint16_t max_string_length = 500;
+ char value_buffer[max_string_length + 1]; // extra byte for NULL symbol
+ strncpy(value_buffer, param_value.c_str(), sizeof(value_buffer));
+ value_buffer[max_string_length] = 0;
+
+ if (bson_object_put_string(&params, param_name.c_str(), value_buffer)) {
+ SDL_LOG_DEBUG("Parameter "
+ << param_name << " has been written to bson with value: "
+ << bson_object_get_string(&params, param_name.c_str()));
+ } else {
+ SDL_LOG_DEBUG("Failed to write parameter " << param_name
+ << " into bson structure");
+ }
+ };
+
+ write_string_to_bson(strings::vehicle_make, data.vehicle_make);
+ write_string_to_bson(strings::vehicle_model, data.vehicle_model);
+ write_string_to_bson(strings::vehicle_model_year, data.vehicle_year);
+ write_string_to_bson(strings::vehicle_trim, data.vehicle_trim);
+ write_string_to_bson(strings::vehicle_system_software_version,
+ data.vehicle_system_software_version);
+ write_string_to_bson(strings::vehicle_system_hardware_version,
+ data.vehicle_system_hardware_version);
+}
+
void ProtocolHandlerImpl::SendStartSessionAck(
ConnectionID connection_id,
uint8_t session_id,
@@ -289,6 +322,12 @@ void ProtocolHandlerImpl::SendStartSessionAck(
<< static_cast<int32_t>(bson_object_get_int64(&params, strings::mtu)));
if (serviceTypeValue == kRpc) {
+ SDL_LOG_DEBUG("Collecting protocol vehicle data");
+ connection_handler::ProtocolVehicleData data;
+ if (connection_handler_.GetProtocolVehicleData(data)) {
+ WriteProtocolVehicleData(params, data);
+ }
+
// Hash ID is only used in RPC case
const bool hash_written = bson_object_put_int32(
&params, strings::hash_id, static_cast<int32_t>(hash_id));
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 b28dee2657..89cb7fe906 100644
--- a/src/components/protocol_handler/test/protocol_handler_tm_test.cc
+++ b/src/components/protocol_handler/test/protocol_handler_tm_test.cc
@@ -5409,6 +5409,109 @@ TEST_F(ProtocolHandlerImplTest,
EXPECT_TRUE(waiter->WaitFor(times, kAsyncExpectationsTimeout));
}
+TEST_F(ProtocolHandlerImplTest,
+ StartSessionAck_ProtocolVehicleData_VehicleDataParamsForV5) {
+ TestAsyncWaiter waiter;
+
+ const size_t maximum_rpc_payload_size = 1500;
+ EXPECT_CALL(protocol_handler_settings_mock, maximum_rpc_payload_size())
+ .WillOnce(Return(maximum_rpc_payload_size));
+ InitProtocolHandlerImpl(0u, 0u);
+
+ EXPECT_CALL(protocol_handler_settings_mock, max_supported_protocol_version())
+ .WillOnce(Return(PROTOCOL_VERSION_5));
+
+ std::map<std::string, std::string> vehicle_mapping = {
+ {protocol_handler::strings::vehicle_make, "TestMake"},
+ {protocol_handler::strings::vehicle_model, "TestModel"},
+ {protocol_handler::strings::vehicle_model_year, "2021"},
+ {protocol_handler::strings::vehicle_trim, "TestTrim"},
+ {protocol_handler::strings::vehicle_system_hardware_version, "TestHW"},
+ {protocol_handler::strings::vehicle_system_software_version, "TestSW"}};
+
+ connection_handler::ProtocolVehicleData data{
+ vehicle_mapping[protocol_handler::strings::vehicle_make],
+ vehicle_mapping[protocol_handler::strings::vehicle_model],
+ vehicle_mapping[protocol_handler::strings::vehicle_model_year],
+ vehicle_mapping[protocol_handler::strings::vehicle_trim],
+ vehicle_mapping
+ [protocol_handler::strings::vehicle_system_software_version],
+ vehicle_mapping
+ [protocol_handler::strings::vehicle_system_hardware_version]};
+
+ EXPECT_CALL(connection_handler_mock, GetProtocolVehicleData(_))
+ .WillOnce(DoAll(SetArgReferee<0>(data), Return(true)));
+
+ const uint32_t hash_id = 123456;
+ char full_version_string[] = "5.0.0";
+
+ BsonObject expected_obj;
+ bson_object_initialize_default(&expected_obj);
+ // mtu
+ bson_object_put_int64(&expected_obj,
+ protocol_handler::strings::mtu,
+ static_cast<int64_t>(maximum_rpc_payload_size));
+ // hashId
+ bson_object_put_int32(&expected_obj,
+ protocol_handler::strings::hash_id,
+ static_cast<int32_t>(hash_id));
+ // protocolVersion
+ bson_object_put_string(&expected_obj,
+ protocol_handler::strings::protocol_version,
+ full_version_string);
+
+ // vehicle data
+ const uint16_t max_string_length = 500;
+ for (auto& data_pair : vehicle_mapping) {
+ char value_buffer[max_string_length + 1]; // extra byte for NULL symbol
+ strncpy(value_buffer, data_pair.second.c_str(), sizeof(value_buffer));
+ value_buffer[max_string_length] = 0;
+
+ bson_object_put_string(
+ &expected_obj, data_pair.first.c_str(), value_buffer);
+ }
+
+ std::vector<uint8_t> expected_param =
+ CreateVectorFromBsonObject(&expected_obj);
+
+ bson_object_deinitialize(&expected_obj);
+
+ EXPECT_CALL(transport_manager_mock,
+ SendMessageToDevice(ControlMessage(FRAME_DATA_START_SERVICE_ACK,
+ PROTECTION_OFF,
+ connection_id,
+ Eq(expected_param))))
+ .WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(E_SUCCESS)));
+
+ connection_handler::SessionTransports dummy_st = {0, 0};
+ EXPECT_CALL(connection_handler_mock,
+ SetSecondaryTransportID(_, kDisabledSecondary))
+ .WillOnce(Return(dummy_st));
+
+#ifdef ENABLE_SECURITY
+ AddSecurityManager();
+
+ EXPECT_CALL(session_observer_mock, KeyFromPair(connection_id, session_id))
+ .WillRepeatedly(Return(connection_key));
+
+ EXPECT_CALL(session_observer_mock, GetSSLContext(connection_key, kRpc))
+ .WillOnce(ReturnNull());
+#endif // ENABLE_SECURITY
+
+ const uint8_t input_protocol_version = 5;
+ utils::SemanticVersion full_version(5, 0, 0);
+
+ protocol_handler_impl->SendStartSessionAck(connection_id,
+ session_id,
+ input_protocol_version,
+ hash_id,
+ kRpc,
+ false /* protection */,
+ full_version);
+
+ EXPECT_TRUE(waiter.WaitFor(1, kAsyncExpectationsTimeout));
+}
+
} // namespace protocol_handler_test
} // namespace components
} // namespace test