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