1 /*
2 * Copyright 2019 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.h"
19
20 #include <memory>
21 #include <unordered_map>
22 #include <utility>
23
24 #include "common/bind.h"
25 #include "hci/hci_layer.h"
26 #include "hci/hci_packets.h"
27 #include "module.h"
28 #include "os/handler.h"
29 #include "os/log.h"
30
31 namespace bluetooth {
32 namespace neighbor {
33
34 struct ReadCallbackHandler {
35 ReadRemoteNameCallback callback;
36 os::Handler* handler;
37 };
38
39 struct CancelCallbackHandler {
40 CancelRemoteNameCallback callback;
41 os::Handler* handler;
42 };
43
44 constexpr RemoteName kEmptyName{};
45
46 struct NameModule::impl {
47 void ReadRemoteNameRequest(
48 hci::Address address,
49 hci::PageScanRepetitionMode page_scan_repetition_mode,
50 uint16_t clock_offset,
51 hci::ClockOffsetValid clock_offset_valid,
52 ReadRemoteNameCallback callback,
53 os::Handler* handler);
54 void CancelRemoteNameRequest(hci::Address address, CancelRemoteNameCallback, os::Handler* handler);
55
56 void Start();
57 void Stop();
58
59 impl(const NameModule& name_module);
60
61 private:
62 const NameModule& module_;
63
64 void EnqueueCommandComplete(std::unique_ptr<hci::CommandBuilder> command);
65 void EnqueueCommandStatus(std::unique_ptr<hci::CommandBuilder> command);
66
67 void OnCommandComplete(hci::CommandCompleteView view);
68 void OnCommandStatus(hci::CommandStatusView status);
69 void OnEvent(hci::EventView view);
70
71 std::unordered_map<hci::Address, std::unique_ptr<ReadCallbackHandler>> read_callback_handler_map_;
72 std::unordered_map<hci::Address, std::unique_ptr<CancelCallbackHandler>> cancel_callback_handler_map_;
73
74 hci::HciLayer* hci_layer_;
75 os::Handler* handler_;
76 };
77
__anon3cee2eab0102() 78 const ModuleFactory neighbor::NameModule::Factory = ModuleFactory([]() { return new neighbor::NameModule(); });
79
impl(const neighbor::NameModule & module)80 neighbor::NameModule::impl::impl(const neighbor::NameModule& module) : module_(module) {}
81
EnqueueCommandComplete(std::unique_ptr<hci::CommandBuilder> command)82 void neighbor::NameModule::impl::EnqueueCommandComplete(std::unique_ptr<hci::CommandBuilder> command) {
83 hci_layer_->EnqueueCommand(std::move(command), handler_->BindOnceOn(this, &impl::OnCommandComplete));
84 }
85
EnqueueCommandStatus(std::unique_ptr<hci::CommandBuilder> command)86 void neighbor::NameModule::impl::EnqueueCommandStatus(std::unique_ptr<hci::CommandBuilder> command) {
87 hci_layer_->EnqueueCommand(std::move(command), handler_->BindOnceOn(this, &impl::OnCommandStatus));
88 }
89
OnCommandComplete(hci::CommandCompleteView view)90 void neighbor::NameModule::impl::OnCommandComplete(hci::CommandCompleteView view) {
91 switch (view.GetCommandOpCode()) {
92 case hci::OpCode::REMOTE_NAME_REQUEST_CANCEL: {
93 auto packet = hci::RemoteNameRequestCancelCompleteView::Create(view);
94 ASSERT(packet.IsValid());
95 ASSERT(packet.GetStatus() == hci::ErrorCode::SUCCESS);
96 hci::Address address = packet.GetBdAddr();
97 ASSERT(cancel_callback_handler_map_.find(address) != cancel_callback_handler_map_.end());
98 cancel_callback_handler_map_.erase(address);
99 } break;
100 default:
101 LOG_WARN("Unhandled command:%s", hci::OpCodeText(view.GetCommandOpCode()).c_str());
102 break;
103 }
104 }
105
OnCommandStatus(hci::CommandStatusView status)106 void neighbor::NameModule::impl::OnCommandStatus(hci::CommandStatusView status) {
107 ASSERT(status.GetStatus() == hci::ErrorCode::SUCCESS);
108
109 switch (status.GetCommandOpCode()) {
110 case hci::OpCode::REMOTE_NAME_REQUEST: {
111 auto packet = hci::RemoteNameRequestStatusView::Create(status);
112 ASSERT(packet.IsValid());
113 } break;
114
115 default:
116 LOG_WARN("Unhandled command:%s", hci::OpCodeText(status.GetCommandOpCode()).c_str());
117 break;
118 }
119 }
120
OnEvent(hci::EventView view)121 void neighbor::NameModule::impl::OnEvent(hci::EventView view) {
122 switch (view.GetEventCode()) {
123 case hci::EventCode::REMOTE_NAME_REQUEST_COMPLETE: {
124 auto packet = hci::RemoteNameRequestCompleteView::Create(view);
125 ASSERT(packet.IsValid());
126 hci::Address address = packet.GetBdAddr();
127 ASSERT(read_callback_handler_map_.find(address) != read_callback_handler_map_.end());
128 auto read_callback_handler = std::move(read_callback_handler_map_[address]);
129 read_callback_handler->handler->Post(common::BindOnce(
130 std::move(read_callback_handler->callback), packet.GetStatus(), address, packet.GetRemoteName()));
131 read_callback_handler_map_.erase(address);
132 } break;
133 default:
134 LOG_ERROR("Unhandled event:%s", hci::EventCodeText(view.GetEventCode()).c_str());
135 break;
136 }
137 }
138
Start()139 void neighbor::NameModule::impl::Start() {
140 hci_layer_ = module_.GetDependency<hci::HciLayer>();
141 handler_ = module_.GetHandler();
142
143 hci_layer_->RegisterEventHandler(
144 hci::EventCode::REMOTE_NAME_REQUEST_COMPLETE, handler_->BindOn(this, &NameModule::impl::OnEvent));
145 }
146
Stop()147 void neighbor::NameModule::impl::Stop() {
148 hci_layer_->UnregisterEventHandler(hci::EventCode::REMOTE_NAME_REQUEST_COMPLETE);
149 }
150
ReadRemoteNameRequest(hci::Address address,hci::PageScanRepetitionMode page_scan_repetition_mode,uint16_t clock_offset,hci::ClockOffsetValid clock_offset_valid,ReadRemoteNameCallback callback,os::Handler * handler)151 void neighbor::NameModule::impl::ReadRemoteNameRequest(
152 hci::Address address,
153 hci::PageScanRepetitionMode page_scan_repetition_mode,
154 uint16_t clock_offset,
155 hci::ClockOffsetValid clock_offset_valid,
156 ReadRemoteNameCallback callback,
157 os::Handler* handler) {
158 LOG_INFO("%s Start read remote name request for %s", __func__, address.ToString().c_str());
159
160 if (read_callback_handler_map_.find(address) != read_callback_handler_map_.end()) {
161 LOG_WARN("Ignoring duplicate read remote name request to:%s", address.ToString().c_str());
162 handler->Post(common::BindOnce(std::move(callback), hci::ErrorCode::UNSPECIFIED_ERROR, address, kEmptyName));
163 return;
164 }
165 read_callback_handler_map_[address] = std::unique_ptr<ReadCallbackHandler>(new ReadCallbackHandler{
166 .callback = std::move(callback),
167 .handler = handler,
168 });
169
170 EnqueueCommandStatus(
171 hci::RemoteNameRequestBuilder::Create(address, page_scan_repetition_mode, clock_offset, clock_offset_valid));
172 }
173
CancelRemoteNameRequest(hci::Address address,CancelRemoteNameCallback callback,os::Handler * handler)174 void neighbor::NameModule::impl::CancelRemoteNameRequest(
175 hci::Address address, CancelRemoteNameCallback callback, os::Handler* handler) {
176 LOG_INFO("%s Cancel remote name request for %s", __func__, address.ToString().c_str());
177
178 if (cancel_callback_handler_map_.find(address) != cancel_callback_handler_map_.end()) {
179 LOG_WARN("Ignoring duplicate cancel remote name request to:%s", address.ToString().c_str());
180 handler->Post(common::BindOnce(std::move(callback), hci::ErrorCode::UNSPECIFIED_ERROR, address));
181 return;
182 }
183 cancel_callback_handler_map_[address] = std::unique_ptr<CancelCallbackHandler>(new CancelCallbackHandler{
184 .callback = std::move(callback),
185 .handler = handler,
186 });
187 EnqueueCommandComplete(hci::RemoteNameRequestCancelBuilder::Create(address));
188 }
189
190 /**
191 * General API here
192 */
NameModule()193 neighbor::NameModule::NameModule() : pimpl_(std::make_unique<impl>(*this)) {}
194
~NameModule()195 neighbor::NameModule::~NameModule() {
196 pimpl_.reset();
197 }
198
ReadRemoteNameRequest(hci::Address address,hci::PageScanRepetitionMode page_scan_repetition_mode,uint16_t clock_offset,hci::ClockOffsetValid clock_offset_valid,ReadRemoteNameCallback callback,os::Handler * handler)199 void neighbor::NameModule::ReadRemoteNameRequest(
200 hci::Address address,
201 hci::PageScanRepetitionMode page_scan_repetition_mode,
202 uint16_t clock_offset,
203 hci::ClockOffsetValid clock_offset_valid,
204 ReadRemoteNameCallback callback,
205 os::Handler* handler) {
206 ASSERT(callback);
207 ASSERT(handler != nullptr);
208 GetHandler()->Post(common::BindOnce(
209 &NameModule::impl::ReadRemoteNameRequest,
210 common::Unretained(pimpl_.get()),
211 address,
212 page_scan_repetition_mode,
213 clock_offset,
214 clock_offset_valid,
215 std::move(callback),
216 handler));
217 }
218
CancelRemoteNameRequest(hci::Address address,CancelRemoteNameCallback callback,os::Handler * handler)219 void neighbor::NameModule::CancelRemoteNameRequest(
220 hci::Address address, CancelRemoteNameCallback callback, os::Handler* handler) {
221 ASSERT(callback);
222 ASSERT(handler != nullptr);
223 GetHandler()->Post(common::BindOnce(
224 &NameModule::impl::CancelRemoteNameRequest,
225 common::Unretained(pimpl_.get()),
226 address,
227 std::move(callback),
228 handler));
229 }
230
231 /**
232 * Module methods here
233 */
ListDependencies(ModuleList * list)234 void neighbor::NameModule::ListDependencies(ModuleList* list) {
235 list->add<hci::HciLayer>();
236 }
237
Start()238 void neighbor::NameModule::Start() {
239 pimpl_->Start();
240 }
241
Stop()242 void neighbor::NameModule::Stop() {
243 pimpl_->Stop();
244 }
245
246 } // namespace neighbor
247 } // namespace bluetooth
248