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