• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 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 <bluetooth/log.h>
20 
21 #include <atomic>
22 #include <format>
23 #include <future>
24 #include <mutex>
25 #include <string>
26 #include <unordered_set>
27 #include <utility>
28 #include <vector>
29 
30 #include "common/bidi_queue.h"
31 #include "common/byte_array.h"
32 #include "hci/acl_manager/acl_scheduler.h"
33 #include "hci/acl_manager/classic_impl.h"
34 #include "hci/acl_manager/le_acceptlist_callbacks.h"
35 #include "hci/acl_manager/le_acl_connection.h"
36 #include "hci/acl_manager/le_impl.h"
37 #include "hci/acl_manager/round_robin_scheduler.h"
38 #include "hci/controller.h"
39 #include "hci/hci_layer.h"
40 #include "hci/remote_name_request.h"
41 #include "main/shim/entry.h"
42 #include "storage/config_keys.h"
43 #include "storage/storage_module.h"
44 
45 namespace bluetooth {
46 namespace hci {
47 
48 constexpr uint16_t kQualcommDebugHandle = 0xedc;
49 constexpr uint16_t kSamsungDebugHandle = 0xeef;
50 
51 using acl_manager::AclConnection;
52 using common::Bind;
53 using common::BindOnce;
54 
55 using acl_manager::classic_impl;
56 using acl_manager::ClassicAclConnection;
57 using acl_manager::ConnectionCallbacks;
58 
59 using acl_manager::le_impl;
60 using acl_manager::LeAcceptlistCallbacks;
61 using acl_manager::LeAclConnection;
62 using acl_manager::LeConnectionCallbacks;
63 
64 using acl_manager::RoundRobinScheduler;
65 
66 using acl_manager::AclScheduler;
67 
68 struct AclManager::impl {
implbluetooth::hci::AclManager::impl69   explicit impl(const AclManager& acl_manager) : acl_manager_(acl_manager) {}
70 
Startbluetooth::hci::AclManager::impl71   void Start() {
72     hci_layer_ = acl_manager_.GetDependency<HciLayer>();
73     handler_ = acl_manager_.GetHandler();
74     controller_ = acl_manager_.GetDependency<Controller>();
75     round_robin_scheduler_ =
76             new RoundRobinScheduler(handler_, controller_, hci_layer_->GetAclQueueEnd());
77     acl_scheduler_ = acl_manager_.GetDependency<AclScheduler>();
78 
79     remote_name_request_module_ = acl_manager_.GetDependency<RemoteNameRequestModule>();
80 
81     bool crash_on_unknown_handle = false;
82     {
83       const std::lock_guard<std::mutex> lock(dumpsys_mutex_);
84       classic_impl_ = new classic_impl(hci_layer_, controller_, handler_, round_robin_scheduler_,
85                                        crash_on_unknown_handle, acl_scheduler_,
86                                        remote_name_request_module_);
87       le_impl_ = new le_impl(hci_layer_, controller_, handler_, round_robin_scheduler_,
88                              crash_on_unknown_handle, classic_impl_);
89     }
90 
91     hci_queue_end_ = hci_layer_->GetAclQueueEnd();
92     hci_queue_end_->RegisterDequeue(handler_,
93                                     common::Bind(&impl::dequeue_and_route_acl_packet_to_connection,
94                                                  common::Unretained(this)));
95   }
96 
Stopbluetooth::hci::AclManager::impl97   void Stop() {
98     hci_queue_end_->UnregisterDequeue();
99     if (enqueue_registered_.exchange(false)) {
100       hci_queue_end_->UnregisterEnqueue();
101     }
102 
103     {
104       const std::lock_guard<std::mutex> lock(dumpsys_mutex_);
105       delete le_impl_;
106       delete classic_impl_;
107       le_impl_ = nullptr;
108       classic_impl_ = nullptr;
109     }
110 
111     unknown_acl_alarm_.reset();
112     waiting_packets_.clear();
113 
114     delete round_robin_scheduler_;
115     hci_queue_end_ = nullptr;
116     handler_ = nullptr;
117     hci_layer_ = nullptr;
118     acl_scheduler_ = nullptr;
119   }
120 
retry_unknown_aclbluetooth::hci::AclManager::impl121   void retry_unknown_acl(bool timed_out) {
122     std::vector<AclView> unsent_packets;
123     for (const auto& itr : waiting_packets_) {
124       auto handle = itr.GetHandle();
125       if (!classic_impl_->send_packet_upward(handle,
126                                              [itr](struct acl_manager::assembler* assembler) {
127                                                assembler->on_incoming_packet(itr);
128                                              }) &&
129           !le_impl_->send_packet_upward(handle, [itr](struct acl_manager::assembler* assembler) {
130             assembler->on_incoming_packet(itr);
131           })) {
132         if (!timed_out) {
133           unsent_packets.push_back(itr);
134         } else {
135           log::error("Dropping packet of size {} to unknown connection 0x{:x}", itr.size(),
136                      itr.GetHandle());
137         }
138       }
139     }
140     waiting_packets_ = std::move(unsent_packets);
141   }
142 
on_unknown_acl_timerbluetooth::hci::AclManager::impl143   static void on_unknown_acl_timer(struct AclManager::impl* impl) {
144     log::info("Timer fired!");
145     impl->retry_unknown_acl(/* timed_out = */ true);
146     impl->unknown_acl_alarm_.reset();
147   }
148 
149   // Invoked from some external Queue Reactable context 2
dequeue_and_route_acl_packet_to_connectionbluetooth::hci::AclManager::impl150   void dequeue_and_route_acl_packet_to_connection() {
151     // Retry any waiting packets first
152     if (!waiting_packets_.empty()) {
153       retry_unknown_acl(/* timed_out = */ false);
154     }
155 
156     auto packet = hci_queue_end_->TryDequeue();
157     log::assert_that(packet != nullptr, "assert failed: packet != nullptr");
158     if (!packet->IsValid()) {
159       log::info("Dropping invalid packet of size {}", packet->size());
160       return;
161     }
162     uint16_t handle = packet->GetHandle();
163     if (handle == kQualcommDebugHandle || handle == kSamsungDebugHandle) {
164       return;
165     }
166     if (classic_impl_->send_packet_upward(handle,
167                                           [&packet](struct acl_manager::assembler* assembler) {
168                                             assembler->on_incoming_packet(*packet);
169                                           })) {
170       return;
171     }
172     if (le_impl_->send_packet_upward(handle, [&packet](struct acl_manager::assembler* assembler) {
173           assembler->on_incoming_packet(*packet);
174         })) {
175       return;
176     }
177     if (unknown_acl_alarm_ == nullptr) {
178       unknown_acl_alarm_.reset(new os::Alarm(handler_));
179     }
180     waiting_packets_.push_back(*packet);
181     log::info("Saving packet of size {} to unknown connection 0x{:x}", packet->size(),
182               packet->GetHandle());
183     unknown_acl_alarm_->Schedule(BindOnce(&on_unknown_acl_timer, common::Unretained(this)),
184                                  kWaitBeforeDroppingUnknownAcl);
185   }
186 
187   template <typename OutputT>
188   void dump(OutputT&& out) const;
189 
190   const AclManager& acl_manager_;
191 
192   classic_impl* classic_impl_ = nullptr;
193   le_impl* le_impl_ = nullptr;
194   AclScheduler* acl_scheduler_ = nullptr;
195   RemoteNameRequestModule* remote_name_request_module_ = nullptr;
196   os::Handler* handler_ = nullptr;
197   Controller* controller_ = nullptr;
198   HciLayer* hci_layer_ = nullptr;
199   RoundRobinScheduler* round_robin_scheduler_ = nullptr;
200   common::BidiQueueEnd<AclBuilder, AclView>* hci_queue_end_ = nullptr;
201   std::atomic_bool enqueue_registered_ = false;
202   uint16_t default_link_policy_settings_ = 0xffff;
203   mutable std::mutex dumpsys_mutex_;
204   std::unique_ptr<os::Alarm> unknown_acl_alarm_;
205   std::vector<AclView> waiting_packets_;
206   static constexpr std::chrono::seconds kWaitBeforeDroppingUnknownAcl{1};
207 };
208 
AclManager()209 AclManager::AclManager() : pimpl_(std::make_unique<impl>(*this)) {}
210 
RegisterCallbacks(ConnectionCallbacks * callbacks,os::Handler * handler)211 void AclManager::RegisterCallbacks(ConnectionCallbacks* callbacks, os::Handler* handler) {
212   log::assert_that(callbacks != nullptr && handler != nullptr,
213                    "assert failed: callbacks != nullptr && handler != nullptr");
214   GetHandler()->Post(common::BindOnce(&classic_impl::handle_register_callbacks,
215                                       common::Unretained(pimpl_->classic_impl_),
216                                       common::Unretained(callbacks), common::Unretained(handler)));
217 }
218 
UnregisterCallbacks(ConnectionCallbacks * callbacks,std::promise<void> promise)219 void AclManager::UnregisterCallbacks(ConnectionCallbacks* callbacks, std::promise<void> promise) {
220   log::assert_that(callbacks != nullptr, "assert failed: callbacks != nullptr");
221   CallOn(pimpl_->classic_impl_, &classic_impl::handle_unregister_callbacks,
222          common::Unretained(callbacks), std::move(promise));
223 }
224 
RegisterLeCallbacks(LeConnectionCallbacks * callbacks,os::Handler * handler)225 void AclManager::RegisterLeCallbacks(LeConnectionCallbacks* callbacks, os::Handler* handler) {
226   log::assert_that(callbacks != nullptr && handler != nullptr,
227                    "assert failed: callbacks != nullptr && handler != nullptr");
228   CallOn(pimpl_->le_impl_, &le_impl::handle_register_le_callbacks, common::Unretained(callbacks),
229          common::Unretained(handler));
230 }
231 
RegisterLeAcceptlistCallbacks(LeAcceptlistCallbacks * callbacks)232 void AclManager::RegisterLeAcceptlistCallbacks(LeAcceptlistCallbacks* callbacks) {
233   log::assert_that(callbacks != nullptr, "assert failed: callbacks != nullptr");
234   CallOn(pimpl_->le_impl_, &le_impl::handle_register_le_acceptlist_callbacks,
235          common::Unretained(callbacks));
236 }
237 
UnregisterLeCallbacks(LeConnectionCallbacks * callbacks,std::promise<void> promise)238 void AclManager::UnregisterLeCallbacks(LeConnectionCallbacks* callbacks,
239                                        std::promise<void> promise) {
240   log::assert_that(callbacks != nullptr, "assert failed: callbacks != nullptr");
241   CallOn(pimpl_->le_impl_, &le_impl::handle_unregister_le_callbacks, common::Unretained(callbacks),
242          std::move(promise));
243 }
244 
UnregisterLeAcceptlistCallbacks(LeAcceptlistCallbacks * callbacks,std::promise<void> promise)245 void AclManager::UnregisterLeAcceptlistCallbacks(LeAcceptlistCallbacks* callbacks,
246                                                  std::promise<void> promise) {
247   log::assert_that(callbacks != nullptr, "assert failed: callbacks != nullptr");
248   CallOn(pimpl_->le_impl_, &le_impl::handle_unregister_le_acceptlist_callbacks,
249          common::Unretained(callbacks), std::move(promise));
250 }
251 
CreateConnection(Address address)252 void AclManager::CreateConnection(Address address) {
253   CallOn(pimpl_->classic_impl_, &classic_impl::create_connection, address);
254 }
255 
CreateLeConnection(AddressWithType address_with_type,bool is_direct)256 void AclManager::CreateLeConnection(AddressWithType address_with_type, bool is_direct) {
257   if (!is_direct) {
258     CallOn(pimpl_->le_impl_, &le_impl::add_device_to_background_connection_list, address_with_type);
259   }
260   CallOn(pimpl_->le_impl_, &le_impl::create_le_connection, address_with_type, true, is_direct);
261 }
262 
SetPrivacyPolicyForInitiatorAddress(LeAddressManager::AddressPolicy address_policy,AddressWithType fixed_address,std::chrono::milliseconds minimum_rotation_time,std::chrono::milliseconds maximum_rotation_time)263 void AclManager::SetPrivacyPolicyForInitiatorAddress(
264         LeAddressManager::AddressPolicy address_policy, AddressWithType fixed_address,
265         std::chrono::milliseconds minimum_rotation_time,
266         std::chrono::milliseconds maximum_rotation_time) {
267   Octet16 rotation_irk{};
268   auto irk_prop = shim::GetStorage()->GetProperty(BTIF_STORAGE_SECTION_ADAPTER,
269                                                   BTIF_STORAGE_KEY_LE_LOCAL_KEY_IRK);
270   if (irk_prop.has_value()) {
271     auto irk = common::ByteArray<16>::FromString(irk_prop.value());
272     if (irk.has_value()) {
273       rotation_irk = irk->bytes;
274     }
275   }
276   CallOn(pimpl_->le_impl_, &le_impl::set_privacy_policy_for_initiator_address, address_policy,
277          fixed_address, rotation_irk, minimum_rotation_time, maximum_rotation_time);
278 }
279 
280 // TODO(jpawlowski): remove once we have config file abstraction in cert tests
SetPrivacyPolicyForInitiatorAddressForTest(LeAddressManager::AddressPolicy address_policy,AddressWithType fixed_address,Octet16 rotation_irk,std::chrono::milliseconds minimum_rotation_time,std::chrono::milliseconds maximum_rotation_time)281 void AclManager::SetPrivacyPolicyForInitiatorAddressForTest(
282         LeAddressManager::AddressPolicy address_policy, AddressWithType fixed_address,
283         Octet16 rotation_irk, std::chrono::milliseconds minimum_rotation_time,
284         std::chrono::milliseconds maximum_rotation_time) {
285   CallOn(pimpl_->le_impl_, &le_impl::set_privacy_policy_for_initiator_address_for_test,
286          address_policy, fixed_address, rotation_irk, minimum_rotation_time, maximum_rotation_time);
287 }
288 
CancelConnect(Address address)289 void AclManager::CancelConnect(Address address) {
290   CallOn(pimpl_->classic_impl_, &classic_impl::cancel_connect, address);
291 }
292 
CancelLeConnect(AddressWithType address_with_type)293 void AclManager::CancelLeConnect(AddressWithType address_with_type) {
294   CallOn(pimpl_->le_impl_, &le_impl::remove_device_from_background_connection_list,
295          address_with_type);
296   CallOn(pimpl_->le_impl_, &le_impl::cancel_connect, address_with_type);
297 }
298 
RemoveFromBackgroundList(AddressWithType address_with_type)299 void AclManager::RemoveFromBackgroundList(AddressWithType address_with_type) {
300   CallOn(pimpl_->le_impl_, &le_impl::remove_device_from_background_connection_list,
301          address_with_type);
302 }
303 
ClearFilterAcceptList()304 void AclManager::ClearFilterAcceptList() {
305   CallOn(pimpl_->le_impl_, &le_impl::clear_filter_accept_list);
306 }
307 
AddDeviceToResolvingList(AddressWithType address_with_type,const std::array<uint8_t,16> & peer_irk,const std::array<uint8_t,16> & local_irk)308 void AclManager::AddDeviceToResolvingList(AddressWithType address_with_type,
309                                           const std::array<uint8_t, 16>& peer_irk,
310                                           const std::array<uint8_t, 16>& local_irk) {
311   CallOn(pimpl_->le_impl_, &le_impl::add_device_to_resolving_list, address_with_type, peer_irk,
312          local_irk);
313 }
314 
RemoveDeviceFromResolvingList(AddressWithType address_with_type)315 void AclManager::RemoveDeviceFromResolvingList(AddressWithType address_with_type) {
316   CallOn(pimpl_->le_impl_, &le_impl::remove_device_from_resolving_list, address_with_type);
317 }
318 
ClearResolvingList()319 void AclManager::ClearResolvingList() { CallOn(pimpl_->le_impl_, &le_impl::clear_resolving_list); }
320 
CentralLinkKey(KeyFlag key_flag)321 void AclManager::CentralLinkKey(KeyFlag key_flag) {
322   CallOn(pimpl_->classic_impl_, &classic_impl::central_link_key, key_flag);
323 }
324 
SwitchRole(Address address,Role role)325 void AclManager::SwitchRole(Address address, Role role) {
326   CallOn(pimpl_->classic_impl_, &classic_impl::switch_role, address, role);
327 }
328 
ReadDefaultLinkPolicySettings()329 uint16_t AclManager::ReadDefaultLinkPolicySettings() {
330   log::assert_that(pimpl_->default_link_policy_settings_ != 0xffff, "Settings were never written");
331   return pimpl_->default_link_policy_settings_;
332 }
333 
WriteDefaultLinkPolicySettings(uint16_t default_link_policy_settings)334 void AclManager::WriteDefaultLinkPolicySettings(uint16_t default_link_policy_settings) {
335   pimpl_->default_link_policy_settings_ = default_link_policy_settings;
336   CallOn(pimpl_->classic_impl_, &classic_impl::write_default_link_policy_settings,
337          default_link_policy_settings);
338 }
339 
OnAdvertisingSetTerminated(ErrorCode status,uint16_t conn_handle,uint8_t adv_set_id,hci::AddressWithType adv_address,bool is_discoverable)340 void AclManager::OnAdvertisingSetTerminated(ErrorCode status, uint16_t conn_handle,
341                                             uint8_t adv_set_id, hci::AddressWithType adv_address,
342                                             bool is_discoverable) {
343   if (status == ErrorCode::SUCCESS) {
344     CallOn(pimpl_->le_impl_, &le_impl::OnAdvertisingSetTerminated, conn_handle, adv_set_id,
345            adv_address, is_discoverable);
346   }
347 }
348 
OnClassicSuspendInitiatedDisconnect(uint16_t handle,ErrorCode reason)349 void AclManager::OnClassicSuspendInitiatedDisconnect(uint16_t handle, ErrorCode reason) {
350   CallOn(pimpl_->classic_impl_, &classic_impl::on_classic_disconnect, handle, reason);
351 }
352 
OnLeSuspendInitiatedDisconnect(uint16_t handle,ErrorCode reason)353 void AclManager::OnLeSuspendInitiatedDisconnect(uint16_t handle, ErrorCode reason) {
354   CallOn(pimpl_->le_impl_, &le_impl::on_le_disconnect, handle, reason);
355 }
356 
SetSystemSuspendState(bool suspended)357 void AclManager::SetSystemSuspendState(bool suspended) {
358   CallOn(pimpl_->le_impl_, &le_impl::set_system_suspend_state, suspended);
359 }
360 
AddDeviceToRelaxedConnectionIntervalList(const Address address)361 void AclManager::AddDeviceToRelaxedConnectionIntervalList(const Address address) {
362   CallOn(pimpl_->le_impl_, &le_impl::add_device_to_relaxed_connection_interval_list, address);
363 }
364 
GetLeAddressManager()365 LeAddressManager* AclManager::GetLeAddressManager() {
366   return pimpl_->le_impl_->le_address_manager_;
367 }
368 
HACK_GetHandle(Address address)369 uint16_t AclManager::HACK_GetHandle(Address address) {
370   return pimpl_->classic_impl_->HACK_get_handle(address);
371 }
372 
HACK_GetLeHandle(Address address)373 uint16_t AclManager::HACK_GetLeHandle(Address address) {
374   return pimpl_->le_impl_->HACK_get_handle(address);
375 }
376 
HACK_GetLeAddress(uint16_t connection_handle)377 Address AclManager::HACK_GetLeAddress(uint16_t connection_handle) {
378   return pimpl_->le_impl_->HACK_get_address(connection_handle);
379 }
380 
HACK_SetAclTxPriority(uint8_t handle,bool high_priority)381 void AclManager::HACK_SetAclTxPriority(uint8_t handle, bool high_priority) {
382   CallOn(pimpl_->round_robin_scheduler_, &RoundRobinScheduler::SetLinkPriority, handle,
383          high_priority);
384 }
385 
ListDependencies(ModuleList * list) const386 void AclManager::ListDependencies(ModuleList* list) const {
387   list->add<HciLayer>();
388   list->add<Controller>();
389   list->add<AclScheduler>();
390   list->add<RemoteNameRequestModule>();
391 }
392 
Start()393 void AclManager::Start() { pimpl_->Start(); }
394 
Stop()395 void AclManager::Stop() { pimpl_->Stop(); }
396 
ToString() const397 std::string AclManager::ToString() const { return "Acl Manager"; }
398 
__anon3621c27f0502() 399 const ModuleFactory AclManager::Factory = ModuleFactory([]() { return new AclManager(); });
400 
401 AclManager::~AclManager() = default;
402 
403 template <typename OutputT>
dump(OutputT && out) const404 void AclManager::impl::dump(OutputT&& out) const {
405   const std::lock_guard<std::mutex> lock(dumpsys_mutex_);
406   const auto accept_list =
407           (le_impl_ != nullptr) ? le_impl_->accept_list : std::unordered_set<AddressWithType>();
408   const auto le_connectability_state_text =
409           (le_impl_ != nullptr) ? connectability_state_machine_text(le_impl_->connectability_state_)
410                                 : "INDETERMINATE";
411   const auto le_create_connection_timeout_alarms_count =
412           (le_impl_ != nullptr)
413                   ? static_cast<int>(le_impl_->create_connection_timeout_alarms_.size())
414                   : 0;
415 
416   std::format_to(out, "\nACL Manager Dumpsys:\n");
417   std::format_to(out,
418                  "    le_connectability_state: \"{}\"\n"
419                  "    le_create_connection_timeout_alarms_count: {}\n"
420                  "    le_filter_accept_list_count: {}\n"
421                  "    le_filter_accept_list: [",
422                  le_connectability_state_text, le_create_connection_timeout_alarms_count,
423                  accept_list.size());
424   for (const auto& it : accept_list) {
425     std::format_to(out, "\n        \"{}\",", it.ToString());
426   }
427   std::format_to(out, "\n    ]\n");
428 }
429 
Dump(int fd) const430 void AclManager::Dump(int fd) const {
431   std::string out;
432   pimpl_->dump(std::back_inserter(out));
433   dprintf(fd, "%s", out.c_str());
434 }
435 
436 }  // namespace hci
437 }  // namespace bluetooth
438