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

Commit 398139f3 authored by Jack He's avatar Jack He Committed by android-build-merger
Browse files

HCI: Use AddressWithType in various LE connection APIs

am: b54aa76d

Change-Id: I8c1bcea5d8d0a2ed607fb124cb71ae1a6b47ce34
parents 2f850a68 b54aa76d
Loading
Loading
Loading
Loading
+34 −15
Original line number Diff line number Diff line
@@ -252,7 +252,7 @@ struct AclManager::impl {
    }
  }

  void on_any_connection_complete(Address address) {
  void on_classic_connection_complete(Address address) {
    auto connecting_addr = connecting_.find(address);
    if (connecting_addr == connecting_.end()) {
      LOG_WARN("No prior connection request for %s", address.ToString().c_str());
@@ -261,17 +261,27 @@ struct AclManager::impl {
    }
  }

  void on_common_le_connection_complete(AddressWithType address_with_type) {
    auto connecting_addr_with_type = connecting_le_.find(address_with_type);
    if (connecting_addr_with_type == connecting_le_.end()) {
      LOG_WARN("No prior connection request for %s", address_with_type.ToString().c_str());
    } else {
      connecting_le_.erase(connecting_addr_with_type);
    }
  }

  void on_le_connection_complete(LeMetaEventView packet) {
    LeConnectionCompleteView connection_complete = LeConnectionCompleteView::Create(packet);
    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);
    // TODO: find out which address and type was used to initiate the connection
    AddressWithType address_with_type(address, peer_address_type);
    on_common_le_connection_complete(address_with_type);
    if (status != ErrorCode::SUCCESS) {
      le_client_handler_->Post(common::BindOnce(&LeConnectionCallbacks::OnLeConnectFail,
                                                common::Unretained(le_client_callbacks_), address, peer_address_type,
                                                status));
                                                common::Unretained(le_client_callbacks_), address_with_type, status));
      return;
    }
    // TODO: Check and save other connection parameters
