1 /* 2 * Copyright 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #define LOG_TAG "bt_gd_neigh" 17 18 #include "neighbor/name_db.h" 19 20 #include <memory> 21 #include <unordered_map> 22 #include <utility> 23 24 #include "common/bind.h" 25 #include "module.h" 26 #include "neighbor/name.h" 27 #include "os/handler.h" 28 #include "os/log.h" 29 30 namespace bluetooth { 31 namespace neighbor { 32 33 namespace { 34 struct PendingRemoteNameRead { 35 ReadRemoteNameDbCallback callback_; 36 os::Handler* handler_; 37 }; 38 } // namespace 39 40 struct NameDbModule::impl { 41 void ReadRemoteNameRequest(hci::Address address, ReadRemoteNameDbCallback callback, os::Handler* handler); 42 43 bool IsNameCached(hci::Address address) const; 44 RemoteName ReadCachedRemoteName(hci::Address address) const; 45 46 impl(const NameDbModule& module); 47 48 void Start(); 49 void Stop(); 50 51 private: 52 std::unordered_map<hci::Address, PendingRemoteNameRead> address_to_pending_read_map_; 53 std::unordered_map<hci::Address, RemoteName> address_to_name_map_; 54 55 void OnRemoteNameResponse(hci::ErrorCode status, hci::Address address, RemoteName name); 56 57 neighbor::NameModule* name_module_; 58 59 const NameDbModule& module_; 60 os::Handler* handler_; 61 }; 62 63 const ModuleFactory neighbor::NameDbModule::Factory = ModuleFactory([]() { return new neighbor::NameDbModule(); }); 64 65 neighbor::NameDbModule::impl::impl(const neighbor::NameDbModule& module) : module_(module) {} 66 67 void neighbor::NameDbModule::impl::ReadRemoteNameRequest(hci::Address address, ReadRemoteNameDbCallback callback, 68 os::Handler* handler) { 69 if (address_to_pending_read_map_.find(address) != address_to_pending_read_map_.end()) { 70 LOG_WARN("Already have remote read db in progress and currently can only have one outstanding"); 71 return; 72 } 73 74 address_to_pending_read_map_[address] = {std::move(callback), std::move(handler)}; 75 76 // TODO(cmanton) Use remote name request defaults for now 77 hci::PageScanRepetitionMode page_scan_repetition_mode = hci::PageScanRepetitionMode::R1; 78 uint16_t clock_offset = 0; 79 hci::ClockOffsetValid clock_offset_valid = hci::ClockOffsetValid::INVALID; 80 name_module_->ReadRemoteNameRequest( 81 address, page_scan_repetition_mode, clock_offset, clock_offset_valid, 82 common::BindOnce(&NameDbModule::impl::OnRemoteNameResponse, common::Unretained(this)), handler_); 83 } 84 85 void neighbor::NameDbModule::impl::OnRemoteNameResponse(hci::ErrorCode status, hci::Address address, RemoteName name) { 86 ASSERT(address_to_pending_read_map_.find(address) != address_to_pending_read_map_.end()); 87 PendingRemoteNameRead callback_handler = std::move(address_to_pending_read_map_.at(address)); 88 89 if (status == hci::ErrorCode::SUCCESS) { 90 address_to_name_map_[address] = name; 91 } 92 callback_handler.handler_->Post( 93 common::BindOnce(std::move(callback_handler.callback_), address, status == hci::ErrorCode::SUCCESS)); 94 } 95 96 bool neighbor::NameDbModule::impl::IsNameCached(hci::Address address) const { 97 return address_to_name_map_.count(address) == 1; 98 } 99 100 RemoteName neighbor::NameDbModule::impl::ReadCachedRemoteName(hci::Address address) const { 101 ASSERT(IsNameCached(address)); 102 return address_to_name_map_.at(address); 103 } 104 105 /** 106 * General API here 107 */ 108 neighbor::NameDbModule::NameDbModule() : pimpl_(std::make_unique<impl>(*this)) {} 109 110 neighbor::NameDbModule::~NameDbModule() { 111 pimpl_.reset(); 112 } 113 114 void neighbor::NameDbModule::ReadRemoteNameRequest(hci::Address address, ReadRemoteNameDbCallback callback, 115 os::Handler* handler) { 116 GetHandler()->Post(common::BindOnce(&NameDbModule::impl::ReadRemoteNameRequest, common::Unretained(pimpl_.get()), 117 address, std::move(callback), handler)); 118 } 119 120 bool neighbor::NameDbModule::IsNameCached(hci::Address address) const { 121 return pimpl_->IsNameCached(address); 122 } 123 124 RemoteName neighbor::NameDbModule::ReadCachedRemoteName(hci::Address address) const { 125 return pimpl_->ReadCachedRemoteName(address); 126 } 127 128 void neighbor::NameDbModule::impl::Start() { 129 name_module_ = module_.GetDependency<neighbor::NameModule>(); 130 handler_ = module_.GetHandler(); 131 } 132 133 void neighbor::NameDbModule::impl::Stop() {} 134 135 /** 136 * Module methods here 137 */ 138 void neighbor::NameDbModule::ListDependencies(ModuleList* list) { 139 list->add<neighbor::NameModule>(); 140 } 141 142 void neighbor::NameDbModule::Start() { 143 pimpl_->Start(); 144 } 145 146 void neighbor::NameDbModule::Stop() { 147 pimpl_->Stop(); 148 } 149 150 } // namespace neighbor 151 } // namespace bluetooth 152