• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2018 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 "acl_connection_handler.h"
18 
19 #include <hci/hci_packets.h>
20 
21 #include "hci/address.h"
22 #include "log.h"
23 
24 namespace rootcanal {
25 
26 using ::bluetooth::hci::Address;
27 using ::bluetooth::hci::AddressType;
28 using ::bluetooth::hci::AddressWithType;
29 
RegisterTaskScheduler(std::function<AsyncTaskId (std::chrono::milliseconds,const TaskCallback &)> event_scheduler)30 void AclConnectionHandler::RegisterTaskScheduler(
31     std::function<AsyncTaskId(std::chrono::milliseconds, const TaskCallback&)>
32         event_scheduler) {
33   schedule_task_ = event_scheduler;
34 }
35 
HasHandle(uint16_t handle) const36 bool AclConnectionHandler::HasHandle(uint16_t handle) const {
37   return acl_connections_.count(handle) != 0;
38 }
39 
HasScoHandle(uint16_t handle) const40 bool AclConnectionHandler::HasScoHandle(uint16_t handle) const {
41   return sco_connections_.count(handle) != 0;
42 }
43 
GetUnusedHandle()44 uint16_t AclConnectionHandler::GetUnusedHandle() {
45   while (HasHandle(last_handle_) || HasScoHandle(last_handle_) ||
46          isochronous_connection_handler_.HasHandle(last_handle_)) {
47     last_handle_ = (last_handle_ + 1) % kReservedHandle;
48   }
49   uint16_t unused_handle = last_handle_;
50   last_handle_ = (last_handle_ + 1) % kReservedHandle;
51   return unused_handle;
52 }
53 
CreatePendingConnection(Address addr,bool authenticate_on_connect)54 bool AclConnectionHandler::CreatePendingConnection(
55     Address addr, bool authenticate_on_connect) {
56   if (classic_connection_pending_) {
57     return false;
58   }
59   classic_connection_pending_ = true;
60   pending_connection_address_ = addr;
61   authenticate_pending_classic_connection_ = authenticate_on_connect;
62   return true;
63 }
64 
HasPendingConnection(Address addr) const65 bool AclConnectionHandler::HasPendingConnection(Address addr) const {
66   return classic_connection_pending_ && pending_connection_address_ == addr;
67 }
68 
AuthenticatePendingConnection() const69 bool AclConnectionHandler::AuthenticatePendingConnection() const {
70   return authenticate_pending_classic_connection_;
71 }
72 
CancelPendingConnection(Address addr)73 bool AclConnectionHandler::CancelPendingConnection(Address addr) {
74   if (!classic_connection_pending_ || pending_connection_address_ != addr) {
75     return false;
76   }
77   classic_connection_pending_ = false;
78   pending_connection_address_ = Address::kEmpty;
79   pending_le_connection_resolved_address_ = AddressWithType();
80   return true;
81 }
82 
CreatePendingLeConnection(AddressWithType peer,AddressWithType resolved_peer,AddressWithType local_address)83 bool AclConnectionHandler::CreatePendingLeConnection(
84     AddressWithType peer, AddressWithType resolved_peer,
85     AddressWithType local_address) {
86   for (auto pair : acl_connections_) {
87     auto connection = std::get<AclConnection>(pair);
88     if (connection.GetAddress() == peer ||
89         connection.GetResolvedAddress() == resolved_peer) {
90       LOG_INFO("%s: %s is already connected", __func__,
91                peer.ToString().c_str());
92       if (connection.GetResolvedAddress() == resolved_peer) {
93         LOG_INFO("%s: allowing a second connection with %s", __func__,
94                  resolved_peer.ToString().c_str());
95       } else {
96         return false;
97       }
98     }
99   }
100   if (le_connection_pending_) {
101     LOG_INFO("%s: connection already pending", __func__);
102     return false;
103   }
104   le_connection_pending_ = true;
105   pending_le_connection_address_ = peer;
106   pending_le_connection_own_address_ = local_address;
107   pending_le_connection_resolved_address_ = resolved_peer;
108   return true;
109 }
110 
HasPendingLeConnection(AddressWithType addr) const111 bool AclConnectionHandler::HasPendingLeConnection(AddressWithType addr) const {
112   return le_connection_pending_ && pending_le_connection_address_ == addr;
113 }
114 
CancelPendingLeConnection(AddressWithType addr)115 bool AclConnectionHandler::CancelPendingLeConnection(AddressWithType addr) {
116   if (!le_connection_pending_ || pending_le_connection_address_ != addr) {
117     return false;
118   }
119   le_connection_pending_ = false;
120   pending_le_connection_address_ =
121       AddressWithType{Address::kEmpty, AddressType::PUBLIC_DEVICE_ADDRESS};
122   pending_le_connection_resolved_address_ =
123       AddressWithType{Address::kEmpty, AddressType::PUBLIC_DEVICE_ADDRESS};
124   return true;
125 }
126 
CreateConnection(Address addr,Address own_addr)127 uint16_t AclConnectionHandler::CreateConnection(Address addr,
128                                                 Address own_addr) {
129   if (CancelPendingConnection(addr)) {
130     uint16_t handle = GetUnusedHandle();
131     acl_connections_.emplace(
132         handle,
133         AclConnection{
134             AddressWithType{addr, AddressType::PUBLIC_DEVICE_ADDRESS},
135             AddressWithType{own_addr, AddressType::PUBLIC_DEVICE_ADDRESS},
136             AddressWithType(), Phy::Type::BR_EDR,
137             bluetooth::hci::Role::CENTRAL});
138     return handle;
139   }
140   return kReservedHandle;
141 }
142 
CreateLeConnection(AddressWithType addr,AddressWithType own_addr,bluetooth::hci::Role role)143 uint16_t AclConnectionHandler::CreateLeConnection(AddressWithType addr,
144                                                   AddressWithType own_addr,
145                                                   bluetooth::hci::Role role) {
146   AddressWithType resolved_peer = pending_le_connection_resolved_address_;
147   if (CancelPendingLeConnection(addr)) {
148     uint16_t handle = GetUnusedHandle();
149     acl_connections_.emplace(handle,
150                              AclConnection{addr, own_addr, resolved_peer,
151                                            Phy::Type::LOW_ENERGY, role});
152     return handle;
153   }
154   return kReservedHandle;
155 }
156 
Disconnect(uint16_t handle,std::function<void (AsyncTaskId)> stopStream)157 bool AclConnectionHandler::Disconnect(
158     uint16_t handle, std::function<void(AsyncTaskId)> stopStream) {
159   if (HasScoHandle(handle)) {
160     sco_connections_.at(handle).StopStream(std::move(stopStream));
161     sco_connections_.erase(handle);
162     return true;
163   }
164   if (HasHandle(handle)) {
165     // It is the responsibility of the caller to remove SCO connections
166     // with connected peer first.
167     uint16_t sco_handle = GetScoHandle(GetAddress(handle).GetAddress());
168     ASSERT(!HasScoHandle(sco_handle));
169     acl_connections_.erase(handle);
170     return true;
171   }
172   return false;
173 }
174 
GetHandle(AddressWithType addr) const175 uint16_t AclConnectionHandler::GetHandle(AddressWithType addr) const {
176   for (auto pair : acl_connections_) {
177     if (std::get<AclConnection>(pair).GetAddress() == addr) {
178       return std::get<0>(pair);
179     }
180   }
181   return kReservedHandle;
182 }
183 
GetHandleOnlyAddress(bluetooth::hci::Address addr) const184 uint16_t AclConnectionHandler::GetHandleOnlyAddress(
185     bluetooth::hci::Address addr) const {
186   for (auto pair : acl_connections_) {
187     if (std::get<AclConnection>(pair).GetAddress().GetAddress() == addr) {
188       return std::get<0>(pair);
189     }
190   }
191   return kReservedHandle;
192 }
193 
GetAddress(uint16_t handle) const194 AddressWithType AclConnectionHandler::GetAddress(uint16_t handle) const {
195   ASSERT_LOG(HasHandle(handle), "Unknown handle %hd", handle);
196   return acl_connections_.at(handle).GetAddress();
197 }
198 
GetScoAddress(uint16_t handle) const199 Address AclConnectionHandler::GetScoAddress(uint16_t handle) const {
200   ASSERT_LOG(HasScoHandle(handle), "Unknown SCO handle %hd", handle);
201   return sco_connections_.at(handle).GetAddress();
202 }
203 
GetOwnAddress(uint16_t handle) const204 AddressWithType AclConnectionHandler::GetOwnAddress(uint16_t handle) const {
205   ASSERT_LOG(HasHandle(handle), "Unknown handle %hd", handle);
206   return acl_connections_.at(handle).GetOwnAddress();
207 }
208 
GetResolvedAddress(uint16_t handle) const209 AddressWithType AclConnectionHandler::GetResolvedAddress(
210     uint16_t handle) const {
211   ASSERT_LOG(HasHandle(handle), "Unknown handle %hd", handle);
212   return acl_connections_.at(handle).GetResolvedAddress();
213 }
214 
Encrypt(uint16_t handle)215 void AclConnectionHandler::Encrypt(uint16_t handle) {
216   if (!HasHandle(handle)) {
217     return;
218   }
219   acl_connections_.at(handle).Encrypt();
220 }
221 
IsEncrypted(uint16_t handle) const222 bool AclConnectionHandler::IsEncrypted(uint16_t handle) const {
223   if (!HasHandle(handle)) {
224     return false;
225   }
226   return acl_connections_.at(handle).IsEncrypted();
227 }
228 
GetPhyType(uint16_t handle) const229 Phy::Type AclConnectionHandler::GetPhyType(uint16_t handle) const {
230   if (!HasHandle(handle)) {
231     return Phy::Type::BR_EDR;
232   }
233   return acl_connections_.at(handle).GetPhyType();
234 }
235 
GetAclLinkPolicySettings(uint16_t handle) const236 uint16_t AclConnectionHandler::GetAclLinkPolicySettings(uint16_t handle) const {
237   return acl_connections_.at(handle).GetLinkPolicySettings();
238 };
239 
SetAclLinkPolicySettings(uint16_t handle,uint16_t settings)240 void AclConnectionHandler::SetAclLinkPolicySettings(uint16_t handle,
241                                                     uint16_t settings) {
242   acl_connections_.at(handle).SetLinkPolicySettings(settings);
243 }
244 
GetAclRole(uint16_t handle) const245 bluetooth::hci::Role AclConnectionHandler::GetAclRole(uint16_t handle) const {
246   return acl_connections_.at(handle).GetRole();
247 };
248 
SetAclRole(uint16_t handle,bluetooth::hci::Role role)249 void AclConnectionHandler::SetAclRole(uint16_t handle,
250                                       bluetooth::hci::Role role) {
251   acl_connections_.at(handle).SetRole(role);
252 }
253 
254 std::unique_ptr<bluetooth::hci::LeSetCigParametersCompleteBuilder>
SetCigParameters(uint8_t id,uint32_t sdu_interval_m_to_s,uint32_t sdu_interval_s_to_m,bluetooth::hci::ClockAccuracy,bluetooth::hci::Packing packing,bluetooth::hci::Enable framed,uint16_t max_transport_latency_m_to_s_,uint16_t max_transport_latency_s_to_m_,std::vector<bluetooth::hci::CisParametersConfig> & streams)255 AclConnectionHandler::SetCigParameters(
256     uint8_t id, uint32_t sdu_interval_m_to_s, uint32_t sdu_interval_s_to_m,
257     bluetooth::hci::ClockAccuracy /* accuracy */,
258     bluetooth::hci::Packing packing, bluetooth::hci::Enable framed,
259     uint16_t max_transport_latency_m_to_s_,
260     uint16_t max_transport_latency_s_to_m_,
261     std::vector<bluetooth::hci::CisParametersConfig>& streams) {
262   std::vector<uint16_t> handles;
263   GroupParameters group_parameters{
264       .id = id,
265       .sdu_interval_m_to_s = sdu_interval_m_to_s,
266       .sdu_interval_s_to_m = sdu_interval_s_to_m,
267       .interleaved = packing == bluetooth::hci::Packing::INTERLEAVED,
268       .framed = framed == bluetooth::hci::Enable::ENABLED,
269       .max_transport_latency_m_to_s = max_transport_latency_m_to_s_,
270       .max_transport_latency_s_to_m = max_transport_latency_s_to_m_};
271   std::vector<StreamParameters> stream_parameters;
272   for (size_t i = 0; i < streams.size(); i++) {
273     auto handle = GetUnusedHandle();
274     StreamParameters a{.group_id = group_parameters.id,
275                        .stream_id = streams[i].cis_id_,
276                        .max_sdu_m_to_s = streams[i].max_sdu_m_to_s_,
277                        .max_sdu_s_to_m = streams[i].max_sdu_s_to_m_,
278                        .rtn_m_to_s = streams[i].rtn_m_to_s_,
279                        .rtn_s_to_m = streams[i].rtn_s_to_m_,
280                        .handle = handle};
281     handles.push_back(handle);
282     stream_parameters.push_back(std::move(a));
283   }
284 
285   return isochronous_connection_handler_.SetCigParameters(
286       group_parameters, stream_parameters, std::move(handles));
287 }
288 
CreatePendingCis(bluetooth::hci::CreateCisConfig config)289 void AclConnectionHandler::CreatePendingCis(
290     bluetooth::hci::CreateCisConfig config) {
291   CisHandles handles;
292   handles.cis_handle_ = config.cis_connection_handle_;
293   handles.acl_handle_ = config.acl_connection_handle_;
294   handles.remote_cis_handle_ = kReservedHandle;
295   pending_streams_.emplace_back(std::move(handles));
296 }
297 
ConnectCis(uint16_t handle)298 bool AclConnectionHandler::ConnectCis(uint16_t handle) {
299   size_t position;
300   CisHandles connection;
301   for (position = 0; position < pending_streams_.size(); position++) {
302     if (handle == pending_streams_[position].cis_handle_) {
303       LOG_INFO("Found handle 0x%04hx", handle);
304       connection = pending_streams_[position];
305       pending_streams_.erase(pending_streams_.begin() + position);
306       connected_streams_.push_back(connection);
307       ASSERT(connection.cis_handle_ != kReservedHandle);
308       ASSERT(connection.acl_handle_ != kReservedHandle);
309       ASSERT(connection.remote_cis_handle_ != kReservedHandle);
310       return true;
311     }
312   }
313 
314   LOG_INFO("No pending CIS connection with handle 0x%04hx", handle);
315   return false;
316 }
317 
SetRemoteCisHandle(uint16_t handle,uint16_t remote_handle)318 void AclConnectionHandler::SetRemoteCisHandle(uint16_t handle,
319                                               uint16_t remote_handle) {
320   for (size_t position = 0; position < pending_streams_.size(); position++) {
321     if (handle == pending_streams_[position].cis_handle_) {
322       LOG_INFO("Added remote handle 0x%04hx to handle 0x%04hx", remote_handle,
323                pending_streams_[position].cis_handle_);
324       pending_streams_[position].remote_cis_handle_ = remote_handle;
325       return;
326     }
327   }
328   LOG_INFO("Couldn't find CIS connection with handle 0x%04hx", handle);
329 }
330 
RejectCis(uint16_t handle)331 bool AclConnectionHandler::RejectCis(uint16_t handle) {
332   size_t position;
333   for (position = 0; position < pending_streams_.size(); position++) {
334     if (handle == pending_streams_[position].cis_handle_) {
335       pending_streams_.erase(pending_streams_.begin() + position);
336       break;
337     }
338   }
339   if (position == pending_streams_.size()) {
340     LOG_INFO("No pending connection with handle 0x%hx", handle);
341     return false;
342   }
343   return true;
344 }
345 
GetPendingAclHandle(uint16_t cis_handle) const346 uint16_t AclConnectionHandler::GetPendingAclHandle(uint16_t cis_handle) const {
347   size_t position;
348   uint16_t handle = 0xffff;
349   for (position = 0; position < pending_streams_.size(); position++) {
350     if (cis_handle == pending_streams_[position].cis_handle_) {
351       handle = pending_streams_[position].acl_handle_;
352       break;
353     }
354   }
355   if (position == pending_streams_.size()) {
356     LOG_INFO("No pending connection with handle 0x%hx", cis_handle);
357   }
358   return handle;
359 }
360 
DisconnectCis(uint16_t cis_handle)361 bool AclConnectionHandler::DisconnectCis(uint16_t cis_handle) {
362   size_t position;
363   for (position = 0; position < connected_streams_.size(); position++) {
364     if (cis_handle == connected_streams_[position].cis_handle_) {
365       connected_streams_.erase(connected_streams_.begin() + position);
366       break;
367     }
368   }
369   if (position == connected_streams_.size()) {
370     LOG_INFO("No connected stream 0x%hx", cis_handle);
371     return false;
372   }
373   return true;
374 }
375 
RemoveCig(uint8_t cig_id)376 bluetooth::hci::ErrorCode AclConnectionHandler::RemoveCig(uint8_t cig_id) {
377   for (const auto& stream : connected_streams_) {
378     if (isochronous_connection_handler_.GetGroupId(stream.cis_handle_) ==
379         cig_id) {
380       return bluetooth::hci::ErrorCode::COMMAND_DISALLOWED;
381     }
382   }
383   for (const auto& stream : pending_streams_) {
384     if (isochronous_connection_handler_.GetGroupId(stream.cis_handle_) ==
385         cig_id) {
386       return bluetooth::hci::ErrorCode::COMMAND_DISALLOWED;
387     }
388   }
389   auto status = isochronous_connection_handler_.RemoveCig(cig_id);
390   if (status == bluetooth::hci::ErrorCode::SUCCESS) {
391     // Clean up?
392   }
393   return status;
394 }
395 
HasPendingCisConnection(uint16_t handle) const396 bool AclConnectionHandler::HasPendingCisConnection(uint16_t handle) const {
397   for (const auto& config : pending_streams_) {
398     if (config.cis_handle_ == handle) {
399       return true;
400     }
401   }
402   return false;
403 }
404 
HasPendingCis() const405 bool AclConnectionHandler::HasPendingCis() const {
406   return !pending_streams_.empty();
407 }
408 
HasConnectedCis(uint16_t handle) const409 bool AclConnectionHandler::HasConnectedCis(uint16_t handle) const {
410   for (const auto& cs : connected_streams_) {
411     if (handle == cs.cis_handle_) {
412       return true;
413     }
414   }
415   return false;
416 }
417 
HasCisHandle(uint16_t handle) const418 bool AclConnectionHandler::HasCisHandle(uint16_t handle) const {
419   for (const auto& cs : pending_streams_) {
420     if (handle == cs.cis_handle_) {
421       return true;
422     }
423   }
424   for (const auto& cs : connected_streams_) {
425     if (handle == cs.cis_handle_) {
426       return true;
427     }
428   }
429   return isochronous_connection_handler_.HasHandle(handle);
430 }
431 
GetAclHandleForCisHandle(uint16_t cis_handle) const432 uint16_t AclConnectionHandler::GetAclHandleForCisHandle(
433     uint16_t cis_handle) const {
434   for (const auto& cs : connected_streams_) {
435     if (cis_handle == cs.cis_handle_) {
436       return cs.acl_handle_;
437     }
438   }
439   return kReservedHandle;
440 }
441 
GetRemoteCisHandleForCisHandle(uint16_t cis_handle) const442 uint16_t AclConnectionHandler::GetRemoteCisHandleForCisHandle(
443     uint16_t cis_handle) const {
444   for (const auto& cs : connected_streams_) {
445     if (cis_handle == cs.cis_handle_) {
446       return cs.remote_cis_handle_;
447     }
448   }
449   return kReservedHandle;
450 }
451 
GetGroupParameters(uint8_t id) const452 GroupParameters AclConnectionHandler::GetGroupParameters(uint8_t id) const {
453   return isochronous_connection_handler_.GetGroupParameters(id);
454 }
455 
GetStreamParameters(uint16_t handle) const456 StreamParameters AclConnectionHandler::GetStreamParameters(
457     uint16_t handle) const {
458   return isochronous_connection_handler_.GetStreamParameters(handle);
459 }
460 
CreateScoConnection(bluetooth::hci::Address addr,ScoConnectionParameters const & parameters,ScoState state,ScoDatapath datapath,bool legacy)461 void AclConnectionHandler::CreateScoConnection(
462     bluetooth::hci::Address addr, ScoConnectionParameters const& parameters,
463     ScoState state, ScoDatapath datapath, bool legacy) {
464   uint16_t sco_handle = GetUnusedHandle();
465   sco_connections_.emplace(
466       sco_handle, ScoConnection(addr, parameters, state, datapath, legacy));
467 }
468 
HasPendingScoConnection(bluetooth::hci::Address addr) const469 bool AclConnectionHandler::HasPendingScoConnection(
470     bluetooth::hci::Address addr) const {
471   for (const auto& pair : sco_connections_) {
472     if (std::get<ScoConnection>(pair).GetAddress() == addr) {
473       ScoState state = std::get<ScoConnection>(pair).GetState();
474       return state == SCO_STATE_PENDING ||
475              state == SCO_STATE_SENT_ESCO_CONNECTION_REQUEST ||
476              state == SCO_STATE_SENT_SCO_CONNECTION_REQUEST;
477     }
478   }
479   return false;
480 }
481 
GetScoConnectionState(bluetooth::hci::Address addr) const482 ScoState AclConnectionHandler::GetScoConnectionState(
483     bluetooth::hci::Address addr) const {
484   for (const auto& pair : sco_connections_) {
485     if (std::get<ScoConnection>(pair).GetAddress() == addr) {
486       return std::get<ScoConnection>(pair).GetState();
487     }
488   }
489   return SCO_STATE_CLOSED;
490 }
491 
IsLegacyScoConnection(bluetooth::hci::Address addr) const492 bool AclConnectionHandler::IsLegacyScoConnection(
493     bluetooth::hci::Address addr) const {
494   for (const auto& pair : sco_connections_) {
495     if (std::get<ScoConnection>(pair).GetAddress() == addr) {
496       return std::get<ScoConnection>(pair).IsLegacy();
497     }
498   }
499   return false;
500 }
501 
CancelPendingScoConnection(bluetooth::hci::Address addr)502 void AclConnectionHandler::CancelPendingScoConnection(
503     bluetooth::hci::Address addr) {
504   for (auto it = sco_connections_.begin(); it != sco_connections_.end(); it++) {
505     if (std::get<ScoConnection>(*it).GetAddress() == addr) {
506       sco_connections_.erase(it);
507       return;
508     }
509   }
510 }
511 
AcceptPendingScoConnection(bluetooth::hci::Address addr,ScoLinkParameters const & parameters,std::function<AsyncTaskId ()> startStream)512 bool AclConnectionHandler::AcceptPendingScoConnection(
513     bluetooth::hci::Address addr, ScoLinkParameters const& parameters,
514     std::function<AsyncTaskId()> startStream) {
515   for (auto& pair : sco_connections_) {
516     if (std::get<ScoConnection>(pair).GetAddress() == addr) {
517       std::get<ScoConnection>(pair).SetLinkParameters(parameters);
518       std::get<ScoConnection>(pair).SetState(ScoState::SCO_STATE_OPENED);
519       std::get<ScoConnection>(pair).StartStream(std::move(startStream));
520       return true;
521     }
522   }
523   return false;
524 }
525 
AcceptPendingScoConnection(bluetooth::hci::Address addr,ScoConnectionParameters const & parameters,std::function<AsyncTaskId ()> startStream)526 bool AclConnectionHandler::AcceptPendingScoConnection(
527     bluetooth::hci::Address addr, ScoConnectionParameters const& parameters,
528     std::function<AsyncTaskId()> startStream) {
529   for (auto& pair : sco_connections_) {
530     if (std::get<ScoConnection>(pair).GetAddress() == addr) {
531       bool ok =
532           std::get<ScoConnection>(pair).NegotiateLinkParameters(parameters);
533       std::get<ScoConnection>(pair).SetState(ok ? ScoState::SCO_STATE_OPENED
534                                                 : ScoState::SCO_STATE_CLOSED);
535       if (ok) {
536         std::get<ScoConnection>(pair).StartStream(std::move(startStream));
537       }
538       return ok;
539     }
540   }
541   return false;
542 }
543 
GetScoHandle(bluetooth::hci::Address addr) const544 uint16_t AclConnectionHandler::GetScoHandle(
545     bluetooth::hci::Address addr) const {
546   for (const auto& pair : sco_connections_) {
547     if (std::get<ScoConnection>(pair).GetAddress() == addr) {
548       return std::get<0>(pair);
549     }
550   }
551   return kReservedHandle;
552 }
553 
GetScoConnectionParameters(bluetooth::hci::Address addr) const554 ScoConnectionParameters AclConnectionHandler::GetScoConnectionParameters(
555     bluetooth::hci::Address addr) const {
556   for (const auto& pair : sco_connections_) {
557     if (std::get<ScoConnection>(pair).GetAddress() == addr) {
558       return std::get<ScoConnection>(pair).GetConnectionParameters();
559     }
560   }
561   return {};
562 }
563 
GetScoLinkParameters(bluetooth::hci::Address addr) const564 ScoLinkParameters AclConnectionHandler::GetScoLinkParameters(
565     bluetooth::hci::Address addr) const {
566   for (const auto& pair : sco_connections_) {
567     if (std::get<ScoConnection>(pair).GetAddress() == addr) {
568       return std::get<ScoConnection>(pair).GetLinkParameters();
569     }
570   }
571   return {};
572 }
573 
GetAclHandles() const574 std::vector<uint16_t> AclConnectionHandler::GetAclHandles() const {
575   std::vector<uint16_t> keys;
576 
577   for (const auto& pair : acl_connections_) {
578     keys.push_back(pair.first);
579   }
580   return keys;
581 }
582 
ResetLinkTimer(uint16_t handle)583 void AclConnectionHandler::ResetLinkTimer(uint16_t handle) {
584   acl_connections_.at(handle).ResetLinkTimer();
585 }
586 
587 std::chrono::steady_clock::duration
TimeUntilLinkNearExpiring(uint16_t handle) const588 AclConnectionHandler::TimeUntilLinkNearExpiring(uint16_t handle) const {
589   return acl_connections_.at(handle).TimeUntilNearExpiring();
590 }
591 
IsLinkNearExpiring(uint16_t handle) const592 bool AclConnectionHandler::IsLinkNearExpiring(uint16_t handle) const {
593   return acl_connections_.at(handle).IsNearExpiring();
594 }
595 
TimeUntilLinkExpired(uint16_t handle) const596 std::chrono::steady_clock::duration AclConnectionHandler::TimeUntilLinkExpired(
597     uint16_t handle) const {
598   return acl_connections_.at(handle).TimeUntilExpired();
599 }
600 
HasLinkExpired(uint16_t handle) const601 bool AclConnectionHandler::HasLinkExpired(uint16_t handle) const {
602   return acl_connections_.at(handle).HasExpired();
603 }
604 
605 }  // namespace rootcanal
606