diff options
author | Andrii Kalinich <AKalinich@luxoft.com> | 2021-01-12 14:06:28 -0500 |
---|---|---|
committer | LitvinenkoIra <ilytvynenko@luxoft.com> | 2021-01-21 10:03:44 +0200 |
commit | 500fa2d826f2d05a124ebda205ce9575c174e514 (patch) | |
tree | c977814c943f97abd8568f5e950b04e9c22ddfb3 /src | |
parent | 98c4ff9811260a939e7892a0aa49d98914ad3b06 (diff) | |
download | sdl_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.
Diffstat (limited to 'src')
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 = [¶ms](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(¶ms, param_name.c_str(), value_buffer)) { + SDL_LOG_DEBUG("Parameter " + << param_name << " has been written to bson with value: " + << bson_object_get_string(¶ms, 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(¶ms, 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( ¶ms, 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 |