• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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