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