Loading system/gd/hci/acl_manager.cc +12 −8 Original line number Diff line number Diff line Loading @@ -266,10 +266,12 @@ struct AclManager::impl { ASSERT(connection_complete.IsValid()); auto status = connection_complete.GetStatus(); auto address = connection_complete.GetPeerAddress(); auto peer_address_type = connection_complete.GetPeerAddressType(); on_any_connection_complete(address); if (status != ErrorCode::SUCCESS) { client_handler_->Post(common::BindOnce(&ConnectionCallbacks::OnConnectFail, common::Unretained(client_callbacks_), address, status)); le_client_handler_->Post(common::BindOnce(&LeConnectionCallbacks::OnLeConnectFail, common::Unretained(le_client_callbacks_), address, peer_address_type, status)); return; } // TODO: Check and save other connection parameters Loading @@ -280,8 +282,8 @@ struct AclManager::impl { start_round_robin(); } std::unique_ptr<AclConnection> connection_proxy(new AclConnection(&acl_manager_, handle, address)); client_handler_->Post(common::BindOnce(&ConnectionCallbacks::OnConnectSuccess, common::Unretained(client_callbacks_), std::move(connection_proxy))); le_client_handler_->Post(common::BindOnce(&LeConnectionCallbacks::OnLeConnectSuccess, common::Unretained(le_client_callbacks_), std::move(connection_proxy))); } void on_le_enhanced_connection_complete(LeMetaEventView packet) { Loading @@ -289,10 +291,12 @@ struct AclManager::impl { ASSERT(connection_complete.IsValid()); auto status = connection_complete.GetStatus(); auto address = connection_complete.GetPeerAddress(); auto peer_address_type = connection_complete.GetPeerAddressType(); on_any_connection_complete(address); if (status != ErrorCode::SUCCESS) { client_handler_->Post(common::BindOnce(&ConnectionCallbacks::OnConnectFail, common::Unretained(client_callbacks_), address, status)); le_client_handler_->Post(common::BindOnce(&LeConnectionCallbacks::OnLeConnectFail, common::Unretained(le_client_callbacks_), address, peer_address_type, status)); return; } // TODO: Check and save other connection parameters Loading @@ -303,8 +307,8 @@ struct AclManager::impl { start_round_robin(); } std::unique_ptr<AclConnection> connection_proxy(new AclConnection(&acl_manager_, handle, address)); client_handler_->Post(common::BindOnce(&ConnectionCallbacks::OnConnectSuccess, common::Unretained(client_callbacks_), std::move(connection_proxy))); le_client_handler_->Post(common::BindOnce(&LeConnectionCallbacks::OnLeConnectSuccess, common::Unretained(le_client_callbacks_), std::move(connection_proxy))); } void on_connection_complete(EventPacketView packet) { Loading system/gd/hci/acl_manager_test.cc +87 −0 Original line number Diff line number Diff line Loading @@ -143,6 +143,15 @@ class TestHciLayer : public HciLayer { registered_events_.erase(event_code); } void RegisterLeEventHandler(SubeventCode subevent_code, common::Callback<void(LeMetaEventView)> event_handler, os::Handler* handler) override { registered_le_events_[subevent_code] = event_handler; } void UnregisterLeEventHandler(SubeventCode subevent_code) { registered_le_events_.erase(subevent_code); } void IncomingEvent(std::unique_ptr<EventPacketBuilder> event_builder) { auto packet = GetPacketView(std::move(event_builder)); EventPacketView event = EventPacketView::Create(packet); Loading @@ -152,6 +161,16 @@ class TestHciLayer : public HciLayer { registered_events_[event_code].Run(event); } void IncomingLeMetaEvent(std::unique_ptr<LeMetaEventBuilder> event_builder) { auto packet = GetPacketView(std::move(event_builder)); EventPacketView event = EventPacketView::Create(packet); LeMetaEventView meta_event_view = LeMetaEventView::Create(event); EXPECT_TRUE(meta_event_view.IsValid()); SubeventCode subevent_code = meta_event_view.GetSubeventCode(); EXPECT_TRUE(registered_le_events_.find(subevent_code) != registered_le_events_.end()); registered_le_events_[subevent_code].Run(meta_event_view); } void IncomingAclData(uint16_t handle) { os::Handler* hci_handler = GetHandler(); auto* queue_end = acl_queue_.GetDownEnd(); Loading Loading @@ -203,6 +222,7 @@ class TestHciLayer : public HciLayer { private: std::map<EventCode, common::Callback<void(EventPacketView)>> registered_events_; std::map<SubeventCode, common::Callback<void(LeMetaEventView)>> registered_le_events_; std::list<base::OnceCallback<void(CommandCompleteView)>> command_complete_callbacks; BidiQueue<AclPacketView, AclPacketBuilder> acl_queue_{3 /* TODO: Set queue depth */}; Loading Loading @@ -244,10 +264,21 @@ class AclManagerNoCallbacksTest : public ::testing::Test { return mock_connection_callback_.connection_promise_->get_future(); } std::future<void> GetLeConnectionFuture() { ASSERT_LOG(mock_le_connection_callbacks_.le_connection_promise_ == nullptr, "Promises promises ... Only one at a time"); mock_le_connection_callbacks_.le_connection_promise_ = std::make_unique<std::promise<void>>(); return mock_le_connection_callbacks_.le_connection_promise_->get_future(); } std::shared_ptr<AclConnection> GetLastConnection() { return mock_connection_callback_.connections_.back(); } std::shared_ptr<AclConnection> GetLastLeConnection() { return mock_le_connection_callbacks_.le_connections_.back(); } void SendAclData(uint16_t handle, std::shared_ptr<AclConnection> connection) { auto queue_end = connection->GetAclQueueEnd(); std::promise<void> promise; Loading Loading @@ -280,6 +311,21 @@ class AclManagerNoCallbacksTest : public ::testing::Test { std::unique_ptr<std::promise<void>> connection_promise_; } mock_connection_callback_; class MockLeConnectionCallbacks : public LeConnectionCallbacks { public: void OnLeConnectSuccess(std::unique_ptr<AclConnection> connection) override { le_connections_.push_back(std::move(connection)); if (le_connection_promise_ != nullptr) { le_connection_promise_->set_value(); le_connection_promise_.reset(); } } MOCK_METHOD3(OnLeConnectFail, void(Address, AddressType, ErrorCode reason)); std::list<std::shared_ptr<AclConnection>> le_connections_; std::unique_ptr<std::promise<void>> le_connection_promise_; } mock_le_connection_callbacks_; class MockAclManagerCallbacks : public AclManagerCallbacks { public: MOCK_METHOD2(OnMasterLinkKeyComplete, void(uint16_t connection_handle, KeyFlag key_flag)); Loading @@ -293,6 +339,7 @@ class AclManagerTest : public AclManagerNoCallbacksTest { void SetUp() override { AclManagerNoCallbacksTest::SetUp(); acl_manager_->RegisterCallbacks(&mock_connection_callback_, client_handler_); acl_manager_->RegisterLeCallbacks(&mock_le_connection_callbacks_, client_handler_); acl_manager_->RegisterAclManagerCallbacks(&mock_acl_manager_callbacks_, client_handler_); } }; Loading Loading @@ -415,6 +462,46 @@ TEST_F(AclManagerTest, invoke_registered_callback_connection_complete_fail) { fake_registry_.SynchronizeModuleHandler(&HciLayer::Factory, std::chrono::milliseconds(20)); } TEST_F(AclManagerTest, invoke_registered_callback_le_connection_complete_success) { acl_manager_->CreateLeConnection(remote, AddressType::PUBLIC_DEVICE_ADDRESS); auto packet = test_hci_layer_->GetCommandPacket(OpCode::LE_CREATE_CONNECTION); auto le_connection_management_command_view = LeConnectionManagementCommandView::Create(packet); auto command_view = LeCreateConnectionView::Create(le_connection_management_command_view); ASSERT(command_view.IsValid()); EXPECT_EQ(command_view.GetPeerAddress(), remote); EXPECT_EQ(command_view.GetPeerAddressType(), AddressType::PUBLIC_DEVICE_ADDRESS); auto first_connection = GetLeConnectionFuture(); test_hci_layer_->IncomingLeMetaEvent( LeConnectionCompleteBuilder::Create(ErrorCode::SUCCESS, 0x123, Role::SLAVE, AddressType::PUBLIC_DEVICE_ADDRESS, remote, 0x0100, 0x0010, 0x0011, MasterClockAccuracy::PPM_30)); auto first_connection_status = first_connection.wait_for(kTimeout); ASSERT_EQ(first_connection_status, std::future_status::ready); std::shared_ptr<AclConnection> connection = GetLastLeConnection(); ASSERT_EQ(connection->GetAddress(), remote); } TEST_F(AclManagerTest, invoke_registered_callback_le_connection_complete_fail) { acl_manager_->CreateLeConnection(remote, AddressType::PUBLIC_DEVICE_ADDRESS); auto packet = test_hci_layer_->GetCommandPacket(OpCode::LE_CREATE_CONNECTION); auto le_connection_management_command_view = LeConnectionManagementCommandView::Create(packet); auto command_view = LeCreateConnectionView::Create(le_connection_management_command_view); ASSERT(command_view.IsValid()); EXPECT_EQ(command_view.GetPeerAddress(), remote); EXPECT_EQ(command_view.GetPeerAddressType(), AddressType::PUBLIC_DEVICE_ADDRESS); EXPECT_CALL(mock_le_connection_callbacks_, OnLeConnectFail(remote, AddressType::PUBLIC_DEVICE_ADDRESS, ErrorCode::CONNECTION_REJECTED_LIMITED_RESOURCES)); test_hci_layer_->IncomingLeMetaEvent(LeConnectionCompleteBuilder::Create( ErrorCode::CONNECTION_REJECTED_LIMITED_RESOURCES, 0x123, Role::SLAVE, AddressType::PUBLIC_DEVICE_ADDRESS, remote, 0x0100, 0x0010, 0x0011, MasterClockAccuracy::PPM_30)); } TEST_F(AclManagerTest, invoke_registered_callback_disconnection_complete) { uint16_t handle = 0x123; Loading system/gd/hci/hci_layer_test.cc +1 −1 Original line number Diff line number Diff line Loading @@ -340,7 +340,7 @@ TEST_F(HciTest, leMetaEvent) { ErrorCode status = ErrorCode::SUCCESS; uint16_t handle = 0x123; Role role = Role::MASTER; PeerAddressType peer_address_type = PeerAddressType::RANDOM_DEVICE_OR_IDENTITY_ADDRESS; AddressType peer_address_type = AddressType::PUBLIC_DEVICE_ADDRESS; Address peer_address = Address::kAny; uint16_t conn_interval = 0x0ABC; uint16_t conn_latency = 0x0123; Loading system/gd/hci/hci_packets.pdl +2 −2 Original line number Diff line number Diff line Loading @@ -3089,7 +3089,7 @@ packet LeConnectionComplete : LeMetaEvent (subevent_code = CONNECTION_COMPLETE) connection_handle : 12, _reserved_ : 4, role : Role, peer_address_type : PeerAddressType, peer_address_type : AddressType, peer_address : Address, conn_interval : 16, // 0x006 - 0x0C80 (7.5ms - 4000ms) conn_latency : 16, // Number of connection events Loading Loading @@ -3158,7 +3158,7 @@ packet LeEnhancedConnectionComplete : LeMetaEvent (subevent_code = ENHANCED_CONN connection_handle : 12, _reserved_ : 4, role : Role, peer_address_type : PeerAddressType, peer_address_type : AddressType, peer_address : Address, local_resolvable_private_address : Address, peer_resolvable_private_address : Address, Loading Loading
system/gd/hci/acl_manager.cc +12 −8 Original line number Diff line number Diff line Loading @@ -266,10 +266,12 @@ struct AclManager::impl { ASSERT(connection_complete.IsValid()); auto status = connection_complete.GetStatus(); auto address = connection_complete.GetPeerAddress(); auto peer_address_type = connection_complete.GetPeerAddressType(); on_any_connection_complete(address); if (status != ErrorCode::SUCCESS) { client_handler_->Post(common::BindOnce(&ConnectionCallbacks::OnConnectFail, common::Unretained(client_callbacks_), address, status)); le_client_handler_->Post(common::BindOnce(&LeConnectionCallbacks::OnLeConnectFail, common::Unretained(le_client_callbacks_), address, peer_address_type, status)); return; } // TODO: Check and save other connection parameters Loading @@ -280,8 +282,8 @@ struct AclManager::impl { start_round_robin(); } std::unique_ptr<AclConnection> connection_proxy(new AclConnection(&acl_manager_, handle, address)); client_handler_->Post(common::BindOnce(&ConnectionCallbacks::OnConnectSuccess, common::Unretained(client_callbacks_), std::move(connection_proxy))); le_client_handler_->Post(common::BindOnce(&LeConnectionCallbacks::OnLeConnectSuccess, common::Unretained(le_client_callbacks_), std::move(connection_proxy))); } void on_le_enhanced_connection_complete(LeMetaEventView packet) { Loading @@ -289,10 +291,12 @@ struct AclManager::impl { ASSERT(connection_complete.IsValid()); auto status = connection_complete.GetStatus(); auto address = connection_complete.GetPeerAddress(); auto peer_address_type = connection_complete.GetPeerAddressType(); on_any_connection_complete(address); if (status != ErrorCode::SUCCESS) { client_handler_->Post(common::BindOnce(&ConnectionCallbacks::OnConnectFail, common::Unretained(client_callbacks_), address, status)); le_client_handler_->Post(common::BindOnce(&LeConnectionCallbacks::OnLeConnectFail, common::Unretained(le_client_callbacks_), address, peer_address_type, status)); return; } // TODO: Check and save other connection parameters Loading @@ -303,8 +307,8 @@ struct AclManager::impl { start_round_robin(); } std::unique_ptr<AclConnection> connection_proxy(new AclConnection(&acl_manager_, handle, address)); client_handler_->Post(common::BindOnce(&ConnectionCallbacks::OnConnectSuccess, common::Unretained(client_callbacks_), std::move(connection_proxy))); le_client_handler_->Post(common::BindOnce(&LeConnectionCallbacks::OnLeConnectSuccess, common::Unretained(le_client_callbacks_), std::move(connection_proxy))); } void on_connection_complete(EventPacketView packet) { Loading
system/gd/hci/acl_manager_test.cc +87 −0 Original line number Diff line number Diff line Loading @@ -143,6 +143,15 @@ class TestHciLayer : public HciLayer { registered_events_.erase(event_code); } void RegisterLeEventHandler(SubeventCode subevent_code, common::Callback<void(LeMetaEventView)> event_handler, os::Handler* handler) override { registered_le_events_[subevent_code] = event_handler; } void UnregisterLeEventHandler(SubeventCode subevent_code) { registered_le_events_.erase(subevent_code); } void IncomingEvent(std::unique_ptr<EventPacketBuilder> event_builder) { auto packet = GetPacketView(std::move(event_builder)); EventPacketView event = EventPacketView::Create(packet); Loading @@ -152,6 +161,16 @@ class TestHciLayer : public HciLayer { registered_events_[event_code].Run(event); } void IncomingLeMetaEvent(std::unique_ptr<LeMetaEventBuilder> event_builder) { auto packet = GetPacketView(std::move(event_builder)); EventPacketView event = EventPacketView::Create(packet); LeMetaEventView meta_event_view = LeMetaEventView::Create(event); EXPECT_TRUE(meta_event_view.IsValid()); SubeventCode subevent_code = meta_event_view.GetSubeventCode(); EXPECT_TRUE(registered_le_events_.find(subevent_code) != registered_le_events_.end()); registered_le_events_[subevent_code].Run(meta_event_view); } void IncomingAclData(uint16_t handle) { os::Handler* hci_handler = GetHandler(); auto* queue_end = acl_queue_.GetDownEnd(); Loading Loading @@ -203,6 +222,7 @@ class TestHciLayer : public HciLayer { private: std::map<EventCode, common::Callback<void(EventPacketView)>> registered_events_; std::map<SubeventCode, common::Callback<void(LeMetaEventView)>> registered_le_events_; std::list<base::OnceCallback<void(CommandCompleteView)>> command_complete_callbacks; BidiQueue<AclPacketView, AclPacketBuilder> acl_queue_{3 /* TODO: Set queue depth */}; Loading Loading @@ -244,10 +264,21 @@ class AclManagerNoCallbacksTest : public ::testing::Test { return mock_connection_callback_.connection_promise_->get_future(); } std::future<void> GetLeConnectionFuture() { ASSERT_LOG(mock_le_connection_callbacks_.le_connection_promise_ == nullptr, "Promises promises ... Only one at a time"); mock_le_connection_callbacks_.le_connection_promise_ = std::make_unique<std::promise<void>>(); return mock_le_connection_callbacks_.le_connection_promise_->get_future(); } std::shared_ptr<AclConnection> GetLastConnection() { return mock_connection_callback_.connections_.back(); } std::shared_ptr<AclConnection> GetLastLeConnection() { return mock_le_connection_callbacks_.le_connections_.back(); } void SendAclData(uint16_t handle, std::shared_ptr<AclConnection> connection) { auto queue_end = connection->GetAclQueueEnd(); std::promise<void> promise; Loading Loading @@ -280,6 +311,21 @@ class AclManagerNoCallbacksTest : public ::testing::Test { std::unique_ptr<std::promise<void>> connection_promise_; } mock_connection_callback_; class MockLeConnectionCallbacks : public LeConnectionCallbacks { public: void OnLeConnectSuccess(std::unique_ptr<AclConnection> connection) override { le_connections_.push_back(std::move(connection)); if (le_connection_promise_ != nullptr) { le_connection_promise_->set_value(); le_connection_promise_.reset(); } } MOCK_METHOD3(OnLeConnectFail, void(Address, AddressType, ErrorCode reason)); std::list<std::shared_ptr<AclConnection>> le_connections_; std::unique_ptr<std::promise<void>> le_connection_promise_; } mock_le_connection_callbacks_; class MockAclManagerCallbacks : public AclManagerCallbacks { public: MOCK_METHOD2(OnMasterLinkKeyComplete, void(uint16_t connection_handle, KeyFlag key_flag)); Loading @@ -293,6 +339,7 @@ class AclManagerTest : public AclManagerNoCallbacksTest { void SetUp() override { AclManagerNoCallbacksTest::SetUp(); acl_manager_->RegisterCallbacks(&mock_connection_callback_, client_handler_); acl_manager_->RegisterLeCallbacks(&mock_le_connection_callbacks_, client_handler_); acl_manager_->RegisterAclManagerCallbacks(&mock_acl_manager_callbacks_, client_handler_); } }; Loading Loading @@ -415,6 +462,46 @@ TEST_F(AclManagerTest, invoke_registered_callback_connection_complete_fail) { fake_registry_.SynchronizeModuleHandler(&HciLayer::Factory, std::chrono::milliseconds(20)); } TEST_F(AclManagerTest, invoke_registered_callback_le_connection_complete_success) { acl_manager_->CreateLeConnection(remote, AddressType::PUBLIC_DEVICE_ADDRESS); auto packet = test_hci_layer_->GetCommandPacket(OpCode::LE_CREATE_CONNECTION); auto le_connection_management_command_view = LeConnectionManagementCommandView::Create(packet); auto command_view = LeCreateConnectionView::Create(le_connection_management_command_view); ASSERT(command_view.IsValid()); EXPECT_EQ(command_view.GetPeerAddress(), remote); EXPECT_EQ(command_view.GetPeerAddressType(), AddressType::PUBLIC_DEVICE_ADDRESS); auto first_connection = GetLeConnectionFuture(); test_hci_layer_->IncomingLeMetaEvent( LeConnectionCompleteBuilder::Create(ErrorCode::SUCCESS, 0x123, Role::SLAVE, AddressType::PUBLIC_DEVICE_ADDRESS, remote, 0x0100, 0x0010, 0x0011, MasterClockAccuracy::PPM_30)); auto first_connection_status = first_connection.wait_for(kTimeout); ASSERT_EQ(first_connection_status, std::future_status::ready); std::shared_ptr<AclConnection> connection = GetLastLeConnection(); ASSERT_EQ(connection->GetAddress(), remote); } TEST_F(AclManagerTest, invoke_registered_callback_le_connection_complete_fail) { acl_manager_->CreateLeConnection(remote, AddressType::PUBLIC_DEVICE_ADDRESS); auto packet = test_hci_layer_->GetCommandPacket(OpCode::LE_CREATE_CONNECTION); auto le_connection_management_command_view = LeConnectionManagementCommandView::Create(packet); auto command_view = LeCreateConnectionView::Create(le_connection_management_command_view); ASSERT(command_view.IsValid()); EXPECT_EQ(command_view.GetPeerAddress(), remote); EXPECT_EQ(command_view.GetPeerAddressType(), AddressType::PUBLIC_DEVICE_ADDRESS); EXPECT_CALL(mock_le_connection_callbacks_, OnLeConnectFail(remote, AddressType::PUBLIC_DEVICE_ADDRESS, ErrorCode::CONNECTION_REJECTED_LIMITED_RESOURCES)); test_hci_layer_->IncomingLeMetaEvent(LeConnectionCompleteBuilder::Create( ErrorCode::CONNECTION_REJECTED_LIMITED_RESOURCES, 0x123, Role::SLAVE, AddressType::PUBLIC_DEVICE_ADDRESS, remote, 0x0100, 0x0010, 0x0011, MasterClockAccuracy::PPM_30)); } TEST_F(AclManagerTest, invoke_registered_callback_disconnection_complete) { uint16_t handle = 0x123; Loading
system/gd/hci/hci_layer_test.cc +1 −1 Original line number Diff line number Diff line Loading @@ -340,7 +340,7 @@ TEST_F(HciTest, leMetaEvent) { ErrorCode status = ErrorCode::SUCCESS; uint16_t handle = 0x123; Role role = Role::MASTER; PeerAddressType peer_address_type = PeerAddressType::RANDOM_DEVICE_OR_IDENTITY_ADDRESS; AddressType peer_address_type = AddressType::PUBLIC_DEVICE_ADDRESS; Address peer_address = Address::kAny; uint16_t conn_interval = 0x0ABC; uint16_t conn_latency = 0x0123; Loading
system/gd/hci/hci_packets.pdl +2 −2 Original line number Diff line number Diff line Loading @@ -3089,7 +3089,7 @@ packet LeConnectionComplete : LeMetaEvent (subevent_code = CONNECTION_COMPLETE) connection_handle : 12, _reserved_ : 4, role : Role, peer_address_type : PeerAddressType, peer_address_type : AddressType, peer_address : Address, conn_interval : 16, // 0x006 - 0x0C80 (7.5ms - 4000ms) conn_latency : 16, // Number of connection events Loading Loading @@ -3158,7 +3158,7 @@ packet LeEnhancedConnectionComplete : LeMetaEvent (subevent_code = ENHANCED_CONN connection_handle : 12, _reserved_ : 4, role : Role, peer_address_type : PeerAddressType, peer_address_type : AddressType, peer_address : Address, local_resolvable_private_address : Address, peer_resolvable_private_address : Address, Loading