• 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 
17 #include "hci/acl_manager.h"
18 
19 #include <atomic>
20 #include <future>
21 #include <mutex>
22 #include <set>
23 
24 #include "common/bidi_queue.h"
25 #include "hci/acl_manager/classic_impl.h"
26 #include "hci/acl_manager/connection_management_callbacks.h"
27 #include "hci/acl_manager/le_acl_connection.h"
28 #include "hci/acl_manager/le_impl.h"
29 #include "hci/acl_manager/round_robin_scheduler.h"
30 #include "hci/controller.h"
31 #include "hci/hci_layer.h"
32 #include "hci_acl_manager_generated.h"
33 #include "security/security_module.h"
34 #include "storage/storage_module.h"
35 
36 namespace bluetooth {
37 namespace hci {
38 
39 constexpr uint16_t kQualcommDebugHandle = 0xedc;
40 
41 using acl_manager::AclConnection;
42 using common::Bind;
43 using common::BindOnce;
44 
45 using acl_manager::classic_impl;
46 using acl_manager::ClassicAclConnection;
47 using acl_manager::ConnectionCallbacks;
48 
49 using acl_manager::le_impl;
50 using acl_manager::LeAclConnection;
51 using acl_manager::LeConnectionCallbacks;
52 
53 using acl_manager::RoundRobinScheduler;
54 
55 struct AclManager::impl {
implbluetooth::hci::AclManager::impl56   impl(const AclManager& acl_manager) : acl_manager_(acl_manager) {}
57 
Startbluetooth::hci::AclManager::impl58   void Start() {
59     hci_layer_ = acl_manager_.GetDependency<HciLayer>();
60     handler_ = acl_manager_.GetHandler();
61     controller_ = acl_manager_.GetDependency<Controller>();
62     round_robin_scheduler_ = new RoundRobinScheduler(handler_, controller_, hci_layer_->GetAclQueueEnd());
63 
64     hci_queue_end_ = hci_layer_->GetAclQueueEnd();
65     hci_queue_end_->RegisterDequeue(
66         handler_, common::Bind(&impl::dequeue_and_route_acl_packet_to_connection, common::Unretained(this)));
67     bool crash_on_unknown_handle = false;
68     {
69       const std::lock_guard<std::mutex> lock(dumpsys_mutex_);
70       classic_impl_ =
71           new classic_impl(hci_layer_, controller_, handler_, round_robin_scheduler_, crash_on_unknown_handle);
72       le_impl_ = new le_impl(hci_layer_, controller_, handler_, round_robin_scheduler_, crash_on_unknown_handle);
73     }
74   }
75 
Stopbluetooth::hci::AclManager::impl76   void Stop() {
77     {
78       const std::lock_guard<std::mutex> lock(dumpsys_mutex_);
79       delete le_impl_;
80       delete classic_impl_;
81       le_impl_ = nullptr;
82       classic_impl_ = nullptr;
83     }
84 
85     hci_queue_end_->UnregisterDequeue();
86     delete round_robin_scheduler_;
87     if (enqueue_registered_.exchange(false)) {
88       hci_queue_end_->UnregisterEnqueue();
89     }
90     hci_queue_end_ = nullptr;
91     handler_ = nullptr;
92     hci_layer_ = nullptr;
93   }
94 
95   // Invoked from some external Queue Reactable context 2
dequeue_and_route_acl_packet_to_connectionbluetooth::hci::AclManager::impl96   void dequeue_and_route_acl_packet_to_connection() {
97     auto packet = hci_queue_end_->TryDequeue();
98     ASSERT(packet != nullptr);
99     if (!packet->IsValid()) {
100       LOG_INFO("Dropping invalid packet of size %zu", packet->size());
101       return;
102     }
103     uint16_t handle = packet->GetHandle();
104     if (handle == kQualcommDebugHandle) return;
105     if (classic_impl_->send_packet_upward(
106             handle, [&packet](struct acl_manager::assembler* assembler) { assembler->on_incoming_packet(*packet); }))
107       return;
108     if (le_impl_->send_packet_upward(
109             handle, [&packet](struct acl_manager::assembler* assembler) { assembler->on_incoming_packet(*packet); }))
110       return;
111     LOG_INFO("Dropping packet of size %zu to unknown connection 0x%0hx", packet->size(), packet->GetHandle());
112   }
113 
114   void Dump(
115       std::promise<flatbuffers::Offset<AclManagerData>> promise, flatbuffers::FlatBufferBuilder* fb_builder) const;
116 
117   const AclManager& acl_manager_;
118 
119   classic_impl* classic_impl_ = nullptr;
120   le_impl* le_impl_ = nullptr;
121   os::Handler* handler_ = nullptr;
122   Controller* controller_ = nullptr;
123   HciLayer* hci_layer_ = nullptr;
124   RoundRobinScheduler* round_robin_scheduler_ = nullptr;
125   common::BidiQueueEnd<AclBuilder, AclView>* hci_queue_end_ = nullptr;
126   std::atomic_bool enqueue_registered_ = false;
127   uint16_t default_link_policy_settings_ = 0xffff;
128   mutable std::mutex dumpsys_mutex_;
129 };
130 
AclManager()131 AclManager::AclManager() : pimpl_(std::make_unique<impl>(*this)) {}
132 
RegisterCallbacks(ConnectionCallbacks * callbacks,os::Handler * handler)133 void AclManager::RegisterCallbacks(ConnectionCallbacks* callbacks, os::Handler* handler) {
134   ASSERT(callbacks != nullptr && handler != nullptr);
135   GetHandler()->Post(common::BindOnce(&classic_impl::handle_register_callbacks,
136                                       common::Unretained(pimpl_->classic_impl_), common::Unretained(callbacks),
137                                       common::Unretained(handler)));
138 }
139 
UnregisterCallbacks(ConnectionCallbacks * callbacks,std::promise<void> promise)140 void AclManager::UnregisterCallbacks(ConnectionCallbacks* callbacks, std::promise<void> promise) {
141   ASSERT(callbacks != nullptr);
142   CallOn(
143       pimpl_->classic_impl_,
144       &classic_impl::handle_unregister_callbacks,
145       common::Unretained(callbacks),
146       std::move(promise));
147 }
148 
RegisterLeCallbacks(LeConnectionCallbacks * callbacks,os::Handler * handler)149 void AclManager::RegisterLeCallbacks(LeConnectionCallbacks* callbacks, os::Handler* handler) {
150   ASSERT(callbacks != nullptr && handler != nullptr);
151   CallOn(
152       pimpl_->le_impl_,
153       &le_impl::handle_register_le_callbacks,
154       common::Unretained(callbacks),
155       common::Unretained(handler));
156 }
157 
UnregisterLeCallbacks(LeConnectionCallbacks * callbacks,std::promise<void> promise)158 void AclManager::UnregisterLeCallbacks(LeConnectionCallbacks* callbacks, std::promise<void> promise) {
159   ASSERT(callbacks != nullptr);
160   CallOn(pimpl_->le_impl_, &le_impl::handle_unregister_le_callbacks, common::Unretained(callbacks), std::move(promise));
161 }
162 
CreateConnection(Address address)163 void AclManager::CreateConnection(Address address) {
164   CallOn(pimpl_->classic_impl_, &classic_impl::create_connection, address);
165 }
166 
CreateLeConnection(AddressWithType address_with_type,bool is_direct)167 void AclManager::CreateLeConnection(AddressWithType address_with_type, bool is_direct) {
168   if (!is_direct) {
169     CallOn(pimpl_->le_impl_, &le_impl::add_device_to_background_connection_list, address_with_type);
170   }
171   CallOn(pimpl_->le_impl_, &le_impl::create_le_connection, address_with_type, true, is_direct);
172 }
173 
IsOnBackgroundList(AddressWithType address_with_type,std::promise<bool> promise)174 void AclManager::IsOnBackgroundList(AddressWithType address_with_type, std::promise<bool> promise) {
175   CallOn(pimpl_->le_impl_, &le_impl::is_on_background_connection_list, address_with_type, std::move(promise));
176 }
177 
SetLeSuggestedDefaultDataParameters(uint16_t octets,uint16_t time)178 void AclManager::SetLeSuggestedDefaultDataParameters(uint16_t octets, uint16_t time) {
179   CallOn(pimpl_->le_impl_, &le_impl::set_le_suggested_default_data_parameters, octets, time);
180 }
181 
SetPrivacyPolicyForInitiatorAddress(LeAddressManager::AddressPolicy address_policy,AddressWithType fixed_address,std::chrono::milliseconds minimum_rotation_time,std::chrono::milliseconds maximum_rotation_time)182 void AclManager::SetPrivacyPolicyForInitiatorAddress(
183     LeAddressManager::AddressPolicy address_policy,
184     AddressWithType fixed_address,
185     std::chrono::milliseconds minimum_rotation_time,
186     std::chrono::milliseconds maximum_rotation_time) {
187   crypto_toolbox::Octet16 rotation_irk{};
188   auto irk = GetDependency<storage::StorageModule>()->GetAdapterConfig().GetLeIdentityResolvingKey();
189   if (irk.has_value()) {
190     rotation_irk = irk->bytes;
191   }
192   CallOn(
193       pimpl_->le_impl_,
194       &le_impl::set_privacy_policy_for_initiator_address,
195       address_policy,
196       fixed_address,
197       rotation_irk,
198       minimum_rotation_time,
199       maximum_rotation_time);
200 }
201 
202 // TODO(jpawlowski): remove once we have config file abstraction in cert tests
SetPrivacyPolicyForInitiatorAddressForTest(LeAddressManager::AddressPolicy address_policy,AddressWithType fixed_address,crypto_toolbox::Octet16 rotation_irk,std::chrono::milliseconds minimum_rotation_time,std::chrono::milliseconds maximum_rotation_time)203 void AclManager::SetPrivacyPolicyForInitiatorAddressForTest(
204     LeAddressManager::AddressPolicy address_policy,
205     AddressWithType fixed_address,
206     crypto_toolbox::Octet16 rotation_irk,
207     std::chrono::milliseconds minimum_rotation_time,
208     std::chrono::milliseconds maximum_rotation_time) {
209   CallOn(
210       pimpl_->le_impl_,
211       &le_impl::set_privacy_policy_for_initiator_address_for_test,
212       address_policy,
213       fixed_address,
214       rotation_irk,
215       minimum_rotation_time,
216       maximum_rotation_time);
217 }
218 
CancelConnect(Address address)219 void AclManager::CancelConnect(Address address) {
220   CallOn(pimpl_->classic_impl_, &classic_impl::cancel_connect, address);
221 }
222 
CancelLeConnect(AddressWithType address_with_type)223 void AclManager::CancelLeConnect(AddressWithType address_with_type) {
224   CallOn(pimpl_->le_impl_, &le_impl::remove_device_from_background_connection_list, address_with_type);
225   CallOn(pimpl_->le_impl_, &le_impl::cancel_connect, address_with_type);
226 }
227 
RemoveFromBackgroundList(AddressWithType address_with_type)228 void AclManager::RemoveFromBackgroundList(AddressWithType address_with_type) {
229   CallOn(pimpl_->le_impl_, &le_impl::remove_device_from_background_connection_list, address_with_type);
230 }
231 
CancelLeConnectAndRemoveFromBackgroundList(AddressWithType address_with_type)232 void AclManager::CancelLeConnectAndRemoveFromBackgroundList(AddressWithType address_with_type) {
233   CallOn(
234       pimpl_->le_impl_,
235       &le_impl::cancel_connection_and_remove_device_from_background_connection_list,
236       address_with_type);
237 }
238 
AddDeviceToFilterAcceptList(AddressWithType address_with_type)239 void AclManager::AddDeviceToFilterAcceptList(AddressWithType address_with_type) {
240   CallOn(pimpl_->le_impl_, &le_impl::add_device_to_connect_list, address_with_type);
241 }
242 
RemoveDeviceFromFilterAcceptList(AddressWithType address_with_type)243 void AclManager::RemoveDeviceFromFilterAcceptList(AddressWithType address_with_type) {
244   CallOn(pimpl_->le_impl_, &le_impl::remove_device_from_connect_list, address_with_type);
245 }
246 
ClearFilterAcceptList()247 void AclManager::ClearFilterAcceptList() {
248   CallOn(pimpl_->le_impl_, &le_impl::clear_connect_list);
249 }
250 
AddDeviceToResolvingList(AddressWithType address_with_type,const std::array<uint8_t,16> & peer_irk,const std::array<uint8_t,16> & local_irk)251 void AclManager::AddDeviceToResolvingList(
252     AddressWithType address_with_type,
253     const std::array<uint8_t, 16>& peer_irk,
254     const std::array<uint8_t, 16>& local_irk) {
255   CallOn(pimpl_->le_impl_, &le_impl::add_device_to_resolving_list, address_with_type, peer_irk, local_irk);
256 }
257 
RemoveDeviceFromResolvingList(AddressWithType address_with_type)258 void AclManager::RemoveDeviceFromResolvingList(AddressWithType address_with_type) {
259   CallOn(pimpl_->le_impl_, &le_impl::remove_device_from_resolving_list, address_with_type);
260 }
261 
ClearResolvingList()262 void AclManager::ClearResolvingList() {
263   CallOn(pimpl_->le_impl_, &le_impl::clear_resolving_list);
264 }
265 
CentralLinkKey(KeyFlag key_flag)266 void AclManager::CentralLinkKey(KeyFlag key_flag) {
267   CallOn(pimpl_->classic_impl_, &classic_impl::central_link_key, key_flag);
268 }
269 
SwitchRole(Address address,Role role)270 void AclManager::SwitchRole(Address address, Role role) {
271   CallOn(pimpl_->classic_impl_, &classic_impl::switch_role, address, role);
272 }
273 
ReadDefaultLinkPolicySettings()274 uint16_t AclManager::ReadDefaultLinkPolicySettings() {
275   ASSERT_LOG(pimpl_->default_link_policy_settings_ != 0xffff, "Settings were never written");
276   return pimpl_->default_link_policy_settings_;
277 }
278 
WriteDefaultLinkPolicySettings(uint16_t default_link_policy_settings)279 void AclManager::WriteDefaultLinkPolicySettings(uint16_t default_link_policy_settings) {
280   pimpl_->default_link_policy_settings_ = default_link_policy_settings;
281   CallOn(pimpl_->classic_impl_, &classic_impl::write_default_link_policy_settings, default_link_policy_settings);
282 }
283 
OnAdvertisingSetTerminated(ErrorCode status,uint16_t conn_handle,hci::AddressWithType adv_address)284 void AclManager::OnAdvertisingSetTerminated(ErrorCode status, uint16_t conn_handle, hci::AddressWithType adv_address) {
285   if (status == ErrorCode::SUCCESS) {
286     CallOn(pimpl_->le_impl_, &le_impl::UpdateLocalAddress, conn_handle, adv_address);
287   }
288 }
289 
SetSecurityModule(security::SecurityModule * security_module)290 void AclManager::SetSecurityModule(security::SecurityModule* security_module) {
291   CallOn(pimpl_->classic_impl_, &classic_impl::set_security_module, security_module);
292 }
293 
GetLeAddressManager()294 LeAddressManager* AclManager::GetLeAddressManager() {
295   return pimpl_->le_impl_->le_address_manager_;
296 }
297 
HACK_GetHandle(Address address)298 uint16_t AclManager::HACK_GetHandle(Address address) {
299   return pimpl_->classic_impl_->HACK_get_handle(address);
300 }
301 
HACK_GetLeHandle(Address address)302 uint16_t AclManager::HACK_GetLeHandle(Address address) {
303   return pimpl_->le_impl_->HACK_get_handle(address);
304 }
305 
HACK_SetNonAclDisconnectCallback(std::function<void (uint16_t,uint8_t)> callback)306 void AclManager::HACK_SetNonAclDisconnectCallback(std::function<void(uint16_t, uint8_t)> callback) {
307   pimpl_->classic_impl_->HACK_SetNonAclDisconnectCallback(callback);
308 }
309 
HACK_SetAclTxPriority(uint8_t handle,bool high_priority)310 void AclManager::HACK_SetAclTxPriority(uint8_t handle, bool high_priority) {
311   CallOn(pimpl_->round_robin_scheduler_, &RoundRobinScheduler::SetLinkPriority, handle, high_priority);
312 }
313 
ListDependencies(ModuleList * list) const314 void AclManager::ListDependencies(ModuleList* list) const {
315   list->add<HciLayer>();
316   list->add<Controller>();
317   list->add<storage::StorageModule>();
318 }
319 
Start()320 void AclManager::Start() {
321   pimpl_->Start();
322 }
323 
Stop()324 void AclManager::Stop() {
325   pimpl_->Stop();
326 }
327 
ToString() const328 std::string AclManager::ToString() const {
329   return "Acl Manager";
330 }
331 
__anon74692b350302() 332 const ModuleFactory AclManager::Factory = ModuleFactory([]() { return new AclManager(); });
333 
334 AclManager::~AclManager() = default;
335 
Dump(std::promise<flatbuffers::Offset<AclManagerData>> promise,flatbuffers::FlatBufferBuilder * fb_builder) const336 void AclManager::impl::Dump(
337     std::promise<flatbuffers::Offset<AclManagerData>> promise, flatbuffers::FlatBufferBuilder* fb_builder) const {
338   const std::lock_guard<std::mutex> lock(dumpsys_mutex_);
339   const auto connect_list = (le_impl_ != nullptr) ? le_impl_->connect_list : std::unordered_set<AddressWithType>();
340   const auto le_connectability_state_text =
341       (le_impl_ != nullptr) ? connectability_state_machine_text(le_impl_->connectability_state_) : "INDETERMINATE";
342   const auto le_create_connection_timeout_alarms_count =
343       (le_impl_ != nullptr) ? (int)le_impl_->create_connection_timeout_alarms_.size() : 0;
344 
345   auto title = fb_builder->CreateString("----- Acl Manager Dumpsys -----");
346   auto le_connectability_state = fb_builder->CreateString(le_connectability_state_text);
347 
348   flatbuffers::Offset<flatbuffers::String> strings[connect_list.size()];
349 
350   size_t cnt = 0;
351   for (const auto& it : connect_list) {
352     strings[cnt++] = fb_builder->CreateString(it.ToString());
353   }
354   auto vecofstrings = fb_builder->CreateVector(strings, connect_list.size());
355 
356   AclManagerDataBuilder builder(*fb_builder);
357   builder.add_title(title);
358   builder.add_le_filter_accept_list_count(connect_list.size());
359   builder.add_le_filter_accept_list(vecofstrings);
360   builder.add_le_connectability_state(le_connectability_state);
361   builder.add_le_create_connection_timeout_alarms_count(le_create_connection_timeout_alarms_count);
362 
363   flatbuffers::Offset<AclManagerData> dumpsys_data = builder.Finish();
364   promise.set_value(dumpsys_data);
365 }
366 
GetDumpsysData(flatbuffers::FlatBufferBuilder * fb_builder) const367 DumpsysDataFinisher AclManager::GetDumpsysData(flatbuffers::FlatBufferBuilder* fb_builder) const {
368   ASSERT(fb_builder != nullptr);
369 
370   std::promise<flatbuffers::Offset<AclManagerData>> promise;
371   auto future = promise.get_future();
372   pimpl_->Dump(std::move(promise), fb_builder);
373 
374   auto dumpsys_data = future.get();
375 
376   return [dumpsys_data](DumpsysDataBuilder* dumpsys_builder) {
377     dumpsys_builder->add_hci_acl_manager_dumpsys_data(dumpsys_data);
378   };
379 }
380 
381 }  // namespace hci
382 }  // namespace bluetooth
383