• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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