diff options
author | JackLivio <jack@livio.io> | 2018-10-19 15:05:09 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-10-19 15:05:09 -0400 |
commit | d36316738785c96dab2ee892762ed08c059fffde (patch) | |
tree | 168a7c0705b5bc8f0dee7ce4b511ccf71759d9b4 /src/components/protocol_handler/test/protocol_handler_tm_test.cc | |
parent | 7f7fcbb998fb17f2954fd103349af67ea9b71a3f (diff) | |
parent | 83c5e805346d55ec7fb9f4ba8b6f6855d992273e (diff) | |
download | sdl_core-hotfix/templates_updates.tar.gz |
Merge pull request #2572 from smartdevicelink/release/5.0.05.0.0hotfix/templates_updatesfeature/show_app_menufeature/progress_bar_seekfeature/open-menu-rpcfeature/open-menu-rfeature/button
Release 5.0.0
Diffstat (limited to 'src/components/protocol_handler/test/protocol_handler_tm_test.cc')
-rw-r--r-- | src/components/protocol_handler/test/protocol_handler_tm_test.cc | 1608 |
1 files changed, 1534 insertions, 74 deletions
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 77de1705da..51284dfcda 100644 --- a/src/components/protocol_handler/test/protocol_handler_tm_test.cc +++ b/src/components/protocol_handler/test/protocol_handler_tm_test.cc @@ -41,15 +41,27 @@ #include "protocol_handler/mock_protocol_handler_settings.h" #include "protocol_handler/mock_session_observer.h" #include "connection_handler/mock_connection_handler.h" +#include "connection_handler/connection_handler_impl.h" #ifdef ENABLE_SECURITY #include "security_manager/mock_security_manager.h" #include "security_manager/mock_ssl_context.h" #endif // ENABLE_SECURITY #include "transport_manager/mock_transport_manager.h" -#include "utils/make_shared.h" +#include "utils/mock_system_time_handler.h" +#include "utils/semantic_version.h" + #include "utils/test_async_waiter.h" #include <bson_object.h> +namespace transport_manager { +namespace transport_adapter { +// taken from transport_adapter_impl.cc +const char* tc_enabled = "enabled"; +const char* tc_tcp_port = "tcp_port"; +const char* tc_tcp_ip_address = "tcp_ip_address"; +} +} + namespace test { namespace components { namespace protocol_handler_test { @@ -87,6 +99,10 @@ using protocol_handler::FRAME_DATA_SERVICE_DATA_ACK; using protocol_handler::FRAME_DATA_SINGLE; using protocol_handler::FRAME_DATA_FIRST; using protocol_handler::FRAME_DATA_LAST_CONSECUTIVE; +using protocol_handler::FRAME_DATA_REGISTER_SECONDARY_TRANSPORT; +using protocol_handler::FRAME_DATA_REGISTER_SECONDARY_TRANSPORT_ACK; +using protocol_handler::FRAME_DATA_REGISTER_SECONDARY_TRANSPORT_NACK; +using protocol_handler::FRAME_DATA_TRANSPORT_EVENT_UPDATE; using protocol_handler::kRpc; using protocol_handler::kControl; using protocol_handler::kAudio; @@ -95,16 +111,24 @@ using protocol_handler::kBulk; using protocol_handler::kInvalidServiceType; // For TM states using transport_manager::TransportManagerListener; +using test::components::security_manager_test::MockSystemTimeHandler; using transport_manager::E_SUCCESS; using transport_manager::DeviceInfo; +#ifdef ENABLE_SECURITY +// For security +using ContextCreationStrategy = + security_manager::SecurityManager::ContextCreationStrategy; +#endif // ENABLE_SECURITY // For CH entities using connection_handler::DeviceHandle; // Google Testing Framework Entities using ::testing::Return; +using ::testing::ReturnRef; using ::testing::ReturnRefOfCopy; using ::testing::ReturnNull; using ::testing::An; using ::testing::AnyOf; +using ::testing::AtLeast; using ::testing::ByRef; using ::testing::DoAll; using ::testing::SaveArg; @@ -183,6 +207,9 @@ class ProtocolHandlerImplTest : public ::testing::Test { . // Return false to avoid call KeepConnectionAlive WillRepeatedly(Return(false)); + + session_connection_map_lock_ptr_ = + std::make_shared<sync_primitives::Lock>(); } void TearDown() OVERRIDE { @@ -209,6 +236,7 @@ class ProtocolHandlerImplTest : public ::testing::Test { const uint32_t hash_id, const bool protection_flag) { return protocol_handler::SessionContext(connection_id, + connection_id, initial_session_id, new_session_id, service_type, @@ -216,7 +244,7 @@ class ProtocolHandlerImplTest : public ::testing::Test { protection_flag); } - void AddSession(const ::utils::SharedPtr<TestAsyncWaiter>& waiter, + void AddSession(const std::shared_ptr<TestAsyncWaiter>& waiter, uint32_t& times) { using namespace protocol_handler; ASSERT_TRUE(NULL != waiter.get()); @@ -241,6 +269,21 @@ class ProtocolHandlerImplTest : public ::testing::Test { HASH_ID_WRONG, callback_protection_flag); + // Expect verification of allowed transport + EXPECT_CALL(session_observer_mock, + TransportTypeProfileStringFromConnHandle(connection_id)) + .WillOnce(Return("TCP_WIFI")); + + std::vector<std::string> audio_service_transports; + audio_service_transports.push_back("TCP_WIFI"); + std::vector<std::string> video_service_transports; + video_service_transports.push_back("TCP_WIFI"); + + EXPECT_CALL(protocol_handler_settings_mock, audio_service_transports()) + .WillOnce(ReturnRef(audio_service_transports)); + EXPECT_CALL(protocol_handler_settings_mock, video_service_transports()) + .WillOnce(ReturnRef(video_service_transports)); + // Expect ConnectionHandler check EXPECT_CALL(session_observer_mock, OnSessionStartedCallback(connection_id, @@ -313,10 +356,11 @@ class ProtocolHandlerImplTest : public ::testing::Test { uint8_t service_type, uint8_t sessionId, uint32_t frame_data, + uint8_t protocol_version = PROTOCOL_VERSION_3, uint32_t dataSize = 0u, const uint8_t* data = NULL) { SendTMMessage(connection_id, - PROTOCOL_VERSION_3, + protocol_version, protection, FRAME_TYPE_CONTROL, service_type, @@ -327,8 +371,20 @@ class ProtocolHandlerImplTest : public ::testing::Test { data); } + void VerifySecondaryTransportParamsInStartSessionAck( + bool config_multiple_transports_enabled, + const std::vector<std::string>& config_secondary_transports_for_usb, + const std::vector<std::string>& config_secondary_transports_for_bluetooth, + const std::vector<std::string>& config_secondary_transports_for_wifi, + const std::vector<std::string>& config_audio_service_transports, + const std::vector<std::string>& config_video_service_transports, + const std::string& connection_type_string, + const std::vector<std::string>& expected_transport_strings, + const std::vector<int32_t>& expected_audio_service_transports, + const std::vector<int32_t>& expected_video_service_transports); + testing::NiceMock<MockProtocolHandlerSettings> protocol_handler_settings_mock; - ::utils::SharedPtr<ProtocolHandlerImpl> protocol_handler_impl; + std::shared_ptr<ProtocolHandlerImpl> protocol_handler_impl; TransportManagerListener* tm_listener; // Uniq connection ::transport_manager::ConnectionUID connection_id; @@ -353,6 +409,10 @@ class ProtocolHandlerImplTest : public ::testing::Test { std::vector<int> force_unprotected_services; #endif // ENABLE_SECURITY std::vector<std::string> empty_rejected_param_; + // Used by OnTransportConfigUpdated() tests. The lifetime of these objects + // should be longer than that of a test case. + connection_handler::SessionConnectionMap session_connection_map_; + std::shared_ptr<sync_primitives::Lock> session_connection_map_lock_ptr_; }; #ifdef ENABLE_SECURITY @@ -407,6 +467,24 @@ TEST_F(ProtocolHandlerImplTest, TestAsyncWaiter waiter; uint32_t times = 0; ServiceType service_type; + // Expect verification of allowed transport + EXPECT_CALL(session_observer_mock, + TransportTypeProfileStringFromConnHandle(connection_id)) + .Times(call_times) + .WillRepeatedly(Return("TCP_WIFI")); + + std::vector<std::string> audio_service_transports; + audio_service_transports.push_back("TCP_WIFI"); + std::vector<std::string> video_service_transports; + video_service_transports.push_back("TCP_WIFI"); + + EXPECT_CALL(protocol_handler_settings_mock, audio_service_transports()) + .Times(call_times) + .WillRepeatedly(ReturnRef(audio_service_transports)); + EXPECT_CALL(protocol_handler_settings_mock, video_service_transports()) + .Times(call_times) + .WillRepeatedly(ReturnRef(video_service_transports)); + // Expect ConnectionHandler check EXPECT_CALL( session_observer_mock, @@ -475,6 +553,24 @@ TEST_F(ProtocolHandlerImplTest, StartSession_Protected_SessionObserverReject) { TestAsyncWaiter waiter; uint32_t times = 0; ServiceType service_type; + // Expect verification of allowed transport + EXPECT_CALL(session_observer_mock, + TransportTypeProfileStringFromConnHandle(connection_id)) + .Times(call_times) + .WillRepeatedly(Return("TCP_WIFI")); + + std::vector<std::string> audio_service_transports; + audio_service_transports.push_back("TCP_WIFI"); + std::vector<std::string> video_service_transports; + video_service_transports.push_back("TCP_WIFI"); + + EXPECT_CALL(protocol_handler_settings_mock, audio_service_transports()) + .Times(call_times) + .WillRepeatedly(ReturnRef(audio_service_transports)); + EXPECT_CALL(protocol_handler_settings_mock, video_service_transports()) + .Times(call_times) + .WillRepeatedly(ReturnRef(video_service_transports)); + // Expect ConnectionHandler check EXPECT_CALL( session_observer_mock, @@ -533,6 +629,21 @@ TEST_F(ProtocolHandlerImplTest, TestAsyncWaiter waiter; uint32_t times = 0; + // Expect verification of allowed transport + EXPECT_CALL(session_observer_mock, + TransportTypeProfileStringFromConnHandle(connection_id)) + .WillOnce(Return("TCP_WIFI")); + + std::vector<std::string> audio_service_transports; + audio_service_transports.push_back("TCP_WIFI"); + std::vector<std::string> video_service_transports; + video_service_transports.push_back("TCP_WIFI"); + + EXPECT_CALL(protocol_handler_settings_mock, audio_service_transports()) + .WillOnce(ReturnRef(audio_service_transports)); + EXPECT_CALL(protocol_handler_settings_mock, video_service_transports()) + .WillOnce(ReturnRef(video_service_transports)); + // Expect ConnectionHandler check EXPECT_CALL(session_observer_mock, OnSessionStartedCallback(connection_id, @@ -577,8 +688,7 @@ TEST_F(ProtocolHandlerImplTest, TEST_F(ProtocolHandlerImplTest, StartSession_Protected_SessionObserverAccept) { SetProtocolVersion2(); - ::utils::SharedPtr<TestAsyncWaiter> waiter = - utils::MakeShared<TestAsyncWaiter>(); + std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>(); uint32_t times = 0; AddSession(waiter, times); @@ -618,6 +728,18 @@ TEST_F(ProtocolHandlerImplTest, const ::transport_manager::ConnectionUID connection_id2 = 0xBu; const uint8_t session_id2 = 2u; +#ifdef ENABLE_SECURITY + AddSecurityManager(); + + EXPECT_CALL(session_observer_mock, KeyFromPair(connection_id2, session_id2)) + .WillOnce(Return(connection_key)); + + EXPECT_CALL(session_observer_mock, + GetSSLContext(connection_key, start_service)) + .Times(2) + .WillRepeatedly(ReturnNull()); +#endif // ENABLE_SECURITY + EXPECT_CALL(session_observer_mock, IsHeartBeatSupported(connection_id1, _)) .WillRepeatedly(Return(false)); EXPECT_CALL(session_observer_mock, IsHeartBeatSupported(connection_id2, _)) @@ -638,6 +760,26 @@ TEST_F(ProtocolHandlerImplTest, TestAsyncWaiter waiter; uint32_t times = 0; + // Expect verification of allowed transport + EXPECT_CALL(session_observer_mock, + TransportTypeProfileStringFromConnHandle(connection_id1)) + .WillOnce(Return("TCP_WIFI")); + EXPECT_CALL(session_observer_mock, + TransportTypeProfileStringFromConnHandle(connection_id2)) + .WillOnce(Return("TCP_WIFI")); + + std::vector<std::string> audio_service_transports; + audio_service_transports.push_back("TCP_WIFI"); + std::vector<std::string> video_service_transports; + video_service_transports.push_back("TCP_WIFI"); + + EXPECT_CALL(protocol_handler_settings_mock, audio_service_transports()) + .Times(2) + .WillRepeatedly(ReturnRef(audio_service_transports)); + EXPECT_CALL(protocol_handler_settings_mock, video_service_transports()) + .Times(2) + .WillRepeatedly(ReturnRef(video_service_transports)); + BsonObject bson_params1; bson_object_initialize_default(&bson_params1); bson_object_put_string(&bson_params1, @@ -774,14 +916,91 @@ TEST_F(ProtocolHandlerImplTest, bson_object_deinitialize(&bson_params2); } +/* + * ProtocolHandler shall send NAck on session_observer rejection + * Check protection flag OFF for all services from kControl to kBulk + */ +TEST_F(ProtocolHandlerImplTest, StartSession_Audio_RejectByTransportType) { + using namespace protocol_handler; + AddConnection(); + const ServiceType start_service = kAudio; + + TestAsyncWaiter waiter; + uint32_t times = 0; + // Expect verification of allowed transport + EXPECT_CALL(session_observer_mock, + TransportTypeProfileStringFromConnHandle(connection_id)) + .WillOnce(Return("TCP_WIFI")); + + std::vector<std::string> audio_service_transports; + audio_service_transports.push_back("AOA_USB"); + std::vector<std::string> video_service_transports; + video_service_transports.push_back("TCP_WIFI"); + + EXPECT_CALL(protocol_handler_settings_mock, audio_service_transports()) + .WillOnce(ReturnRef(audio_service_transports)); + EXPECT_CALL(protocol_handler_settings_mock, video_service_transports()) + .WillOnce(ReturnRef(video_service_transports)); + + // Expect send Ack + EXPECT_CALL(transport_manager_mock, + SendMessageToDevice(ControlMessage(FRAME_DATA_START_SERVICE_NACK, + PROTECTION_OFF))) + .WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(E_SUCCESS))); + times++; + + SendControlMessage( + PROTECTION_OFF, start_service, NEW_SESSION_ID, FRAME_DATA_START_SERVICE); + + EXPECT_TRUE(waiter.WaitFor(times, kAsyncExpectationsTimeout)); +} + +/* + * ProtocolHandler shall send NAck on session_observer rejection + * Check protection flag OFF for all services from kControl to kBulk + */ +TEST_F(ProtocolHandlerImplTest, StartSession_Video_RejectByTransportType) { + using namespace protocol_handler; + AddConnection(); + const ServiceType start_service = kMobileNav; + + TestAsyncWaiter waiter; + uint32_t times = 0; + // Expect verification of allowed transport + EXPECT_CALL(session_observer_mock, + TransportTypeProfileStringFromConnHandle(connection_id)) + .WillOnce(Return("TCP_WIFI")); + + std::vector<std::string> audio_service_transports; + audio_service_transports.push_back("TCP_WIFI"); + std::vector<std::string> video_service_transports; + video_service_transports.push_back("AOA_USB"); + + EXPECT_CALL(protocol_handler_settings_mock, audio_service_transports()) + .WillOnce(ReturnRef(audio_service_transports)); + EXPECT_CALL(protocol_handler_settings_mock, video_service_transports()) + .WillOnce(ReturnRef(video_service_transports)); + + // Expect send Ack + EXPECT_CALL(transport_manager_mock, + SendMessageToDevice(ControlMessage(FRAME_DATA_START_SERVICE_NACK, + PROTECTION_OFF))) + .WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(E_SUCCESS))); + times++; + + SendControlMessage( + PROTECTION_OFF, start_service, NEW_SESSION_ID, FRAME_DATA_START_SERVICE); + + EXPECT_TRUE(waiter.WaitFor(times, kAsyncExpectationsTimeout)); +} + // TODO(EZamakhov): add test for get_hash_id/set_hash_id from // protocol_handler_impl.cc /* * ProtocolHandler shall send NAck on session_observer rejection */ TEST_F(ProtocolHandlerImplTest, EndSession_SessionObserverReject) { - ::utils::SharedPtr<TestAsyncWaiter> waiter = - utils::MakeShared<TestAsyncWaiter>(); + std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>(); uint32_t times = 0; AddSession(waiter, times); @@ -814,8 +1033,7 @@ TEST_F(ProtocolHandlerImplTest, EndSession_SessionObserverReject) { * ProtocolHandler shall send NAck on wrong hash code */ TEST_F(ProtocolHandlerImplTest, EndSession_Success) { - ::utils::SharedPtr<TestAsyncWaiter> waiter = - utils::MakeShared<TestAsyncWaiter>(); + std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>(); uint32_t times = 0; AddSession(waiter, times); @@ -848,8 +1066,7 @@ TEST_F(ProtocolHandlerImplTest, EndSession_Success) { #ifdef ENABLE_SECURITY TEST_F(ProtocolHandlerImplTest, SecurityEnable_StartSessionProtocoloV1) { using namespace protocol_handler; - ::utils::SharedPtr<TestAsyncWaiter> waiter = - utils::MakeShared<TestAsyncWaiter>(); + std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>(); uint32_t times = 0; AddSession(waiter, times); @@ -857,6 +1074,21 @@ TEST_F(ProtocolHandlerImplTest, SecurityEnable_StartSessionProtocoloV1) { // Add security manager AddSecurityManager(); const ServiceType start_service = kRpc; + // Expect verification of allowed transport + EXPECT_CALL(session_observer_mock, + TransportTypeProfileStringFromConnHandle(connection_id)) + .WillOnce(Return("TCP_WIFI")); + + std::vector<std::string> audio_service_transports; + audio_service_transports.push_back("TCP_WIFI"); + std::vector<std::string> video_service_transports; + video_service_transports.push_back("TCP_WIFI"); + + EXPECT_CALL(protocol_handler_settings_mock, audio_service_transports()) + .WillOnce(ReturnRef(audio_service_transports)); + EXPECT_CALL(protocol_handler_settings_mock, video_service_transports()) + .WillOnce(ReturnRef(video_service_transports)); + // Expect ConnectionHandler check EXPECT_CALL(session_observer_mock, OnSessionStartedCallback(connection_id, @@ -913,6 +1145,21 @@ TEST_F(ProtocolHandlerImplTest, SecurityEnable_StartSessionUnprotected) { TestAsyncWaiter waiter; uint32_t times = 0; + // Expect verification of allowed transport + EXPECT_CALL(session_observer_mock, + TransportTypeProfileStringFromConnHandle(connection_id)) + .WillOnce(Return("TCP_WIFI")); + + std::vector<std::string> audio_service_transports; + audio_service_transports.push_back("TCP_WIFI"); + std::vector<std::string> video_service_transports; + video_service_transports.push_back("TCP_WIFI"); + + EXPECT_CALL(protocol_handler_settings_mock, audio_service_transports()) + .WillOnce(ReturnRef(audio_service_transports)); + EXPECT_CALL(protocol_handler_settings_mock, video_service_transports()) + .WillOnce(ReturnRef(video_service_transports)); + // Expect ConnectionHandler check EXPECT_CALL(session_observer_mock, OnSessionStartedCallback(connection_id, @@ -968,6 +1215,21 @@ TEST_F(ProtocolHandlerImplTest, SecurityEnable_StartSessionProtected_Fail) { PROTECTION_ON); context.is_new_service_ = true; + // Expect verification of allowed transport + EXPECT_CALL(session_observer_mock, + TransportTypeProfileStringFromConnHandle(connection_id)) + .WillOnce(Return("TCP_WIFI")); + + std::vector<std::string> audio_service_transports; + audio_service_transports.push_back("TCP_WIFI"); + std::vector<std::string> video_service_transports; + video_service_transports.push_back("TCP_WIFI"); + + EXPECT_CALL(protocol_handler_settings_mock, audio_service_transports()) + .WillOnce(ReturnRef(audio_service_transports)); + EXPECT_CALL(protocol_handler_settings_mock, video_service_transports()) + .WillOnce(ReturnRef(video_service_transports)); + // Expect ConnectionHandler check EXPECT_CALL(session_observer_mock, OnSessionStartedCallback(connection_id, @@ -987,7 +1249,10 @@ TEST_F(ProtocolHandlerImplTest, SecurityEnable_StartSessionProtected_Fail) { SetProtocolVersion2(); // Expect start protection for unprotected session - EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key)) + EXPECT_CALL(security_manager_mock, + CreateSSLContext(connection_key, + security_manager::SecurityManager:: + ContextCreationStrategy::kUseExisting)) . // Return fail protection WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), ReturnNull())); @@ -1018,6 +1283,21 @@ TEST_F(ProtocolHandlerImplTest, TestAsyncWaiter waiter; uint32_t times = 0; + // Expect verification of allowed transport + EXPECT_CALL(session_observer_mock, + TransportTypeProfileStringFromConnHandle(connection_id)) + .WillOnce(Return("TCP_WIFI")); + + std::vector<std::string> audio_service_transports; + audio_service_transports.push_back("TCP_WIFI"); + std::vector<std::string> video_service_transports; + video_service_transports.push_back("TCP_WIFI"); + + EXPECT_CALL(protocol_handler_settings_mock, audio_service_transports()) + .WillOnce(ReturnRef(audio_service_transports)); + EXPECT_CALL(protocol_handler_settings_mock, video_service_transports()) + .WillOnce(ReturnRef(video_service_transports)); + // Expect ConnectionHandler check EXPECT_CALL(session_observer_mock, OnSessionStartedCallback(connection_id, @@ -1042,7 +1322,7 @@ TEST_F(ProtocolHandlerImplTest, SetProtocolVersion2(); // call new SSLContext creation - EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key)) + EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key, _)) . // Return new SSLContext WillOnce( @@ -1094,6 +1374,21 @@ TEST_F(ProtocolHandlerImplTest, PROTECTION_ON); context.is_new_service_ = true; + // Expect verification of allowed transport + EXPECT_CALL(session_observer_mock, + TransportTypeProfileStringFromConnHandle(connection_id)) + .WillOnce(Return("TCP_WIFI")); + + std::vector<std::string> audio_service_transports; + audio_service_transports.push_back("TCP_WIFI"); + std::vector<std::string> video_service_transports; + video_service_transports.push_back("TCP_WIFI"); + + EXPECT_CALL(protocol_handler_settings_mock, audio_service_transports()) + .WillOnce(ReturnRef(audio_service_transports)); + EXPECT_CALL(protocol_handler_settings_mock, video_service_transports()) + .WillOnce(ReturnRef(video_service_transports)); + // Expect ConnectionHandler check EXPECT_CALL(session_observer_mock, OnSessionStartedCallback(connection_id, @@ -1119,7 +1414,7 @@ TEST_F(ProtocolHandlerImplTest, .WillOnce(ReturnRefOfCopy(services)); // call new SSLContext creation - EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key)) + EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key, _)) . // Return new SSLContext WillOnce(Return(&ssl_context_mock)); @@ -1175,6 +1470,21 @@ TEST_F(ProtocolHandlerImplTest, TestAsyncWaiter waiter; uint32_t times = 0; + // Expect verification of allowed transport + EXPECT_CALL(session_observer_mock, + TransportTypeProfileStringFromConnHandle(connection_id)) + .WillOnce(Return("TCP_WIFI")); + + std::vector<std::string> audio_service_transports; + audio_service_transports.push_back("TCP_WIFI"); + std::vector<std::string> video_service_transports; + video_service_transports.push_back("TCP_WIFI"); + + EXPECT_CALL(protocol_handler_settings_mock, audio_service_transports()) + .WillOnce(ReturnRef(audio_service_transports)); + EXPECT_CALL(protocol_handler_settings_mock, video_service_transports()) + .WillOnce(ReturnRef(video_service_transports)); + // Expect ConnectionHandler check EXPECT_CALL(session_observer_mock, OnSessionStartedCallback(connection_id, @@ -1198,7 +1508,7 @@ TEST_F(ProtocolHandlerImplTest, times++; // call new SSLContext creation - EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key)) + EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key, _)) . // Return new SSLContext WillOnce( @@ -1273,6 +1583,21 @@ TEST_F( TestAsyncWaiter waiter; uint32_t times = 0; + // Expect verification of allowed transport + EXPECT_CALL(session_observer_mock, + TransportTypeProfileStringFromConnHandle(connection_id)) + .WillOnce(Return("TCP_WIFI")); + + std::vector<std::string> audio_service_transports; + audio_service_transports.push_back("TCP_WIFI"); + std::vector<std::string> video_service_transports; + video_service_transports.push_back("TCP_WIFI"); + + EXPECT_CALL(protocol_handler_settings_mock, audio_service_transports()) + .WillOnce(ReturnRef(audio_service_transports)); + EXPECT_CALL(protocol_handler_settings_mock, video_service_transports()) + .WillOnce(ReturnRef(video_service_transports)); + // Expect ConnectionHandler check EXPECT_CALL(session_observer_mock, OnSessionStartedCallback(connection_id, @@ -1296,7 +1621,7 @@ TEST_F( times++; // call new SSLContext creation - EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key)) + EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key, _)) . // Return new SSLContext WillOnce( @@ -1369,6 +1694,21 @@ TEST_F(ProtocolHandlerImplTest, TestAsyncWaiter waiter; uint32_t times = 0; + // Expect verification of allowed transport + EXPECT_CALL(session_observer_mock, + TransportTypeProfileStringFromConnHandle(connection_id)) + .WillOnce(Return("TCP_WIFI")); + + std::vector<std::string> audio_service_transports; + audio_service_transports.push_back("TCP_WIFI"); + std::vector<std::string> video_service_transports; + video_service_transports.push_back("TCP_WIFI"); + + EXPECT_CALL(protocol_handler_settings_mock, audio_service_transports()) + .WillOnce(ReturnRef(audio_service_transports)); + EXPECT_CALL(protocol_handler_settings_mock, video_service_transports()) + .WillOnce(ReturnRef(video_service_transports)); + // Expect ConnectionHandler check EXPECT_CALL(session_observer_mock, OnSessionStartedCallback(connection_id, @@ -1392,7 +1732,10 @@ TEST_F(ProtocolHandlerImplTest, times++; // call new SSLContext creation - EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key)) + EXPECT_CALL(security_manager_mock, + CreateSSLContext(connection_key, + security_manager::SecurityManager:: + ContextCreationStrategy::kUseExisting)) . // Return new SSLContext WillOnce( @@ -1420,27 +1763,37 @@ TEST_F(ProtocolHandlerImplTest, // Expect add listener for handshake result EXPECT_CALL(security_manager_mock, AddListener(_)) - // Emulate handshake fail - .WillOnce(Invoke(OnHandshakeDoneFunctor( - connection_key, - security_manager::SSLContext::Handshake_Result_Success))); + // Emulate handshake + .WillOnce( + DoAll(NotifyTestAsyncWaiter(&waiter), + Invoke(OnHandshakeDoneFunctor( + connection_key, + security_manager::SSLContext::Handshake_Result_Success)))); + times++; // Listener check SSLContext EXPECT_CALL(session_observer_mock, GetSSLContext(connection_key, start_service)) . // Emulate protection for service is not enabled - WillOnce(ReturnNull()); + WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), ReturnNull())); + times++; + + EXPECT_CALL(security_manager_mock, IsSystemTimeProviderReady()) + .WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(true))); + times++; - // Expect service protection enable EXPECT_CALL(session_observer_mock, - SetProtectionFlag(connection_key, start_service)); + SetProtectionFlag(connection_key, start_service)) + .WillOnce(NotifyTestAsyncWaiter(&waiter)); + times++; - // Expect send Ack with PROTECTION_OFF (on fail handshake) + // Expect send Ack with PROTECTION_ON (on successfull handshake) EXPECT_CALL(transport_manager_mock, SendMessageToDevice( ControlMessage(FRAME_DATA_START_SERVICE_ACK, PROTECTION_ON))) .WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(E_SUCCESS))); + times++; SendControlMessage( @@ -1450,14 +1803,1138 @@ TEST_F(ProtocolHandlerImplTest, } #endif // ENABLE_SECURITY +void ProtocolHandlerImplTest::VerifySecondaryTransportParamsInStartSessionAck( + bool config_multiple_transports_enabled, + const std::vector<std::string>& config_secondary_transports_for_usb, + const std::vector<std::string>& config_secondary_transports_for_bluetooth, + const std::vector<std::string>& config_secondary_transports_for_wifi, + const std::vector<std::string>& config_audio_service_transports, + const std::vector<std::string>& config_video_service_transports, + const std::string& connection_type_string, + const std::vector<std::string>& expected_transport_strings, + const std::vector<int32_t>& expected_audio_service_transports, + const std::vector<int32_t>& expected_video_service_transports) { + const size_t maximum_rpc_payload_size = 1500; + EXPECT_CALL(protocol_handler_settings_mock, maximum_rpc_payload_size()) + .WillRepeatedly(Return(maximum_rpc_payload_size)); + InitProtocolHandlerImpl(0u, 0u); + + TestAsyncWaiter waiter; + uint32_t times = 0; + + const uint8_t input_protocol_version = 5; + const uint32_t hash_id = 123456; + utils::SemanticVersion full_version(5, 1, 0); + char full_version_string[] = "5.1.0"; + + // configuration setup + EXPECT_CALL(protocol_handler_settings_mock, max_supported_protocol_version()) + .WillRepeatedly(Return(PROTOCOL_VERSION_5)); + EXPECT_CALL(protocol_handler_settings_mock, multiple_transports_enabled()) + .WillRepeatedly(Return(config_multiple_transports_enabled)); + EXPECT_CALL(protocol_handler_settings_mock, secondary_transports_for_usb()) + .Times(AtLeast(0)) + .WillRepeatedly(ReturnRef(config_secondary_transports_for_usb)); + EXPECT_CALL(protocol_handler_settings_mock, + secondary_transports_for_bluetooth()) + .Times(AtLeast(0)) + .WillRepeatedly(ReturnRef(config_secondary_transports_for_bluetooth)); + EXPECT_CALL(protocol_handler_settings_mock, secondary_transports_for_wifi()) + .Times(AtLeast(0)) + .WillRepeatedly(ReturnRef(config_secondary_transports_for_wifi)); + EXPECT_CALL(protocol_handler_settings_mock, audio_service_transports()) + .WillOnce(ReturnRef(config_audio_service_transports)); + EXPECT_CALL(protocol_handler_settings_mock, video_service_transports()) + .WillOnce(ReturnRef(config_video_service_transports)); + + EXPECT_CALL(session_observer_mock, + TransportTypeProfileStringFromConnHandle(connection_id)) + .WillRepeatedly(Return(connection_type_string)); + + // Prepare expected BSON parameters. When we add another param in Start + // Service ACK frame in future, it should be also added here. + 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); + // secondaryTransports + BsonArray secondary_transports; + bson_array_initialize(&secondary_transports, + expected_transport_strings.size()); + for (std::vector<std::string>::const_iterator it = + expected_transport_strings.begin(); + it != expected_transport_strings.end(); + ++it) { + // note: if there is no transport allowed, we can either make the array + // empty, or completely omit the array. (The spec allows both cases.) In + // this test case we make the array empty. + bson_array_add_string(&secondary_transports, + const_cast<char*>(it->c_str())); + } + bson_object_put_array(&expected_obj, + protocol_handler::strings::secondary_transports, + &secondary_transports); + // audioServiceTransports + BsonArray audio_service_transports; + if (expected_audio_service_transports.size() > 0) { + bson_array_initialize(&audio_service_transports, + expected_audio_service_transports.size()); + for (std::vector<int32_t>::const_iterator it = + expected_audio_service_transports.begin(); + it != expected_audio_service_transports.end(); + ++it) { + bson_array_add_int32(&audio_service_transports, *it); + } + bson_object_put_array(&expected_obj, + protocol_handler::strings::audio_service_transports, + &audio_service_transports); + } + // videoServiceTransports + BsonArray video_service_transports; + if (expected_video_service_transports.size() > 0) { + bson_array_initialize(&video_service_transports, + expected_video_service_transports.size()); + for (std::vector<int32_t>::const_iterator it = + expected_video_service_transports.begin(); + it != expected_video_service_transports.end(); + ++it) { + bson_array_add_int32(&video_service_transports, *it); + } + bson_object_put_array(&expected_obj, + protocol_handler::strings::video_service_transports, + &video_service_transports); + } + + 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))); + times++; + +#ifdef ENABLE_SECURITY + AddSecurityManager(); + + EXPECT_CALL(session_observer_mock, KeyFromPair(connection_id, session_id)) + .WillOnce(Return(connection_key)); + + EXPECT_CALL(session_observer_mock, GetSSLContext(connection_key, kRpc)) + .WillOnce(ReturnNull()); +#endif // ENABLE_SECURITY + + protocol_handler_impl->SendStartSessionAck(connection_id, + session_id, + input_protocol_version, + hash_id, + protocol_handler::SERVICE_TYPE_RPC, + false /* protection */, + full_version); + + EXPECT_TRUE(waiter.WaitFor(times, kAsyncExpectationsTimeout)); +} + +TEST_F(ProtocolHandlerImplTest, + StartSessionAck_SecondaryTransportParams_Enabled) { + // config allows secondary transport only when connected through Bluetooth, + // and the secondary is Wi-Fi + std::vector<std::string> secondary_transports_for_usb; // empty + std::vector<std::string> secondary_transports_for_bluetooth; + secondary_transports_for_bluetooth.push_back("WiFi"); + std::vector<std::string> secondary_transports_for_wifi; // empty + // config allows video and audio services to run on all transports except + // Bluetooth + std::vector<std::string> audio_service_transports; + audio_service_transports.push_back("IAP_USB"); + audio_service_transports.push_back("IAP_USB_HOST_MODE"); + audio_service_transports.push_back("IAP_USB_DEVICE_MODE"); + audio_service_transports.push_back("IAP_CARPLAY"); + audio_service_transports.push_back("AOA_USB"); + audio_service_transports.push_back("TCP_WIFI"); + std::vector<std::string> video_service_transports; + video_service_transports.push_back("IAP_USB"); + video_service_transports.push_back("IAP_USB_HOST_MODE"); + video_service_transports.push_back("IAP_USB_DEVICE_MODE"); + video_service_transports.push_back("IAP_CARPLAY"); + video_service_transports.push_back("AOA_USB"); + video_service_transports.push_back("TCP_WIFI"); + + // assume the device is Android and is connected through Bluetooth SPP + std::string connection_type_string("SPP_BLUETOOTH"); + + // Core should specify WiFi for secondary transport, and should allow video + // and audio services only on secondary transport + std::vector<std::string> expected_transport_strings; + expected_transport_strings.push_back("TCP_WIFI"); + std::vector<int32_t> expected_audio_service_transports; + expected_audio_service_transports.push_back(2); + std::vector<int32_t> expected_video_service_transports; + expected_video_service_transports.push_back(2); + + // A TransportUpdateEvent is also issued after Start Service ACK. We don't + // check it in this test case. + EXPECT_CALL(session_observer_mock, ProtocolVersionUsed(_, _, _)) + .WillRepeatedly(Return(false)); + + VerifySecondaryTransportParamsInStartSessionAck( + true, + secondary_transports_for_usb, + secondary_transports_for_bluetooth, + secondary_transports_for_wifi, + audio_service_transports, + video_service_transports, + connection_type_string, + expected_transport_strings, + expected_audio_service_transports, + expected_video_service_transports); +} + +TEST_F(ProtocolHandlerImplTest, + StartSessionAck_SecondaryTransportParams_NoSecondaryTransport) { + // config allows secondary transport only when connected through Bluetooth, + // and the secondary is Wi-Fi + std::vector<std::string> secondary_transports_for_usb; // empty + std::vector<std::string> secondary_transports_for_bluetooth; + secondary_transports_for_bluetooth.push_back("WiFi"); + std::vector<std::string> secondary_transports_for_wifi; // empty + // config allows video and audio services to run on all transports except + // Bluetooth + std::vector<std::string> audio_service_transports; + audio_service_transports.push_back("IAP_USB"); + audio_service_transports.push_back("IAP_USB_HOST_MODE"); + audio_service_transports.push_back("IAP_USB_DEVICE_MODE"); + audio_service_transports.push_back("IAP_CARPLAY"); + audio_service_transports.push_back("AOA_USB"); + audio_service_transports.push_back("TCP_WIFI"); + std::vector<std::string> video_service_transports; + video_service_transports.push_back("IAP_USB"); + video_service_transports.push_back("IAP_USB_HOST_MODE"); + video_service_transports.push_back("IAP_USB_DEVICE_MODE"); + video_service_transports.push_back("IAP_CARPLAY"); + video_service_transports.push_back("AOA_USB"); + video_service_transports.push_back("TCP_WIFI"); + + // assume the device is iOS and is connected through iAP over USB + std::string connection_type_string("IAP_USB"); + + // Core should not offer any secondary transport. It will allow both video + // and audio services on primary transport. + std::vector<std::string> expected_transport_strings; // empty + std::vector<int32_t> expected_audio_service_transports; + expected_audio_service_transports.push_back(1); + std::vector<int32_t> expected_video_service_transports; + expected_video_service_transports.push_back(1); + + EXPECT_CALL(session_observer_mock, ProtocolVersionUsed(_, _, _)) + .WillRepeatedly(Return(false)); + + VerifySecondaryTransportParamsInStartSessionAck( + true, + secondary_transports_for_usb, + secondary_transports_for_bluetooth, + secondary_transports_for_wifi, + audio_service_transports, + video_service_transports, + connection_type_string, + expected_transport_strings, + expected_audio_service_transports, + expected_video_service_transports); +} + +TEST_F(ProtocolHandlerImplTest, + StartSessionAck_SecondaryTransportParams_MultipleSecondaryTransports) { + // config allows secondary transport only when connected through Bluetooth, + // and the secondary is Wi-Fi and USB + std::vector<std::string> secondary_transports_for_usb; // empty + std::vector<std::string> secondary_transports_for_bluetooth; + secondary_transports_for_bluetooth.push_back("WiFi"); + secondary_transports_for_bluetooth.push_back("USB"); + std::vector<std::string> secondary_transports_for_wifi; // empty + // config allows video and audio services to run on all transports except + // Bluetooth + std::vector<std::string> audio_service_transports; + audio_service_transports.push_back("IAP_USB"); + audio_service_transports.push_back("IAP_USB_HOST_MODE"); + audio_service_transports.push_back("IAP_USB_DEVICE_MODE"); + audio_service_transports.push_back("IAP_CARPLAY"); + audio_service_transports.push_back("AOA_USB"); + audio_service_transports.push_back("TCP_WIFI"); + std::vector<std::string> video_service_transports; + video_service_transports.push_back("IAP_USB"); + video_service_transports.push_back("IAP_USB_HOST_MODE"); + video_service_transports.push_back("IAP_USB_DEVICE_MODE"); + video_service_transports.push_back("IAP_CARPLAY"); + video_service_transports.push_back("AOA_USB"); + video_service_transports.push_back("TCP_WIFI"); + + // assume the device is iOS and is connected through iAP over Bluetooth + std::string connection_type_string("IAP_BLUETOOTH"); + + // Core should offer both Wi-Fi and USB for secondary transport. Since the + // device is iOS, Core should specify "IAP_USB". + std::vector<std::string> expected_transport_strings; + expected_transport_strings.push_back("TCP_WIFI"); + expected_transport_strings.push_back("IAP_USB"); + std::vector<int32_t> expected_audio_service_transports; + expected_audio_service_transports.push_back(2); + std::vector<int32_t> expected_video_service_transports; + expected_video_service_transports.push_back(2); + + EXPECT_CALL(session_observer_mock, ProtocolVersionUsed(_, _, _)) + .WillRepeatedly(Return(false)); + + VerifySecondaryTransportParamsInStartSessionAck( + true, + secondary_transports_for_usb, + secondary_transports_for_bluetooth, + secondary_transports_for_wifi, + audio_service_transports, + video_service_transports, + connection_type_string, + expected_transport_strings, + expected_audio_service_transports, + expected_video_service_transports); +} + +TEST_F( + ProtocolHandlerImplTest, + StartSessionAck_SecondaryTransportParams_ServiceAllowedOnBothTransports) { + std::vector<std::string> secondary_transports_for_usb; + secondary_transports_for_usb.push_back("WiFi"); + std::vector<std::string> secondary_transports_for_bluetooth; + secondary_transports_for_bluetooth.push_back("USB"); + std::vector<std::string> secondary_transports_for_wifi; // empty + // config allows video service to run on Wi-Fi transports only, and audio + // service to run on all transports + std::vector<std::string> audio_service_transports; + audio_service_transports.push_back("IAP_BLUETOOTH"); + audio_service_transports.push_back("IAP_USB"); + audio_service_transports.push_back("IAP_USB_HOST_MODE"); + audio_service_transports.push_back("IAP_USB_DEVICE_MODE"); + audio_service_transports.push_back("IAP_CARPLAY"); + audio_service_transports.push_back("SPP_BLUETOOTH"); + audio_service_transports.push_back("AOA_USB"); + audio_service_transports.push_back("TCP_WIFI"); + std::vector<std::string> video_service_transports; + video_service_transports.push_back("IAP_CARPLAY"); + video_service_transports.push_back("TCP_WIFI"); + + // assume the device is Android and is connected through AOA + std::string connection_type_string("AOA_USB"); + + // Core should offer Wi-Fi for secondary transport. It should allow audio + // service to run on both primary and secondary, while video service to run + // on secondary only. Since the list specifies AOA_USB then TCP_WIFI, the + // priority is primary > secondary. + std::vector<std::string> expected_transport_strings; + expected_transport_strings.push_back("TCP_WIFI"); + std::vector<int32_t> expected_audio_service_transports; + expected_audio_service_transports.push_back(1); // primary preferred + expected_audio_service_transports.push_back(2); + std::vector<int32_t> expected_video_service_transports; + expected_video_service_transports.push_back(2); + + EXPECT_CALL(session_observer_mock, ProtocolVersionUsed(_, _, _)) + .WillRepeatedly(Return(false)); + + VerifySecondaryTransportParamsInStartSessionAck( + true, + secondary_transports_for_usb, + secondary_transports_for_bluetooth, + secondary_transports_for_wifi, + audio_service_transports, + video_service_transports, + connection_type_string, + expected_transport_strings, + expected_audio_service_transports, + expected_video_service_transports); +} + +TEST_F(ProtocolHandlerImplTest, + StartSessionAck_SecondaryTransportParams_SecondaryDisabled) { + std::vector<std::string> secondary_transports_for_usb; // empty + std::vector<std::string> secondary_transports_for_bluetooth; // empty + std::vector<std::string> secondary_transports_for_wifi; // empty + // config allows video and audio services to run on all transports + std::vector<std::string> audio_service_transports; + audio_service_transports.push_back("IAP_BLUETOOTH"); + audio_service_transports.push_back("IAP_USB"); + audio_service_transports.push_back("IAP_USB_HOST_MODE"); + audio_service_transports.push_back("IAP_USB_DEVICE_MODE"); + audio_service_transports.push_back("IAP_CARPLAY"); + audio_service_transports.push_back("SPP_BLUETOOTH"); + audio_service_transports.push_back("AOA_USB"); + audio_service_transports.push_back("TCP_WIFI"); + std::vector<std::string> video_service_transports; + video_service_transports.push_back("IAP_BLUETOOTH"); + video_service_transports.push_back("IAP_USB"); + video_service_transports.push_back("IAP_USB_HOST_MODE"); + video_service_transports.push_back("IAP_USB_DEVICE_MODE"); + video_service_transports.push_back("IAP_CARPLAY"); + video_service_transports.push_back("SPP_BLUETOOTH"); + video_service_transports.push_back("AOA_USB"); + video_service_transports.push_back("TCP_WIFI"); + + // assume the device is iOS and is connected through iAP over Bluetooth + std::string connection_type_string("IAP_BLUETOOTH"); + + // Core should not offer any secondary transport. It should still send + // the video/audio service transport lists. + std::vector<std::string> expected_transport_strings; // empty + std::vector<int32_t> expected_audio_service_transports; + expected_audio_service_transports.push_back(1); + std::vector<int32_t> expected_video_service_transports; + expected_video_service_transports.push_back(1); + + connection_handler::SessionTransports dummy_st = {0, 0}; + EXPECT_CALL(connection_handler_mock, + SetSecondaryTransportID(_, kDisabledSecondary)) + .WillOnce(Return(dummy_st)); + + EXPECT_CALL(session_observer_mock, ProtocolVersionUsed(_, _, _)) + .WillRepeatedly(Return(false)); + + VerifySecondaryTransportParamsInStartSessionAck( + false, /* disabled */ + secondary_transports_for_usb, + secondary_transports_for_bluetooth, + secondary_transports_for_wifi, + audio_service_transports, + video_service_transports, + connection_type_string, + expected_transport_strings, + expected_audio_service_transports, + expected_video_service_transports); +} + +TEST_F(ProtocolHandlerImplTest, + StartSessionAck_SecondaryTransportParams_ServicesMapEmpty) { + std::vector<std::string> secondary_transports_for_usb; // empty + std::vector<std::string> secondary_transports_for_bluetooth; + secondary_transports_for_bluetooth.push_back("USB"); + std::vector<std::string> secondary_transports_for_wifi; + secondary_transports_for_wifi.push_back("USB"); + // config does not specify video and audio services + std::vector<std::string> audio_service_transports; // empty + std::vector<std::string> video_service_transports; // empty + + // assume the device is connected through Wi-Fi (so not sure if it's iOS or + // Android) + std::string connection_type_string("TCP_WIFI"); + + // Core should offer USB transport for secondary transport. (Since the OS type + // is unknown, it will offer both IAP_USB and AOA_USB.) Also, it should allow + // video/audio services on all transports. + std::vector<std::string> expected_transport_strings; + expected_transport_strings.push_back("IAP_USB"); + expected_transport_strings.push_back("AOA_USB"); + std::vector<int32_t> expected_audio_service_transports; + expected_audio_service_transports.push_back(1); + expected_audio_service_transports.push_back(2); + std::vector<int32_t> expected_video_service_transports; + expected_video_service_transports.push_back(1); + expected_video_service_transports.push_back(2); + + EXPECT_CALL(session_observer_mock, ProtocolVersionUsed(_, _, _)) + .WillRepeatedly(Return(false)); + + VerifySecondaryTransportParamsInStartSessionAck( + true, + secondary_transports_for_usb, + secondary_transports_for_bluetooth, + secondary_transports_for_wifi, + audio_service_transports, + video_service_transports, + connection_type_string, + expected_transport_strings, + expected_audio_service_transports, + expected_video_service_transports); +} + +TEST_F( + ProtocolHandlerImplTest, + StartSessionAck_SecondaryTransportParams_SecondaryDisabled_ServicesMapEmpty) { + std::vector<std::string> secondary_transports_for_usb; // empty + std::vector<std::string> secondary_transports_for_bluetooth; // empty + std::vector<std::string> secondary_transports_for_wifi; // empty + // config does not specify video and audio services + std::vector<std::string> audio_service_transports; // empty + std::vector<std::string> video_service_transports; // empty + + std::string connection_type_string("IAP_BLUETOOTH"); + + // Core should not offer any secondary transport. It should still send + // the video/audio service transport lists. + std::vector<std::string> expected_transport_strings; // empty + std::vector<int32_t> expected_audio_service_transports; + expected_audio_service_transports.push_back(1); + std::vector<int32_t> expected_video_service_transports; + expected_video_service_transports.push_back(1); + + connection_handler::SessionTransports dummy_st = {0, 0}; + EXPECT_CALL(connection_handler_mock, + SetSecondaryTransportID(_, kDisabledSecondary)) + .WillOnce(Return(dummy_st)); + + EXPECT_CALL(session_observer_mock, ProtocolVersionUsed(_, _, _)) + .WillRepeatedly(Return(false)); + + VerifySecondaryTransportParamsInStartSessionAck( + false, /* disabled */ + secondary_transports_for_usb, + secondary_transports_for_bluetooth, + secondary_transports_for_wifi, + audio_service_transports, + video_service_transports, + connection_type_string, + expected_transport_strings, + expected_audio_service_transports, + expected_video_service_transports); +} + +// Secondary transport param should not be included for apps with v5.0.0 +TEST_F(ProtocolHandlerImplTest, + StartSessionAck_Unprotected_NoSecondaryTransportParamsForV5) { + TestAsyncWaiter waiter; + uint32_t times = 0; + + const uint8_t input_protocol_version = 5; + const uint32_t hash_id = 123456; + utils::SemanticVersion full_version(5, 0, 0); + char full_version_string[] = "5.0.0"; + + const size_t maximum_rpc_payload_size = 1500; + EXPECT_CALL(protocol_handler_settings_mock, maximum_rpc_payload_size()) + .WillRepeatedly(Return(maximum_rpc_payload_size)); + InitProtocolHandlerImpl(0u, 0u); + + // configuration + std::vector<std::string> config_secondary_transports_for_usb; // empty + std::vector<std::string> config_secondary_transports_for_bluetooth; + config_secondary_transports_for_bluetooth.push_back("USB"); + std::vector<std::string> config_secondary_transports_for_wifi; + config_secondary_transports_for_wifi.push_back("USB"); + + // assume the device is iOS and is connected through iAP over Bluetooth + std::string connection_type_string("IAP_BLUETOOTH"); + + // configuration setup + EXPECT_CALL(protocol_handler_settings_mock, max_supported_protocol_version()) + .WillRepeatedly(Return(PROTOCOL_VERSION_5)); + EXPECT_CALL(protocol_handler_settings_mock, multiple_transports_enabled()) + .WillRepeatedly(Return(true)); + EXPECT_CALL(protocol_handler_settings_mock, secondary_transports_for_usb()) + .Times(AtLeast(0)) + .WillRepeatedly(ReturnRef(config_secondary_transports_for_usb)); + EXPECT_CALL(protocol_handler_settings_mock, + secondary_transports_for_bluetooth()) + .Times(AtLeast(0)) + .WillRepeatedly(ReturnRef(config_secondary_transports_for_bluetooth)); + EXPECT_CALL(protocol_handler_settings_mock, secondary_transports_for_wifi()) + .Times(AtLeast(0)) + .WillRepeatedly(ReturnRef(config_secondary_transports_for_wifi)); + + EXPECT_CALL(session_observer_mock, + TransportTypeProfileStringFromConnHandle(connection_id)) + .WillRepeatedly(Return(connection_type_string)); + + // BSON params should not include any of "secondaryTransports", + // "audioServiceTransports" and "videoServiceTransports" since v5.0.0 app + // does not understand them + 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); + + 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))); + times++; + + connection_handler::SessionTransports dummy_st = {0, 0}; + EXPECT_CALL(connection_handler_mock, + SetSecondaryTransportID(_, kDisabledSecondary)) + .WillOnce(Return(dummy_st)); + + // Since the protocol version is less than 5.1.0, Core should not issue + // TransportEventUpdate frame. Enable ProtocolVersionUsed() call and verify + // that transport_manager_mock will NOT receive another SendMessageToDevice() + // call. + ON_CALL(session_observer_mock, ProtocolVersionUsed(_, _, _)) + .WillByDefault(Return(true)); + +#ifdef ENABLE_SECURITY + AddSecurityManager(); + + EXPECT_CALL(session_observer_mock, KeyFromPair(connection_id, session_id)) + .WillOnce(Return(connection_key)); + + EXPECT_CALL(session_observer_mock, GetSSLContext(connection_key, kRpc)) + .WillOnce(ReturnNull()); +#endif // ENABLE_SECURITY + + protocol_handler_impl->SendStartSessionAck(connection_id, + session_id, + input_protocol_version, + hash_id, + protocol_handler::SERVICE_TYPE_RPC, + false /* protection */, + full_version); + + EXPECT_TRUE(waiter.WaitFor(times, kAsyncExpectationsTimeout)); +} + +TEST_F(ProtocolHandlerImplTest, StartSessionAck_PrimaryTransportUSBHostMode) { + // config allows secondary transport only when connected through Bluetooth, + // and the secondary is Wi-Fi + std::vector<std::string> secondary_transports_for_usb; + secondary_transports_for_usb.push_back("WiFi"); + std::vector<std::string> secondary_transports_for_bluetooth; // empty + std::vector<std::string> secondary_transports_for_wifi; // empty + // config allows video and audio services to run on all transports except + // Bluetooth + std::vector<std::string> audio_service_transports; + audio_service_transports.push_back("IAP_USB_DEVICE_MODE"); + audio_service_transports.push_back("IAP_CARPLAY"); + audio_service_transports.push_back("AOA_USB"); + audio_service_transports.push_back("TCP_WIFI"); + std::vector<std::string> video_service_transports; + video_service_transports.push_back("IAP_USB"); + video_service_transports.push_back("IAP_CARPLAY"); + video_service_transports.push_back("AOA_USB"); + video_service_transports.push_back("TCP_WIFI"); + + // assume the device is IOS and is connected through USB Host Mode + std::string connection_type_string("IAP_USB_HOST_MODE"); + + // Core should specify WiFi for secondary transport, and should allow video + // services on both transports, and audio only on secondary transport + std::vector<std::string> expected_transport_strings; + expected_transport_strings.push_back("TCP_WIFI"); + std::vector<int32_t> expected_audio_service_transports; + expected_audio_service_transports.push_back(2); + std::vector<int32_t> expected_video_service_transports; + expected_video_service_transports.push_back(1); + expected_video_service_transports.push_back(2); + + // A TransportUpdateEvent is also issued after Start Service ACK. We don't + // check it in this test case. + EXPECT_CALL(session_observer_mock, ProtocolVersionUsed(_, _, _)) + .WillRepeatedly(Return(false)); + + VerifySecondaryTransportParamsInStartSessionAck( + true, + secondary_transports_for_usb, + secondary_transports_for_bluetooth, + secondary_transports_for_wifi, + audio_service_transports, + video_service_transports, + connection_type_string, + expected_transport_strings, + expected_audio_service_transports, + expected_video_service_transports); +} + +TEST_F(ProtocolHandlerImplTest, + TransportEventUpdate_afterVersionNegotiation_TCPEnabled) { + TestAsyncWaiter waiter; + uint32_t times = 0; + + const uint8_t input_protocol_version = 5; + const uint32_t hash_id = 123456; + utils::SemanticVersion full_version(5, 1, 0); + + const size_t maximum_rpc_payload_size = 1500; + EXPECT_CALL(protocol_handler_settings_mock, maximum_rpc_payload_size()) + .WillRepeatedly(Return(maximum_rpc_payload_size)); + InitProtocolHandlerImpl(0u, 0u); + + // TCP configuration setup + bool tcp_enabled = true; + char tcp_address[] = "192.168.1.1"; + int32_t tcp_port = 12345; + std::string tcp_port_str = "12345"; + protocol_handler_impl->set_tcp_config( + tcp_enabled, std::string(tcp_address), tcp_port_str); + + // configuration setup + std::vector<std::string> config_secondary_transports_for_usb; // empty + std::vector<std::string> config_secondary_transports_for_bluetooth; + config_secondary_transports_for_bluetooth.push_back("WiFi"); + std::vector<std::string> config_secondary_transports_for_wifi; // empty + std::vector<std::string> config_audio_service_transports; + config_audio_service_transports.push_back("IAP_USB"); + config_audio_service_transports.push_back("IAP_USB_HOST_MODE"); + config_audio_service_transports.push_back("IAP_USB_DEVICE_MODE"); + config_audio_service_transports.push_back("IAP_CARPLAY"); + config_audio_service_transports.push_back("AOA_USB"); + config_audio_service_transports.push_back("TCP_WIFI"); + std::vector<std::string> config_video_service_transports; + config_video_service_transports.push_back("IAP_USB"); + config_video_service_transports.push_back("IAP_USB_HOST_MODE"); + config_video_service_transports.push_back("IAP_USB_DEVICE_MODE"); + config_video_service_transports.push_back("IAP_CARPLAY"); + config_video_service_transports.push_back("AOA_USB"); + config_video_service_transports.push_back("TCP_WIFI"); + + EXPECT_CALL(protocol_handler_settings_mock, max_supported_protocol_version()) + .WillRepeatedly(Return(PROTOCOL_VERSION_5)); + EXPECT_CALL(protocol_handler_settings_mock, multiple_transports_enabled()) + .WillRepeatedly(Return(true)); + EXPECT_CALL(protocol_handler_settings_mock, secondary_transports_for_usb()) + .Times(AtLeast(0)) + .WillRepeatedly(ReturnRef(config_secondary_transports_for_usb)); + EXPECT_CALL(protocol_handler_settings_mock, + secondary_transports_for_bluetooth()) + .Times(AtLeast(0)) + .WillRepeatedly(ReturnRef(config_secondary_transports_for_bluetooth)); + EXPECT_CALL(protocol_handler_settings_mock, secondary_transports_for_wifi()) + .Times(AtLeast(0)) + .WillRepeatedly(ReturnRef(config_secondary_transports_for_wifi)); + EXPECT_CALL(protocol_handler_settings_mock, audio_service_transports()) + .WillOnce(ReturnRef(config_audio_service_transports)); + EXPECT_CALL(protocol_handler_settings_mock, video_service_transports()) + .WillOnce(ReturnRef(config_video_service_transports)); + + // assume the device is iOS and is connected through iAP over Bluetooth + std::string connection_type_string("IAP_BLUETOOTH"); + + EXPECT_CALL(session_observer_mock, + TransportTypeProfileStringFromConnHandle(connection_id)) + .WillRepeatedly(Return(connection_type_string)); + + EXPECT_CALL( + transport_manager_mock, + SendMessageToDevice(ControlMessage( + FRAME_DATA_START_SERVICE_ACK, PROTECTION_OFF, connection_id, _))) + .WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(E_SUCCESS))); + times++; + + EXPECT_CALL(session_observer_mock, ProtocolVersionUsed(_, _, _)) + .WillRepeatedly( + DoAll(SetArgReferee<2>(PROTOCOL_VERSION_5), Return(true))); + + BsonObject expected_obj; + bson_object_initialize_default(&expected_obj); + // IP address + bson_object_put_string( + &expected_obj, protocol_handler::strings::tcp_ip_address, tcp_address); + // TCP port number + bson_object_put_int32( + &expected_obj, protocol_handler::strings::tcp_port, tcp_port); + + std::vector<uint8_t> expected_param = + CreateVectorFromBsonObject(&expected_obj); + + bson_object_deinitialize(&expected_obj); + + EXPECT_CALL( + transport_manager_mock, + SendMessageToDevice(ControlMessage(FRAME_DATA_TRANSPORT_EVENT_UPDATE, + PROTECTION_OFF, + connection_id, + Eq(expected_param)))) + .WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(E_SUCCESS))); + times++; + +#ifdef ENABLE_SECURITY + AddSecurityManager(); + + EXPECT_CALL(session_observer_mock, KeyFromPair(connection_id, session_id)) + .WillOnce(Return(connection_key)); + + EXPECT_CALL(session_observer_mock, GetSSLContext(connection_key, kRpc)) + .WillOnce(ReturnNull()); +#endif // ENABLE_SECURITY + + protocol_handler_impl->SendStartSessionAck(connection_id, + session_id, + input_protocol_version, + hash_id, + protocol_handler::SERVICE_TYPE_RPC, + false /* protection */, + full_version); + + EXPECT_TRUE(waiter.WaitFor(times, kAsyncExpectationsTimeout)); +} + +TEST_F(ProtocolHandlerImplTest, + TransportEventUpdate_afterVersionNegotiation_TCPDisabled) { + TestAsyncWaiter waiter; + uint32_t times = 0; + + const uint8_t input_protocol_version = 5; + const uint32_t hash_id = 123456; + utils::SemanticVersion full_version(5, 1, 0); + + const size_t maximum_rpc_payload_size = 1500; + EXPECT_CALL(protocol_handler_settings_mock, maximum_rpc_payload_size()) + .WillRepeatedly(Return(maximum_rpc_payload_size)); + InitProtocolHandlerImpl(0u, 0u); + + // TCP configuration setup + bool tcp_enabled = false; + char tcp_address[] = "192.168.2.3"; + std::string tcp_port_str = "12345"; + protocol_handler_impl->set_tcp_config( + tcp_enabled, std::string(tcp_address), tcp_port_str); + + std::vector<std::string> config_secondary_transports_for_usb; // empty + std::vector<std::string> config_secondary_transports_for_bluetooth; + config_secondary_transports_for_bluetooth.push_back("WiFi"); + std::vector<std::string> config_secondary_transports_for_wifi; // empty + std::vector<std::string> config_audio_service_transports; + config_audio_service_transports.push_back("IAP_USB"); + config_audio_service_transports.push_back("IAP_USB_HOST_MODE"); + config_audio_service_transports.push_back("IAP_USB_DEVICE_MODE"); + config_audio_service_transports.push_back("IAP_CARPLAY"); + config_audio_service_transports.push_back("AOA_USB"); + config_audio_service_transports.push_back("TCP_WIFI"); + std::vector<std::string> config_video_service_transports; + config_video_service_transports.push_back("IAP_USB"); + config_video_service_transports.push_back("IAP_USB_HOST_MODE"); + config_video_service_transports.push_back("IAP_USB_DEVICE_MODE"); + config_video_service_transports.push_back("IAP_CARPLAY"); + config_video_service_transports.push_back("AOA_USB"); + config_video_service_transports.push_back("TCP_WIFI"); + + EXPECT_CALL(protocol_handler_settings_mock, max_supported_protocol_version()) + .WillRepeatedly(Return(PROTOCOL_VERSION_5)); + EXPECT_CALL(protocol_handler_settings_mock, multiple_transports_enabled()) + .WillRepeatedly(Return(true)); + EXPECT_CALL(protocol_handler_settings_mock, secondary_transports_for_usb()) + .Times(AtLeast(0)) + .WillRepeatedly(ReturnRef(config_secondary_transports_for_usb)); + EXPECT_CALL(protocol_handler_settings_mock, + secondary_transports_for_bluetooth()) + .Times(AtLeast(0)) + .WillRepeatedly(ReturnRef(config_secondary_transports_for_bluetooth)); + EXPECT_CALL(protocol_handler_settings_mock, secondary_transports_for_wifi()) + .Times(AtLeast(0)) + .WillRepeatedly(ReturnRef(config_secondary_transports_for_wifi)); + EXPECT_CALL(protocol_handler_settings_mock, audio_service_transports()) + .WillOnce(ReturnRef(config_audio_service_transports)); + EXPECT_CALL(protocol_handler_settings_mock, video_service_transports()) + .WillOnce(ReturnRef(config_video_service_transports)); + + // assume the device is iOS and is connected through iAP over Bluetooth + std::string connection_type_string("IAP_BLUETOOTH"); + + EXPECT_CALL(session_observer_mock, + TransportTypeProfileStringFromConnHandle(connection_id)) + .WillRepeatedly(Return(connection_type_string)); + + EXPECT_CALL( + transport_manager_mock, + SendMessageToDevice(ControlMessage( + FRAME_DATA_START_SERVICE_ACK, PROTECTION_OFF, connection_id, _))) + .WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(E_SUCCESS))); + times++; + + EXPECT_CALL(session_observer_mock, ProtocolVersionUsed(_, _, _)) + .WillRepeatedly( + DoAll(SetArgReferee<2>(PROTOCOL_VERSION_5), Return(true))); + + BsonObject expected_obj; + bson_object_initialize_default(&expected_obj); + // IP address + char empty_ip_address[] = ""; + bson_object_put_string(&expected_obj, + protocol_handler::strings::tcp_ip_address, + empty_ip_address); + // TCP port number should be omitted + + std::vector<uint8_t> expected_param = + CreateVectorFromBsonObject(&expected_obj); + + bson_object_deinitialize(&expected_obj); + + EXPECT_CALL( + transport_manager_mock, + SendMessageToDevice(ControlMessage(FRAME_DATA_TRANSPORT_EVENT_UPDATE, + PROTECTION_OFF, + connection_id, + Eq(expected_param)))) + .WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(E_SUCCESS))); + times++; + +#ifdef ENABLE_SECURITY + AddSecurityManager(); + + EXPECT_CALL(session_observer_mock, KeyFromPair(connection_id, session_id)) + .WillOnce(Return(connection_key)); + + EXPECT_CALL(session_observer_mock, GetSSLContext(connection_key, kRpc)) + .WillOnce(ReturnNull()); +#endif // ENABLE_SECURITY + + protocol_handler_impl->SendStartSessionAck(connection_id, + session_id, + input_protocol_version, + hash_id, + protocol_handler::SERVICE_TYPE_RPC, + false /* protection */, + full_version); + + EXPECT_TRUE(waiter.WaitFor(times, kAsyncExpectationsTimeout)); +} + +TEST_F(ProtocolHandlerImplTest, + OnTransportConfigUpdated_TransportEventUpdate_TCPEnabled) { + using connection_handler::SessionConnectionMap; + using connection_handler::SessionTransports; + + TestAsyncWaiter waiter; + uint32_t times = 0; + + char tcp_address[] = "172.16.2.3"; + int32_t tcp_port = 23456; + std::string tcp_port_str = "23456"; + + transport_manager::transport_adapter::TransportConfig configs; + configs[transport_manager::transport_adapter::tc_enabled] = + std::string("true"); + configs[transport_manager::transport_adapter::tc_tcp_port] = tcp_port_str; + configs[transport_manager::transport_adapter::tc_tcp_ip_address] = + std::string(tcp_address); + + transport_manager::ConnectionUID device1_primary_connection_id = 100; + transport_manager::ConnectionUID device2_primary_connection_id = 101; + transport_manager::ConnectionUID device2_secondary_connection_id = 150; + + SessionTransports st1 = {device1_primary_connection_id, kDisabledSecondary}; + SessionTransports st2 = {device2_primary_connection_id, + device2_secondary_connection_id}; + session_connection_map_[0x11] = st1; + session_connection_map_[0x22] = st2; + + EXPECT_CALL(connection_handler_mock, session_connection_map()) + .WillOnce(Return(DataAccessor<SessionConnectionMap>( + session_connection_map_, session_connection_map_lock_ptr_))); + + EXPECT_CALL(session_observer_mock, ProtocolVersionUsed(_, _, _)) + .WillRepeatedly( + DoAll(SetArgReferee<2>(PROTOCOL_VERSION_5), Return(true))); + + BsonObject expected_obj; + bson_object_initialize_default(&expected_obj); + // IP address + bson_object_put_string( + &expected_obj, protocol_handler::strings::tcp_ip_address, tcp_address); + // TCP port number + bson_object_put_int32( + &expected_obj, protocol_handler::strings::tcp_port, tcp_port); + + std::vector<uint8_t> expected_param = + CreateVectorFromBsonObject(&expected_obj); + + bson_object_deinitialize(&expected_obj); + + // since device 1 doesn't support secondary transport feature, + // TransportEvetUpdate should be delivered only to device 2 + EXPECT_CALL( + transport_manager_mock, + SendMessageToDevice(ControlMessage(FRAME_DATA_TRANSPORT_EVENT_UPDATE, + PROTECTION_OFF, + device2_primary_connection_id, + Eq(expected_param)))) + .WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(E_SUCCESS))); + times++; + + tm_listener->OnTransportConfigUpdated(configs); + + EXPECT_TRUE(waiter.WaitFor(times, kAsyncExpectationsTimeout)); +} + +TEST_F(ProtocolHandlerImplTest, + OnTransportConfigUpdated_TransportEventUpdate_TCPDisabled) { + using connection_handler::SessionConnectionMap; + using connection_handler::SessionTransports; + + TestAsyncWaiter waiter; + uint32_t times = 0; + + char tcp_address[] = "172.16.2.3"; + std::string tcp_port_str = "23456"; + + transport_manager::transport_adapter::TransportConfig configs; + configs[transport_manager::transport_adapter::tc_enabled] = + std::string("false"); + configs[transport_manager::transport_adapter::tc_tcp_port] = tcp_port_str; + configs[transport_manager::transport_adapter::tc_tcp_ip_address] = + std::string(tcp_address); + + transport_manager::ConnectionUID device1_primary_connection_id = 100; + transport_manager::ConnectionUID device1_secondary_connection_id = 150; + transport_manager::ConnectionUID device2_primary_connection_id = 101; + transport_manager::ConnectionUID device3_primary_connection_id = 102; + transport_manager::ConnectionUID device3_secondary_connection_id = 151; + + SessionTransports st1 = {device1_primary_connection_id, + device1_secondary_connection_id}; + SessionTransports st2 = {device2_primary_connection_id, kDisabledSecondary}; + SessionTransports st3 = {device3_primary_connection_id, + device3_secondary_connection_id}; + session_connection_map_[0x11] = st1; + session_connection_map_[0x22] = st2; + session_connection_map_[0x33] = st3; + + EXPECT_CALL(connection_handler_mock, session_connection_map()) + .WillOnce(Return(DataAccessor<SessionConnectionMap>( + session_connection_map_, session_connection_map_lock_ptr_))); + + EXPECT_CALL(session_observer_mock, ProtocolVersionUsed(_, _, _)) + .WillRepeatedly( + DoAll(SetArgReferee<2>(PROTOCOL_VERSION_5), Return(true))); + + BsonObject expected_obj; + bson_object_initialize_default(&expected_obj); + // IP address + char empty_ip_address[] = ""; + bson_object_put_string(&expected_obj, + protocol_handler::strings::tcp_ip_address, + empty_ip_address); + // TCP port number should be omitted + + std::vector<uint8_t> expected_param = + CreateVectorFromBsonObject(&expected_obj); + + bson_object_deinitialize(&expected_obj); + + // both device 1 and device 3 should receive TransportEventUpdate frames + EXPECT_CALL( + transport_manager_mock, + SendMessageToDevice(ControlMessage(FRAME_DATA_TRANSPORT_EVENT_UPDATE, + PROTECTION_OFF, + device1_primary_connection_id, + Eq(expected_param)))) + .WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(E_SUCCESS))); + times++; + EXPECT_CALL( + transport_manager_mock, + SendMessageToDevice(ControlMessage(FRAME_DATA_TRANSPORT_EVENT_UPDATE, + PROTECTION_OFF, + device3_primary_connection_id, + Eq(expected_param)))) + .WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(E_SUCCESS))); + times++; + + tm_listener->OnTransportConfigUpdated(configs); + + EXPECT_TRUE(waiter.WaitFor(times, kAsyncExpectationsTimeout)); +} + +TEST_F(ProtocolHandlerImplTest, RegisterSecondaryTransport_SUCCESS) { + AddConnection(); + + TestAsyncWaiter waiter; + uint32_t times = 0; + + transport_manager::ConnectionUID primary_connection_id = 123; + + EXPECT_CALL(session_observer_mock, + ProtocolVersionUsed(primary_connection_id, _, _)) + .WillRepeatedly( + DoAll(SetArgReferee<2>(PROTOCOL_VERSION_5), Return(true))); + + EXPECT_CALL(connection_handler_mock, + OnSecondaryTransportStarted(_, connection_id, session_id)) + .WillOnce(DoAll(SetArgReferee<0>(primary_connection_id), Return(true))); + + EXPECT_CALL(transport_manager_mock, + SendMessageToDevice( + ControlMessage(FRAME_DATA_REGISTER_SECONDARY_TRANSPORT_ACK, + PROTECTION_OFF, + connection_id, + _))) + .WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(E_SUCCESS))); + times++; + + SendControlMessage(PROTECTION_OFF, + kControl, + session_id, + FRAME_DATA_REGISTER_SECONDARY_TRANSPORT, + PROTOCOL_VERSION_5); + + EXPECT_TRUE(waiter.WaitFor(times, kAsyncExpectationsTimeout)); +} + +TEST_F(ProtocolHandlerImplTest, RegisterSecondaryTransport_FAILURE) { + AddConnection(); + + TestAsyncWaiter waiter; + uint32_t times = 0; + + transport_manager::ConnectionUID primary_connection_id = 123; + + EXPECT_CALL(session_observer_mock, + ProtocolVersionUsed(primary_connection_id, _, _)) + .WillRepeatedly( + DoAll(SetArgReferee<2>(PROTOCOL_VERSION_5), Return(true))); + + // check the behavior when OnSecondaryTransportStarted() returns false + EXPECT_CALL(connection_handler_mock, + OnSecondaryTransportStarted(_, connection_id, session_id)) + .WillOnce(DoAll(SetArgReferee<0>(primary_connection_id), Return(false))); + + EXPECT_CALL(transport_manager_mock, + SendMessageToDevice( + ControlMessage(FRAME_DATA_REGISTER_SECONDARY_TRANSPORT_NACK, + PROTECTION_OFF, + connection_id, + _))) + .WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(E_SUCCESS))); + times++; + + SendControlMessage(PROTECTION_OFF, + kControl, + session_id, + FRAME_DATA_REGISTER_SECONDARY_TRANSPORT, + PROTOCOL_VERSION_5); + + EXPECT_TRUE(waiter.WaitFor(times, kAsyncExpectationsTimeout)); +} + TEST_F(ProtocolHandlerImplTest, DISABLED_FloodVerification) { const size_t period_msec = 10000; const size_t max_messages = 1000; InitProtocolHandlerImpl(period_msec, max_messages); AddConnection(); - ::utils::SharedPtr<TestAsyncWaiter> waiter = - utils::MakeShared<TestAsyncWaiter>(); + std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>(); uint32_t times = 0; AddSession(waiter, times); @@ -1494,8 +2971,7 @@ TEST_F(ProtocolHandlerImplTest, DISABLED_FloodVerification_ThresholdValue) { InitProtocolHandlerImpl(period_msec, max_messages); AddConnection(); - ::utils::SharedPtr<TestAsyncWaiter> waiter = - utils::MakeShared<TestAsyncWaiter>(); + std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>(); uint32_t times = 0; AddSession(waiter, times); @@ -1531,8 +3007,7 @@ TEST_F(ProtocolHandlerImplTest, DISABLED_FloodVerification_VideoFrameSkip) { InitProtocolHandlerImpl(period_msec, max_messages); AddConnection(); - ::utils::SharedPtr<TestAsyncWaiter> waiter = - utils::MakeShared<TestAsyncWaiter>(); + std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>(); uint32_t times = 0; AddSession(waiter, times); @@ -1560,8 +3035,7 @@ TEST_F(ProtocolHandlerImplTest, DISABLED_FloodVerification_AudioFrameSkip) { InitProtocolHandlerImpl(period_msec, max_messages); AddConnection(); - ::utils::SharedPtr<TestAsyncWaiter> waiter = - utils::MakeShared<TestAsyncWaiter>(); + std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>(); uint32_t times = 0; AddSession(waiter, times); @@ -1589,8 +3063,7 @@ TEST_F(ProtocolHandlerImplTest, DISABLED_FloodVerificationDisable) { InitProtocolHandlerImpl(period_msec, max_messages); AddConnection(); - ::utils::SharedPtr<TestAsyncWaiter> waiter = - utils::MakeShared<TestAsyncWaiter>(); + std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>(); uint32_t times = 0; AddSession(waiter, times); @@ -1618,8 +3091,7 @@ TEST_F(ProtocolHandlerImplTest, MalformedVerificationDisable) { InitProtocolHandlerImpl(0u, 0u, false, period_msec, max_messages); AddConnection(); - ::utils::SharedPtr<TestAsyncWaiter> waiter = - utils::MakeShared<TestAsyncWaiter>(); + std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>(); uint32_t times = 0; AddSession(waiter, times); @@ -1651,8 +3123,7 @@ TEST_F(ProtocolHandlerImplTest, DISABLED_MalformedLimitVerification) { InitProtocolHandlerImpl(0u, 0u, true, period_msec, max_messages); AddConnection(); - ::utils::SharedPtr<TestAsyncWaiter> waiter = - utils::MakeShared<TestAsyncWaiter>(); + std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>(); uint32_t times = 0; AddSession(waiter, times); @@ -1699,8 +3170,7 @@ TEST_F(ProtocolHandlerImplTest, InitProtocolHandlerImpl(0u, 0u, true, period_msec, max_messages); AddConnection(); - ::utils::SharedPtr<TestAsyncWaiter> waiter = - utils::MakeShared<TestAsyncWaiter>(); + std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>(); uint32_t times = 0; AddSession(waiter, times); @@ -1771,8 +3241,7 @@ TEST_F(ProtocolHandlerImplTest, MalformedLimitVerification_MalformedOnly) { InitProtocolHandlerImpl(0u, 0u, true, period_msec, max_messages); AddConnection(); - ::utils::SharedPtr<TestAsyncWaiter> waiter = - utils::MakeShared<TestAsyncWaiter>(); + std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>(); uint32_t times = 0; AddSession(waiter, times); @@ -1832,8 +3301,7 @@ TEST_F(ProtocolHandlerImplTest, MalformedLimitVerification_NullTimePeriod) { InitProtocolHandlerImpl(0u, 0u, true, period_msec, max_messages); AddConnection(); - ::utils::SharedPtr<TestAsyncWaiter> waiter = - utils::MakeShared<TestAsyncWaiter>(); + std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>(); uint32_t times = 0; AddSession(waiter, times); @@ -1866,8 +3334,7 @@ TEST_F(ProtocolHandlerImplTest, MalformedLimitVerification_NullCount) { InitProtocolHandlerImpl(0u, 0u, true, period_msec, max_messages); AddConnection(); - ::utils::SharedPtr<TestAsyncWaiter> waiter = - utils::MakeShared<TestAsyncWaiter>(); + std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>(); uint32_t times = 0; AddSession(waiter, times); @@ -1910,8 +3377,7 @@ TEST_F(ProtocolHandlerImplTest, TEST_F(ProtocolHandlerImplTest, DISABLED_SendEndServicePrivate_EndSession_MessageSent) { // Arrange - ::utils::SharedPtr<TestAsyncWaiter> waiter = - utils::MakeShared<TestAsyncWaiter>(); + std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>(); uint32_t times = 0; AddSession(waiter, times); @@ -1935,8 +3401,7 @@ TEST_F(ProtocolHandlerImplTest, TEST_F(ProtocolHandlerImplTest, SendEndServicePrivate_ServiceTypeControl_MessageSent) { // Arrange - ::utils::SharedPtr<TestAsyncWaiter> waiter = - utils::MakeShared<TestAsyncWaiter>(); + std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>(); uint32_t times = 0; AddSession(waiter, times); @@ -1955,7 +3420,8 @@ TEST_F(ProtocolHandlerImplTest, times++; // Act - protocol_handler_impl->SendEndService(connection_id, session_id, kControl); + protocol_handler_impl->SendEndService( + connection_id, connection_id, session_id, kControl); EXPECT_TRUE(waiter->WaitFor(times, kAsyncExpectationsTimeout)); } @@ -1974,8 +3440,7 @@ TEST_F(ProtocolHandlerImplTest, SendHeartBeat_NoConnection_NotSent) { TEST_F(ProtocolHandlerImplTest, SendHeartBeat_Successful) { // Arrange - ::utils::SharedPtr<TestAsyncWaiter> waiter = - utils::MakeShared<TestAsyncWaiter>(); + std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>(); uint32_t times = 0; AddSession(waiter, times); @@ -1989,7 +3454,8 @@ TEST_F(ProtocolHandlerImplTest, SendHeartBeat_Successful) { transport_manager_mock, SendMessageToDevice(ExpectedMessage( FRAME_TYPE_CONTROL, FRAME_DATA_HEART_BEAT, PROTECTION_OFF, kControl))) - .WillOnce(Return(E_SUCCESS)); + .WillOnce(DoAll(NotifyTestAsyncWaiter(waiter), Return(E_SUCCESS))); + times++; // Act protocol_handler_impl->SendHeartBeat(connection_id, session_id); @@ -1999,8 +3465,7 @@ TEST_F(ProtocolHandlerImplTest, SendHeartBeat_Successful) { TEST_F(ProtocolHandlerImplTest, SendHeartBeatAck_Successful) { // Arrange - ::utils::SharedPtr<TestAsyncWaiter> waiter = - utils::MakeShared<TestAsyncWaiter>(); + std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>(); uint32_t times = 0; AddSession(waiter, times); @@ -2029,8 +3494,7 @@ TEST_F(ProtocolHandlerImplTest, SendHeartBeatAck_Successful) { TEST_F(ProtocolHandlerImplTest, DISABLED_SendHeartBeatAck_WrongProtocolVersion_NotSent) { // Arrange - ::utils::SharedPtr<TestAsyncWaiter> waiter = - utils::MakeShared<TestAsyncWaiter>(); + std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>(); uint32_t times = 0; AddSession(waiter, times); @@ -2059,8 +3523,7 @@ TEST_F(ProtocolHandlerImplTest, TEST_F(ProtocolHandlerImplTest, SendMessageToMobileApp_SendSingleControlMessage) { // Arrange - ::utils::SharedPtr<TestAsyncWaiter> waiter = - utils::MakeShared<TestAsyncWaiter>(); + std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>(); uint32_t times = 0; AddSession(waiter, times); @@ -2068,7 +3531,7 @@ TEST_F(ProtocolHandlerImplTest, const bool is_final = true; const uint32_t total_data_size = 1; UCharDataVector data(total_data_size); - RawMessagePtr message = utils::MakeShared<RawMessage>( + RawMessagePtr message = std::make_shared<RawMessage>( connection_key, PROTOCOL_VERSION_3, &data[0], total_data_size, kControl); // Expect getting pair from key from session observer EXPECT_CALL(session_observer_mock, @@ -2086,7 +3549,8 @@ TEST_F(ProtocolHandlerImplTest, transport_manager_mock, SendMessageToDevice(ExpectedMessage( FRAME_TYPE_SINGLE, FRAME_DATA_SINGLE, PROTECTION_OFF, kControl))) - .WillOnce(Return(E_SUCCESS)); + .WillOnce(DoAll(NotifyTestAsyncWaiter(waiter), Return(E_SUCCESS))); + times++; // Act protocol_handler_impl->SendMessageToMobileApp(message, is_final); @@ -2097,8 +3561,7 @@ TEST_F(ProtocolHandlerImplTest, TEST_F(ProtocolHandlerImplTest, SendMessageToMobileApp_SendSingleNonControlMessage) { // Arrange - ::utils::SharedPtr<TestAsyncWaiter> waiter = - utils::MakeShared<TestAsyncWaiter>(); + std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>(); uint32_t times = 0; AddSession(waiter, times); @@ -2106,7 +3569,7 @@ TEST_F(ProtocolHandlerImplTest, const bool is_final = true; const uint32_t total_data_size = 1; UCharDataVector data(total_data_size); - RawMessagePtr message = utils::MakeShared<RawMessage>( + RawMessagePtr message = std::make_shared<RawMessage>( connection_key, PROTOCOL_VERSION_3, &data[0], total_data_size, kRpc); // Expect getting pair from key from session observer EXPECT_CALL(session_observer_mock, @@ -2140,8 +3603,7 @@ TEST_F(ProtocolHandlerImplTest, TEST_F(ProtocolHandlerImplTest, SendMessageToMobileApp_SendMultiframeMessage) { // Arrange - ::utils::SharedPtr<TestAsyncWaiter> waiter = - utils::MakeShared<TestAsyncWaiter>(); + std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>(); uint32_t times = 0; AddSession(waiter, times); @@ -2150,7 +3612,7 @@ TEST_F(ProtocolHandlerImplTest, SendMessageToMobileApp_SendMultiframeMessage) { const uint32_t total_data_size = MAXIMUM_FRAME_DATA_V2_SIZE * 2; UCharDataVector data(total_data_size); const uint8_t first_consecutive_frame = 0x01; - RawMessagePtr message = utils::MakeShared<RawMessage>( + RawMessagePtr message = std::make_shared<RawMessage>( connection_key, PROTOCOL_VERSION_3, &data[0], total_data_size, kBulk); // Expect getting pair from key from session observer EXPECT_CALL(session_observer_mock, @@ -2195,8 +3657,7 @@ TEST_F(ProtocolHandlerImplTest, SendMessageToMobileApp_SendMultiframeMessage) { } TEST_F(ProtocolHandlerImplTest, SendServiceDataAck_PreVersion5) { - ::utils::SharedPtr<TestAsyncWaiter> waiter = - utils::MakeShared<TestAsyncWaiter>(); + std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>(); uint32_t times = 0; AddSession(waiter, times); @@ -2222,8 +3683,7 @@ TEST_F(ProtocolHandlerImplTest, SendServiceDataAck_PreVersion5) { } TEST_F(ProtocolHandlerImplTest, SendServiceDataAck_AfterVersion5) { - ::utils::SharedPtr<TestAsyncWaiter> waiter = - utils::MakeShared<TestAsyncWaiter>(); + std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>(); uint32_t times = 0; AddSession(waiter, times); |