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 <future>
23 #include <mutex>
24
25 #include "common/bidi_queue.h"
26 #include "common/byte_array.h"
27 #include "dumpsys_data_generated.h"
28 #include "hci/acl_manager/acl_scheduler.h"
29 #include "hci/acl_manager/classic_impl.h"
30 #include "hci/acl_manager/le_acceptlist_callbacks.h"
31 #include "hci/acl_manager/le_acl_connection.h"
32 #include "hci/acl_manager/le_impl.h"
33 #include "hci/acl_manager/round_robin_scheduler.h"
34 #include "hci/controller.h"
35 #include "hci/hci_layer.h"
36 #include "hci/remote_name_request.h"
37 #include "hci_acl_manager_generated.h"
38 #include "security/security_module.h"
39 #include "storage/config_keys.h"
40 #include "storage/storage_module.h"
41
42 namespace bluetooth {
43 namespace hci {
44
45 constexpr uint16_t kQualcommDebugHandle = 0xedc;
46
47 using acl_manager::AclConnection;
48 using common::Bind;
49 using common::BindOnce;
50
51 using acl_manager::classic_impl;
52 using acl_manager::ClassicAclConnection;
53 using acl_manager::ConnectionCallbacks;
54
55 using acl_manager::le_impl;
56 using acl_manager::LeAcceptlistCallbacks;
57 using acl_manager::LeAclConnection;
58 using acl_manager::LeConnectionCallbacks;
59
60 using acl_manager::RoundRobinScheduler;
61
62 using acl_manager::AclScheduler;
63
64 struct AclManager::impl {
implbluetooth::hci::AclManager::impl65 impl(const AclManager& acl_manager) : acl_manager_(acl_manager) {}
66
Startbluetooth::hci::AclManager::impl67 void Start() {
68 hci_layer_ = acl_manager_.GetDependency<HciLayer>();
69 handler_ = acl_manager_.GetHandler();
70 controller_ = acl_manager_.GetDependency<Controller>();
71 round_robin_scheduler_ = new RoundRobinScheduler(handler_, controller_, hci_layer_->GetAclQueueEnd());
72 acl_scheduler_ = acl_manager_.GetDependency<AclScheduler>();
73
74 remote_name_request_module_ = acl_manager_.GetDependency<RemoteNameRequestModule>();
75
76 bool crash_on_unknown_handle = false;
77 {
78 const std::lock_guard<std::mutex> lock(dumpsys_mutex_);
79 classic_impl_ = new classic_impl(
80 hci_layer_,
81 controller_,
82 handler_,
83 round_robin_scheduler_,
84 crash_on_unknown_handle,
85 acl_scheduler_,
86 remote_name_request_module_);
87 le_impl_ = new le_impl(hci_layer_, controller_, handler_, round_robin_scheduler_, crash_on_unknown_handle);
88 }
89
90 hci_queue_end_ = hci_layer_->GetAclQueueEnd();
91 hci_queue_end_->RegisterDequeue(
92 handler_, common::Bind(&impl::dequeue_and_route_acl_packet_to_connection, common::Unretained(this)));
93 }
94
Stopbluetooth::hci::AclManager::impl95 void Stop() {
96 hci_queue_end_->UnregisterDequeue();
97 if (enqueue_registered_.exchange(false)) {
98 hci_queue_end_->UnregisterEnqueue();
99 }
100
101 {
102 const std::lock_guard<std::mutex> lock(dumpsys_mutex_);
103 delete le_impl_;
104 delete classic_impl_;
105 le_impl_ = nullptr;
106 classic_impl_ = nullptr;
107 }
108
109 unknown_acl_alarm_.reset();
110 waiting_packets_.clear();
111
112 delete round_robin_scheduler_;
113 hci_queue_end_ = nullptr;
114 handler_ = nullptr;
115 hci_layer_ = nullptr;
116 acl_scheduler_ = nullptr;
117 }
118
retry_unknown_aclbluetooth::hci::AclManager::impl119 void retry_unknown_acl(bool timed_out) {
120 std::vector<AclView> unsent_packets;
121 for (const auto& itr : waiting_packets_) {
122 auto handle = itr.GetHandle();
123 if (!classic_impl_->send_packet_upward(
124 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(
135 "Dropping packet of size {} to unknown connection 0x{:x}",
136 itr.size(),
137 itr.GetHandle());
138 }
139 }
140 }
141 waiting_packets_ = std::move(unsent_packets);
142 }
143
on_unknown_acl_timerbluetooth::hci::AclManager::impl144 static void on_unknown_acl_timer(struct AclManager::impl* impl) {
145 log::info("Timer fired!");
146 impl->retry_unknown_acl(/* timed_out = */ true);
147 impl->unknown_acl_alarm_.reset();
148 }
149
150 // Invoked from some external Queue Reactable context 2
dequeue_and_route_acl_packet_to_connectionbluetooth::hci::AclManager::impl151 void dequeue_and_route_acl_packet_to_connection() {
152 // Retry any waiting packets first
153 if (!waiting_packets_.empty()) {
154 retry_unknown_acl(/* timed_out = */ false);
155 }
156
157 auto packet = hci_queue_end_->TryDequeue();
158 log::assert_that(packet != nullptr, "assert failed: packet != nullptr");
159 if (!packet->IsValid()) {
160 log::info("Dropping invalid packet of size {}", packet->size());
161 return;
162 }
163 uint16_t handle = packet->GetHandle();
164 if (handle == kQualcommDebugHandle) return;
165 if (classic_impl_->send_packet_upward(
166 handle, [&packet](struct acl_manager::assembler* assembler) { assembler->on_incoming_packet(*packet); }))
167 return;
168 if (le_impl_->send_packet_upward(
169 handle, [&packet](struct acl_manager::assembler* assembler) { assembler->on_incoming_packet(*packet); }))
170 return;
171 if (unknown_acl_alarm_ == nullptr) {
172 unknown_acl_alarm_.reset(new os::Alarm(handler_));
173 }
174 waiting_packets_.push_back(*packet);
175 log::info(
176 "Saving packet of size {} to unknown connection 0x{:x}",
177 packet->size(),
178 packet->GetHandle());
179 unknown_acl_alarm_->Schedule(
180 BindOnce(&on_unknown_acl_timer, common::Unretained(this)), kWaitBeforeDroppingUnknownAcl);
181 }
182
183 void Dump(
184 std::promise<flatbuffers::Offset<AclManagerData>> promise, flatbuffers::FlatBufferBuilder* fb_builder) const;
185
186 const AclManager& acl_manager_;
187
188 classic_impl* classic_impl_ = nullptr;
189 le_impl* le_impl_ = nullptr;
190 AclScheduler* acl_scheduler_ = nullptr;
191 RemoteNameRequestModule* remote_name_request_module_ = nullptr;
192 os::Handler* handler_ = nullptr;
193 Controller* controller_ = nullptr;
194 HciLayer* hci_layer_ = nullptr;
195 RoundRobinScheduler* round_robin_scheduler_ = nullptr;
196 common::BidiQueueEnd<AclBuilder, AclView>* hci_queue_end_ = nullptr;
197 std::atomic_bool enqueue_registered_ = false;
198 uint16_t default_link_policy_settings_ = 0xffff;
199 mutable std::mutex dumpsys_mutex_;
200 std::unique_ptr<os::Alarm> unknown_acl_alarm_;
201 std::vector<AclView> waiting_packets_;
202 static constexpr std::chrono::seconds kWaitBeforeDroppingUnknownAcl{1};
203 };
204
AclManager()205 AclManager::AclManager() : pimpl_(std::make_unique<impl>(*this)) {}
206
RegisterCallbacks(ConnectionCallbacks * callbacks,os::Handler * handler)207 void AclManager::RegisterCallbacks(ConnectionCallbacks* callbacks, os::Handler* handler) {
208 log::assert_that(
209 callbacks != nullptr && handler != nullptr,
210 "assert failed: callbacks != nullptr && handler != nullptr");
211 GetHandler()->Post(common::BindOnce(
212 &classic_impl::handle_register_callbacks,
213 common::Unretained(pimpl_->classic_impl_),
214 common::Unretained(callbacks),
215 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(
221 pimpl_->classic_impl_,
222 &classic_impl::handle_unregister_callbacks,
223 common::Unretained(callbacks),
224 std::move(promise));
225 }
226
RegisterLeCallbacks(LeConnectionCallbacks * callbacks,os::Handler * handler)227 void AclManager::RegisterLeCallbacks(LeConnectionCallbacks* callbacks, os::Handler* handler) {
228 log::assert_that(
229 callbacks != nullptr && handler != nullptr,
230 "assert failed: callbacks != nullptr && handler != nullptr");
231 CallOn(
232 pimpl_->le_impl_,
233 &le_impl::handle_register_le_callbacks,
234 common::Unretained(callbacks),
235 common::Unretained(handler));
236 }
237
RegisterLeAcceptlistCallbacks(LeAcceptlistCallbacks * callbacks)238 void AclManager::RegisterLeAcceptlistCallbacks(LeAcceptlistCallbacks* callbacks) {
239 log::assert_that(callbacks != nullptr, "assert failed: callbacks != nullptr");
240 CallOn(
241 pimpl_->le_impl_,
242 &le_impl::handle_register_le_acceptlist_callbacks,
243 common::Unretained(callbacks));
244 }
245
UnregisterLeCallbacks(LeConnectionCallbacks * callbacks,std::promise<void> promise)246 void AclManager::UnregisterLeCallbacks(LeConnectionCallbacks* callbacks, std::promise<void> promise) {
247 log::assert_that(callbacks != nullptr, "assert failed: callbacks != nullptr");
248 CallOn(pimpl_->le_impl_, &le_impl::handle_unregister_le_callbacks, common::Unretained(callbacks), std::move(promise));
249 }
250
UnregisterLeAcceptlistCallbacks(LeAcceptlistCallbacks * callbacks,std::promise<void> promise)251 void AclManager::UnregisterLeAcceptlistCallbacks(
252 LeAcceptlistCallbacks* callbacks, std::promise<void> promise) {
253 log::assert_that(callbacks != nullptr, "assert failed: callbacks != nullptr");
254 CallOn(
255 pimpl_->le_impl_,
256 &le_impl::handle_unregister_le_acceptlist_callbacks,
257 common::Unretained(callbacks),
258 std::move(promise));
259 }
260
CreateConnection(Address address)261 void AclManager::CreateConnection(Address address) {
262 CallOn(pimpl_->classic_impl_, &classic_impl::create_connection, address);
263 }
264
CreateLeConnection(AddressWithType address_with_type,bool is_direct)265 void AclManager::CreateLeConnection(AddressWithType address_with_type, bool is_direct) {
266 if (!is_direct) {
267 CallOn(pimpl_->le_impl_, &le_impl::add_device_to_background_connection_list, address_with_type);
268 }
269 CallOn(pimpl_->le_impl_, &le_impl::create_le_connection, address_with_type, true, is_direct);
270 }
271
IsOnBackgroundList(AddressWithType address_with_type,std::promise<bool> promise)272 void AclManager::IsOnBackgroundList(AddressWithType address_with_type, std::promise<bool> promise) {
273 CallOn(pimpl_->le_impl_, &le_impl::is_on_background_connection_list, address_with_type, std::move(promise));
274 }
275
SetLeSuggestedDefaultDataParameters(uint16_t octets,uint16_t time)276 void AclManager::SetLeSuggestedDefaultDataParameters(uint16_t octets, uint16_t time) {
277 CallOn(pimpl_->le_impl_, &le_impl::set_le_suggested_default_data_parameters, octets, time);
278 }
279
LeSetDefaultSubrate(uint16_t subrate_min,uint16_t subrate_max,uint16_t max_latency,uint16_t cont_num,uint16_t sup_tout)280 void AclManager::LeSetDefaultSubrate(
281 uint16_t subrate_min, uint16_t subrate_max, uint16_t max_latency, uint16_t cont_num, uint16_t sup_tout) {
282 CallOn(pimpl_->le_impl_, &le_impl::LeSetDefaultSubrate, subrate_min, subrate_max, max_latency, cont_num, sup_tout);
283 }
284
SetPrivacyPolicyForInitiatorAddress(LeAddressManager::AddressPolicy address_policy,AddressWithType fixed_address,std::chrono::milliseconds minimum_rotation_time,std::chrono::milliseconds maximum_rotation_time)285 void AclManager::SetPrivacyPolicyForInitiatorAddress(
286 LeAddressManager::AddressPolicy address_policy,
287 AddressWithType fixed_address,
288 std::chrono::milliseconds minimum_rotation_time,
289 std::chrono::milliseconds maximum_rotation_time) {
290 Octet16 rotation_irk{};
291 auto irk_prop = GetDependency<storage::StorageModule>()->GetProperty(
292 BTIF_STORAGE_SECTION_ADAPTER, BTIF_STORAGE_KEY_LE_LOCAL_KEY_IRK);
293 if (irk_prop.has_value()) {
294 auto irk = common::ByteArray<16>::FromString(irk_prop.value());
295 if (irk.has_value()) {
296 rotation_irk = irk->bytes;
297 }
298 }
299 CallOn(
300 pimpl_->le_impl_,
301 &le_impl::set_privacy_policy_for_initiator_address,
302 address_policy,
303 fixed_address,
304 rotation_irk,
305 minimum_rotation_time,
306 maximum_rotation_time);
307 }
308
309 // 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)310 void AclManager::SetPrivacyPolicyForInitiatorAddressForTest(
311 LeAddressManager::AddressPolicy address_policy,
312 AddressWithType fixed_address,
313 Octet16 rotation_irk,
314 std::chrono::milliseconds minimum_rotation_time,
315 std::chrono::milliseconds maximum_rotation_time) {
316 CallOn(
317 pimpl_->le_impl_,
318 &le_impl::set_privacy_policy_for_initiator_address_for_test,
319 address_policy,
320 fixed_address,
321 rotation_irk,
322 minimum_rotation_time,
323 maximum_rotation_time);
324 }
325
CancelConnect(Address address)326 void AclManager::CancelConnect(Address address) {
327 CallOn(pimpl_->classic_impl_, &classic_impl::cancel_connect, address);
328 }
329
CancelLeConnect(AddressWithType address_with_type)330 void AclManager::CancelLeConnect(AddressWithType address_with_type) {
331 CallOn(pimpl_->le_impl_, &le_impl::remove_device_from_background_connection_list, address_with_type);
332 CallOn(pimpl_->le_impl_, &le_impl::cancel_connect, address_with_type);
333 }
334
RemoveFromBackgroundList(AddressWithType address_with_type)335 void AclManager::RemoveFromBackgroundList(AddressWithType address_with_type) {
336 CallOn(pimpl_->le_impl_, &le_impl::remove_device_from_background_connection_list, address_with_type);
337 }
338
ClearFilterAcceptList()339 void AclManager::ClearFilterAcceptList() {
340 CallOn(pimpl_->le_impl_, &le_impl::clear_filter_accept_list);
341 }
342
AddDeviceToResolvingList(AddressWithType address_with_type,const std::array<uint8_t,16> & peer_irk,const std::array<uint8_t,16> & local_irk)343 void AclManager::AddDeviceToResolvingList(
344 AddressWithType address_with_type,
345 const std::array<uint8_t, 16>& peer_irk,
346 const std::array<uint8_t, 16>& local_irk) {
347 CallOn(pimpl_->le_impl_, &le_impl::add_device_to_resolving_list, address_with_type, peer_irk, local_irk);
348 }
349
RemoveDeviceFromResolvingList(AddressWithType address_with_type)350 void AclManager::RemoveDeviceFromResolvingList(AddressWithType address_with_type) {
351 CallOn(pimpl_->le_impl_, &le_impl::remove_device_from_resolving_list, address_with_type);
352 }
353
ClearResolvingList()354 void AclManager::ClearResolvingList() {
355 CallOn(pimpl_->le_impl_, &le_impl::clear_resolving_list);
356 }
357
CentralLinkKey(KeyFlag key_flag)358 void AclManager::CentralLinkKey(KeyFlag key_flag) {
359 CallOn(pimpl_->classic_impl_, &classic_impl::central_link_key, key_flag);
360 }
361
SwitchRole(Address address,Role role)362 void AclManager::SwitchRole(Address address, Role role) {
363 CallOn(pimpl_->classic_impl_, &classic_impl::switch_role, address, role);
364 }
365
ReadDefaultLinkPolicySettings()366 uint16_t AclManager::ReadDefaultLinkPolicySettings() {
367 log::assert_that(pimpl_->default_link_policy_settings_ != 0xffff, "Settings were never written");
368 return pimpl_->default_link_policy_settings_;
369 }
370
WriteDefaultLinkPolicySettings(uint16_t default_link_policy_settings)371 void AclManager::WriteDefaultLinkPolicySettings(uint16_t default_link_policy_settings) {
372 pimpl_->default_link_policy_settings_ = default_link_policy_settings;
373 CallOn(pimpl_->classic_impl_, &classic_impl::write_default_link_policy_settings, default_link_policy_settings);
374 }
375
OnAdvertisingSetTerminated(ErrorCode status,uint16_t conn_handle,uint8_t adv_set_id,hci::AddressWithType adv_address,bool is_discoverable)376 void AclManager::OnAdvertisingSetTerminated(
377 ErrorCode status,
378 uint16_t conn_handle,
379 uint8_t adv_set_id,
380 hci::AddressWithType adv_address,
381 bool is_discoverable) {
382 if (status == ErrorCode::SUCCESS) {
383 CallOn(
384 pimpl_->le_impl_,
385 &le_impl::OnAdvertisingSetTerminated,
386 conn_handle,
387 adv_set_id,
388 adv_address,
389 is_discoverable);
390 }
391 }
392
OnClassicSuspendInitiatedDisconnect(uint16_t handle,ErrorCode reason)393 void AclManager::OnClassicSuspendInitiatedDisconnect(uint16_t handle, ErrorCode reason) {
394 CallOn(pimpl_->classic_impl_, &classic_impl::on_classic_disconnect, handle, reason);
395 }
396
OnLeSuspendInitiatedDisconnect(uint16_t handle,ErrorCode reason)397 void AclManager::OnLeSuspendInitiatedDisconnect(uint16_t handle, ErrorCode reason) {
398 CallOn(pimpl_->le_impl_, &le_impl::on_le_disconnect, handle, reason);
399 }
400
SetSystemSuspendState(bool suspended)401 void AclManager::SetSystemSuspendState(bool suspended) {
402 CallOn(pimpl_->le_impl_, &le_impl::set_system_suspend_state, suspended);
403 }
404
GetLeAddressManager()405 LeAddressManager* AclManager::GetLeAddressManager() {
406 return pimpl_->le_impl_->le_address_manager_;
407 }
408
HACK_GetHandle(Address address)409 uint16_t AclManager::HACK_GetHandle(Address address) {
410 return pimpl_->classic_impl_->HACK_get_handle(address);
411 }
412
HACK_GetLeHandle(Address address)413 uint16_t AclManager::HACK_GetLeHandle(Address address) {
414 return pimpl_->le_impl_->HACK_get_handle(address);
415 }
416
HACK_GetLeAddress(uint16_t connection_handle)417 Address AclManager::HACK_GetLeAddress(uint16_t connection_handle) {
418 return pimpl_->le_impl_->HACK_get_address(connection_handle);
419 }
420
HACK_SetAclTxPriority(uint8_t handle,bool high_priority)421 void AclManager::HACK_SetAclTxPriority(uint8_t handle, bool high_priority) {
422 CallOn(pimpl_->round_robin_scheduler_, &RoundRobinScheduler::SetLinkPriority, handle, high_priority);
423 }
424
ListDependencies(ModuleList * list) const425 void AclManager::ListDependencies(ModuleList* list) const {
426 list->add<HciLayer>();
427 list->add<Controller>();
428 list->add<storage::StorageModule>();
429 list->add<AclScheduler>();
430 list->add<RemoteNameRequestModule>();
431 }
432
Start()433 void AclManager::Start() {
434 pimpl_->Start();
435 }
436
Stop()437 void AclManager::Stop() {
438 pimpl_->Stop();
439 }
440
ToString() const441 std::string AclManager::ToString() const {
442 return "Acl Manager";
443 }
444
__anon33ac91890502() 445 const ModuleFactory AclManager::Factory = ModuleFactory([]() { return new AclManager(); });
446
447 AclManager::~AclManager() = default;
448
Dump(std::promise<flatbuffers::Offset<AclManagerData>> promise,flatbuffers::FlatBufferBuilder * fb_builder) const449 void AclManager::impl::Dump(
450 std::promise<flatbuffers::Offset<AclManagerData>> promise, flatbuffers::FlatBufferBuilder* fb_builder) const {
451 const std::lock_guard<std::mutex> lock(dumpsys_mutex_);
452 const auto accept_list = (le_impl_ != nullptr) ? le_impl_->accept_list : std::unordered_set<AddressWithType>();
453 const auto le_connectability_state_text =
454 (le_impl_ != nullptr) ? connectability_state_machine_text(le_impl_->connectability_state_) : "INDETERMINATE";
455 const auto le_create_connection_timeout_alarms_count =
456 (le_impl_ != nullptr) ? (int)le_impl_->create_connection_timeout_alarms_.size() : 0;
457
458 auto title = fb_builder->CreateString("----- Acl Manager Dumpsys -----");
459 auto le_connectability_state = fb_builder->CreateString(le_connectability_state_text);
460
461 flatbuffers::Offset<flatbuffers::String> strings[accept_list.size()];
462
463 size_t cnt = 0;
464 for (const auto& it : accept_list) {
465 strings[cnt++] = fb_builder->CreateString(it.ToString());
466 }
467 auto vecofstrings = fb_builder->CreateVector(strings, accept_list.size());
468
469 AclManagerDataBuilder builder(*fb_builder);
470 builder.add_title(title);
471 builder.add_le_filter_accept_list_count(accept_list.size());
472 builder.add_le_filter_accept_list(vecofstrings);
473 builder.add_le_connectability_state(le_connectability_state);
474 builder.add_le_create_connection_timeout_alarms_count(le_create_connection_timeout_alarms_count);
475
476 flatbuffers::Offset<AclManagerData> dumpsys_data = builder.Finish();
477 promise.set_value(dumpsys_data);
478 }
479
GetDumpsysData(flatbuffers::FlatBufferBuilder * fb_builder) const480 DumpsysDataFinisher AclManager::GetDumpsysData(flatbuffers::FlatBufferBuilder* fb_builder) const {
481 log::assert_that(fb_builder != nullptr, "assert failed: fb_builder != nullptr");
482
483 std::promise<flatbuffers::Offset<AclManagerData>> promise;
484 auto future = promise.get_future();
485 pimpl_->Dump(std::move(promise), fb_builder);
486
487 auto dumpsys_data = future.get();
488
489 return [dumpsys_data](DumpsysDataBuilder* dumpsys_builder) {
490 dumpsys_builder->add_hci_acl_manager_dumpsys_data(dumpsys_data);
491 };
492 }
493
494 } // namespace hci
495 } // namespace bluetooth
496