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