• 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(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