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

Commit 77b10459 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "gd: Add a remote name database"

parents 9a6b5d7a fff5c6b6
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@ filegroup {
            "discoverability.cc",
            "inquiry.cc",
            "name.cc",
            "name_db.cc",
            "page.cc",
            "scan.cc",
    ],
+5 −1
Original line number Diff line number Diff line
@@ -41,7 +41,7 @@ struct CancelCallbackHandler {
  os::Handler* handler;
};

constexpr std::array<uint8_t, 248> kEmptyName{};
constexpr RemoteName kEmptyName{};

struct NameModule::impl {
  void ReadRemoteNameRequest(hci::Address address, hci::PageScanRepetitionMode page_scan_repetition_mode,
@@ -195,6 +195,8 @@ void neighbor::NameModule::ReadRemoteNameRequest(hci::Address address,
                                                 hci::PageScanRepetitionMode page_scan_repetition_mode,
                                                 uint16_t clock_offset, hci::ClockOffsetValid clock_offset_valid,
                                                 ReadRemoteNameCallback callback, os::Handler* handler) {
  ASSERT(callback);
  ASSERT(handler != nullptr);
  GetHandler()->Post(common::BindOnce(&NameModule::impl::ReadRemoteNameRequest, common::Unretained(pimpl_.get()),
                                      address, page_scan_repetition_mode, clock_offset, clock_offset_valid,
                                      std::move(callback), handler));
@@ -202,6 +204,8 @@ void neighbor::NameModule::ReadRemoteNameRequest(hci::Address address,

void neighbor::NameModule::CancelRemoteNameRequest(hci::Address address, CancelRemoteNameCallback callback,
                                                   os::Handler* handler) {
  ASSERT(callback);
  ASSERT(handler != nullptr);
  GetHandler()->Post(common::BindOnce(&NameModule::impl::CancelRemoteNameRequest, common::Unretained(pimpl_.get()),
                                      address, std::move(callback), handler));
}
+2 −2
Original line number Diff line number Diff line
@@ -27,8 +27,8 @@
namespace bluetooth {
namespace neighbor {

using ReadRemoteNameCallback =
    common::OnceCallback<void(hci::ErrorCode status, hci::Address address, std::array<uint8_t, 248> name)>;
using RemoteName = std::array<uint8_t, 248>;
using ReadRemoteNameCallback = common::OnceCallback<void(hci::ErrorCode status, hci::Address address, RemoteName name)>;
using CancelRemoteNameCallback = common::OnceCallback<void(hci::ErrorCode status, hci::Address address)>;

class NameModule : public bluetooth::Module {
+151 −0
Original line number Diff line number Diff line
/*
 * Copyright 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#define LOG_TAG "bt_gd_neigh"

#include "neighbor/name_db.h"

#include <memory>
#include <unordered_map>
#include <utility>

#include "common/bind.h"
#include "module.h"
#include "neighbor/name.h"
#include "os/handler.h"
#include "os/log.h"

namespace bluetooth {
namespace neighbor {

namespace {
struct PendingRemoteNameRead {
  ReadRemoteNameDbCallback callback_;
  os::Handler* handler_;
};
}  // namespace

struct NameDbModule::impl {
  void ReadRemoteNameRequest(hci::Address address, ReadRemoteNameDbCallback callback, os::Handler* handler);

  bool IsNameCached(hci::Address address) const;
  RemoteName ReadCachedRemoteName(hci::Address address) const;

  impl(const NameDbModule& module);

  void Start();
  void Stop();

 private:
  std::unordered_map<hci::Address, PendingRemoteNameRead> address_to_pending_read_map_;
  std::unordered_map<hci::Address, RemoteName> address_to_name_map_;

  void OnRemoteNameResponse(hci::ErrorCode status, hci::Address address, RemoteName name);

  neighbor::NameModule* name_module_;

  const NameDbModule& module_;
  os::Handler* handler_;
};

const ModuleFactory neighbor::NameDbModule::Factory = ModuleFactory([]() { return new neighbor::NameDbModule(); });

neighbor::NameDbModule::impl::impl(const neighbor::NameDbModule& module) : module_(module) {}

void neighbor::NameDbModule::impl::ReadRemoteNameRequest(hci::Address address, ReadRemoteNameDbCallback callback,
                                                         os::Handler* handler) {
  if (address_to_pending_read_map_.find(address) != address_to_pending_read_map_.end()) {
    LOG_WARN("Already have remote read db in progress and currently can only have one outstanding");
    return;
  }

  address_to_pending_read_map_[address] = {std::move(callback), std::move(handler)};

  // TODO(cmanton) Use remote name request defaults for now
  hci::PageScanRepetitionMode page_scan_repetition_mode = hci::PageScanRepetitionMode::R1;
  uint16_t clock_offset = 0;
  hci::ClockOffsetValid clock_offset_valid = hci::ClockOffsetValid::INVALID;
  name_module_->ReadRemoteNameRequest(
      address, page_scan_repetition_mode, clock_offset, clock_offset_valid,
      common::BindOnce(&NameDbModule::impl::OnRemoteNameResponse, common::Unretained(this)), handler_);
}

void neighbor::NameDbModule::impl::OnRemoteNameResponse(hci::ErrorCode status, hci::Address address, RemoteName name) {
  ASSERT(address_to_pending_read_map_.find(address) != address_to_pending_read_map_.end());
  PendingRemoteNameRead callback_handler = std::move(address_to_pending_read_map_.at(address));

  if (status == hci::ErrorCode::SUCCESS) {
    address_to_name_map_[address] = name;
  }
  callback_handler.handler_->Post(
      common::BindOnce(std::move(callback_handler.callback_), address, status == hci::ErrorCode::SUCCESS));
}

bool neighbor::NameDbModule::impl::IsNameCached(hci::Address address) const {
  return address_to_name_map_.count(address) == 1;
}

RemoteName neighbor::NameDbModule::impl::ReadCachedRemoteName(hci::Address address) const {
  ASSERT(IsNameCached(address));
  return address_to_name_map_.at(address);
}

/**
 * General API here
 */
neighbor::NameDbModule::NameDbModule() : pimpl_(std::make_unique<impl>(*this)) {}

neighbor::NameDbModule::~NameDbModule() {
  pimpl_.reset();
}

void neighbor::NameDbModule::ReadRemoteNameRequest(hci::Address address, ReadRemoteNameDbCallback callback,
                                                   os::Handler* handler) {
  GetHandler()->Post(common::BindOnce(&NameDbModule::impl::ReadRemoteNameRequest, common::Unretained(pimpl_.get()),
                                      address, std::move(callback), handler));
}

bool neighbor::NameDbModule::IsNameCached(hci::Address address) const {
  return pimpl_->IsNameCached(address);
}

RemoteName neighbor::NameDbModule::ReadCachedRemoteName(hci::Address address) const {
  return pimpl_->ReadCachedRemoteName(address);
}

void neighbor::NameDbModule::impl::Start() {
  name_module_ = module_.GetDependency<neighbor::NameModule>();
  handler_ = module_.GetHandler();
}

void neighbor::NameDbModule::impl::Stop() {}

/**
 * Module methods here
 */
void neighbor::NameDbModule::ListDependencies(ModuleList* list) {
  list->add<neighbor::NameModule>();
}

void neighbor::NameDbModule::Start() {
  pimpl_->Start();
}

void neighbor::NameDbModule::Stop() {
  pimpl_->Stop();
}

}  // namespace neighbor
}  // namespace bluetooth
+58 −0
Original line number Diff line number Diff line
/*
 * Copyright 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#pragma once

#include <array>
#include <cstdint>
#include <memory>

#include "common/bind.h"
#include "hci/address.h"
#include "hci/hci_packets.h"
#include "module.h"
#include "neighbor/name.h"

namespace bluetooth {
namespace neighbor {

using ReadRemoteNameDbCallback = common::OnceCallback<void(hci::Address address, bool success)>;

class NameDbModule : public bluetooth::Module {
 public:
  void ReadRemoteNameRequest(hci::Address address, ReadRemoteNameDbCallback callback, os::Handler* handler);

  bool IsNameCached(hci::Address address) const;
  RemoteName ReadCachedRemoteName(hci::Address address) const;

  static const ModuleFactory Factory;

  NameDbModule();
  ~NameDbModule();

 protected:
  void ListDependencies(ModuleList* list) override;
  void Start() override;
  void Stop() override;

 private:
  struct impl;
  std::unique_ptr<impl> pimpl_;

  DISALLOW_COPY_AND_ASSIGN(NameDbModule);
};

}  // namespace neighbor
}  // namespace bluetooth