Loading system/gd/hci/acl_manager.cc +10 −0 Original line number Diff line number Diff line Loading @@ -243,6 +243,16 @@ void AclManager::UnregisterLeCallbacks(LeConnectionCallbacks* callbacks, std::pr CallOn(pimpl_->le_impl_, &le_impl::handle_unregister_le_callbacks, common::Unretained(callbacks), std::move(promise)); } void AclManager::UnregisterLeAcceptlistCallbacks( LeAcceptlistCallbacks* callbacks, std::promise<void> promise) { ASSERT(callbacks != nullptr); CallOn( pimpl_->le_impl_, &le_impl::handle_unregister_le_acceptlist_callbacks, common::Unretained(callbacks), std::move(promise)); } void AclManager::CreateConnection(Address address) { CallOn(pimpl_->classic_impl_, &classic_impl::create_connection, address); } Loading system/gd/hci/acl_manager.h +2 −0 Original line number Diff line number Diff line Loading @@ -80,6 +80,8 @@ public: virtual void RegisterLeCallbacks(acl_manager::LeConnectionCallbacks* callbacks, os::Handler* handler); virtual void UnregisterLeCallbacks(acl_manager::LeConnectionCallbacks* callbacks, std::promise<void> promise); void RegisterLeAcceptlistCallbacks(acl_manager::LeAcceptlistCallbacks* callbacks); void UnregisterLeAcceptlistCallbacks( acl_manager::LeAcceptlistCallbacks* callbacks, std::promise<void> promise); // Generates OnConnectSuccess if connected, or OnConnectFail otherwise virtual void CreateConnection(Address address); Loading system/gd/hci/acl_manager/le_acceptlist_callbacks.h +6 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,12 @@ class LeAcceptlistCallbacks { // Invoked when controller sends Connection Complete event with Success error code // AddressWithType is the address returned by the controller. virtual void OnLeConnectSuccess(AddressWithType) = 0; // Invoked when controller sends Connection Complete event with failing error code // AddressWithType is the address returned by the controller. virtual void OnLeConnectFail(AddressWithType, ErrorCode reason) = 0; // Invoked when an LE connection is disconnected. AddressWithType is the remote address // associated with this connection at the time of connection. virtual void OnLeDisconnection(AddressWithType) = 0; // Invoked when the resolving list has changed, so we need to re-resolve our addresses. virtual void OnResolvingListChange() = 0; }; Loading system/gd/hci/acl_manager/le_impl.h +27 −20 Original line number Diff line number Diff line Loading @@ -313,6 +313,17 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { return connections.send_packet_upward(handle, cb); } void report_le_connection_failure(AddressWithType address, ErrorCode status) { le_client_handler_->Post(common::BindOnce( &LeConnectionCallbacks::OnLeConnectFail, common::Unretained(le_client_callbacks_), address, status)); if (le_acceptlist_callbacks_ != nullptr) { le_acceptlist_callbacks_->OnLeConnectFail(address, status); } } // connection canceled by LeAddressManager.OnPause(), will auto reconnect by LeAddressManager.OnResume() void on_le_connection_canceled_on_pause() { ASSERT_LOG(pause_connection, "Connection must be paused to ack the le address manager"); Loading Loading @@ -387,11 +398,7 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { } if (status != ErrorCode::SUCCESS) { le_client_handler_->Post(common::BindOnce( &LeConnectionCallbacks::OnLeConnectFail, common::Unretained(le_client_callbacks_), remote_address, status)); report_le_connection_failure(remote_address, status); return; } } else { Loading @@ -404,11 +411,7 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { if (status != ErrorCode::SUCCESS) { std::string error_code = ErrorCodeText(status); LOG_WARN("Received on_le_connection_complete with error code %s", error_code.c_str()); le_client_handler_->Post(common::BindOnce( &LeConnectionCallbacks::OnLeConnectFail, common::Unretained(le_client_callbacks_), remote_address, status)); report_le_connection_failure(remote_address, status); return; } Loading Loading @@ -543,11 +546,7 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { } if (status != ErrorCode::SUCCESS) { le_client_handler_->Post(common::BindOnce( &LeConnectionCallbacks::OnLeConnectFail, common::Unretained(le_client_callbacks_), remote_address, status)); report_le_connection_failure(remote_address, status); return; } Loading @@ -561,11 +560,7 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { if (status != ErrorCode::SUCCESS) { std::string error_code = ErrorCodeText(status); LOG_WARN("Received on_le_enhanced_connection_complete with error code %s", error_code.c_str()); le_client_handler_->Post(common::BindOnce( &LeConnectionCallbacks::OnLeConnectFail, common::Unretained(le_client_callbacks_), remote_address, status)); report_le_connection_failure(remote_address, status); return; } Loading Loading @@ -668,6 +663,9 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { callbacks->OnDisconnection(reason); }, kRemoveConnectionAfterwards); if (le_acceptlist_callbacks_ != nullptr) { le_acceptlist_callbacks_->OnLeDisconnection(remote_address); } connections.crash_on_unknown_handle_ = event_also_routes_to_other_receivers; if (background_connections_.count(remote_address) == 1) { Loading Loading @@ -1222,6 +1220,15 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { promise.set_value(); } void handle_unregister_le_acceptlist_callbacks( LeAcceptlistCallbacks* callbacks, std::promise<void> promise) { ASSERT_LOG( le_acceptlist_callbacks_ == callbacks, "Registered le callback entity is different then unregister request"); le_acceptlist_callbacks_ = nullptr; promise.set_value(); } bool check_connection_parameters( uint16_t conn_interval_min, uint16_t conn_interval_max, uint16_t conn_latency, uint16_t supervision_timeout) { if (conn_interval_min < 0x0006 || conn_interval_min > 0x0C80 || conn_interval_max < 0x0006 || Loading system/gd/hci/acl_manager/le_impl_test.cc +87 −1 Original line number Diff line number Diff line Loading @@ -407,7 +407,9 @@ class MockLeConnectionCallbacks : public LeConnectionCallbacks { class MockLeAcceptlistCallbacks : public LeAcceptlistCallbacks { public: MOCK_METHOD(void, OnLeConnectSuccess, (AddressWithType address_with_type), (override)); MOCK_METHOD(void, OnLeConnectSuccess, (AddressWithType address), (override)); MOCK_METHOD(void, OnLeConnectFail, (AddressWithType address, ErrorCode reason), (override)); MOCK_METHOD(void, OnLeDisconnection, (AddressWithType address), (override)); MOCK_METHOD(void, OnResolvingListChange, (), (override)); }; Loading Loading @@ -1726,6 +1728,90 @@ TEST_F(LeImplTest, ResolvingListCallback) { Mock::VerifyAndClearExpectations(&callbacks); } TEST_F(LeImplTest, ConnectionFailedAcceptlistCallback) { // arrange MockLeAcceptlistCallbacks callbacks; le_impl_->handle_register_le_acceptlist_callbacks(&callbacks); set_random_device_address_policy(); // expect AddressWithType remote_address; ErrorCode reason; EXPECT_CALL(callbacks, OnLeConnectFail(_, _)) .WillOnce([&](AddressWithType addr, ErrorCode error) { remote_address = addr; reason = error; }); // act auto command = LeEnhancedConnectionCompleteBuilder::Create( ErrorCode::CONTROLLER_BUSY, kHciHandle, Role::PERIPHERAL, AddressType::PUBLIC_DEVICE_ADDRESS, remote_address_, local_rpa_, remote_rpa_, 0x0024, 0x0000, 0x0011, ClockAccuracy::PPM_30); auto bytes = Serialize<LeEnhancedConnectionCompleteBuilder>(std::move(command)); auto view = CreateLeEventView<hci::LeEnhancedConnectionCompleteView>(bytes); ASSERT_TRUE(view.IsValid()); le_impl_->on_le_event(view); sync_handler(); // assert EXPECT_EQ(remote_address, remote_public_address_with_type_); EXPECT_EQ(reason, ErrorCode::CONTROLLER_BUSY); } TEST_F(LeImplTest, DisconnectionAcceptlistCallback) { // expect MockLeAcceptlistCallbacks callbacks; AddressWithType remote_address; EXPECT_CALL(callbacks, OnLeDisconnection(_)).WillOnce([&](AddressWithType addr) { remote_address = addr; }); // we need to capture the LeAclConnection so it is not immediately dropped => disconnected std::unique_ptr<LeAclConnection> connection; EXPECT_CALL(mock_le_connection_callbacks_, OnLeConnectSuccess(_, _)) .WillOnce([&](AddressWithType, std::unique_ptr<LeAclConnection> conn) { connection = std::move(conn); connection->RegisterCallbacks(&connection_management_callbacks_, handler_); }); // arrange: an active connection to a peer le_impl_->handle_register_le_acceptlist_callbacks(&callbacks); set_random_device_address_policy(); auto command = LeEnhancedConnectionCompleteBuilder::Create( ErrorCode::SUCCESS, kHciHandle, Role::PERIPHERAL, AddressType::PUBLIC_DEVICE_ADDRESS, remote_address_, local_rpa_, remote_rpa_, 0x0024, 0x0000, 0x0011, ClockAccuracy::PPM_30); auto bytes = Serialize<LeEnhancedConnectionCompleteBuilder>(std::move(command)); auto view = CreateLeEventView<hci::LeEnhancedConnectionCompleteView>(bytes); ASSERT_TRUE(view.IsValid()); le_impl_->on_le_event(view); sync_handler(); // act le_impl_->on_le_disconnect(kHciHandle, ErrorCode::REMOTE_USER_TERMINATED_CONNECTION); sync_handler(); // assert EXPECT_EQ(remote_public_address_with_type_, remote_address); Mock::VerifyAndClearExpectations(&callbacks); } } // namespace acl_manager } // namespace hci } // namespace bluetooth Loading
system/gd/hci/acl_manager.cc +10 −0 Original line number Diff line number Diff line Loading @@ -243,6 +243,16 @@ void AclManager::UnregisterLeCallbacks(LeConnectionCallbacks* callbacks, std::pr CallOn(pimpl_->le_impl_, &le_impl::handle_unregister_le_callbacks, common::Unretained(callbacks), std::move(promise)); } void AclManager::UnregisterLeAcceptlistCallbacks( LeAcceptlistCallbacks* callbacks, std::promise<void> promise) { ASSERT(callbacks != nullptr); CallOn( pimpl_->le_impl_, &le_impl::handle_unregister_le_acceptlist_callbacks, common::Unretained(callbacks), std::move(promise)); } void AclManager::CreateConnection(Address address) { CallOn(pimpl_->classic_impl_, &classic_impl::create_connection, address); } Loading
system/gd/hci/acl_manager.h +2 −0 Original line number Diff line number Diff line Loading @@ -80,6 +80,8 @@ public: virtual void RegisterLeCallbacks(acl_manager::LeConnectionCallbacks* callbacks, os::Handler* handler); virtual void UnregisterLeCallbacks(acl_manager::LeConnectionCallbacks* callbacks, std::promise<void> promise); void RegisterLeAcceptlistCallbacks(acl_manager::LeAcceptlistCallbacks* callbacks); void UnregisterLeAcceptlistCallbacks( acl_manager::LeAcceptlistCallbacks* callbacks, std::promise<void> promise); // Generates OnConnectSuccess if connected, or OnConnectFail otherwise virtual void CreateConnection(Address address); Loading
system/gd/hci/acl_manager/le_acceptlist_callbacks.h +6 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,12 @@ class LeAcceptlistCallbacks { // Invoked when controller sends Connection Complete event with Success error code // AddressWithType is the address returned by the controller. virtual void OnLeConnectSuccess(AddressWithType) = 0; // Invoked when controller sends Connection Complete event with failing error code // AddressWithType is the address returned by the controller. virtual void OnLeConnectFail(AddressWithType, ErrorCode reason) = 0; // Invoked when an LE connection is disconnected. AddressWithType is the remote address // associated with this connection at the time of connection. virtual void OnLeDisconnection(AddressWithType) = 0; // Invoked when the resolving list has changed, so we need to re-resolve our addresses. virtual void OnResolvingListChange() = 0; }; Loading
system/gd/hci/acl_manager/le_impl.h +27 −20 Original line number Diff line number Diff line Loading @@ -313,6 +313,17 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { return connections.send_packet_upward(handle, cb); } void report_le_connection_failure(AddressWithType address, ErrorCode status) { le_client_handler_->Post(common::BindOnce( &LeConnectionCallbacks::OnLeConnectFail, common::Unretained(le_client_callbacks_), address, status)); if (le_acceptlist_callbacks_ != nullptr) { le_acceptlist_callbacks_->OnLeConnectFail(address, status); } } // connection canceled by LeAddressManager.OnPause(), will auto reconnect by LeAddressManager.OnResume() void on_le_connection_canceled_on_pause() { ASSERT_LOG(pause_connection, "Connection must be paused to ack the le address manager"); Loading Loading @@ -387,11 +398,7 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { } if (status != ErrorCode::SUCCESS) { le_client_handler_->Post(common::BindOnce( &LeConnectionCallbacks::OnLeConnectFail, common::Unretained(le_client_callbacks_), remote_address, status)); report_le_connection_failure(remote_address, status); return; } } else { Loading @@ -404,11 +411,7 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { if (status != ErrorCode::SUCCESS) { std::string error_code = ErrorCodeText(status); LOG_WARN("Received on_le_connection_complete with error code %s", error_code.c_str()); le_client_handler_->Post(common::BindOnce( &LeConnectionCallbacks::OnLeConnectFail, common::Unretained(le_client_callbacks_), remote_address, status)); report_le_connection_failure(remote_address, status); return; } Loading Loading @@ -543,11 +546,7 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { } if (status != ErrorCode::SUCCESS) { le_client_handler_->Post(common::BindOnce( &LeConnectionCallbacks::OnLeConnectFail, common::Unretained(le_client_callbacks_), remote_address, status)); report_le_connection_failure(remote_address, status); return; } Loading @@ -561,11 +560,7 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { if (status != ErrorCode::SUCCESS) { std::string error_code = ErrorCodeText(status); LOG_WARN("Received on_le_enhanced_connection_complete with error code %s", error_code.c_str()); le_client_handler_->Post(common::BindOnce( &LeConnectionCallbacks::OnLeConnectFail, common::Unretained(le_client_callbacks_), remote_address, status)); report_le_connection_failure(remote_address, status); return; } Loading Loading @@ -668,6 +663,9 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { callbacks->OnDisconnection(reason); }, kRemoveConnectionAfterwards); if (le_acceptlist_callbacks_ != nullptr) { le_acceptlist_callbacks_->OnLeDisconnection(remote_address); } connections.crash_on_unknown_handle_ = event_also_routes_to_other_receivers; if (background_connections_.count(remote_address) == 1) { Loading Loading @@ -1222,6 +1220,15 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { promise.set_value(); } void handle_unregister_le_acceptlist_callbacks( LeAcceptlistCallbacks* callbacks, std::promise<void> promise) { ASSERT_LOG( le_acceptlist_callbacks_ == callbacks, "Registered le callback entity is different then unregister request"); le_acceptlist_callbacks_ = nullptr; promise.set_value(); } bool check_connection_parameters( uint16_t conn_interval_min, uint16_t conn_interval_max, uint16_t conn_latency, uint16_t supervision_timeout) { if (conn_interval_min < 0x0006 || conn_interval_min > 0x0C80 || conn_interval_max < 0x0006 || Loading
system/gd/hci/acl_manager/le_impl_test.cc +87 −1 Original line number Diff line number Diff line Loading @@ -407,7 +407,9 @@ class MockLeConnectionCallbacks : public LeConnectionCallbacks { class MockLeAcceptlistCallbacks : public LeAcceptlistCallbacks { public: MOCK_METHOD(void, OnLeConnectSuccess, (AddressWithType address_with_type), (override)); MOCK_METHOD(void, OnLeConnectSuccess, (AddressWithType address), (override)); MOCK_METHOD(void, OnLeConnectFail, (AddressWithType address, ErrorCode reason), (override)); MOCK_METHOD(void, OnLeDisconnection, (AddressWithType address), (override)); MOCK_METHOD(void, OnResolvingListChange, (), (override)); }; Loading Loading @@ -1726,6 +1728,90 @@ TEST_F(LeImplTest, ResolvingListCallback) { Mock::VerifyAndClearExpectations(&callbacks); } TEST_F(LeImplTest, ConnectionFailedAcceptlistCallback) { // arrange MockLeAcceptlistCallbacks callbacks; le_impl_->handle_register_le_acceptlist_callbacks(&callbacks); set_random_device_address_policy(); // expect AddressWithType remote_address; ErrorCode reason; EXPECT_CALL(callbacks, OnLeConnectFail(_, _)) .WillOnce([&](AddressWithType addr, ErrorCode error) { remote_address = addr; reason = error; }); // act auto command = LeEnhancedConnectionCompleteBuilder::Create( ErrorCode::CONTROLLER_BUSY, kHciHandle, Role::PERIPHERAL, AddressType::PUBLIC_DEVICE_ADDRESS, remote_address_, local_rpa_, remote_rpa_, 0x0024, 0x0000, 0x0011, ClockAccuracy::PPM_30); auto bytes = Serialize<LeEnhancedConnectionCompleteBuilder>(std::move(command)); auto view = CreateLeEventView<hci::LeEnhancedConnectionCompleteView>(bytes); ASSERT_TRUE(view.IsValid()); le_impl_->on_le_event(view); sync_handler(); // assert EXPECT_EQ(remote_address, remote_public_address_with_type_); EXPECT_EQ(reason, ErrorCode::CONTROLLER_BUSY); } TEST_F(LeImplTest, DisconnectionAcceptlistCallback) { // expect MockLeAcceptlistCallbacks callbacks; AddressWithType remote_address; EXPECT_CALL(callbacks, OnLeDisconnection(_)).WillOnce([&](AddressWithType addr) { remote_address = addr; }); // we need to capture the LeAclConnection so it is not immediately dropped => disconnected std::unique_ptr<LeAclConnection> connection; EXPECT_CALL(mock_le_connection_callbacks_, OnLeConnectSuccess(_, _)) .WillOnce([&](AddressWithType, std::unique_ptr<LeAclConnection> conn) { connection = std::move(conn); connection->RegisterCallbacks(&connection_management_callbacks_, handler_); }); // arrange: an active connection to a peer le_impl_->handle_register_le_acceptlist_callbacks(&callbacks); set_random_device_address_policy(); auto command = LeEnhancedConnectionCompleteBuilder::Create( ErrorCode::SUCCESS, kHciHandle, Role::PERIPHERAL, AddressType::PUBLIC_DEVICE_ADDRESS, remote_address_, local_rpa_, remote_rpa_, 0x0024, 0x0000, 0x0011, ClockAccuracy::PPM_30); auto bytes = Serialize<LeEnhancedConnectionCompleteBuilder>(std::move(command)); auto view = CreateLeEventView<hci::LeEnhancedConnectionCompleteView>(bytes); ASSERT_TRUE(view.IsValid()); le_impl_->on_le_event(view); sync_handler(); // act le_impl_->on_le_disconnect(kHciHandle, ErrorCode::REMOTE_USER_TERMINATED_CONNECTION); sync_handler(); // assert EXPECT_EQ(remote_public_address_with_type_, remote_address); Mock::VerifyAndClearExpectations(&callbacks); } } // namespace acl_manager } // namespace hci } // namespace bluetooth