You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
164 lines
5.0 KiB
164 lines
5.0 KiB
/*
|
|
* 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, std::list<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; adding callback to callback list");
|
|
address_to_pending_read_map_[address].push_back({std::move(callback), handler});
|
|
return;
|
|
}
|
|
|
|
std::list<PendingRemoteNameRead> tmp;
|
|
address_to_pending_read_map_[address] = std::move(tmp);
|
|
address_to_pending_read_map_[address].push_back({std::move(callback), 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());
|
|
if (status == hci::ErrorCode::SUCCESS) {
|
|
address_to_name_map_[address] = name;
|
|
}
|
|
auto& callback_list = address_to_pending_read_map_.at(address);
|
|
for (auto& it : callback_list) {
|
|
it.handler_->Call(std::move(it.callback_), address, status == hci::ErrorCode::SUCCESS);
|
|
}
|
|
address_to_pending_read_map_.erase(address);
|
|
}
|
|
|
|
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
|