Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 078939bf authored by Chris Manton's avatar Chris Manton
Browse files

gd_acl: Add add/remove acceptlist

Also rename Accept/Ignore LeConnections

Bug: 173985410
Tag: #refactor
Test: gd/cert/run

Change-Id: I96c3d09bf86887f9fdff9fb09475c909f0045f02
parent e7c7fb67
Loading
Loading
Loading
Loading
+12 −4
Original line number Diff line number Diff line
@@ -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__]++;
+120 −19
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include <base/location.h>
#include <base/strings/stringprintf.h>
#include <time.h>
#include <unordered_set>

#include <chrono>
#include <cstdint>
@@ -77,6 +78,49 @@ using OnDisconnect = std::function<void(HciHandle, hci::ErrorCode reason)>;

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<hci::AddressWithType> GetCopy() const {
    return acceptlist_set_;
  }

  bool IsFull() const {
    return acceptlist_set_.size() == static_cast<size_t>(max_acceptlist_size_);
  }

  void Clear() { acceptlist_set_.clear(); }

 private:
  uint8_t max_acceptlist_size_{0};
  std::unordered_set<hci::AddressWithType> 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<HciHandle, std::unique_ptr<ClassicShimAclConnection>>
      handle_to_classic_connection_map_;
  std::map<HciHandle, std::unique_ptr<LeShimAclConnection>>
@@ -590,6 +637,8 @@ struct shim::legacy::Acl::impl {
  FixedQueue<std::unique_ptr<ConnectionDescriptor>> connection_history_ =
      FixedQueue<std::unique_ptr<ConnectionDescriptor>>(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<bool> 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<std::string> 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<Acl::impl>();
  pimpl_ = std::make_unique<Acl::impl>(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<bool> 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<LeConnectionDescriptor>(
          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<void>();
    ;

    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);
}
+15 −10
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

#pragma once

#include <future>
#include <memory>

#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<bool> 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<bluetooth::packet::RawBuilder> packet);
                 std::unique_ptr<packet::RawBuilder> 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<bluetooth::packet::RawBuilder> packet);
                       std::unique_ptr<packet::RawBuilder> packet);

 private:
  os::Handler* handler_;
+21 −5
Original line number Diff line number Diff line
@@ -16,9 +16,11 @@

#include <cstddef>
#include <cstdint>
#include <future>

#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<bool> 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();
}
+5 −3
Original line number Diff line number Diff line
@@ -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
Loading