1 /*
2 * Copyright 2020 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 "main/shim/acl.h"
18
19 #include <base/location.h>
20 #include <base/strings/stringprintf.h>
21 #include <time.h>
22
23 #include <chrono>
24 #include <cstdint>
25 #include <functional>
26 #include <future>
27 #include <map>
28 #include <memory>
29 #include <optional>
30 #include <string>
31 #include <unordered_set>
32
33 #include "btif/include/btif_hh.h"
34 #include "common/interfaces/ILoggable.h"
35 #include "device/include/controller.h"
36 #include "gd/common/bidi_queue.h"
37 #include "gd/common/bind.h"
38 #include "gd/common/init_flags.h"
39 #include "gd/common/strings.h"
40 #include "gd/common/sync_map_count.h"
41 #include "gd/hci/acl_manager.h"
42 #include "gd/hci/acl_manager/acl_connection.h"
43 #include "gd/hci/acl_manager/classic_acl_connection.h"
44 #include "gd/hci/acl_manager/connection_management_callbacks.h"
45 #include "gd/hci/acl_manager/le_acl_connection.h"
46 #include "gd/hci/acl_manager/le_connection_management_callbacks.h"
47 #include "gd/hci/acl_manager/le_impl.h"
48 #include "gd/hci/address.h"
49 #include "gd/hci/address_with_type.h"
50 #include "gd/hci/class_of_device.h"
51 #include "gd/hci/controller.h"
52 #include "gd/os/handler.h"
53 #include "gd/os/queue.h"
54 #include "main/shim/btm.h"
55 #include "main/shim/dumpsys.h"
56 #include "main/shim/entry.h"
57 #include "main/shim/helpers.h"
58 #include "main/shim/stack.h"
59 #include "osi/include/allocator.h"
60 #include "stack/acl/acl.h"
61 #include "stack/btm/btm_int_types.h"
62 #include "stack/include/acl_hci_link_interface.h"
63 #include "stack/include/ble_acl_interface.h"
64 #include "stack/include/bt_hdr.h"
65 #include "stack/include/btm_api.h"
66 #include "stack/include/btm_status.h"
67 #include "stack/include/gatt_api.h"
68 #include "stack/include/pan_api.h"
69 #include "stack/include/sec_hci_link_interface.h"
70 #include "stack/l2cap/l2c_int.h"
71 #include "types/ble_address_with_type.h"
72 #include "types/raw_address.h"
73
74 extern tBTM_CB btm_cb;
75
76 bt_status_t do_in_main_thread(const base::Location& from_here,
77 base::OnceClosure task);
78
79 using namespace bluetooth;
80
81 class ConnectAddressWithType : public bluetooth::common::IRedactableLoggable {
82 public:
ConnectAddressWithType(hci::AddressWithType address_with_type)83 explicit ConnectAddressWithType(hci::AddressWithType address_with_type)
84 : address_(address_with_type.GetAddress()),
85 type_(address_with_type.ToFilterAcceptListAddressType()) {}
86
87 // TODO: remove this method
ToString() const88 std::string const ToString() const {
89 std::stringstream ss;
90 ss << address_.ToString() << "[" << FilterAcceptListAddressTypeText(type_)
91 << "]";
92 return ss.str();
93 }
94
ToStringForLogging() const95 std::string ToStringForLogging() const override {
96 return ToString();
97 }
ToRedactedStringForLogging() const98 std::string ToRedactedStringForLogging() const override {
99 std::stringstream ss;
100 ss << address_.ToRedactedStringForLogging() << "["
101 << FilterAcceptListAddressTypeText(type_) << "]";
102 return ss.str();
103 }
operator ==(const ConnectAddressWithType & rhs) const104 bool operator==(const ConnectAddressWithType& rhs) const {
105 return address_ == rhs.address_ && type_ == rhs.type_;
106 }
107
108 private:
109 friend std::hash<ConnectAddressWithType>;
110 hci::Address address_;
111 hci::FilterAcceptListAddressType type_;
112 };
113
114 namespace std {
115 template <>
116 struct hash<ConnectAddressWithType> {
operator ()std::hash117 std::size_t operator()(const ConnectAddressWithType& val) const {
118 static_assert(sizeof(uint64_t) >=
119 (bluetooth::hci::Address::kLength +
120 sizeof(bluetooth::hci::FilterAcceptListAddressType)));
121 uint64_t int_addr = 0;
122 memcpy(reinterpret_cast<uint8_t*>(&int_addr), val.address_.data(),
123 bluetooth::hci::Address::kLength);
124 memcpy(reinterpret_cast<uint8_t*>(&int_addr) +
125 bluetooth::hci::Address::kLength,
126 &val.type_, sizeof(bluetooth::hci::FilterAcceptListAddressType));
127 return std::hash<uint64_t>{}(int_addr);
128 }
129 };
130 } // namespace std
131
132 namespace {
133
134 constexpr uint32_t kRunicBjarkan = 0x0016D2;
135 constexpr uint32_t kRunicHagall = 0x0016BC;
136
137 using HciHandle = uint16_t;
138 using PageNumber = uint8_t;
139
140 using CreationTime = std::chrono::time_point<std::chrono::system_clock>;
141 using TeardownTime = std::chrono::time_point<std::chrono::system_clock>;
142
143 constexpr char kBtmLogTag[] = "ACL";
144
145 using SendDataUpwards = void (*const)(BT_HDR*);
146 using OnDisconnect = std::function<void(HciHandle, hci::ErrorCode reason)>;
147
148 constexpr char kConnectionDescriptorTimeFormat[] = "%Y-%m-%d %H:%M:%S";
149
150 constexpr unsigned MillisPerSecond = 1000;
EpochMillisToString(long long time_ms)151 std::string EpochMillisToString(long long time_ms) {
152 time_t time_sec = time_ms / MillisPerSecond;
153 struct tm tm;
154 localtime_r(&time_sec, &tm);
155 std::string s = common::StringFormatTime(kConnectionDescriptorTimeFormat, tm);
156 return base::StringPrintf(
157 "%s.%03u", s.c_str(),
158 static_cast<unsigned int>(time_ms % MillisPerSecond));
159 }
160
IsRpa(const hci::AddressWithType address_with_type)161 inline bool IsRpa(const hci::AddressWithType address_with_type) {
162 return address_with_type.GetAddressType() ==
163 hci::AddressType::RANDOM_DEVICE_ADDRESS &&
164 ((address_with_type.GetAddress().address.data()[5] & 0xc0) == 0x40);
165 }
166
167 class ShadowAcceptlist {
168 public:
ShadowAcceptlist(uint8_t max_acceptlist_size)169 ShadowAcceptlist(uint8_t max_acceptlist_size)
170 : max_acceptlist_size_(max_acceptlist_size) {}
171
Add(const hci::AddressWithType & address_with_type)172 bool Add(const hci::AddressWithType& address_with_type) {
173 if (acceptlist_set_.size() == max_acceptlist_size_) {
174 LOG_ERROR("Acceptlist is full size:%zu", acceptlist_set_.size());
175 return false;
176 }
177 if (!acceptlist_set_.insert(ConnectAddressWithType(address_with_type))
178 .second) {
179 LOG_WARN("Attempted to add duplicate le address to acceptlist:%s",
180 ADDRESS_TO_LOGGABLE_CSTR(address_with_type));
181 }
182 return true;
183 }
184
Remove(const hci::AddressWithType & address_with_type)185 bool Remove(const hci::AddressWithType& address_with_type) {
186 auto iter = acceptlist_set_.find(ConnectAddressWithType(address_with_type));
187 if (iter == acceptlist_set_.end()) {
188 LOG_WARN("Unknown device being removed from acceptlist:%s",
189 ADDRESS_TO_LOGGABLE_CSTR(address_with_type));
190 return false;
191 }
192 acceptlist_set_.erase(ConnectAddressWithType(*iter));
193 return true;
194 }
195
GetCopy() const196 std::unordered_set<ConnectAddressWithType> GetCopy() const {
197 return acceptlist_set_;
198 }
199
IsFull() const200 bool IsFull() const {
201 return acceptlist_set_.size() == static_cast<size_t>(max_acceptlist_size_);
202 }
203
Clear()204 void Clear() { acceptlist_set_.clear(); }
205
GetMaxSize() const206 uint8_t GetMaxSize() const { return max_acceptlist_size_; }
207
208 private:
209 uint8_t max_acceptlist_size_{0};
210 std::unordered_set<ConnectAddressWithType> acceptlist_set_;
211 };
212
213 class ShadowAddressResolutionList {
214 public:
ShadowAddressResolutionList(uint8_t max_address_resolution_size)215 ShadowAddressResolutionList(uint8_t max_address_resolution_size)
216 : max_address_resolution_size_(max_address_resolution_size) {}
217
Add(const hci::AddressWithType & address_with_type)218 bool Add(const hci::AddressWithType& address_with_type) {
219 if (address_resolution_set_.size() == max_address_resolution_size_) {
220 LOG_ERROR("Address Resolution is full size:%zu",
221 address_resolution_set_.size());
222 return false;
223 }
224 if (!address_resolution_set_.insert(address_with_type).second) {
225 LOG_WARN("Attempted to add duplicate le address to address_resolution:%s",
226 ADDRESS_TO_LOGGABLE_CSTR(address_with_type));
227 }
228 return true;
229 }
230
Remove(const hci::AddressWithType & address_with_type)231 bool Remove(const hci::AddressWithType& address_with_type) {
232 auto iter = address_resolution_set_.find(address_with_type);
233 if (iter == address_resolution_set_.end()) {
234 LOG_WARN("Unknown device being removed from address_resolution:%s",
235 ADDRESS_TO_LOGGABLE_CSTR(address_with_type));
236 return false;
237 }
238 address_resolution_set_.erase(iter);
239 return true;
240 }
241
GetCopy() const242 std::unordered_set<hci::AddressWithType> GetCopy() const {
243 return address_resolution_set_;
244 }
245
IsFull() const246 bool IsFull() const {
247 return address_resolution_set_.size() ==
248 static_cast<size_t>(max_address_resolution_size_);
249 }
250
Size() const251 size_t Size() const { return address_resolution_set_.size(); }
252
Clear()253 void Clear() { address_resolution_set_.clear(); }
254
GetMaxSize() const255 uint8_t GetMaxSize() const { return max_address_resolution_size_; }
256
257 private:
258 uint8_t max_address_resolution_size_{0};
259 std::unordered_set<hci::AddressWithType> address_resolution_set_;
260 };
261
262 struct ConnectionDescriptor {
263 CreationTime creation_time_;
264 TeardownTime teardown_time_;
265 uint16_t handle_;
266 bool is_locally_initiated_;
267 hci::ErrorCode disconnect_reason_;
ConnectionDescriptor__anon0266bf8b0111::ConnectionDescriptor268 ConnectionDescriptor(CreationTime creation_time, TeardownTime teardown_time,
269 uint16_t handle, bool is_locally_initiated,
270 hci::ErrorCode disconnect_reason)
271 : creation_time_(creation_time),
272 teardown_time_(teardown_time),
273 handle_(handle),
274 is_locally_initiated_(is_locally_initiated),
275 disconnect_reason_(disconnect_reason) {}
276 virtual std::string GetPrivateRemoteAddress() const = 0;
~ConnectionDescriptor__anon0266bf8b0111::ConnectionDescriptor277 virtual ~ConnectionDescriptor() {}
ToString__anon0266bf8b0111::ConnectionDescriptor278 std::string ToString() const {
279 return base::StringPrintf(
280 "peer:%s handle:0x%04x is_locally_initiated:%s"
281 " creation_time:%s teardown_time:%s disconnect_reason:%s",
282 GetPrivateRemoteAddress().c_str(), handle_,
283 logbool(is_locally_initiated_).c_str(),
284 common::StringFormatTimeWithMilliseconds(
285 kConnectionDescriptorTimeFormat, creation_time_)
286 .c_str(),
287 common::StringFormatTimeWithMilliseconds(
288 kConnectionDescriptorTimeFormat, teardown_time_)
289 .c_str(),
290 hci::ErrorCodeText(disconnect_reason_).c_str());
291 }
292 };
293
294 struct ClassicConnectionDescriptor : public ConnectionDescriptor {
295 const hci::Address remote_address_;
ClassicConnectionDescriptor__anon0266bf8b0111::ClassicConnectionDescriptor296 ClassicConnectionDescriptor(const hci::Address& remote_address,
297 CreationTime creation_time,
298 TeardownTime teardown_time, uint16_t handle,
299 bool is_locally_initiated,
300 hci::ErrorCode disconnect_reason)
301 : ConnectionDescriptor(creation_time, teardown_time, handle,
302 is_locally_initiated, disconnect_reason),
303 remote_address_(remote_address) {}
GetPrivateRemoteAddress__anon0266bf8b0111::ClassicConnectionDescriptor304 virtual std::string GetPrivateRemoteAddress() const {
305 return ADDRESS_TO_LOGGABLE_CSTR(remote_address_);
306 }
307 };
308
309 struct LeConnectionDescriptor : public ConnectionDescriptor {
310 const hci::AddressWithType remote_address_with_type_;
LeConnectionDescriptor__anon0266bf8b0111::LeConnectionDescriptor311 LeConnectionDescriptor(hci::AddressWithType& remote_address_with_type,
312 CreationTime creation_time, TeardownTime teardown_time,
313 uint16_t handle, bool is_locally_initiated,
314 hci::ErrorCode disconnect_reason)
315 : ConnectionDescriptor(creation_time, teardown_time, handle,
316 is_locally_initiated, disconnect_reason),
317 remote_address_with_type_(remote_address_with_type) {}
GetPrivateRemoteAddress__anon0266bf8b0111::LeConnectionDescriptor318 std::string GetPrivateRemoteAddress() const {
319 return ADDRESS_TO_LOGGABLE_CSTR(remote_address_with_type_);
320 }
321 };
322
323 template <typename T>
324 class FixedQueue {
325 public:
FixedQueue(size_t max_size)326 explicit FixedQueue(size_t max_size) : max_size_(max_size) {}
Push(T element)327 void Push(T element) {
328 if (queue_.size() == max_size_) {
329 queue_.pop_front();
330 }
331 queue_.push_back(std::move(element));
332 }
333
ReadElementsAsString() const334 std::vector<std::string> ReadElementsAsString() const {
335 std::vector<std::string> vector;
336 for (auto& entry : queue_) {
337 vector.push_back(entry->ToString());
338 }
339 return vector;
340 }
341
342 private:
343 size_t max_size_{1};
344 std::deque<T> queue_;
345 };
346
347 constexpr size_t kConnectionHistorySize = 40;
348
LowByte(uint16_t val)349 inline uint8_t LowByte(uint16_t val) { return val & 0xff; }
HighByte(uint16_t val)350 inline uint8_t HighByte(uint16_t val) { return val >> 8; }
351
ValidateAclInterface(const shim::legacy::acl_interface_t & acl_interface)352 void ValidateAclInterface(const shim::legacy::acl_interface_t& acl_interface) {
353 ASSERT_LOG(acl_interface.on_send_data_upwards != nullptr,
354 "Must provide to receive data on acl links");
355 ASSERT_LOG(acl_interface.on_packets_completed != nullptr,
356 "Must provide to receive completed packet indication");
357
358 ASSERT_LOG(acl_interface.connection.classic.on_connected != nullptr,
359 "Must provide to respond to successful classic connections");
360 ASSERT_LOG(acl_interface.connection.classic.on_failed != nullptr,
361 "Must provide to respond when classic connection attempts fail");
362 ASSERT_LOG(
363 acl_interface.connection.classic.on_disconnected != nullptr,
364 "Must provide to respond when active classic connection disconnects");
365
366 ASSERT_LOG(acl_interface.connection.le.on_connected != nullptr,
367 "Must provide to respond to successful le connections");
368 ASSERT_LOG(acl_interface.connection.le.on_failed != nullptr,
369 "Must provide to respond when le connection attempts fail");
370 ASSERT_LOG(acl_interface.connection.le.on_disconnected != nullptr,
371 "Must provide to respond when active le connection disconnects");
372 }
373
374 } // namespace
375
376 #define TRY_POSTING_ON_MAIN(cb, ...) \
377 do { \
378 if (cb == nullptr) { \
379 LOG_WARN("Dropping ACL event with no callback"); \
380 } else { \
381 do_in_main_thread(FROM_HERE, base::Bind(cb, ##__VA_ARGS__)); \
382 } \
383 } while (0)
384
385 constexpr HciHandle kInvalidHciHandle = 0xffff;
386
387 class ShimAclConnection {
388 public:
ShimAclConnection(const HciHandle handle,SendDataUpwards send_data_upwards,os::Handler * handler,hci::acl_manager::AclConnection::QueueUpEnd * queue_up_end,CreationTime creation_time)389 ShimAclConnection(const HciHandle handle, SendDataUpwards send_data_upwards,
390 os::Handler* handler,
391 hci::acl_manager::AclConnection::QueueUpEnd* queue_up_end,
392 CreationTime creation_time)
393 : handle_(handle),
394 handler_(handler),
395 send_data_upwards_(send_data_upwards),
396 queue_up_end_(queue_up_end),
397 creation_time_(creation_time) {
398 queue_up_end_->RegisterDequeue(
399 handler_, common::Bind(&ShimAclConnection::data_ready_callback,
400 common::Unretained(this)));
401 }
402
~ShimAclConnection()403 virtual ~ShimAclConnection() {
404 if (!queue_.empty())
405 LOG_ERROR(
406 "ACL cleaned up with non-empty queue handle:0x%04x stranded_pkts:%zu",
407 handle_, queue_.size());
408 ASSERT_LOG(is_disconnected_,
409 "Shim Acl was not properly disconnected handle:0x%04x", handle_);
410 }
411
EnqueuePacket(std::unique_ptr<packet::RawBuilder> packet)412 void EnqueuePacket(std::unique_ptr<packet::RawBuilder> packet) {
413 // TODO Handle queue size exceeds some threshold
414 queue_.push(std::move(packet));
415 RegisterEnqueue();
416 }
417
handle_enqueue()418 std::unique_ptr<packet::BasePacketBuilder> handle_enqueue() {
419 auto packet = std::move(queue_.front());
420 queue_.pop();
421 if (queue_.empty()) {
422 UnregisterEnqueue();
423 }
424 return packet;
425 }
426
data_ready_callback()427 void data_ready_callback() {
428 auto packet = queue_up_end_->TryDequeue();
429 uint16_t length = packet->size();
430 std::vector<uint8_t> preamble;
431 preamble.push_back(LowByte(handle_));
432 preamble.push_back(HighByte(handle_));
433 preamble.push_back(LowByte(length));
434 preamble.push_back(HighByte(length));
435 BT_HDR* p_buf = MakeLegacyBtHdrPacket(std::move(packet), preamble);
436 ASSERT_LOG(p_buf != nullptr,
437 "Unable to allocate BT_HDR legacy packet handle:%04x", handle_);
438 if (send_data_upwards_ == nullptr) {
439 LOG_WARN("Dropping ACL data with no callback");
440 osi_free(p_buf);
441 } else if (do_in_main_thread(FROM_HERE,
442 base::Bind(send_data_upwards_, p_buf)) !=
443 BT_STATUS_SUCCESS) {
444 osi_free(p_buf);
445 }
446 }
447
448 virtual void InitiateDisconnect(hci::DisconnectReason reason) = 0;
449 virtual bool IsLocallyInitiated() const = 0;
450
GetCreationTime() const451 CreationTime GetCreationTime() const { return creation_time_; }
Handle() const452 uint16_t Handle() const { return handle_; }
453
Shutdown()454 void Shutdown() {
455 Disconnect();
456 LOG_INFO("Shutdown and disconnect ACL connection handle:0x%04x", handle_);
457 }
458
459 protected:
460 const uint16_t handle_{kInvalidHciHandle};
461 os::Handler* handler_;
462
UnregisterEnqueue()463 void UnregisterEnqueue() {
464 if (!is_enqueue_registered_) return;
465 is_enqueue_registered_ = false;
466 queue_up_end_->UnregisterEnqueue();
467 }
468
Disconnect()469 void Disconnect() {
470 if (is_disconnected_) {
471 LOG_ERROR(
472 "Cannot disconnect ACL multiple times handle:%04x creation_time:%s",
473 handle_,
474 common::StringFormatTimeWithMilliseconds(
475 kConnectionDescriptorTimeFormat, creation_time_)
476 .c_str());
477 return;
478 }
479 is_disconnected_ = true;
480 UnregisterEnqueue();
481 queue_up_end_->UnregisterDequeue();
482 if (!queue_.empty())
483 LOG_WARN(
484 "ACL disconnect with non-empty queue handle:%04x stranded_pkts::%zu",
485 handle_, queue_.size());
486 }
487
488 virtual void ReadRemoteControllerInformation() = 0;
489
490 private:
491 SendDataUpwards send_data_upwards_;
492 hci::acl_manager::AclConnection::QueueUpEnd* queue_up_end_;
493
494 std::queue<std::unique_ptr<packet::RawBuilder>> queue_;
495 bool is_enqueue_registered_{false};
496 bool is_disconnected_{false};
497 CreationTime creation_time_;
498
RegisterEnqueue()499 void RegisterEnqueue() {
500 ASSERT_LOG(!is_disconnected_,
501 "Unable to send data over disconnected channel handle:%04x",
502 handle_);
503 if (is_enqueue_registered_) return;
504 is_enqueue_registered_ = true;
505 queue_up_end_->RegisterEnqueue(
506 handler_, common::Bind(&ShimAclConnection::handle_enqueue,
507 common::Unretained(this)));
508 }
509
510 virtual void RegisterCallbacks() = 0;
511 };
512
513 class ClassicShimAclConnection
514 : public ShimAclConnection,
515 public hci::acl_manager::ConnectionManagementCallbacks {
516 public:
ClassicShimAclConnection(SendDataUpwards send_data_upwards,OnDisconnect on_disconnect,const shim::legacy::acl_classic_link_interface_t & interface,os::Handler * handler,std::unique_ptr<hci::acl_manager::ClassicAclConnection> connection,CreationTime creation_time)517 ClassicShimAclConnection(
518 SendDataUpwards send_data_upwards, OnDisconnect on_disconnect,
519 const shim::legacy::acl_classic_link_interface_t& interface,
520 os::Handler* handler,
521 std::unique_ptr<hci::acl_manager::ClassicAclConnection> connection,
522 CreationTime creation_time)
523 : ShimAclConnection(connection->GetHandle(), send_data_upwards, handler,
524 connection->GetAclQueueEnd(), creation_time),
525 on_disconnect_(on_disconnect),
526 interface_(interface),
527 connection_(std::move(connection)) {}
528
RegisterCallbacks()529 void RegisterCallbacks() override {
530 connection_->RegisterCallbacks(this, handler_);
531 }
532
ReadRemoteControllerInformation()533 void ReadRemoteControllerInformation() override {
534 connection_->ReadRemoteVersionInformation();
535 connection_->ReadRemoteSupportedFeatures();
536 }
537
OnConnectionPacketTypeChanged(uint16_t packet_type)538 void OnConnectionPacketTypeChanged(uint16_t packet_type) override {
539 TRY_POSTING_ON_MAIN(interface_.on_packet_type_changed, packet_type);
540 }
541
OnAuthenticationComplete(hci::ErrorCode hci_status)542 void OnAuthenticationComplete(hci::ErrorCode hci_status) override {
543 TRY_POSTING_ON_MAIN(interface_.on_authentication_complete, handle_,
544 ToLegacyHciErrorCode(hci_status));
545 }
546
OnEncryptionChange(hci::EncryptionEnabled enabled)547 void OnEncryptionChange(hci::EncryptionEnabled enabled) override {
548 bool is_enabled = (enabled == hci::EncryptionEnabled::ON ||
549 enabled == hci::EncryptionEnabled::BR_EDR_AES_CCM);
550 TRY_POSTING_ON_MAIN(interface_.on_encryption_change, is_enabled);
551 }
552
OnChangeConnectionLinkKeyComplete()553 void OnChangeConnectionLinkKeyComplete() override {
554 TRY_POSTING_ON_MAIN(interface_.on_change_connection_link_key_complete);
555 }
556
OnReadClockOffsetComplete(uint16_t clock_offset)557 void OnReadClockOffsetComplete(uint16_t clock_offset) override {
558 LOG_INFO("UNIMPLEMENTED");
559 }
560
OnModeChange(hci::ErrorCode status,hci::Mode current_mode,uint16_t interval)561 void OnModeChange(hci::ErrorCode status, hci::Mode current_mode,
562 uint16_t interval) override {
563 TRY_POSTING_ON_MAIN(interface_.on_mode_change, ToLegacyHciErrorCode(status),
564 handle_, ToLegacyHciMode(current_mode), interval);
565 }
566
OnSniffSubrating(hci::ErrorCode hci_status,uint16_t maximum_transmit_latency,uint16_t maximum_receive_latency,uint16_t minimum_remote_timeout,uint16_t minimum_local_timeout)567 void OnSniffSubrating(hci::ErrorCode hci_status,
568 uint16_t maximum_transmit_latency,
569 uint16_t maximum_receive_latency,
570 uint16_t minimum_remote_timeout,
571 uint16_t minimum_local_timeout) {
572 TRY_POSTING_ON_MAIN(interface_.on_sniff_subrating,
573 ToLegacyHciErrorCode(hci_status), handle_,
574 maximum_transmit_latency, maximum_receive_latency,
575 minimum_remote_timeout, minimum_local_timeout);
576 }
577
OnQosSetupComplete(hci::ServiceType service_type,uint32_t token_rate,uint32_t peak_bandwidth,uint32_t latency,uint32_t delay_variation)578 void OnQosSetupComplete(hci::ServiceType service_type, uint32_t token_rate,
579 uint32_t peak_bandwidth, uint32_t latency,
580 uint32_t delay_variation) override {
581 LOG_INFO("UNIMPLEMENTED");
582 }
583
OnFlowSpecificationComplete(hci::FlowDirection flow_direction,hci::ServiceType service_type,uint32_t token_rate,uint32_t token_bucket_size,uint32_t peak_bandwidth,uint32_t access_latency)584 void OnFlowSpecificationComplete(hci::FlowDirection flow_direction,
585 hci::ServiceType service_type,
586 uint32_t token_rate,
587 uint32_t token_bucket_size,
588 uint32_t peak_bandwidth,
589 uint32_t access_latency) override {
590 LOG_INFO("UNIMPLEMENTED");
591 }
592
OnFlushOccurred()593 void OnFlushOccurred() override { LOG_INFO("UNIMPLEMENTED"); }
594
OnRoleDiscoveryComplete(hci::Role current_role)595 void OnRoleDiscoveryComplete(hci::Role current_role) override {
596 LOG_INFO("UNIMPLEMENTED");
597 }
598
OnReadLinkPolicySettingsComplete(uint16_t link_policy_settings)599 void OnReadLinkPolicySettingsComplete(
600 uint16_t link_policy_settings) override {
601 LOG_INFO("UNIMPLEMENTED");
602 }
603
OnReadAutomaticFlushTimeoutComplete(uint16_t flush_timeout)604 void OnReadAutomaticFlushTimeoutComplete(uint16_t flush_timeout) override {
605 LOG_INFO("UNIMPLEMENTED");
606 }
607
OnReadTransmitPowerLevelComplete(uint8_t transmit_power_level)608 void OnReadTransmitPowerLevelComplete(uint8_t transmit_power_level) override {
609 LOG_INFO("UNIMPLEMENTED");
610 }
611
OnReadLinkSupervisionTimeoutComplete(uint16_t link_supervision_timeout)612 void OnReadLinkSupervisionTimeoutComplete(
613 uint16_t link_supervision_timeout) override {
614 LOG_INFO("UNIMPLEMENTED");
615 }
616
OnReadFailedContactCounterComplete(uint16_t failed_contact_counter)617 void OnReadFailedContactCounterComplete(
618 uint16_t failed_contact_counter) override {
619 LOG_INFO("UNIMPLEMENTED");
620 }
621
OnReadLinkQualityComplete(uint8_t link_quality)622 void OnReadLinkQualityComplete(uint8_t link_quality) override {
623 LOG_INFO("UNIMPLEMENTED");
624 }
625
OnReadAfhChannelMapComplete(hci::AfhMode afh_mode,std::array<uint8_t,10> afh_channel_map)626 void OnReadAfhChannelMapComplete(
627 hci::AfhMode afh_mode, std::array<uint8_t, 10> afh_channel_map) override {
628 LOG_INFO("UNIMPLEMENTED");
629 }
630
OnReadRssiComplete(uint8_t rssi)631 void OnReadRssiComplete(uint8_t rssi) override { LOG_INFO("UNIMPLEMENTED"); }
632
OnReadClockComplete(uint32_t clock,uint16_t accuracy)633 void OnReadClockComplete(uint32_t clock, uint16_t accuracy) override {
634 LOG_INFO("UNIMPLEMENTED");
635 }
636
OnCentralLinkKeyComplete(hci::KeyFlag key_flag)637 void OnCentralLinkKeyComplete(hci::KeyFlag key_flag) override {
638 LOG_INFO("%s UNIMPLEMENTED", __func__);
639 }
640
OnRoleChange(hci::ErrorCode hci_status,hci::Role new_role)641 void OnRoleChange(hci::ErrorCode hci_status, hci::Role new_role) override {
642 TRY_POSTING_ON_MAIN(
643 interface_.on_role_change, ToLegacyHciErrorCode(hci_status),
644 ToRawAddress(connection_->GetAddress()), ToLegacyRole(new_role));
645 BTM_LogHistory(kBtmLogTag, ToRawAddress(connection_->GetAddress()),
646 "Role change",
647 base::StringPrintf("classic New_role:%s status:%s",
648 hci::RoleText(new_role).c_str(),
649 hci::ErrorCodeText(hci_status).c_str()));
650 }
651
OnDisconnection(hci::ErrorCode reason)652 void OnDisconnection(hci::ErrorCode reason) override {
653 Disconnect();
654 on_disconnect_(handle_, reason);
655 }
656
OnReadRemoteVersionInformationComplete(hci::ErrorCode hci_status,uint8_t lmp_version,uint16_t manufacturer_name,uint16_t sub_version)657 void OnReadRemoteVersionInformationComplete(hci::ErrorCode hci_status,
658 uint8_t lmp_version,
659 uint16_t manufacturer_name,
660 uint16_t sub_version) override {
661 TRY_POSTING_ON_MAIN(interface_.on_read_remote_version_information_complete,
662 ToLegacyHciErrorCode(hci_status), handle_, lmp_version,
663 manufacturer_name, sub_version);
664 }
665
OnReadRemoteSupportedFeaturesComplete(uint64_t features)666 void OnReadRemoteSupportedFeaturesComplete(uint64_t features) override {
667 TRY_POSTING_ON_MAIN(interface_.on_read_remote_supported_features_complete,
668 handle_, features);
669
670 if (features & ((uint64_t(1) << 63))) {
671 connection_->ReadRemoteExtendedFeatures(1);
672 return;
673 }
674 LOG_DEBUG("Device does not support extended features");
675 }
676
OnReadRemoteExtendedFeaturesComplete(uint8_t page_number,uint8_t max_page_number,uint64_t features)677 void OnReadRemoteExtendedFeaturesComplete(uint8_t page_number,
678 uint8_t max_page_number,
679 uint64_t features) override {
680 TRY_POSTING_ON_MAIN(interface_.on_read_remote_extended_features_complete,
681 handle_, page_number, max_page_number, features);
682
683 // Supported features aliases to extended features page 0
684 if (page_number == 0 && !(features & ((uint64_t(1) << 63)))) {
685 LOG_DEBUG("Device does not support extended features");
686 return;
687 }
688
689 if (max_page_number != 0 && page_number != max_page_number)
690 connection_->ReadRemoteExtendedFeatures(page_number + 1);
691 }
692
GetRemoteAddress() const693 hci::Address GetRemoteAddress() const { return connection_->GetAddress(); }
694
InitiateDisconnect(hci::DisconnectReason reason)695 void InitiateDisconnect(hci::DisconnectReason reason) override {
696 connection_->Disconnect(reason);
697 }
698
HoldMode(uint16_t max_interval,uint16_t min_interval)699 void HoldMode(uint16_t max_interval, uint16_t min_interval) {
700 ASSERT(connection_->HoldMode(max_interval, min_interval));
701 }
702
SniffMode(uint16_t max_interval,uint16_t min_interval,uint16_t attempt,uint16_t timeout)703 void SniffMode(uint16_t max_interval, uint16_t min_interval, uint16_t attempt,
704 uint16_t timeout) {
705 ASSERT(
706 connection_->SniffMode(max_interval, min_interval, attempt, timeout));
707 }
708
ExitSniffMode()709 void ExitSniffMode() { ASSERT(connection_->ExitSniffMode()); }
710
SniffSubrating(uint16_t maximum_latency,uint16_t minimum_remote_timeout,uint16_t minimum_local_timeout)711 void SniffSubrating(uint16_t maximum_latency, uint16_t minimum_remote_timeout,
712 uint16_t minimum_local_timeout) {
713 ASSERT(connection_->SniffSubrating(maximum_latency, minimum_remote_timeout,
714 minimum_local_timeout));
715 }
716
SetConnectionEncryption(hci::Enable is_encryption_enabled)717 void SetConnectionEncryption(hci::Enable is_encryption_enabled) {
718 ASSERT(connection_->SetConnectionEncryption(is_encryption_enabled));
719 }
720
IsLocallyInitiated() const721 bool IsLocallyInitiated() const override {
722 return connection_->locally_initiated_;
723 }
724
725 private:
726 OnDisconnect on_disconnect_;
727 const shim::legacy::acl_classic_link_interface_t interface_;
728 std::unique_ptr<hci::acl_manager::ClassicAclConnection> connection_;
729 };
730
731 class LeShimAclConnection
732 : public ShimAclConnection,
733 public hci::acl_manager::LeConnectionManagementCallbacks {
734 public:
LeShimAclConnection(SendDataUpwards send_data_upwards,OnDisconnect on_disconnect,const shim::legacy::acl_le_link_interface_t & interface,os::Handler * handler,std::unique_ptr<hci::acl_manager::LeAclConnection> connection,std::chrono::time_point<std::chrono::system_clock> creation_time)735 LeShimAclConnection(
736 SendDataUpwards send_data_upwards, OnDisconnect on_disconnect,
737 const shim::legacy::acl_le_link_interface_t& interface,
738 os::Handler* handler,
739 std::unique_ptr<hci::acl_manager::LeAclConnection> connection,
740 std::chrono::time_point<std::chrono::system_clock> creation_time)
741 : ShimAclConnection(connection->GetHandle(), send_data_upwards, handler,
742 connection->GetAclQueueEnd(), creation_time),
743 on_disconnect_(on_disconnect),
744 interface_(interface),
745 connection_(std::move(connection)) {}
746
RegisterCallbacks()747 void RegisterCallbacks() override {
748 connection_->RegisterCallbacks(this, handler_);
749 }
750
LeSubrateRequest(uint16_t subrate_min,uint16_t subrate_max,uint16_t max_latency,uint16_t cont_num,uint16_t sup_tout)751 void LeSubrateRequest(uint16_t subrate_min, uint16_t subrate_max,
752 uint16_t max_latency, uint16_t cont_num,
753 uint16_t sup_tout) {
754 connection_->LeSubrateRequest(subrate_min, subrate_max, max_latency,
755 cont_num, sup_tout);
756 }
757
ReadRemoteControllerInformation()758 void ReadRemoteControllerInformation() override {
759 // TODO Issue LeReadRemoteFeatures Command
760 }
761
GetLocalAddressWithType()762 bluetooth::hci::AddressWithType GetLocalAddressWithType() {
763 return connection_->GetLocalAddress();
764 }
765
GetAdvertisingSetConnectedTo()766 std::optional<uint8_t> GetAdvertisingSetConnectedTo() {
767 return std::visit(
768 [](auto&& data) {
769 using T = std::decay_t<decltype(data)>;
770 if constexpr (std::is_same_v<T, hci::acl_manager::DataAsPeripheral>) {
771 return data.advertising_set_id;
772 } else {
773 return std::optional<uint8_t>{};
774 }
775 },
776 connection_->GetRoleSpecificData());
777 }
778
OnConnectionUpdate(hci::ErrorCode hci_status,uint16_t connection_interval,uint16_t connection_latency,uint16_t supervision_timeout)779 void OnConnectionUpdate(hci::ErrorCode hci_status,
780 uint16_t connection_interval,
781 uint16_t connection_latency,
782 uint16_t supervision_timeout) {
783 TRY_POSTING_ON_MAIN(
784 interface_.on_connection_update, ToLegacyHciErrorCode(hci_status),
785 handle_, connection_interval, connection_latency, supervision_timeout);
786 }
OnDataLengthChange(uint16_t max_tx_octets,uint16_t max_tx_time,uint16_t max_rx_octets,uint16_t max_rx_time)787 void OnDataLengthChange(uint16_t max_tx_octets, uint16_t max_tx_time,
788 uint16_t max_rx_octets, uint16_t max_rx_time) {
789 TRY_POSTING_ON_MAIN(interface_.on_data_length_change, handle_,
790 max_tx_octets, max_tx_time, max_rx_octets, max_rx_time);
791 }
OnLeSubrateChange(hci::ErrorCode hci_status,uint16_t subrate_factor,uint16_t peripheral_latency,uint16_t continuation_number,uint16_t supervision_timeout)792 void OnLeSubrateChange(hci::ErrorCode hci_status, uint16_t subrate_factor,
793 uint16_t peripheral_latency,
794 uint16_t continuation_number,
795 uint16_t supervision_timeout) {
796 TRY_POSTING_ON_MAIN(interface_.on_le_subrate_change, handle_,
797 subrate_factor, peripheral_latency, continuation_number,
798 supervision_timeout, ToLegacyHciErrorCode(hci_status));
799 }
800
OnReadRemoteVersionInformationComplete(hci::ErrorCode hci_status,uint8_t lmp_version,uint16_t manufacturer_name,uint16_t sub_version)801 void OnReadRemoteVersionInformationComplete(hci::ErrorCode hci_status,
802 uint8_t lmp_version,
803 uint16_t manufacturer_name,
804 uint16_t sub_version) override {
805 TRY_POSTING_ON_MAIN(interface_.on_read_remote_version_information_complete,
806 ToLegacyHciErrorCode(hci_status), handle_, lmp_version,
807 manufacturer_name, sub_version);
808 }
809
OnLeReadRemoteFeaturesComplete(hci::ErrorCode hci_status,uint64_t features)810 void OnLeReadRemoteFeaturesComplete(hci::ErrorCode hci_status,
811 uint64_t features) {
812 // TODO
813 }
814
OnPhyUpdate(hci::ErrorCode hci_status,uint8_t tx_phy,uint8_t rx_phy)815 void OnPhyUpdate(hci::ErrorCode hci_status, uint8_t tx_phy,
816 uint8_t rx_phy) override {
817 if (common::init_flags::pass_phy_update_callback_is_enabled()) {
818 TRY_POSTING_ON_MAIN(
819 interface_.on_phy_update,
820 static_cast<tGATT_STATUS>(ToLegacyHciErrorCode(hci_status)), handle_,
821 tx_phy, rx_phy);
822 } else {
823 LOG_WARN("Not posting OnPhyUpdate callback since it is disabled: (tx:%x, rx:%x, status:%s)",
824 tx_phy, rx_phy, hci::ErrorCodeText(hci_status).c_str());
825 }
826 }
827
OnDisconnection(hci::ErrorCode reason)828 void OnDisconnection(hci::ErrorCode reason) {
829 Disconnect();
830 on_disconnect_(handle_, reason);
831 }
832
GetRemoteAddressWithType() const833 hci::AddressWithType GetRemoteAddressWithType() const {
834 return connection_->GetRemoteAddress();
835 }
836
InitiateDisconnect(hci::DisconnectReason reason)837 void InitiateDisconnect(hci::DisconnectReason reason) override {
838 connection_->Disconnect(reason);
839 }
840
IsLocallyInitiated() const841 bool IsLocallyInitiated() const override {
842 return connection_->locally_initiated_;
843 }
844
IsInFilterAcceptList() const845 bool IsInFilterAcceptList() const {
846 return connection_->IsInFilterAcceptList();
847 }
848
849 private:
850 OnDisconnect on_disconnect_;
851 const shim::legacy::acl_le_link_interface_t interface_;
852 std::unique_ptr<hci::acl_manager::LeAclConnection> connection_;
853 };
854
855 struct shim::legacy::Acl::impl {
implshim::legacy::Acl::impl856 impl(uint8_t max_acceptlist_size, uint8_t max_address_resolution_size)
857 : shadow_acceptlist_(ShadowAcceptlist(max_acceptlist_size)),
858 shadow_address_resolution_list_(
859 ShadowAddressResolutionList(max_address_resolution_size)) {}
860
861 std::map<HciHandle, std::unique_ptr<ClassicShimAclConnection>>
862 handle_to_classic_connection_map_;
863 std::map<HciHandle, std::unique_ptr<LeShimAclConnection>>
864 handle_to_le_connection_map_;
865
866 SyncMapCount<std::string> classic_acl_disconnect_reason_;
867 SyncMapCount<std::string> le_acl_disconnect_reason_;
868
869 FixedQueue<std::unique_ptr<ConnectionDescriptor>> connection_history_ =
870 FixedQueue<std::unique_ptr<ConnectionDescriptor>>(kConnectionHistorySize);
871
872 ShadowAcceptlist shadow_acceptlist_;
873 ShadowAddressResolutionList shadow_address_resolution_list_;
874
IsClassicAclshim::legacy::Acl::impl875 bool IsClassicAcl(HciHandle handle) {
876 return handle_to_classic_connection_map_.find(handle) !=
877 handle_to_classic_connection_map_.end();
878 }
879
EnqueueClassicPacketshim::legacy::Acl::impl880 void EnqueueClassicPacket(HciHandle handle,
881 std::unique_ptr<packet::RawBuilder> packet) {
882 ASSERT_LOG(IsClassicAcl(handle), "handle %d is not a classic connection",
883 handle);
884 handle_to_classic_connection_map_[handle]->EnqueuePacket(std::move(packet));
885 }
886
IsLeAclshim::legacy::Acl::impl887 bool IsLeAcl(HciHandle handle) {
888 return handle_to_le_connection_map_.find(handle) !=
889 handle_to_le_connection_map_.end();
890 }
891
EnqueueLePacketshim::legacy::Acl::impl892 void EnqueueLePacket(HciHandle handle,
893 std::unique_ptr<packet::RawBuilder> packet) {
894 ASSERT_LOG(IsLeAcl(handle), "handle %d is not a LE connection", handle);
895 handle_to_le_connection_map_[handle]->EnqueuePacket(std::move(packet));
896 }
897
DisconnectClassicConnectionsshim::legacy::Acl::impl898 void DisconnectClassicConnections(std::promise<void> promise) {
899 LOG_INFO("Disconnect gd acl shim classic connections");
900 std::vector<HciHandle> disconnect_handles;
901 for (auto& connection : handle_to_classic_connection_map_) {
902 disconnect_classic(connection.first, HCI_ERR_REMOTE_POWER_OFF,
903 "Suspend disconnect");
904 disconnect_handles.push_back(connection.first);
905 }
906
907 // Since this is a suspend disconnect, we immediately also call
908 // |OnClassicSuspendInitiatedDisconnect| without waiting for it to happen.
909 // We want the stack to clean up ahead of the link layer (since we will mask
910 // away that event). The reason we do this in a separate loop is that this
911 // will also remove the handle from the connection map.
912 for (auto& handle : disconnect_handles) {
913 auto found = handle_to_classic_connection_map_.find(handle);
914 if (found != handle_to_classic_connection_map_.end()) {
915 GetAclManager()->OnClassicSuspendInitiatedDisconnect(
916 found->first, hci::ErrorCode::CONNECTION_TERMINATED_BY_LOCAL_HOST);
917 }
918 }
919
920 promise.set_value();
921 }
922
ShutdownClassicConnectionsshim::legacy::Acl::impl923 void ShutdownClassicConnections(std::promise<void> promise) {
924 LOG_INFO("Shutdown gd acl shim classic connections");
925 for (auto& connection : handle_to_classic_connection_map_) {
926 connection.second->Shutdown();
927 }
928 handle_to_classic_connection_map_.clear();
929 promise.set_value();
930 }
931
DisconnectLeConnectionsshim::legacy::Acl::impl932 void DisconnectLeConnections(std::promise<void> promise) {
933 LOG_INFO("Disconnect gd acl shim le connections");
934 std::vector<HciHandle> disconnect_handles;
935 for (auto& connection : handle_to_le_connection_map_) {
936 disconnect_le(connection.first, HCI_ERR_REMOTE_POWER_OFF,
937 "Suspend disconnect");
938 disconnect_handles.push_back(connection.first);
939 }
940
941 // Since this is a suspend disconnect, we immediately also call
942 // |OnLeSuspendInitiatedDisconnect| without waiting for it to happen. We
943 // want the stack to clean up ahead of the link layer (since we will mask
944 // away that event). The reason we do this in a separate loop is that this
945 // will also remove the handle from the connection map.
946 for (auto& handle : disconnect_handles) {
947 auto found = handle_to_le_connection_map_.find(handle);
948 if (found != handle_to_le_connection_map_.end()) {
949 GetAclManager()->OnLeSuspendInitiatedDisconnect(
950 found->first, hci::ErrorCode::CONNECTION_TERMINATED_BY_LOCAL_HOST);
951 }
952 }
953 promise.set_value();
954 }
955
ShutdownLeConnectionsshim::legacy::Acl::impl956 void ShutdownLeConnections(std::promise<void> promise) {
957 LOG_INFO("Shutdown gd acl shim le connections");
958 for (auto& connection : handle_to_le_connection_map_) {
959 connection.second->Shutdown();
960 }
961 handle_to_le_connection_map_.clear();
962 promise.set_value();
963 }
964
FinalShutdownshim::legacy::Acl::impl965 void FinalShutdown(std::promise<void> promise) {
966 if (!handle_to_classic_connection_map_.empty()) {
967 for (auto& connection : handle_to_classic_connection_map_) {
968 connection.second->Shutdown();
969 }
970 handle_to_classic_connection_map_.clear();
971 LOG_INFO("Cleared all classic connections count:%zu",
972 handle_to_classic_connection_map_.size());
973 }
974
975 if (!handle_to_le_connection_map_.empty()) {
976 for (auto& connection : handle_to_le_connection_map_) {
977 connection.second->Shutdown();
978 }
979 handle_to_le_connection_map_.clear();
980 LOG_INFO("Cleared all le connections count:%zu",
981 handle_to_le_connection_map_.size());
982 }
983 promise.set_value();
984 }
985
HoldModeshim::legacy::Acl::impl986 void HoldMode(HciHandle handle, uint16_t max_interval,
987 uint16_t min_interval) {
988 ASSERT_LOG(IsClassicAcl(handle), "handle %d is not a classic connection",
989 handle);
990 handle_to_classic_connection_map_[handle]->HoldMode(max_interval,
991 min_interval);
992 }
993
ExitSniffModeshim::legacy::Acl::impl994 void ExitSniffMode(HciHandle handle) {
995 ASSERT_LOG(IsClassicAcl(handle), "handle %d is not a classic connection",
996 handle);
997 handle_to_classic_connection_map_[handle]->ExitSniffMode();
998 }
999
SniffModeshim::legacy::Acl::impl1000 void SniffMode(HciHandle handle, uint16_t max_interval, uint16_t min_interval,
1001 uint16_t attempt, uint16_t timeout) {
1002 ASSERT_LOG(IsClassicAcl(handle), "handle %d is not a classic connection",
1003 handle);
1004 handle_to_classic_connection_map_[handle]->SniffMode(
1005 max_interval, min_interval, attempt, timeout);
1006 }
1007
SniffSubratingshim::legacy::Acl::impl1008 void SniffSubrating(HciHandle handle, uint16_t maximum_latency,
1009 uint16_t minimum_remote_timeout,
1010 uint16_t minimum_local_timeout) {
1011 ASSERT_LOG(IsClassicAcl(handle), "handle %d is not a classic connection",
1012 handle);
1013 handle_to_classic_connection_map_[handle]->SniffSubrating(
1014 maximum_latency, minimum_remote_timeout, minimum_local_timeout);
1015 }
1016
LeSetDefaultSubrateshim::legacy::Acl::impl1017 void LeSetDefaultSubrate(uint16_t subrate_min, uint16_t subrate_max,
1018 uint16_t max_latency, uint16_t cont_num,
1019 uint16_t sup_tout) {
1020 GetAclManager()->LeSetDefaultSubrate(subrate_min, subrate_max, max_latency,
1021 cont_num, sup_tout);
1022 }
1023
LeSubrateRequestshim::legacy::Acl::impl1024 void LeSubrateRequest(HciHandle handle, uint16_t subrate_min,
1025 uint16_t subrate_max, uint16_t max_latency,
1026 uint16_t cont_num, uint16_t sup_tout) {
1027 ASSERT_LOG(IsLeAcl(handle), "handle %d is not a LE connection", handle);
1028 handle_to_le_connection_map_[handle]->LeSubrateRequest(
1029 subrate_min, subrate_max, max_latency, cont_num, sup_tout);
1030 }
1031
SetConnectionEncryptionshim::legacy::Acl::impl1032 void SetConnectionEncryption(HciHandle handle, hci::Enable enable) {
1033 ASSERT_LOG(IsClassicAcl(handle), "handle %d is not a classic connection",
1034 handle);
1035 handle_to_classic_connection_map_[handle]->SetConnectionEncryption(enable);
1036 }
1037
disconnect_classicshim::legacy::Acl::impl1038 void disconnect_classic(uint16_t handle, tHCI_STATUS reason,
1039 std::string comment) {
1040 auto connection = handle_to_classic_connection_map_.find(handle);
1041 if (connection != handle_to_classic_connection_map_.end()) {
1042 auto remote_address = connection->second->GetRemoteAddress();
1043 connection->second->InitiateDisconnect(
1044 ToDisconnectReasonFromLegacy(reason));
1045 LOG_DEBUG("Disconnection initiated classic remote:%s handle:%hu",
1046 ADDRESS_TO_LOGGABLE_CSTR(remote_address), handle);
1047 BTM_LogHistory(kBtmLogTag, ToRawAddress(remote_address),
1048 "Disconnection initiated",
1049 base::StringPrintf("classic reason:%s comment:%s",
1050 hci_status_code_text(reason).c_str(),
1051 comment.c_str()));
1052 classic_acl_disconnect_reason_.Put(comment);
1053 } else {
1054 LOG_WARN("Unable to disconnect unknown classic connection handle:0x%04x",
1055 handle);
1056 }
1057 }
1058
disconnect_leshim::legacy::Acl::impl1059 void disconnect_le(uint16_t handle, tHCI_STATUS reason, std::string comment) {
1060 auto connection = handle_to_le_connection_map_.find(handle);
1061 if (connection != handle_to_le_connection_map_.end()) {
1062 auto remote_address_with_type =
1063 connection->second->GetRemoteAddressWithType();
1064 if (!common::init_flags::use_unified_connection_manager_is_enabled()) {
1065 GetAclManager()->RemoveFromBackgroundList(remote_address_with_type);
1066 }
1067 connection->second->InitiateDisconnect(
1068 ToDisconnectReasonFromLegacy(reason));
1069 LOG_DEBUG("Disconnection initiated le remote:%s handle:%hu",
1070 ADDRESS_TO_LOGGABLE_CSTR(remote_address_with_type), handle);
1071 BTM_LogHistory(kBtmLogTag,
1072 ToLegacyAddressWithType(remote_address_with_type),
1073 "Disconnection initiated",
1074 base::StringPrintf("Le reason:%s comment:%s",
1075 hci_status_code_text(reason).c_str(),
1076 comment.c_str()));
1077 le_acl_disconnect_reason_.Put(comment);
1078 } else {
1079 LOG_WARN("Unable to disconnect unknown le connection handle:0x%04x",
1080 handle);
1081 }
1082 }
1083
accept_le_connection_fromshim::legacy::Acl::impl1084 void accept_le_connection_from(const hci::AddressWithType& address_with_type,
1085 bool is_direct, std::promise<bool> promise) {
1086 if (shadow_acceptlist_.IsFull()) {
1087 LOG_ERROR("Acceptlist is full preventing new Le connection");
1088 promise.set_value(false);
1089 return;
1090 }
1091 shadow_acceptlist_.Add(address_with_type);
1092 promise.set_value(true);
1093 GetAclManager()->CreateLeConnection(address_with_type, is_direct);
1094 LOG_DEBUG("Allow Le connection from remote:%s",
1095 ADDRESS_TO_LOGGABLE_CSTR(address_with_type));
1096 BTM_LogHistory(kBtmLogTag, ToLegacyAddressWithType(address_with_type),
1097 "Allow connection from", "Le");
1098 }
1099
ignore_le_connection_fromshim::legacy::Acl::impl1100 void ignore_le_connection_from(
1101 const hci::AddressWithType& address_with_type) {
1102 shadow_acceptlist_.Remove(address_with_type);
1103 GetAclManager()->CancelLeConnect(address_with_type);
1104 LOG_DEBUG("Ignore Le connection from remote:%s",
1105 ADDRESS_TO_LOGGABLE_CSTR(address_with_type));
1106 BTM_LogHistory(kBtmLogTag, ToLegacyAddressWithType(address_with_type),
1107 "Ignore connection from", "Le");
1108 }
1109
clear_acceptlistshim::legacy::Acl::impl1110 void clear_acceptlist() {
1111 auto shadow_acceptlist = shadow_acceptlist_.GetCopy();
1112 size_t count = shadow_acceptlist.size();
1113 GetAclManager()->ClearFilterAcceptList();
1114 shadow_acceptlist_.Clear();
1115 LOG_DEBUG("Cleared entire Le address acceptlist count:%zu", count);
1116 }
1117
le_randshim::legacy::Acl::impl1118 void le_rand(LeRandCallback cb ) {
1119 controller_get_interface()->le_rand(cb);
1120 }
1121
AddToAddressResolutionshim::legacy::Acl::impl1122 void AddToAddressResolution(const hci::AddressWithType& address_with_type,
1123 const std::array<uint8_t, 16>& peer_irk,
1124 const std::array<uint8_t, 16>& local_irk) {
1125 if (shadow_address_resolution_list_.IsFull()) {
1126 LOG_WARN("Le Address Resolution list is full size:%zu",
1127 shadow_address_resolution_list_.Size());
1128 return;
1129 }
1130 // TODO This should really be added upon successful completion
1131 shadow_address_resolution_list_.Add(address_with_type);
1132 GetAclManager()->AddDeviceToResolvingList(address_with_type, peer_irk,
1133 local_irk);
1134 }
1135
RemoveFromAddressResolutionshim::legacy::Acl::impl1136 void RemoveFromAddressResolution(
1137 const hci::AddressWithType& address_with_type) {
1138 // TODO This should really be removed upon successful removal
1139 if (!shadow_address_resolution_list_.Remove(address_with_type)) {
1140 LOG_WARN("Unable to remove from Le Address Resolution list device:%s",
1141 ADDRESS_TO_LOGGABLE_CSTR(address_with_type));
1142 }
1143 GetAclManager()->RemoveDeviceFromResolvingList(address_with_type);
1144 }
1145
ClearResolvingListshim::legacy::Acl::impl1146 void ClearResolvingList() {
1147 GetAclManager()->ClearResolvingList();
1148 // TODO This should really be cleared after successful clear status
1149 shadow_address_resolution_list_.Clear();
1150 }
1151
SetSystemSuspendStateshim::legacy::Acl::impl1152 void SetSystemSuspendState(bool suspended) {
1153 GetAclManager()->SetSystemSuspendState(suspended);
1154 }
1155
DumpConnectionHistoryshim::legacy::Acl::impl1156 void DumpConnectionHistory() const {
1157 std::vector<std::string> history =
1158 connection_history_.ReadElementsAsString();
1159 for (auto& entry : history) {
1160 LOG_DEBUG("%s", entry.c_str());
1161 }
1162 const auto acceptlist = shadow_acceptlist_.GetCopy();
1163 LOG_DEBUG("Shadow le accept list size:%-3zu controller_max_size:%hhu",
1164 acceptlist.size(), shadow_acceptlist_.GetMaxSize());
1165 for (auto& entry : acceptlist) {
1166 LOG_DEBUG("acceptlist:%s", ADDRESS_TO_LOGGABLE_CSTR(entry));
1167 }
1168 }
1169
1170 #define DUMPSYS_TAG "shim::acl"
DumpConnectionHistoryshim::legacy::Acl::impl1171 void DumpConnectionHistory(int fd) const {
1172 std::vector<std::string> history =
1173 connection_history_.ReadElementsAsString();
1174 for (auto& entry : history) {
1175 LOG_DUMPSYS(fd, "%s", entry.c_str());
1176 }
1177 if (classic_acl_disconnect_reason_.Size() > 0) {
1178 LOG_DUMPSYS(fd, "Classic sources of initiated disconnects");
1179 for (const auto& item :
1180 classic_acl_disconnect_reason_.GetSortedHighToLow()) {
1181 LOG_DUMPSYS(fd, " %s:%zu", item.item.c_str(), item.count);
1182 }
1183 }
1184 if (le_acl_disconnect_reason_.Size() > 0) {
1185 LOG_DUMPSYS(fd, "Le sources of initiated disconnects");
1186 for (const auto& item : le_acl_disconnect_reason_.GetSortedHighToLow()) {
1187 LOG_DUMPSYS(fd, " %s:%zu", item.item.c_str(), item.count);
1188 }
1189 }
1190
1191 auto acceptlist = shadow_acceptlist_.GetCopy();
1192 LOG_DUMPSYS(fd,
1193 "Shadow le accept list size:%-3zu "
1194 "controller_max_size:%hhu",
1195 acceptlist.size(), shadow_acceptlist_.GetMaxSize());
1196 unsigned cnt = 0;
1197 for (auto& entry : acceptlist) {
1198 LOG_DUMPSYS(fd, " %03u %s", ++cnt, ADDRESS_TO_LOGGABLE_CSTR(entry));
1199 }
1200 auto address_resolution_list = shadow_address_resolution_list_.GetCopy();
1201 LOG_DUMPSYS(fd,
1202 "Shadow le address resolution list size:%-3zu "
1203 "controller_max_size:%hhu",
1204 address_resolution_list.size(),
1205 shadow_address_resolution_list_.GetMaxSize());
1206 cnt = 0;
1207 for (auto& entry : address_resolution_list) {
1208 LOG_DUMPSYS(fd, " %03u %s", ++cnt, ADDRESS_TO_LOGGABLE_CSTR(entry));
1209 }
1210 }
1211 #undef DUMPSYS_TAG
1212 };
1213
1214 #define DUMPSYS_TAG "shim::legacy::l2cap"
1215 extern tL2C_CB l2cb;
DumpsysL2cap(int fd)1216 void DumpsysL2cap(int fd) {
1217 LOG_DUMPSYS_TITLE(fd, DUMPSYS_TAG);
1218 for (int i = 0; i < MAX_L2CAP_LINKS; i++) {
1219 const tL2C_LCB& lcb = l2cb.lcb_pool[i];
1220 if (!lcb.in_use) continue;
1221 LOG_DUMPSYS(fd, "link_state:%s", link_state_text(lcb.link_state).c_str());
1222 LOG_DUMPSYS(fd, "handle:0x%04x", lcb.Handle());
1223
1224 const tL2C_CCB* ccb = lcb.ccb_queue.p_first_ccb;
1225 while (ccb != nullptr) {
1226 LOG_DUMPSYS(
1227 fd, " active channel lcid:0x%04x rcid:0x%04x is_ecoc:%s in_use:%s",
1228 ccb->local_cid, ccb->remote_cid, common::ToString(ccb->ecoc).c_str(),
1229 common::ToString(ccb->in_use).c_str());
1230 ccb = ccb->p_next_ccb;
1231 }
1232 }
1233 }
1234
1235 #undef DUMPSYS_TAG
1236 #define DUMPSYS_TAG "shim::legacy::acl"
DumpsysAcl(int fd)1237 void DumpsysAcl(int fd) {
1238 const tACL_CB& acl_cb = btm_cb.acl_cb_;
1239
1240 LOG_DUMPSYS_TITLE(fd, DUMPSYS_TAG);
1241
1242 if (shim::Stack::GetInstance()->IsRunning()) {
1243 shim::Stack::GetInstance()->GetAcl()->DumpConnectionHistory(fd);
1244 }
1245
1246 for (int i = 0; i < MAX_L2CAP_LINKS; i++) {
1247 const tACL_CONN& link = acl_cb.acl_db[i];
1248 if (!link.in_use) continue;
1249
1250 LOG_DUMPSYS(fd, "remote_addr:%s handle:0x%04x transport:%s",
1251 ADDRESS_TO_LOGGABLE_CSTR(link.remote_addr), link.hci_handle,
1252 bt_transport_text(link.transport).c_str());
1253 LOG_DUMPSYS(fd, " link_up_issued:%5s",
1254 (link.link_up_issued) ? "true" : "false");
1255 LOG_DUMPSYS(fd, " flush_timeout:0x%04x", link.flush_timeout_in_ticks);
1256 LOG_DUMPSYS(fd, " link_supervision_timeout:%.3f sec",
1257 ticks_to_seconds(link.link_super_tout));
1258 LOG_DUMPSYS(fd, " disconnect_reason:0x%02x", link.disconnect_reason);
1259
1260 if (link.is_transport_br_edr()) {
1261 for (int j = 0; j < HCI_EXT_FEATURES_PAGE_MAX + 1; j++) {
1262 if (!link.peer_lmp_feature_valid[j]) continue;
1263 LOG_DUMPSYS(fd, " peer_lmp_features[%d] valid:%s data:%s", j,
1264 common::ToString(link.peer_lmp_feature_valid[j]).c_str(),
1265 bd_features_text(link.peer_lmp_feature_pages[j]).c_str());
1266 }
1267 LOG_DUMPSYS(fd, " [classic] link_policy:%s",
1268 link_policy_text(static_cast<tLINK_POLICY>(link.link_policy))
1269 .c_str());
1270 LOG_DUMPSYS(fd, " [classic] sniff_subrating:%s",
1271 common::ToString(HCI_SNIFF_SUB_RATE_SUPPORTED(
1272 link.peer_lmp_feature_pages[0]))
1273 .c_str());
1274
1275 LOG_DUMPSYS(fd, " pkt_types_mask:0x%04x", link.pkt_types_mask);
1276 LOG_DUMPSYS(fd, " role:%s", RoleText(link.link_role).c_str());
1277 } else if (link.is_transport_ble()) {
1278 LOG_DUMPSYS(fd, " [le] peer_features valid:%s data:%s",
1279 common::ToString(link.peer_le_features_valid).c_str(),
1280 bd_features_text(link.peer_le_features).c_str());
1281
1282 LOG_DUMPSYS(fd, " [le] active_remote_addr:%s[%s]",
1283 ADDRESS_TO_LOGGABLE_CSTR(link.active_remote_addr),
1284 AddressTypeText(link.active_remote_addr_type).c_str());
1285 }
1286 }
1287 }
1288 #undef DUMPSYS_TAG
1289
1290 using Record = common::TimestampedEntry<std::string>;
1291 const std::string kTimeFormat("%Y-%m-%d %H:%M:%S");
1292
1293 #define DUMPSYS_TAG "shim::legacy::btm"
DumpsysBtm(int fd)1294 void DumpsysBtm(int fd) {
1295 LOG_DUMPSYS_TITLE(fd, DUMPSYS_TAG);
1296 if (btm_cb.history_ != nullptr) {
1297 std::vector<Record> history = btm_cb.history_->Pull();
1298 for (auto& record : history) {
1299 time_t then = record.timestamp / 1000;
1300 struct tm tm;
1301 localtime_r(&then, &tm);
1302 auto s2 = common::StringFormatTime(kTimeFormat, tm);
1303 LOG_DUMPSYS(fd, " %s.%03u %s", s2.c_str(),
1304 static_cast<unsigned int>(record.timestamp % 1000),
1305 record.entry.c_str());
1306 }
1307 }
1308 }
1309 #undef DUMPSYS_TAG
1310
1311 #define DUMPSYS_TAG "shim::legacy::record"
DumpsysRecord(int fd)1312 void DumpsysRecord(int fd) {
1313 LOG_DUMPSYS_TITLE(fd, DUMPSYS_TAG);
1314
1315 if (btm_cb.sec_dev_rec == nullptr) {
1316 LOG_DUMPSYS(fd, "Record is empty - no devices");
1317 return;
1318 }
1319
1320 unsigned cnt = 0;
1321 list_node_t* end = list_end(btm_cb.sec_dev_rec);
1322 for (list_node_t* node = list_begin(btm_cb.sec_dev_rec); node != end;
1323 node = list_next(node)) {
1324 tBTM_SEC_DEV_REC* p_dev_rec =
1325 static_cast<tBTM_SEC_DEV_REC*>(list_node(node));
1326 // TODO: handle in tBTM_SEC_DEV_REC.ToString
1327 LOG_DUMPSYS(fd, "%03u %s", ++cnt, p_dev_rec->ToString().c_str());
1328 }
1329 }
1330 #undef DUMPSYS_TAG
1331
1332 #define DUMPSYS_TAG "shim::legacy::stack"
DumpsysNeighbor(int fd)1333 void DumpsysNeighbor(int fd) {
1334 LOG_DUMPSYS(fd, "Stack information %lc%lc", kRunicBjarkan, kRunicHagall);
1335 if (btm_cb.neighbor.classic_inquiry.start_time_ms == 0) {
1336 LOG_DUMPSYS(fd, "Classic inquiry:disabled");
1337 } else {
1338 LOG_DUMPSYS(fd, "Classic inquiry:enabled duration_s:%.3f results:%lu",
1339 (timestamper_in_milliseconds.GetTimestamp() -
1340 btm_cb.neighbor.classic_inquiry.start_time_ms) /
1341 1000.0,
1342 btm_cb.neighbor.classic_inquiry.results);
1343 }
1344 if (btm_cb.neighbor.le_scan.start_time_ms == 0) {
1345 LOG_DUMPSYS(fd, "Le scan:disabled");
1346 } else {
1347 LOG_DUMPSYS(fd, "Le scan:enabled duration_s:%.3f results:%lu",
1348 (timestamper_in_milliseconds.GetTimestamp() -
1349 btm_cb.neighbor.le_scan.start_time_ms) /
1350 1000.0,
1351 btm_cb.neighbor.le_scan.results);
1352 }
1353 const auto copy = btm_cb.neighbor.inquiry_history_->Pull();
1354 LOG_DUMPSYS(fd, "Last %zu inquiry scans:", copy.size());
1355 for (const auto& it : copy) {
1356 LOG_DUMPSYS(fd,
1357 " %s - %s duration_ms:%-5llu num_resp:%-2u"
1358 " std:%-2u rssi:%-2u ext:%-2u %12s",
1359 EpochMillisToString(it.entry.start_time_ms).c_str(),
1360 EpochMillisToString(it.timestamp).c_str(),
1361 it.timestamp - it.entry.start_time_ms, it.entry.num_resp,
1362 it.entry.resp_type[BTM_INQ_RESULT_STANDARD],
1363 it.entry.resp_type[BTM_INQ_RESULT_WITH_RSSI],
1364 it.entry.resp_type[BTM_INQ_RESULT_EXTENDED],
1365 btm_inquiry_cmpl_status_text(it.entry.status).c_str());
1366 }
1367 }
1368 #undef DUMPSYS_TAG
1369
Dump(int fd) const1370 void shim::legacy::Acl::Dump(int fd) const {
1371 DumpsysRecord(fd);
1372 DumpsysNeighbor(fd);
1373 DumpsysAcl(fd);
1374 DumpsysL2cap(fd);
1375 DumpsysBtm(fd);
1376 }
1377
Acl(os::Handler * handler,const acl_interface_t & acl_interface,uint8_t max_acceptlist_size,uint8_t max_address_resolution_size)1378 shim::legacy::Acl::Acl(os::Handler* handler,
1379 const acl_interface_t& acl_interface,
1380 uint8_t max_acceptlist_size,
1381 uint8_t max_address_resolution_size)
1382 : handler_(handler), acl_interface_(acl_interface) {
1383 ASSERT(handler_ != nullptr);
1384 ValidateAclInterface(acl_interface_);
1385 pimpl_ = std::make_unique<Acl::impl>(max_acceptlist_size,
1386 max_address_resolution_size);
1387 GetAclManager()->RegisterCallbacks(this, handler_);
1388 GetAclManager()->RegisterLeCallbacks(this, handler_);
1389 GetController()->RegisterCompletedMonitorAclPacketsCallback(
1390 handler->BindOn(this, &Acl::on_incoming_acl_credits));
1391 shim::RegisterDumpsysFunction(static_cast<void*>(this),
1392 [this](int fd) { Dump(fd); });
1393
1394 GetAclManager()->HACK_SetNonAclDisconnectCallback(
1395 [this](uint16_t handle, uint8_t reason) {
1396 TRY_POSTING_ON_MAIN(acl_interface_.connection.sco.on_disconnected,
1397 handle, static_cast<tHCI_REASON>(reason));
1398
1399 // HACKCEPTION! LE ISO connections, just like SCO are not registered in
1400 // GD, so ISO can use same hack to get notified about disconnections
1401 TRY_POSTING_ON_MAIN(acl_interface_.connection.le.on_iso_disconnected,
1402 handle, static_cast<tHCI_REASON>(reason));
1403 });
1404 }
1405
~Acl()1406 shim::legacy::Acl::~Acl() {
1407 shim::UnregisterDumpsysFunction(static_cast<void*>(this));
1408 GetController()->UnregisterCompletedMonitorAclPacketsCallback();
1409
1410 if (CheckForOrphanedAclConnections()) {
1411 pimpl_->DumpConnectionHistory();
1412 }
1413 }
1414
CheckForOrphanedAclConnections() const1415 bool shim::legacy::Acl::CheckForOrphanedAclConnections() const {
1416 bool orphaned_acl_connections = false;
1417
1418 if (!pimpl_->handle_to_classic_connection_map_.empty()) {
1419 LOG_ERROR("About to destroy classic active ACL");
1420 for (const auto& connection : pimpl_->handle_to_classic_connection_map_) {
1421 LOG_ERROR(" Orphaned classic ACL handle:0x%04x bd_addr:%s created:%s",
1422 connection.second->Handle(),
1423 ADDRESS_TO_LOGGABLE_CSTR(connection.second->GetRemoteAddress()),
1424 common::StringFormatTimeWithMilliseconds(
1425 kConnectionDescriptorTimeFormat,
1426 connection.second->GetCreationTime())
1427 .c_str());
1428 }
1429 orphaned_acl_connections = true;
1430 }
1431
1432 if (!pimpl_->handle_to_le_connection_map_.empty()) {
1433 LOG_ERROR("About to destroy le active ACL");
1434 for (const auto& connection : pimpl_->handle_to_le_connection_map_) {
1435 LOG_ERROR(" Orphaned le ACL handle:0x%04x bd_addr:%s created:%s",
1436 connection.second->Handle(),
1437 ADDRESS_TO_LOGGABLE_CSTR(connection.second->GetRemoteAddressWithType()),
1438 common::StringFormatTimeWithMilliseconds(
1439 kConnectionDescriptorTimeFormat,
1440 connection.second->GetCreationTime())
1441 .c_str());
1442 }
1443 orphaned_acl_connections = true;
1444 }
1445 return orphaned_acl_connections;
1446 }
1447
on_incoming_acl_credits(uint16_t handle,uint16_t credits)1448 void shim::legacy::Acl::on_incoming_acl_credits(uint16_t handle,
1449 uint16_t credits) {
1450 TRY_POSTING_ON_MAIN(acl_interface_.on_packets_completed, handle, credits);
1451 }
1452
write_data_sync(HciHandle handle,std::unique_ptr<packet::RawBuilder> packet)1453 void shim::legacy::Acl::write_data_sync(
1454 HciHandle handle, std::unique_ptr<packet::RawBuilder> packet) {
1455 if (pimpl_->IsClassicAcl(handle)) {
1456 pimpl_->EnqueueClassicPacket(handle, std::move(packet));
1457 } else if (pimpl_->IsLeAcl(handle)) {
1458 pimpl_->EnqueueLePacket(handle, std::move(packet));
1459 } else {
1460 LOG_ERROR("Unable to find destination to write data\n");
1461 }
1462 }
1463
WriteData(HciHandle handle,std::unique_ptr<packet::RawBuilder> packet)1464 void shim::legacy::Acl::WriteData(HciHandle handle,
1465 std::unique_ptr<packet::RawBuilder> packet) {
1466 handler_->Post(common::BindOnce(&Acl::write_data_sync,
1467 common::Unretained(this), handle,
1468 std::move(packet)));
1469 }
1470
CreateClassicConnection(const hci::Address & address)1471 void shim::legacy::Acl::CreateClassicConnection(const hci::Address& address) {
1472 GetAclManager()->CreateConnection(address);
1473 LOG_DEBUG("Connection initiated for classic to remote:%s",
1474 ADDRESS_TO_LOGGABLE_CSTR(address));
1475 BTM_LogHistory(kBtmLogTag, ToRawAddress(address), "Initiated connection",
1476 "classic");
1477 }
1478
CancelClassicConnection(const hci::Address & address)1479 void shim::legacy::Acl::CancelClassicConnection(const hci::Address& address) {
1480 GetAclManager()->CancelConnect(address);
1481 LOG_DEBUG("Connection cancelled for classic to remote:%s",
1482 ADDRESS_TO_LOGGABLE_CSTR(address));
1483 BTM_LogHistory(kBtmLogTag, ToRawAddress(address), "Cancelled connection",
1484 "classic");
1485 }
1486
AcceptLeConnectionFrom(const hci::AddressWithType & address_with_type,bool is_direct,std::promise<bool> promise)1487 void shim::legacy::Acl::AcceptLeConnectionFrom(
1488 const hci::AddressWithType& address_with_type, bool is_direct,
1489 std::promise<bool> promise) {
1490 LOG_DEBUG("AcceptLeConnectionFrom %s",
1491 ADDRESS_TO_LOGGABLE_CSTR(address_with_type.GetAddress()));
1492 handler_->CallOn(pimpl_.get(), &Acl::impl::accept_le_connection_from,
1493 address_with_type, is_direct, std::move(promise));
1494 }
1495
IgnoreLeConnectionFrom(const hci::AddressWithType & address_with_type)1496 void shim::legacy::Acl::IgnoreLeConnectionFrom(
1497 const hci::AddressWithType& address_with_type) {
1498 LOG_DEBUG("IgnoreLeConnectionFrom %s",
1499 ADDRESS_TO_LOGGABLE_CSTR(address_with_type.GetAddress()));
1500 handler_->CallOn(pimpl_.get(), &Acl::impl::ignore_le_connection_from,
1501 address_with_type);
1502 }
1503
OnClassicLinkDisconnected(HciHandle handle,hci::ErrorCode reason)1504 void shim::legacy::Acl::OnClassicLinkDisconnected(HciHandle handle,
1505 hci::ErrorCode reason) {
1506 hci::Address remote_address =
1507 pimpl_->handle_to_classic_connection_map_[handle]->GetRemoteAddress();
1508 CreationTime creation_time =
1509 pimpl_->handle_to_classic_connection_map_[handle]->GetCreationTime();
1510 bool is_locally_initiated =
1511 pimpl_->handle_to_classic_connection_map_[handle]->IsLocallyInitiated();
1512
1513 TeardownTime teardown_time = std::chrono::system_clock::now();
1514
1515 pimpl_->handle_to_classic_connection_map_.erase(handle);
1516 TRY_POSTING_ON_MAIN(acl_interface_.connection.classic.on_disconnected,
1517 ToLegacyHciErrorCode(hci::ErrorCode::SUCCESS), handle,
1518 ToLegacyHciErrorCode(reason));
1519 LOG_DEBUG("Disconnected classic link remote:%s handle:%hu reason:%s",
1520 ADDRESS_TO_LOGGABLE_CSTR(remote_address), handle,
1521 ErrorCodeText(reason).c_str());
1522 BTM_LogHistory(
1523 kBtmLogTag, ToRawAddress(remote_address), "Disconnected",
1524 base::StringPrintf("classic reason:%s", ErrorCodeText(reason).c_str()));
1525 pimpl_->connection_history_.Push(
1526 std::move(std::make_unique<ClassicConnectionDescriptor>(
1527 remote_address, creation_time, teardown_time, handle,
1528 is_locally_initiated, reason)));
1529 }
1530
GetConnectionLocalAddress(const RawAddress & remote_bda)1531 bluetooth::hci::AddressWithType shim::legacy::Acl::GetConnectionLocalAddress(
1532 const RawAddress& remote_bda) {
1533 bluetooth::hci::AddressWithType address_with_type;
1534 auto remote_address = ToGdAddress(remote_bda);
1535 for (auto& [handle, connection] : pimpl_->handle_to_le_connection_map_) {
1536 if (connection->GetRemoteAddressWithType().GetAddress() == remote_address) {
1537 return connection->GetLocalAddressWithType();
1538 }
1539 }
1540 LOG_WARN("address not found!");
1541 return address_with_type;
1542 }
1543
GetAdvertisingSetConnectedTo(const RawAddress & remote_bda)1544 std::optional<uint8_t> shim::legacy::Acl::GetAdvertisingSetConnectedTo(
1545 const RawAddress& remote_bda) {
1546 auto remote_address = ToGdAddress(remote_bda);
1547 for (auto& [handle, connection] : pimpl_->handle_to_le_connection_map_) {
1548 if (connection->GetRemoteAddressWithType().GetAddress() == remote_address) {
1549 return connection->GetAdvertisingSetConnectedTo();
1550 }
1551 }
1552 LOG_WARN("address not found!");
1553 return {};
1554 }
1555
OnLeLinkDisconnected(HciHandle handle,hci::ErrorCode reason)1556 void shim::legacy::Acl::OnLeLinkDisconnected(HciHandle handle,
1557 hci::ErrorCode reason) {
1558 hci::AddressWithType remote_address_with_type =
1559 pimpl_->handle_to_le_connection_map_[handle]->GetRemoteAddressWithType();
1560 CreationTime creation_time =
1561 pimpl_->handle_to_le_connection_map_[handle]->GetCreationTime();
1562 bool is_locally_initiated =
1563 pimpl_->handle_to_le_connection_map_[handle]->IsLocallyInitiated();
1564
1565 TeardownTime teardown_time = std::chrono::system_clock::now();
1566
1567 pimpl_->handle_to_le_connection_map_.erase(handle);
1568 TRY_POSTING_ON_MAIN(acl_interface_.connection.le.on_disconnected,
1569 ToLegacyHciErrorCode(hci::ErrorCode::SUCCESS), handle,
1570 ToLegacyHciErrorCode(reason));
1571 LOG_DEBUG("Disconnected le link remote:%s handle:%hu reason:%s",
1572 ADDRESS_TO_LOGGABLE_CSTR(remote_address_with_type), handle,
1573 ErrorCodeText(reason).c_str());
1574 BTM_LogHistory(
1575 kBtmLogTag, ToLegacyAddressWithType(remote_address_with_type),
1576 "Disconnected",
1577 base::StringPrintf("Le reason:%s", ErrorCodeText(reason).c_str()));
1578 pimpl_->connection_history_.Push(
1579 std::move(std::make_unique<LeConnectionDescriptor>(
1580 remote_address_with_type, creation_time, teardown_time, handle,
1581 is_locally_initiated, reason)));
1582 }
1583
OnConnectSuccess(std::unique_ptr<hci::acl_manager::ClassicAclConnection> connection)1584 void shim::legacy::Acl::OnConnectSuccess(
1585 std::unique_ptr<hci::acl_manager::ClassicAclConnection> connection) {
1586 ASSERT(connection != nullptr);
1587 auto handle = connection->GetHandle();
1588 bool locally_initiated = connection->locally_initiated_;
1589 const hci::Address remote_address = connection->GetAddress();
1590 const RawAddress bd_addr = ToRawAddress(remote_address);
1591
1592 pimpl_->handle_to_classic_connection_map_.emplace(
1593 handle, std::make_unique<ClassicShimAclConnection>(
1594 acl_interface_.on_send_data_upwards,
1595 std::bind(&shim::legacy::Acl::OnClassicLinkDisconnected, this,
1596 std::placeholders::_1, std::placeholders::_2),
1597 acl_interface_.link.classic, handler_, std::move(connection),
1598 std::chrono::system_clock::now()));
1599 pimpl_->handle_to_classic_connection_map_[handle]->RegisterCallbacks();
1600 pimpl_->handle_to_classic_connection_map_[handle]
1601 ->ReadRemoteControllerInformation();
1602
1603 TRY_POSTING_ON_MAIN(acl_interface_.connection.classic.on_connected, bd_addr,
1604 handle, false, locally_initiated);
1605 LOG_DEBUG("Connection successful classic remote:%s handle:%hu initiator:%s",
1606 ADDRESS_TO_LOGGABLE_CSTR(remote_address), handle,
1607 (locally_initiated) ? "local" : "remote");
1608 BTM_LogHistory(kBtmLogTag, ToRawAddress(remote_address),
1609 "Connection successful",
1610 (locally_initiated) ? "classic Local initiated"
1611 : "classic Remote initiated");
1612 }
1613
OnConnectRequest(hci::Address address,hci::ClassOfDevice cod)1614 void shim::legacy::Acl::OnConnectRequest(hci::Address address,
1615 hci::ClassOfDevice cod) {
1616 const RawAddress bd_addr = ToRawAddress(address);
1617
1618 types::ClassOfDevice legacy_cod;
1619 legacy_cod.FromOctets(cod.data());
1620
1621 TRY_POSTING_ON_MAIN(acl_interface_.connection.classic.on_connect_request,
1622 bd_addr, legacy_cod);
1623 LOG_DEBUG("Received connect request remote:%s",
1624 ADDRESS_TO_LOGGABLE_CSTR(address));
1625 BTM_LogHistory(kBtmLogTag, ToRawAddress(address), "Connection request");
1626 }
1627
OnConnectFail(hci::Address address,hci::ErrorCode reason,bool locally_initiated)1628 void shim::legacy::Acl::OnConnectFail(hci::Address address,
1629 hci::ErrorCode reason,
1630 bool locally_initiated) {
1631 const RawAddress bd_addr = ToRawAddress(address);
1632 TRY_POSTING_ON_MAIN(acl_interface_.connection.classic.on_failed, bd_addr,
1633 ToLegacyHciErrorCode(reason), locally_initiated);
1634 LOG_WARN("Connection failed classic remote:%s reason:%s",
1635 ADDRESS_TO_LOGGABLE_CSTR(address), hci::ErrorCodeText(reason).c_str());
1636 BTM_LogHistory(kBtmLogTag, ToRawAddress(address), "Connection failed",
1637 base::StringPrintf("classic reason:%s",
1638 hci::ErrorCodeText(reason).c_str()));
1639 }
1640
HACK_OnEscoConnectRequest(hci::Address address,hci::ClassOfDevice cod)1641 void shim::legacy::Acl::HACK_OnEscoConnectRequest(hci::Address address,
1642 hci::ClassOfDevice cod) {
1643 const RawAddress bd_addr = ToRawAddress(address);
1644 types::ClassOfDevice legacy_cod;
1645 types::ClassOfDevice::FromString(cod.ToLegacyConfigString(), legacy_cod);
1646
1647 TRY_POSTING_ON_MAIN(acl_interface_.connection.sco.on_esco_connect_request,
1648 bd_addr, legacy_cod);
1649 LOG_DEBUG("Received ESCO connect request remote:%s",
1650 ADDRESS_TO_LOGGABLE_CSTR(address));
1651 BTM_LogHistory(kBtmLogTag, ToRawAddress(address), "ESCO Connection request");
1652 }
1653
HACK_OnScoConnectRequest(hci::Address address,hci::ClassOfDevice cod)1654 void shim::legacy::Acl::HACK_OnScoConnectRequest(hci::Address address,
1655 hci::ClassOfDevice cod) {
1656 const RawAddress bd_addr = ToRawAddress(address);
1657 types::ClassOfDevice legacy_cod;
1658 types::ClassOfDevice::FromString(cod.ToLegacyConfigString(), legacy_cod);
1659
1660 TRY_POSTING_ON_MAIN(acl_interface_.connection.sco.on_sco_connect_request,
1661 bd_addr, legacy_cod);
1662 LOG_DEBUG("Received SCO connect request remote:%s", ADDRESS_TO_LOGGABLE_CSTR(address));
1663 BTM_LogHistory(kBtmLogTag, ToRawAddress(address), "SCO Connection request");
1664 }
1665
OnLeConnectSuccess(hci::AddressWithType address_with_type,std::unique_ptr<hci::acl_manager::LeAclConnection> connection)1666 void shim::legacy::Acl::OnLeConnectSuccess(
1667 hci::AddressWithType address_with_type,
1668 std::unique_ptr<hci::acl_manager::LeAclConnection> connection) {
1669 ASSERT(connection != nullptr);
1670 auto handle = connection->GetHandle();
1671
1672 // Save the peer address, if any
1673 hci::AddressWithType peer_address_with_type =
1674 connection->peer_address_with_type_;
1675
1676 hci::Role connection_role = connection->GetRole();
1677 bool locally_initiated = connection->locally_initiated_;
1678
1679 uint16_t conn_interval = connection->interval_;
1680 uint16_t conn_latency = connection->latency_;
1681 uint16_t conn_timeout = connection->supervision_timeout_;
1682
1683 RawAddress local_rpa =
1684 ToRawAddress(connection->local_resolvable_private_address_);
1685 RawAddress peer_rpa =
1686 ToRawAddress(connection->peer_resolvable_private_address_);
1687 tBLE_ADDR_TYPE peer_addr_type =
1688 (tBLE_ADDR_TYPE)connection->peer_address_with_type_.GetAddressType();
1689
1690 auto can_read_discoverable_characteristics = std::visit(
1691 [&](auto&& data) {
1692 using T = std::decay_t<decltype(data)>;
1693 if constexpr (std::is_same_v<T, hci::acl_manager::DataAsPeripheral>) {
1694 return data.connected_to_discoverable;
1695 } else {
1696 // if we are the central, the peer can always see discoverable
1697 // characteristics
1698 return true;
1699 }
1700 },
1701 connection->GetRoleSpecificData());
1702
1703 pimpl_->handle_to_le_connection_map_.emplace(
1704 handle, std::make_unique<LeShimAclConnection>(
1705 acl_interface_.on_send_data_upwards,
1706 std::bind(&shim::legacy::Acl::OnLeLinkDisconnected, this,
1707 std::placeholders::_1, std::placeholders::_2),
1708 acl_interface_.link.le, handler_, std::move(connection),
1709 std::chrono::system_clock::now()));
1710 pimpl_->handle_to_le_connection_map_[handle]->RegisterCallbacks();
1711
1712 // Once an le connection has successfully been established
1713 // the device address is removed from the controller accept list.
1714
1715 if (IsRpa(address_with_type)) {
1716 LOG_DEBUG("Connection address is rpa:%s identity_addr:%s",
1717 ADDRESS_TO_LOGGABLE_CSTR(address_with_type),
1718 ADDRESS_TO_LOGGABLE_CSTR(peer_address_with_type));
1719 pimpl_->shadow_acceptlist_.Remove(peer_address_with_type);
1720 } else {
1721 LOG_DEBUG("Connection address is not rpa addr:%s",
1722 ADDRESS_TO_LOGGABLE_CSTR(address_with_type));
1723 pimpl_->shadow_acceptlist_.Remove(address_with_type);
1724 }
1725
1726 if (!pimpl_->handle_to_le_connection_map_[handle]->IsInFilterAcceptList() &&
1727 connection_role == hci::Role::CENTRAL) {
1728 pimpl_->handle_to_le_connection_map_[handle]->InitiateDisconnect(
1729 hci::DisconnectReason::REMOTE_USER_TERMINATED_CONNECTION);
1730 LOG_INFO("Disconnected ACL after connection canceled");
1731 BTM_LogHistory(kBtmLogTag, ToLegacyAddressWithType(address_with_type),
1732 "Connection canceled", "Le");
1733 return;
1734 }
1735
1736 pimpl_->handle_to_le_connection_map_[handle]
1737 ->ReadRemoteControllerInformation();
1738
1739 tBLE_BD_ADDR legacy_address_with_type =
1740 ToLegacyAddressWithType(address_with_type);
1741
1742 TRY_POSTING_ON_MAIN(acl_interface_.connection.le.on_connected,
1743 legacy_address_with_type, handle,
1744 ToLegacyRole(connection_role), conn_interval,
1745 conn_latency, conn_timeout, local_rpa, peer_rpa,
1746 peer_addr_type, can_read_discoverable_characteristics);
1747
1748 LOG_DEBUG("Connection successful le remote:%s handle:%hu initiator:%s",
1749 ADDRESS_TO_LOGGABLE_CSTR(address_with_type), handle,
1750 (locally_initiated) ? "local" : "remote");
1751 BTM_LogHistory(kBtmLogTag, ToLegacyAddressWithType(address_with_type),
1752 "Connection successful", "Le");
1753 }
1754
OnLeConnectFail(hci::AddressWithType address_with_type,hci::ErrorCode reason)1755 void shim::legacy::Acl::OnLeConnectFail(hci::AddressWithType address_with_type,
1756 hci::ErrorCode reason) {
1757 tBLE_BD_ADDR legacy_address_with_type =
1758 ToLegacyAddressWithType(address_with_type);
1759
1760 uint16_t handle = 0; /* TODO Unneeded */
1761 bool enhanced = true; /* TODO logging metrics only */
1762 tHCI_STATUS status = ToLegacyHciErrorCode(reason);
1763
1764 TRY_POSTING_ON_MAIN(acl_interface_.connection.le.on_failed,
1765 legacy_address_with_type, handle, enhanced, status);
1766
1767 pimpl_->shadow_acceptlist_.Remove(address_with_type);
1768 LOG_WARN("Connection failed le remote:%s",
1769 ADDRESS_TO_LOGGABLE_CSTR(address_with_type));
1770 BTM_LogHistory(
1771 kBtmLogTag, ToLegacyAddressWithType(address_with_type),
1772 "Connection failed",
1773 base::StringPrintf("le reason:%s", hci::ErrorCodeText(reason).c_str()));
1774 }
1775
DisconnectClassic(uint16_t handle,tHCI_STATUS reason,std::string comment)1776 void shim::legacy::Acl::DisconnectClassic(uint16_t handle, tHCI_STATUS reason,
1777 std::string comment) {
1778 handler_->CallOn(pimpl_.get(), &Acl::impl::disconnect_classic, handle, reason,
1779 comment);
1780 }
1781
DisconnectLe(uint16_t handle,tHCI_STATUS reason,std::string comment)1782 void shim::legacy::Acl::DisconnectLe(uint16_t handle, tHCI_STATUS reason,
1783 std::string comment) {
1784 handler_->CallOn(pimpl_.get(), &Acl::impl::disconnect_le, handle, reason,
1785 comment);
1786 }
1787
HoldMode(uint16_t hci_handle,uint16_t max_interval,uint16_t min_interval)1788 bool shim::legacy::Acl::HoldMode(uint16_t hci_handle, uint16_t max_interval,
1789 uint16_t min_interval) {
1790 handler_->CallOn(pimpl_.get(), &Acl::impl::HoldMode, hci_handle, max_interval,
1791 min_interval);
1792 return false; // TODO void
1793 }
1794
SniffMode(uint16_t hci_handle,uint16_t max_interval,uint16_t min_interval,uint16_t attempt,uint16_t timeout)1795 bool shim::legacy::Acl::SniffMode(uint16_t hci_handle, uint16_t max_interval,
1796 uint16_t min_interval, uint16_t attempt,
1797 uint16_t timeout) {
1798 handler_->CallOn(pimpl_.get(), &Acl::impl::SniffMode, hci_handle,
1799 max_interval, min_interval, attempt, timeout);
1800 return false;
1801 }
1802
ExitSniffMode(uint16_t hci_handle)1803 bool shim::legacy::Acl::ExitSniffMode(uint16_t hci_handle) {
1804 handler_->CallOn(pimpl_.get(), &Acl::impl::ExitSniffMode, hci_handle);
1805 return false;
1806 }
1807
SniffSubrating(uint16_t hci_handle,uint16_t maximum_latency,uint16_t minimum_remote_timeout,uint16_t minimum_local_timeout)1808 bool shim::legacy::Acl::SniffSubrating(uint16_t hci_handle,
1809 uint16_t maximum_latency,
1810 uint16_t minimum_remote_timeout,
1811 uint16_t minimum_local_timeout) {
1812 handler_->CallOn(pimpl_.get(), &Acl::impl::SniffSubrating, hci_handle,
1813 maximum_latency, minimum_remote_timeout,
1814 minimum_local_timeout);
1815 return false;
1816 }
1817
LeSetDefaultSubrate(uint16_t subrate_min,uint16_t subrate_max,uint16_t max_latency,uint16_t cont_num,uint16_t sup_tout)1818 void shim::legacy::Acl::LeSetDefaultSubrate(uint16_t subrate_min,
1819 uint16_t subrate_max,
1820 uint16_t max_latency,
1821 uint16_t cont_num,
1822 uint16_t sup_tout) {
1823 handler_->CallOn(pimpl_.get(), &Acl::impl::LeSetDefaultSubrate, subrate_min,
1824 subrate_max, max_latency, cont_num, sup_tout);
1825 }
1826
LeSubrateRequest(uint16_t hci_handle,uint16_t subrate_min,uint16_t subrate_max,uint16_t max_latency,uint16_t cont_num,uint16_t sup_tout)1827 void shim::legacy::Acl::LeSubrateRequest(uint16_t hci_handle,
1828 uint16_t subrate_min,
1829 uint16_t subrate_max,
1830 uint16_t max_latency,
1831 uint16_t cont_num, uint16_t sup_tout) {
1832 handler_->CallOn(pimpl_.get(), &Acl::impl::LeSubrateRequest, hci_handle,
1833 subrate_min, subrate_max, max_latency, cont_num, sup_tout);
1834 }
1835
DumpConnectionHistory(int fd) const1836 void shim::legacy::Acl::DumpConnectionHistory(int fd) const {
1837 pimpl_->DumpConnectionHistory(fd);
1838 }
1839
DisconnectAllForSuspend()1840 void shim::legacy::Acl::DisconnectAllForSuspend() {
1841 if (CheckForOrphanedAclConnections()) {
1842 std::promise<void> disconnect_promise;
1843 auto disconnect_future = disconnect_promise.get_future();
1844 handler_->CallOn(pimpl_.get(), &Acl::impl::DisconnectClassicConnections,
1845 std::move(disconnect_promise));
1846 disconnect_future.wait();
1847
1848 disconnect_promise = std::promise<void>();
1849
1850 disconnect_future = disconnect_promise.get_future();
1851 handler_->CallOn(pimpl_.get(), &Acl::impl::DisconnectLeConnections,
1852 std::move(disconnect_promise));
1853 disconnect_future.wait();
1854 LOG_WARN("Disconnected open ACL connections");
1855 }
1856 }
1857
Shutdown()1858 void shim::legacy::Acl::Shutdown() {
1859 if (CheckForOrphanedAclConnections()) {
1860 std::promise<void> shutdown_promise;
1861 auto shutdown_future = shutdown_promise.get_future();
1862 handler_->CallOn(pimpl_.get(), &Acl::impl::ShutdownClassicConnections,
1863 std::move(shutdown_promise));
1864 shutdown_future.wait();
1865
1866 shutdown_promise = std::promise<void>();
1867
1868 shutdown_future = shutdown_promise.get_future();
1869 handler_->CallOn(pimpl_.get(), &Acl::impl::ShutdownLeConnections,
1870 std::move(shutdown_promise));
1871 shutdown_future.wait();
1872 LOG_WARN("Flushed open ACL connections");
1873 } else {
1874 LOG_INFO("All ACL connections have been previously closed");
1875 }
1876 }
1877
FinalShutdown()1878 void shim::legacy::Acl::FinalShutdown() {
1879 std::promise<void> promise;
1880 auto future = promise.get_future();
1881 GetAclManager()->UnregisterCallbacks(this, std::move(promise));
1882 future.wait();
1883 LOG_DEBUG("Unregistered classic callbacks from gd acl manager");
1884
1885 promise = std::promise<void>();
1886 future = promise.get_future();
1887 GetAclManager()->UnregisterLeCallbacks(this, std::move(promise));
1888 future.wait();
1889 LOG_DEBUG("Unregistered le callbacks from gd acl manager");
1890
1891 promise = std::promise<void>();
1892 future = promise.get_future();
1893 handler_->CallOn(pimpl_.get(), &Acl::impl::FinalShutdown, std::move(promise));
1894 future.wait();
1895 LOG_INFO("Unregistered and cleared any orphaned ACL connections");
1896 }
1897
ClearFilterAcceptList()1898 void shim::legacy::Acl::ClearFilterAcceptList() {
1899 handler_->CallOn(pimpl_.get(), &Acl::impl::clear_acceptlist);
1900 }
1901
LeRand(LeRandCallback cb)1902 void shim::legacy::Acl::LeRand(LeRandCallback cb) {
1903 handler_->CallOn(pimpl_.get(), &Acl::impl::le_rand, cb);
1904 }
1905
AddToAddressResolution(const hci::AddressWithType & address_with_type,const std::array<uint8_t,16> & peer_irk,const std::array<uint8_t,16> & local_irk)1906 void shim::legacy::Acl::AddToAddressResolution(
1907 const hci::AddressWithType& address_with_type,
1908 const std::array<uint8_t, 16>& peer_irk,
1909 const std::array<uint8_t, 16>& local_irk) {
1910 handler_->CallOn(pimpl_.get(), &Acl::impl::AddToAddressResolution,
1911 address_with_type, peer_irk, local_irk);
1912 }
1913
RemoveFromAddressResolution(const hci::AddressWithType & address_with_type)1914 void shim::legacy::Acl::RemoveFromAddressResolution(
1915 const hci::AddressWithType& address_with_type) {
1916 handler_->CallOn(pimpl_.get(), &Acl::impl::RemoveFromAddressResolution,
1917 address_with_type);
1918 }
1919
ClearAddressResolution()1920 void shim::legacy::Acl::ClearAddressResolution() {
1921 handler_->CallOn(pimpl_.get(), &Acl::impl::ClearResolvingList);
1922 }
1923
SetSystemSuspendState(bool suspended)1924 void shim::legacy::Acl::SetSystemSuspendState(bool suspended) {
1925 handler_->CallOn(pimpl_.get(), &Acl::impl::SetSystemSuspendState, suspended);
1926 }
1927