• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "hci/hci_packets.h"
26 #include "hci/remote_name_request.h"
27 #include "module.h"
28 #include "os/handler.h"
29 #include "os/log.h"
30 
31 namespace bluetooth {
32 namespace neighbor {
33 
34 namespace {
35 struct PendingRemoteNameRead {
36   ReadRemoteNameDbCallback callback_;
37   os::Handler* handler_;
38 };
39 }  // namespace
40 
41 struct NameDbModule::impl {
42   void ReadRemoteNameRequest(
43       hci::Address address, ReadRemoteNameDbCallback callback, os::Handler* handler);
44 
45   bool IsNameCached(hci::Address address) const;
46   RemoteName ReadCachedRemoteName(hci::Address address) const;
47 
48   impl(const NameDbModule& module);
49 
50   void Start();
51   void Stop();
52 
53  private:
54   std::unordered_map<hci::Address, std::list<PendingRemoteNameRead>> address_to_pending_read_map_;
55   std::unordered_map<hci::Address, RemoteName> address_to_name_map_;
56 
57   void OnRemoteNameResponse(hci::Address address, hci::ErrorCode status, RemoteName name);
58 
59   hci::RemoteNameRequestModule* name_module_;
60 
61   const NameDbModule& module_;
62   os::Handler* handler_;
63 };
64 
65 const ModuleFactory neighbor::NameDbModule::Factory =
__anon709e61440202() 66     ModuleFactory([]() { return new neighbor::NameDbModule(); });
67 
impl(const neighbor::NameDbModule & module)68 neighbor::NameDbModule::impl::impl(const neighbor::NameDbModule& module) : module_(module) {}
69 
ReadRemoteNameRequest(hci::Address address,ReadRemoteNameDbCallback callback,os::Handler * handler)70 void neighbor::NameDbModule::impl::ReadRemoteNameRequest(
71     hci::Address address, ReadRemoteNameDbCallback callback, os::Handler* handler) {
72   if (address_to_pending_read_map_.find(address) != address_to_pending_read_map_.end()) {
73     LOG_WARN("Already have remote read db in progress; adding callback to callback list");
74     address_to_pending_read_map_[address].push_back({std::move(callback), handler});
75     return;
76   }
77 
78   std::list<PendingRemoteNameRead> tmp;
79   address_to_pending_read_map_[address] = std::move(tmp);
80   address_to_pending_read_map_[address].push_back({std::move(callback), handler});
81 
82   // TODO(cmanton) Use remote name request defaults for now
83   hci::PageScanRepetitionMode page_scan_repetition_mode = hci::PageScanRepetitionMode::R1;
84   uint16_t clock_offset = 0;
85   hci::ClockOffsetValid clock_offset_valid = hci::ClockOffsetValid::INVALID;
86   name_module_->StartRemoteNameRequest(
87       address,
88       hci::RemoteNameRequestBuilder::Create(
89           address, page_scan_repetition_mode, clock_offset, clock_offset_valid),
90       handler_->BindOnce(
91           [](neighbor::NameDbModule::impl* self, hci::Address address, hci::ErrorCode status) {
92             self->OnRemoteNameResponse(address, status, {});
93           },
94           common::Unretained(this),
95           address),
96       handler_->BindOnce(
97           [&](uint64_t features) { LOG_WARN("UNIMPLEMENTED: ignoring host supported features"); }),
98       handler_->BindOnceOn(this, &NameDbModule::impl::OnRemoteNameResponse, address));
99 }
100 
OnRemoteNameResponse(hci::Address address,hci::ErrorCode status,RemoteName name)101 void neighbor::NameDbModule::impl::OnRemoteNameResponse(
102     hci::Address address, hci::ErrorCode status, RemoteName name) {
103   ASSERT(address_to_pending_read_map_.find(address) != address_to_pending_read_map_.end());
104   if (status == hci::ErrorCode::SUCCESS) {
105     address_to_name_map_[address] = name;
106   }
107   auto& callback_list = address_to_pending_read_map_.at(address);
108   for (auto& it : callback_list) {
109     it.handler_->Call(std::move(it.callback_), address, status == hci::ErrorCode::SUCCESS);
110   }
111   address_to_pending_read_map_.erase(address);
112 }
113 
IsNameCached(hci::Address address) const114 bool neighbor::NameDbModule::impl::IsNameCached(hci::Address address) const {
115   return address_to_name_map_.count(address) == 1;
116 }
117 
ReadCachedRemoteName(hci::Address address) const118 RemoteName neighbor::NameDbModule::impl::ReadCachedRemoteName(hci::Address address) const {
119   ASSERT(IsNameCached(address));
120   return address_to_name_map_.at(address);
121 }
122 
123 /**
124  * General API here
125  */
NameDbModule()126 neighbor::NameDbModule::NameDbModule() : pimpl_(std::make_unique<impl>(*this)) {}
127 
~NameDbModule()128 neighbor::NameDbModule::~NameDbModule() {
129   pimpl_.reset();
130 }
131 
ReadRemoteNameRequest(hci::Address address,ReadRemoteNameDbCallback callback,os::Handler * handler)132 void neighbor::NameDbModule::ReadRemoteNameRequest(
133     hci::Address address, ReadRemoteNameDbCallback callback, os::Handler* handler) {
134   GetHandler()->Post(common::BindOnce(
135       &NameDbModule::impl::ReadRemoteNameRequest,
136       common::Unretained(pimpl_.get()),
137       address,
138       std::move(callback),
139       handler));
140 }
141 
IsNameCached(hci::Address address) const142 bool neighbor::NameDbModule::IsNameCached(hci::Address address) const {
143   return pimpl_->IsNameCached(address);
144 }
145 
ReadCachedRemoteName(hci::Address address) const146 RemoteName neighbor::NameDbModule::ReadCachedRemoteName(hci::Address address) const {
147   return pimpl_->ReadCachedRemoteName(address);
148 }
149 
Start()150 void neighbor::NameDbModule::impl::Start() {
151   name_module_ = module_.GetDependency<hci::RemoteNameRequestModule>();
152   handler_ = module_.GetHandler();
153 }
154 
Stop()155 void neighbor::NameDbModule::impl::Stop() {}
156 
157 /**
158  * Module methods here
159  */
ListDependencies(ModuleList * list) const160 void neighbor::NameDbModule::ListDependencies(ModuleList* list) const {
161   list->add<hci::RemoteNameRequestModule>();
162 }
163 
Start()164 void neighbor::NameDbModule::Start() {
165   pimpl_->Start();
166 }
167 
Stop()168 void neighbor::NameDbModule::Stop() {
169   pimpl_->Stop();
170 }
171 
172 }  // namespace neighbor
173 }  // namespace bluetooth
174