From 3467d21d29b813bca14595e909629d4894213da9 Mon Sep 17 00:00:00 2001 From: Chris Manton Date: Tue, 9 Feb 2021 18:49:18 -0800 Subject: [PATCH] gd_acl: Add add/remove acceptlist Also rename Accept/Ignore LeConnections Bug: 173985410 Tag: #refactor Test: gd/cert/run Change-Id: I96c3d09bf86887f9fdff9fb09475c909f0045f02 --- bta/test/common/mock_main_shim_acl.cc | 16 +++- main/shim/acl.cc | 139 ++++++++++++++++++++++++---- main/shim/acl.h | 25 +++-- main/shim/acl_api.cc | 26 +++++- main/shim/acl_api.h | 8 +- main/shim/link_connection_interface.h | 14 ++- main/shim/stack.cc | 6 +- stack/acl/btm_acl.cc | 2 +- stack/test/common/mock_main_shim_acl_api.cc | 20 ++-- 9 files changed, 202 insertions(+), 54 deletions(-) diff --git a/bta/test/common/mock_main_shim_acl.cc b/bta/test/common/mock_main_shim_acl.cc index 96b175d49..84a54f02b 100644 --- a/bta/test/common/mock_main_shim_acl.cc +++ b/bta/test/common/mock_main_shim_acl.cc @@ -37,17 +37,25 @@ void bluetooth::shim::ACL_CreateClassicConnection( const RawAddress& raw_address) { mock_function_count_map[__func__]++; } -void bluetooth::shim::ACL_CancelLeConnection( - const tBLE_BD_ADDR& legacy_address_with_type) { +void bluetooth::shim::ACL_CancelClassicConnection( + const RawAddress& raw_address) { mock_function_count_map[__func__]++; } -void bluetooth::shim::ACL_ConfigureLePrivacy(bool is_le_privacy_enabled) { +bool bluetooth::shim::ACL_AcceptLeConnectionFrom( + const tBLE_BD_ADDR& legacy_address_with_type) { mock_function_count_map[__func__]++; + return true; } -void bluetooth::shim::ACL_CreateLeConnection( +void bluetooth::shim::ACL_IgnoreLeConnectionFrom( const tBLE_BD_ADDR& legacy_address_with_type) { mock_function_count_map[__func__]++; } +void bluetooth::shim::ACL_IgnoreAllLeConnections() { + mock_function_count_map[__func__]++; +} +void bluetooth::shim::ACL_ConfigureLePrivacy(bool is_le_privacy_enabled) { + mock_function_count_map[__func__]++; +} void bluetooth::shim::ACL_Disconnect(uint16_t handle, bool is_classic, tHCI_STATUS reason) { mock_function_count_map[__func__]++; diff --git a/main/shim/acl.cc b/main/shim/acl.cc index 87bac42e8..b96b415ff 100644 --- a/main/shim/acl.cc +++ b/main/shim/acl.cc @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -77,6 +78,49 @@ using OnDisconnect = std::function; constexpr char kConnectionDescriptorTimeFormat[] = "%Y-%m-%d %H:%M:%S"; +class ShadowAcceptlist { + public: + ShadowAcceptlist(uint8_t max_acceptlist_size) + : max_acceptlist_size_(max_acceptlist_size) {} + + bool Add(const hci::AddressWithType& address_with_type) { + if (acceptlist_set_.size() == max_acceptlist_size_) { + LOG_ERROR("Acceptlist is full size:%zu", acceptlist_set_.size()); + return false; + } + if (!acceptlist_set_.insert(address_with_type).second) { + LOG_WARN("Attempted to add duplicate le address to acceptlist:%s", + PRIVATE_ADDRESS(address_with_type)); + } + return true; + } + + bool Remove(const hci::AddressWithType& address_with_type) { + auto iter = acceptlist_set_.find(address_with_type); + if (iter == acceptlist_set_.end()) { + LOG_WARN("Unknown device being removed from acceptlist:%s", + PRIVATE_ADDRESS(address_with_type)); + return false; + } + acceptlist_set_.erase(iter); + return true; + } + + std::unordered_set GetCopy() const { + return acceptlist_set_; + } + + bool IsFull() const { + return acceptlist_set_.size() == static_cast(max_acceptlist_size_); + } + + void Clear() { acceptlist_set_.clear(); } + + private: + uint8_t max_acceptlist_size_{0}; + std::unordered_set acceptlist_set_; +}; + struct ConnectionDescriptor { CreationTime creation_time_; TeardownTime teardown_time_; @@ -582,6 +626,9 @@ class LeShimAclConnection }; struct shim::legacy::Acl::impl { + impl(uint8_t max_acceptlist_size) + : shadow_acceptlist_(ShadowAcceptlist(max_acceptlist_size)) {} + std::map> handle_to_classic_connection_map_; std::map> @@ -590,6 +637,8 @@ struct shim::legacy::Acl::impl { FixedQueue> connection_history_ = FixedQueue>(kConnectionHistorySize); + ShadowAcceptlist shadow_acceptlist_; + bool IsClassicAcl(HciHandle handle) { return handle_to_classic_connection_map_.find(handle) != handle_to_classic_connection_map_.end(); @@ -668,12 +717,52 @@ struct shim::legacy::Acl::impl { handle_to_classic_connection_map_[handle]->SetConnectionEncryption(enable); } + void accept_le_connection_from(const hci::AddressWithType& address_with_type, + std::promise promise) { + if (shadow_acceptlist_.IsFull()) { + LOG_ERROR("Acceptlist is full preventing new Le connection"); + promise.set_value(false); + return; + } + shadow_acceptlist_.Add(address_with_type); + promise.set_value(true); + GetAclManager()->CreateLeConnection(address_with_type); + LOG_DEBUG("Allow Le connection from remote:%s", + PRIVATE_ADDRESS(address_with_type)); + BTM_LogHistory(kBtmLogTag, ToLegacyAddressWithType(address_with_type), + "Allow connection from", "Le"); + } + + void ignore_le_connection_from( + const hci::AddressWithType& address_with_type) { + shadow_acceptlist_.Remove(address_with_type); + GetAclManager()->CancelLeConnect(address_with_type); + LOG_DEBUG("Ignore Le connection from remote:%s", + PRIVATE_ADDRESS(address_with_type)); + BTM_LogHistory(kBtmLogTag, ToLegacyAddressWithType(address_with_type), + "Ignore connection from", "Le"); + } + + void clear_acceptlist() { + auto shadow_acceptlist = shadow_acceptlist_.GetCopy(); + size_t count = shadow_acceptlist.size(); + for (auto address_with_type : shadow_acceptlist) { + ignore_le_connection_from(address_with_type); + } + shadow_acceptlist_.Clear(); + LOG_DEBUG("Cleared entire Le address acceptlist count:%zu", count); + } + void DumpConnectionHistory() const { std::vector history = connection_history_.ReadElementsAsString(); for (auto& entry : history) { LOG_DEBUG("%s", entry.c_str()); } + const auto acceptlist = shadow_acceptlist_.GetCopy(); + for (auto& entry : acceptlist) { + LOG_DEBUG("acceptlist:%s", entry.ToString().c_str()); + } } #define DUMPSYS_TAG "shim::acl" @@ -683,6 +772,11 @@ struct shim::legacy::Acl::impl { for (auto& entry : history) { LOG_DUMPSYS(fd, "%s", entry.c_str()); } + unsigned cnt = 0; + auto acceptlist = shadow_acceptlist_.GetCopy(); + for (auto& entry : acceptlist) { + LOG_DUMPSYS(fd, "%03u le acceptlist:%s", ++cnt, entry.ToString().c_str()); + } } #undef DUMPSYS_TAG }; @@ -809,10 +903,11 @@ void shim::legacy::Acl::Dump(int fd) const { } shim::legacy::Acl::Acl(os::Handler* handler, - const acl_interface_t& acl_interface) + const acl_interface_t& acl_interface, + uint8_t max_acceptlist_size) : handler_(handler), acl_interface_(acl_interface) { ValidateAclInterface(acl_interface_); - pimpl_ = std::make_unique(); + pimpl_ = std::make_unique(max_acceptlist_size); GetAclManager()->RegisterCallbacks(this, handler_); GetAclManager()->RegisterLeCallbacks(this, handler_); GetController()->RegisterCompletedMonitorAclPacketsCallback( @@ -899,22 +994,24 @@ void shim::legacy::Acl::CreateClassicConnection(const hci::Address& address) { "classic"); } -void shim::legacy::Acl::CreateLeConnection( - const hci::AddressWithType& address_with_type) { - GetAclManager()->CreateLeConnection(address_with_type); - LOG_DEBUG("Connection initiated for le connection to remote:%s", - PRIVATE_ADDRESS(address_with_type)); - BTM_LogHistory(kBtmLogTag, ToLegacyAddressWithType(address_with_type), - "Initiated connection", "le"); +void shim::legacy::Acl::CancelClassicConnection(const hci::Address& address) { + GetAclManager()->CancelConnect(address); + LOG_DEBUG("Connection cancelled for classic to remote:%s", + PRIVATE_ADDRESS(address)); + BTM_LogHistory(kBtmLogTag, ToRawAddress(address), "Cancelled connection", + "classic"); +} + +void shim::legacy::Acl::AcceptLeConnectionFrom( + const hci::AddressWithType& address_with_type, std::promise promise) { + handler_->CallOn(pimpl_.get(), &Acl::impl::accept_le_connection_from, + address_with_type, std::move(promise)); } -void shim::legacy::Acl::CancelLeConnection( +void shim::legacy::Acl::IgnoreLeConnectionFrom( const hci::AddressWithType& address_with_type) { - GetAclManager()->CancelLeConnect(address_with_type); - LOG_DEBUG("Cancelled le connection to remote:%s", - PRIVATE_ADDRESS(address_with_type)); - BTM_LogHistory(kBtmLogTag, ToLegacyAddressWithType(address_with_type), - "Cancelled connection", "le"); + handler_->CallOn(pimpl_.get(), &Acl::impl::ignore_le_connection_from, + address_with_type); } void shim::legacy::Acl::OnClassicLinkDisconnected(HciHandle handle, @@ -965,7 +1062,7 @@ void shim::legacy::Acl::OnLeLinkDisconnected(HciHandle handle, BTM_LogHistory( kBtmLogTag, ToLegacyAddressWithType(remote_address_with_type), "Disconnected", - base::StringPrintf("le reason:%s", ErrorCodeText(reason).c_str())); + base::StringPrintf("Le reason:%s", ErrorCodeText(reason).c_str())); pimpl_->connection_history_.Push( std::move(std::make_unique( remote_address_with_type, creation_time, teardown_time, handle, @@ -1054,7 +1151,7 @@ void shim::legacy::Acl::OnLeConnectSuccess( PRIVATE_ADDRESS(address_with_type), handle, (locally_initiated) ? "local" : "remote"); BTM_LogHistory(kBtmLogTag, ToLegacyAddressWithType(address_with_type), - "Connection successful", "le"); + "Connection successful", "Le"); } void shim::legacy::Acl::OnLeConnectFail(hci::AddressWithType address_with_type, @@ -1124,7 +1221,7 @@ void shim::legacy::Acl::DisconnectLe(uint16_t handle, tHCI_STATUS reason) { PRIVATE_ADDRESS(remote_address_with_type), handle); BTM_LogHistory(kBtmLogTag, ToLegacyAddressWithType(remote_address_with_type), - "Disconnection initiated", "le"); + "Disconnection initiated", "Le"); } else { LOG_WARN("Unable to disconnect unknown le connection handle:0x%04x", handle); @@ -1179,7 +1276,7 @@ void shim::legacy::Acl::Shutdown() { shutdown_future.wait(); shutdown_promise = std::promise(); - ; + shutdown_future = shutdown_promise.get_future(); handler_->CallOn(pimpl_.get(), &Acl::impl::ShutdownLeConnections, std::move(shutdown_promise)); @@ -1189,3 +1286,7 @@ void shim::legacy::Acl::Shutdown() { LOG_INFO("All ACL connections have been previously closed"); } } + +void shim::legacy::Acl::ClearAcceptList() { + handler_->CallOn(pimpl_.get(), &Acl::impl::clear_acceptlist); +} diff --git a/main/shim/acl.h b/main/shim/acl.h index be9faa32a..f063391cf 100644 --- a/main/shim/acl.h +++ b/main/shim/acl.h @@ -16,6 +16,7 @@ #pragma once +#include #include #include "gd/hci/acl_manager/connection_callbacks.h" @@ -38,7 +39,8 @@ class Acl : public hci::acl_manager::ConnectionCallbacks, public LinkConnectionInterface, public LinkPolicyInterface { public: - Acl(os::Handler* handler, const acl_interface_t& acl_interface); + Acl(os::Handler* handler, const acl_interface_t& acl_interface, + uint8_t max_acceptlist_size); ~Acl(); // hci::acl_manager::ConnectionCallbacks @@ -55,13 +57,14 @@ class Acl : public hci::acl_manager::ConnectionCallbacks, void OnLeLinkDisconnected(uint16_t handle, hci::ErrorCode reason); // LinkConnectionInterface - void CreateClassicConnection(const bluetooth::hci::Address& address) override; - void CreateLeConnection( - const bluetooth::hci::AddressWithType& address_with_type) override; - void CancelLeConnection( - const bluetooth::hci::AddressWithType& address_with_type) override; - void DisconnectClassic(uint16_t handle, tHCI_STATUS reason) override; - void DisconnectLe(uint16_t handle, tHCI_STATUS reason) override; + void CreateClassicConnection(const hci::Address& address) override; + void CancelClassicConnection(const hci::Address& address) override; + void AcceptLeConnectionFrom(const hci::AddressWithType& address_with_type, + std::promise promise) override; + void IgnoreLeConnectionFrom( + const hci::AddressWithType& address_with_type) override; + void DisconnectClassic(uint16_t handle, tHCI_REASON reason) override; + void DisconnectLe(uint16_t handle, tHCI_REASON reason) override; // LinkPolicyInterface bool HoldMode(uint16_t hci_handle, uint16_t max_interval, @@ -77,7 +80,7 @@ class Acl : public hci::acl_manager::ConnectionCallbacks, void HACK_OnScoDisconnected(uint16_t handle, uint8_t reason); void WriteData(uint16_t hci_handle, - std::unique_ptr packet); + std::unique_ptr packet); void ConfigureLePrivacy(bool is_le_privacy_enabled); @@ -86,10 +89,12 @@ class Acl : public hci::acl_manager::ConnectionCallbacks, void Shutdown(); + void ClearAcceptList(); + protected: void on_incoming_acl_credits(uint16_t handle, uint16_t credits); void write_data_sync(uint16_t hci_handle, - std::unique_ptr packet); + std::unique_ptr packet); private: os::Handler* handler_; diff --git a/main/shim/acl_api.cc b/main/shim/acl_api.cc index 4960372dd..538bc9dd8 100644 --- a/main/shim/acl_api.cc +++ b/main/shim/acl_api.cc @@ -16,9 +16,11 @@ #include #include +#include #include "gd/hci/acl_manager.h" #include "main/shim/acl_api.h" +#include "main/shim/dumpsys.h" #include "main/shim/helpers.h" #include "main/shim/stack.h" #include "types/ble_address_with_type.h" @@ -30,15 +32,25 @@ void bluetooth::shim::ACL_CreateClassicConnection( Stack::GetInstance()->GetAcl()->CreateClassicConnection(address); } -void bluetooth::shim::ACL_CreateLeConnection( +void bluetooth::shim::ACL_CancelClassicConnection( + const RawAddress& raw_address) { + auto address = ToGdAddress(raw_address); + Stack::GetInstance()->GetAcl()->CancelClassicConnection(address); +} + +bool bluetooth::shim::ACL_AcceptLeConnectionFrom( const tBLE_BD_ADDR& legacy_address_with_type) { - Stack::GetInstance()->GetAcl()->CreateLeConnection( - ToAddressWithTypeFromLegacy(legacy_address_with_type)); + std::promise promise; + auto future = promise.get_future(); + Stack::GetInstance()->GetAcl()->AcceptLeConnectionFrom( + ToAddressWithTypeFromLegacy(legacy_address_with_type), + std::move(promise)); + return future.get(); } -void bluetooth::shim::ACL_CancelLeConnection( +void bluetooth::shim::ACL_IgnoreLeConnectionFrom( const tBLE_BD_ADDR& legacy_address_with_type) { - Stack::GetInstance()->GetAcl()->CancelLeConnection( + Stack::GetInstance()->GetAcl()->IgnoreLeConnectionFrom( ToAddressWithTypeFromLegacy(legacy_address_with_type)); } @@ -78,3 +90,7 @@ void bluetooth::shim::ACL_Disconnect(uint16_t handle, bool is_classic, void bluetooth::shim::ACL_Shutdown() { Stack::GetInstance()->GetAcl()->Shutdown(); } + +void bluetooth::shim::ACL_IgnoreAllLeConnections() { + return Stack::GetInstance()->GetAcl()->ClearAcceptList(); +} diff --git a/main/shim/acl_api.h b/main/shim/acl_api.h index 16c5e28a2..9e5c0bd16 100644 --- a/main/shim/acl_api.h +++ b/main/shim/acl_api.h @@ -24,14 +24,16 @@ namespace bluetooth { namespace shim { -void ACL_CancelClassicConnection(const RawAddress& raw_address); -void ACL_CancelLeConnection(const tBLE_BD_ADDR& legacy_address_with_type); void ACL_CreateClassicConnection(const RawAddress& raw_address); -void ACL_CreateLeConnection(const tBLE_BD_ADDR& legacy_address_with_type); +void ACL_CancelClassicConnection(const RawAddress& raw_address); +bool ACL_AcceptLeConnectionFrom(const tBLE_BD_ADDR& legacy_address_with_type); +void ACL_IgnoreLeConnectionFrom(const tBLE_BD_ADDR& legacy_address_with_type); + void ACL_Disconnect(uint16_t handle, bool is_classic, tHCI_STATUS reason); void ACL_WriteData(uint16_t handle, const BT_HDR* p_buf); void ACL_ConfigureLePrivacy(bool is_le_privacy_enabled); void ACL_Shutdown(); +void ACL_IgnoreAllLeConnections(); } // namespace shim } // namespace bluetooth diff --git a/main/shim/link_connection_interface.h b/main/shim/link_connection_interface.h index 022d1b9e1..1c140b6d1 100644 --- a/main/shim/link_connection_interface.h +++ b/main/shim/link_connection_interface.h @@ -17,6 +17,7 @@ #pragma once #include +#include #include "gd/hci/address.h" #include "gd/hci/address_with_type.h" @@ -31,13 +32,16 @@ class LinkConnectionInterface { virtual void CreateClassicConnection( const bluetooth::hci::Address& address) = 0; - virtual void CreateLeConnection( - const bluetooth::hci::AddressWithType& address_with_type) = 0; - virtual void CancelLeConnection( + virtual void CancelClassicConnection( + const bluetooth::hci::Address& address) = 0; + virtual void AcceptLeConnectionFrom( + const bluetooth::hci::AddressWithType& address_with_type, + std::promise) = 0; + virtual void IgnoreLeConnectionFrom( const bluetooth::hci::AddressWithType& address_with_type) = 0; - virtual void DisconnectClassic(uint16_t handle, tHCI_STATUS reason) = 0; - virtual void DisconnectLe(uint16_t handle, tHCI_STATUS reason) = 0; + virtual void DisconnectClassic(uint16_t handle, tHCI_REASON reason) = 0; + virtual void DisconnectLe(uint16_t handle, tHCI_REASON reason) = 0; }; } // namespace shim diff --git a/main/shim/stack.cc b/main/shim/stack.cc index 52daab439..6410c90ae 100644 --- a/main/shim/stack.cc +++ b/main/shim/stack.cc @@ -16,6 +16,8 @@ #define LOG_TAG "bt_gd_shim" +#include "device/include/controller.h" + #include "gd/att/att_module.h" #include "gd/common/init_flags.h" #include "gd/hal/hci_hal.h" @@ -137,7 +139,9 @@ void Stack::StartEverything() { } if (common::init_flags::gd_acl_is_enabled()) { if (!common::init_flags::gd_core_is_enabled()) { - acl_ = new legacy::Acl(stack_handler_, legacy::GetAclInterface()); + acl_ = new legacy::Acl( + stack_handler_, legacy::GetAclInterface(), + controller_get_interface()->get_ble_acceptlist_size()); } } if (!common::init_flags::gd_core_is_enabled()) { diff --git a/stack/acl/btm_acl.cc b/stack/acl/btm_acl.cc index 6623f0e4b..2a2c5e361 100644 --- a/stack/acl/btm_acl.cc +++ b/stack/acl/btm_acl.cc @@ -2746,7 +2746,7 @@ bool acl_create_le_connection_with_id(uint8_t id, const RawAddress& bd_addr) { gatt_find_in_device_record(bd_addr, &address_with_type); LOG_DEBUG("Creating le connection to:%s", address_with_type.ToString().c_str()); - bluetooth::shim::ACL_CreateLeConnection(address_with_type); + bluetooth::shim::ACL_AcceptLeConnectionFrom(address_with_type); return true; } return connection_manager::direct_connect_add(id, bd_addr); diff --git a/stack/test/common/mock_main_shim_acl_api.cc b/stack/test/common/mock_main_shim_acl_api.cc index 0dce0643e..d2cccd716 100644 --- a/stack/test/common/mock_main_shim_acl_api.cc +++ b/stack/test/common/mock_main_shim_acl_api.cc @@ -34,21 +34,26 @@ extern std::map mock_function_count_map; #define UNUSED_ATTR #endif -void bluetooth::shim::ACL_CancelLeConnection( - const tBLE_BD_ADDR& legacy_address_with_type) { +void bluetooth::shim::ACL_CreateClassicConnection( + const RawAddress& raw_address) { mock_function_count_map[__func__]++; } -void bluetooth::shim::ACL_ConfigureLePrivacy(bool is_le_privacy_enabled) { +void bluetooth::shim::ACL_CancelClassicConnection( + const RawAddress& raw_address) { mock_function_count_map[__func__]++; } -void bluetooth::shim::ACL_CreateClassicConnection( - const RawAddress& raw_address) { +bool bluetooth::shim::ACL_AcceptLeConnectionFrom( + const tBLE_BD_ADDR& legacy_address_with_type) { mock_function_count_map[__func__]++; + return true; } -void bluetooth::shim::ACL_CreateLeConnection( +void bluetooth::shim::ACL_IgnoreLeConnectionFrom( const tBLE_BD_ADDR& legacy_address_with_type) { mock_function_count_map[__func__]++; } +void bluetooth::shim::ACL_ConfigureLePrivacy(bool is_le_privacy_enabled) { + mock_function_count_map[__func__]++; +} void bluetooth::shim::ACL_WriteData(uint16_t handle, const BT_HDR* p_buf) { mock_function_count_map[__func__]++; } @@ -56,3 +61,6 @@ void bluetooth::shim::ACL_Disconnect(uint16_t handle, bool is_classic, tHCI_STATUS reason) { mock_function_count_map[__func__]++; } +void bluetooth::shim::ACL_IgnoreAllLeConnections() { + mock_function_count_map[__func__]++; +} -- 2.11.0