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, std::list<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
__anonca2456900202() 63 const ModuleFactory neighbor::NameDbModule::Factory = ModuleFactory([]() { return new neighbor::NameDbModule(); });
64
impl(const neighbor::NameDbModule & module)65 neighbor::NameDbModule::impl::impl(const neighbor::NameDbModule& module) : module_(module) {}
66
ReadRemoteNameRequest(hci::Address address,ReadRemoteNameDbCallback callback,os::Handler * handler)67 void neighbor::NameDbModule::impl::ReadRemoteNameRequest(
68 hci::Address address, ReadRemoteNameDbCallback callback, 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; adding callback to callback list");
71 address_to_pending_read_map_[address].push_back({std::move(callback), handler});
72 return;
73 }
74
75 std::list<PendingRemoteNameRead> tmp;
76 address_to_pending_read_map_[address] = std::move(tmp);
77 address_to_pending_read_map_[address].push_back({std::move(callback), handler});
78
79 // TODO(cmanton) Use remote name request defaults for now
80 hci::PageScanRepetitionMode page_scan_repetition_mode = hci::PageScanRepetitionMode::R1;
81 uint16_t clock_offset = 0;
82 hci::ClockOffsetValid clock_offset_valid = hci::ClockOffsetValid::INVALID;
83 name_module_->ReadRemoteNameRequest(
84 address,
85 page_scan_repetition_mode,
86 clock_offset,
87 clock_offset_valid,
88 common::BindOnce(&NameDbModule::impl::OnRemoteNameResponse, common::Unretained(this)),
89 handler_);
90 }
91
OnRemoteNameResponse(hci::ErrorCode status,hci::Address address,RemoteName name)92 void neighbor::NameDbModule::impl::OnRemoteNameResponse(hci::ErrorCode status, hci::Address address, RemoteName name) {
93 ASSERT(address_to_pending_read_map_.find(address) != address_to_pending_read_map_.end());
94 if (status == hci::ErrorCode::SUCCESS) {
95 address_to_name_map_[address] = name;
96 }
97 auto& callback_list = address_to_pending_read_map_.at(address);
98 for (auto& it : callback_list) {
99 it.handler_->Call(std::move(it.callback_), address, status == hci::ErrorCode::SUCCESS);
100 }
101 address_to_pending_read_map_.erase(address);
102 }
103
IsNameCached(hci::Address address) const104 bool neighbor::NameDbModule::impl::IsNameCached(hci::Address address) const {
105 return address_to_name_map_.count(address) == 1;
106 }
107
ReadCachedRemoteName(hci::Address address) const108 RemoteName neighbor::NameDbModule::impl::ReadCachedRemoteName(hci::Address address) const {
109 ASSERT(IsNameCached(address));
110 return address_to_name_map_.at(address);
111 }
112
113 /**
114 * General API here
115 */
NameDbModule()116 neighbor::NameDbModule::NameDbModule() : pimpl_(std::make_unique<impl>(*this)) {}
117
~NameDbModule()118 neighbor::NameDbModule::~NameDbModule() {
119 pimpl_.reset();
120 }
121
ReadRemoteNameRequest(hci::Address address,ReadRemoteNameDbCallback callback,os::Handler * handler)122 void neighbor::NameDbModule::ReadRemoteNameRequest(
123 hci::Address address, ReadRemoteNameDbCallback callback, os::Handler* handler) {
124 GetHandler()->Post(common::BindOnce(
125 &NameDbModule::impl::ReadRemoteNameRequest,
126 common::Unretained(pimpl_.get()),
127 address,
128 std::move(callback),
129 handler));
130 }
131
IsNameCached(hci::Address address) const132 bool neighbor::NameDbModule::IsNameCached(hci::Address address) const {
133 return pimpl_->IsNameCached(address);
134 }
135
ReadCachedRemoteName(hci::Address address) const136 RemoteName neighbor::NameDbModule::ReadCachedRemoteName(hci::Address address) const {
137 return pimpl_->ReadCachedRemoteName(address);
138 }
139
Start()140 void neighbor::NameDbModule::impl::Start() {
141 name_module_ = module_.GetDependency<neighbor::NameModule>();
142 handler_ = module_.GetHandler();
143 }
144
Stop()145 void neighbor::NameDbModule::impl::Stop() {}
146
147 /**
148 * Module methods here
149 */
ListDependencies(ModuleList * list)150 void neighbor::NameDbModule::ListDependencies(ModuleList* list) {
151 list->add<neighbor::NameModule>();
152 }
153
Start()154 void neighbor::NameDbModule::Start() {
155 pimpl_->Start();
156 }
157
Stop()158 void neighbor::NameDbModule::Stop() {
159 pimpl_->Stop();
160 }
161
162 } // namespace neighbor
163 } // namespace bluetooth
164