@@ -284,7 +294,8 @@ struct AclManager::impl {
    std::unique_ptr<AclConnection> connection_proxy(
        new AclConnection(&acl_manager_, handle, address, peer_address_type));
    le_client_handler_->Post(common::BindOnce(&LeConnectionCallbacks::OnLeConnectSuccess,
                                              common::Unretained(le_client_callbacks_), std::move(connection_proxy)));
                                              common::Unretained(le_client_callbacks_), address_with_type,
                                              std::move(connection_proxy)));
  }

  void on_le_enhanced_connection_complete(LeMetaEventView packet) {
@@ -293,10 +304,15 @@ struct AclManager::impl {
    auto status = connection_complete.GetStatus();
    auto address = connection_complete.GetPeerAddress();
    auto peer_address_type = connection_complete.GetPeerAddressType();
    on_any_connection_complete(address);
    auto peer_resolvable_address = connection_complete.GetPeerResolvablePrivateAddress();
    AddressWithType reporting_address_with_type(address, peer_address_type);
    if (!peer_resolvable_address.IsEmpty()) {
      reporting_address_with_type = AddressWithType(peer_resolvable_address, AddressType::RANDOM_DEVICE_ADDRESS);
    }
    on_common_le_connection_complete(reporting_address_with_type);
    if (status != ErrorCode::SUCCESS) {
      le_client_handler_->Post(common::BindOnce(&LeConnectionCallbacks::OnLeConnectFail,
                                                common::Unretained(le_client_callbacks_), address, peer_address_type,
                                                common::Unretained(le_client_callbacks_), reporting_address_with_type,
                                                status));
      return;
    }
@@ -310,7 +326,8 @@ struct AclManager::impl {
    std::unique_ptr<AclConnection> connection_proxy(
        new AclConnection(&acl_manager_, handle, address, peer_address_type));
    le_client_handler_->Post(common::BindOnce(&LeConnectionCallbacks::OnLeConnectSuccess,
                                              common::Unretained(le_client_callbacks_), std::move(connection_proxy)));
                                              common::Unretained(le_client_callbacks_), reporting_address_with_type,
                                              std::move(connection_proxy)));
  }

  void on_connection_complete(EventPacketView packet) {
@@ -318,7 +335,7 @@ struct AclManager::impl {
    ASSERT(connection_complete.IsValid());
    auto status = connection_complete.GetStatus();
    auto address = connection_complete.GetBdAddr();
    on_any_connection_complete(address);
    on_classic_connection_complete(address);
    if (status != ErrorCode::SUCCESS) {
      client_handler_->Post(common::BindOnce(&ConnectionCallbacks::OnConnectFail, common::Unretained(client_callbacks_),
                                             address, status));
@@ -838,7 +855,7 @@ struct AclManager::impl {
                               handler_);
  }

  void create_le_connection(Address address, AddressType address_type) {
  void create_le_connection(AddressWithType address_with_type) {
    // TODO: Add white list handling.
    // TODO: Configure default LE connection parameters?
    uint16_t le_scan_interval = 0x0020;
@@ -853,11 +870,12 @@ struct AclManager::impl {
    uint16_t maximum_ce_length = 0x0C00;
    ASSERT(le_client_callbacks_ != nullptr);

    connecting_.insert(address);
    connecting_le_.insert(address_with_type);

    hci_layer_->EnqueueCommand(
        LeCreateConnectionBuilder::Create(le_scan_interval, le_scan_window, initiator_filter_policy, address_type,
                                          address, own_address_type, conn_interval_min, conn_interval_max, conn_latency,
        LeCreateConnectionBuilder::Create(le_scan_interval, le_scan_window, initiator_filter_policy,
                                          address_with_type.GetAddressType(), address_with_type.GetAddress(),
                                          own_address_type, conn_interval_min, conn_interval_max, conn_latency,
                                          supervision_timeout, minimum_ce_length, maximum_ce_length),
        common::BindOnce([](CommandStatusView status) {
          ASSERT(status.IsValid());
@@ -1540,6 +1558,7 @@ struct AclManager::impl {
  common::BidiQueueEnd<AclPacketBuilder, AclPacketView>* hci_queue_end_ = nullptr;
  std::map<uint16_t, AclManager::acl_connection> acl_connections_;
  std::set<Address> connecting_;
  std::set<AddressWithType> connecting_le_;
  common::Callback<bool(Address, ClassOfDevice)> should_accept_connection_;
};

@@ -1696,9 +1715,9 @@ void AclManager::CreateConnection(Address address) {
  GetHandler()->Post(common::BindOnce(&impl::create_connection, common::Unretained(pimpl_.get()), address));
}

void AclManager::CreateLeConnection(Address address, AddressType address_type) {
void AclManager::CreateLeConnection(AddressWithType address_with_type) {
  GetHandler()->Post(
      common::BindOnce(&impl::create_le_connection, common::Unretained(pimpl_.get()), address, address_type));
      common::BindOnce(&impl::create_le_connection, common::Unretained(pimpl_.get()), address_with_type));
}

void AclManager::CancelConnect(Address address) {
+7 −4
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include "common/bidi_queue.h"
#include "common/callback.h"
#include "hci/address.h"
#include "hci/address_with_type.h"
#include "hci/hci_layer.h"
#include "hci/hci_packets.h"
#include "module.h"
@@ -82,7 +83,8 @@ class ConnectionManagementCallbacks {

class AclConnection {
 public:
  AclConnection() : manager_(nullptr), handle_(0), address_(Address::kEmpty){};
  AclConnection()
      : manager_(nullptr), handle_(0), address_(Address::kEmpty), address_type_(AddressType::PUBLIC_DEVICE_ADDRESS){};
  virtual ~AclConnection() = default;

  virtual Address GetAddress() const {
@@ -165,9 +167,10 @@ class LeConnectionCallbacks {
 public:
  virtual ~LeConnectionCallbacks() = default;
  // Invoked when controller sends Connection Complete event with Success error code
  virtual void OnLeConnectSuccess(std::unique_ptr<AclConnection> /* , initiated_by_local ? */) = 0;
  // AddressWithType is always equal to the object used in AclManager#CreateLeConnection
  virtual void OnLeConnectSuccess(AddressWithType, std::unique_ptr<AclConnection> /* , initiated_by_local ? */) = 0;
  // Invoked when controller sends Connection Complete event with non-Success error code
  virtual void OnLeConnectFail(Address, AddressType, ErrorCode reason) = 0;
  virtual void OnLeConnectFail(AddressWithType, ErrorCode reason) = 0;
};

class AclManagerCallbacks {
@@ -205,7 +208,7 @@ class AclManager : public Module {
  virtual void CreateConnection(Address address);

  // Generates OnLeConnectSuccess if connected, or OnLeConnectFail otherwise
  virtual void CreateLeConnection(Address address, AddressType address_type);
  virtual void CreateLeConnection(AddressWithType address_with_type);

  // Generates OnConnectFail with error code "terminated by local host 0x16" if cancelled, or OnConnectSuccess if not
  // successfully cancelled and already connected
+1 −1
Original line number Diff line number Diff line
@@ -40,7 +40,7 @@ class MockAclManager : public AclManager {
  MOCK_METHOD(void, RegisterCallbacks, (ConnectionCallbacks * callbacks, os::Handler* handler), (override));
  MOCK_METHOD(void, RegisterLeCallbacks, (LeConnectionCallbacks * callbacks, os::Handler* handler), (override));
  MOCK_METHOD(void, CreateConnection, (Address address), (override));
  MOCK_METHOD(void, CreateLeConnection, (Address address, AddressType address_type), (override));
  MOCK_METHOD(void, CreateLeConnection, (AddressWithType address_with_type), (override));
  MOCK_METHOD(void, CancelConnect, (Address address), (override));
};

+12 −10
Original line number Diff line number Diff line
@@ -305,7 +305,7 @@ class AclManagerNoCallbacksTest : public ::testing::Test {
        connection_promise_.reset();
      }
    }
    MOCK_METHOD2(OnConnectFail, void(Address, ErrorCode reason));
    MOCK_METHOD(void, OnConnectFail, (Address, ErrorCode reason), (override));

    std::list<std::shared_ptr<AclConnection>> connections_;
    std::unique_ptr<std::promise<void>> connection_promise_;
@@ -313,14 +313,14 @@ class AclManagerNoCallbacksTest : public ::testing::Test {

  class MockLeConnectionCallbacks : public LeConnectionCallbacks {
   public:
    void OnLeConnectSuccess(std::unique_ptr<AclConnection> connection) override {
    void OnLeConnectSuccess(AddressWithType address_with_type, 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));
    MOCK_METHOD(void, OnLeConnectFail, (AddressWithType, ErrorCode reason), (override));

    std::list<std::shared_ptr<AclConnection>> le_connections_;
    std::unique_ptr<std::promise<void>> le_connection_promise_;
@@ -328,9 +328,9 @@ class AclManagerNoCallbacksTest : public ::testing::Test {

  class MockAclManagerCallbacks : public AclManagerCallbacks {
   public:
    MOCK_METHOD2(OnMasterLinkKeyComplete, void(uint16_t connection_handle, KeyFlag key_flag));
    MOCK_METHOD2(OnRoleChange, void(Address bd_addr, Role new_role));
    MOCK_METHOD1(OnReadDefaultLinkPolicySettingsComplete, void(uint16_t default_link_policy_settings));
    MOCK_METHOD(void, OnMasterLinkKeyComplete, (uint16_t connection_handle, KeyFlag key_flag), (override));
    MOCK_METHOD(void, OnRoleChange, (Address bd_addr, Role new_role), (override));
    MOCK_METHOD(void, OnReadDefaultLinkPolicySettingsComplete, (uint16_t default_link_policy_settings), (override));
  } mock_acl_manager_callbacks_;
};

@@ -463,7 +463,8 @@ TEST_F(AclManagerTest, invoke_registered_callback_connection_complete_fail) {
}

TEST_F(AclManagerTest, invoke_registered_callback_le_connection_complete_success) {
  acl_manager_->CreateLeConnection(remote, AddressType::PUBLIC_DEVICE_ADDRESS);
  AddressWithType remote_with_type(remote, AddressType::PUBLIC_DEVICE_ADDRESS);
  acl_manager_->CreateLeConnection(remote_with_type);

  auto packet = test_hci_layer_->GetCommandPacket(OpCode::LE_CREATE_CONNECTION);
  auto le_connection_management_command_view = LeConnectionManagementCommandView::Create(packet);
@@ -486,7 +487,8 @@ TEST_F(AclManagerTest, invoke_registered_callback_le_connection_complete_success
}

TEST_F(AclManagerTest, invoke_registered_callback_le_connection_complete_fail) {
  acl_manager_->CreateLeConnection(remote, AddressType::PUBLIC_DEVICE_ADDRESS);
  AddressWithType remote_with_type(remote, AddressType::PUBLIC_DEVICE_ADDRESS);
  acl_manager_->CreateLeConnection(remote_with_type);

  auto packet = test_hci_layer_->GetCommandPacket(OpCode::LE_CREATE_CONNECTION);
  auto le_connection_management_command_view = LeConnectionManagementCommandView::Create(packet);
@@ -495,8 +497,8 @@ TEST_F(AclManagerTest, invoke_registered_callback_le_connection_complete_fail) {
  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));
  EXPECT_CALL(mock_le_connection_callbacks_,
              OnLeConnectFail(remote_with_type, 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));
+9 −9
Original line number Diff line number Diff line
@@ -79,7 +79,7 @@ void LinkManager::ConnectFixedChannelServices(hci::AddressWithType address_with_
  }
  pending_link->second.pending_fixed_channel_connections_.push_back(std::move(pending_fixed_channel_connection));
  // Then create new ACL connection
  acl_manager_->CreateLeConnection(address_with_type.GetAddress(), address_with_type.GetAddressType());
  acl_manager_->CreateLeConnection(address_with_type);
}

Link* LinkManager::GetLink(hci::AddressWithType address_with_type) {
@@ -89,15 +89,16 @@ Link* LinkManager::GetLink(hci::AddressWithType address_with_type) {
  return &links_.find(address_with_type)->second;
}

void LinkManager::OnLeConnectSuccess(std::unique_ptr<hci::AclConnection> acl_connection) {
void LinkManager::OnLeConnectSuccess(hci::AddressWithType connecting_address_with_type,
                                     std::unique_ptr<hci::AclConnection> acl_connection) {
  // Same link should not be connected twice
  hci::AddressWithType address_with_type(acl_connection->GetAddress(), acl_connection->GetAddressType());
  ASSERT_LOG(GetLink(address_with_type) == nullptr, "%s is connected twice without disconnection",
  hci::AddressWithType connected_address_with_type(acl_connection->GetAddress(), acl_connection->GetAddressType());
  ASSERT_LOG(GetLink(connected_address_with_type) == nullptr, "%s is connected twice without disconnection",
             acl_connection->GetAddress().ToString().c_str());
  auto* link_queue_up_end = acl_connection->GetAclQueueEnd();
  links_.try_emplace(address_with_type, l2cap_handler_, std::move(acl_connection),
  links_.try_emplace(connected_address_with_type, l2cap_handler_, std::move(acl_connection),
                     std::make_unique<l2cap::internal::Fifo>(link_queue_up_end, l2cap_handler_), parameter_provider_);
  auto* link = GetLink(address_with_type);
  auto* link = GetLink(connected_address_with_type);
  // Allocate and distribute channels for all registered fixed channel services
  auto fixed_channel_services = service_manager_->GetRegisteredServices();
  for (auto& fixed_channel_service : fixed_channel_services) {
@@ -106,7 +107,7 @@ void LinkManager::OnLeConnectSuccess(std::unique_ptr<hci::AclConnection> acl_con
        std::make_unique<FixedChannel>(fixed_channel_impl, l2cap_handler_));
  }
  // Remove device from pending links list, if any
  auto pending_link = pending_links_.find(address_with_type);
  auto pending_link = pending_links_.find(connecting_address_with_type);
  if (pending_link == pending_links_.end()) {
    // This an incoming connection, exit
    return;
@@ -115,9 +116,8 @@ void LinkManager::OnLeConnectSuccess(std::unique_ptr<hci::AclConnection> acl_con
  pending_links_.erase(pending_link);
}

void LinkManager::OnLeConnectFail(hci::Address device, hci::AddressType address_type, hci::ErrorCode reason) {
void LinkManager::OnLeConnectFail(hci::AddressWithType address_with_type, hci::ErrorCode reason) {
  // Notify all pending links for this device
  hci::AddressWithType address_with_type(device, address_type);
  auto pending_link = pending_links_.find(address_with_type);
  if (pending_link == pending_links_.end()) {
    // There is no pending link, exit
Loading