• 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 
Reset(std::function<void (TaskId)> stopStream)30 void AclConnectionHandler::Reset(std::function<void(TaskId)> stopStream) {
31   // Leave no dangling periodic task.
32   for (auto& [_, sco_connection] : sco_connections_) {
33     sco_connection.StopStream(stopStream);
34   }
35 
36   sco_connections_.clear();
37   acl_connections_.clear();
38 }
39 
HasHandle(uint16_t handle) const40 bool AclConnectionHandler::HasHandle(uint16_t handle) const {
41   return acl_connections_.count(handle) != 0;
42 }
43 
HasScoHandle(uint16_t handle) const44 bool AclConnectionHandler::HasScoHandle(uint16_t handle) const {
45   return sco_connections_.count(handle) != 0;
46 }
47 
GetUnusedHandle()48 uint16_t AclConnectionHandler::GetUnusedHandle() {
49   while (HasHandle(last_handle_) || HasScoHandle(last_handle_) ||
50          isochronous_connection_handler_.HasHandle(last_handle_)) {
51     last_handle_ = (last_handle_ + 1) % kReservedHandle;
52   }
53   uint16_t unused_handle = last_handle_;
54   last_handle_ = (last_handle_ + 1) % kReservedHandle;
55   return unused_handle;
56 }
57 
CreatePendingConnection(Address addr,bool authenticate_on_connect,bool allow_role_switch)58 bool AclConnectionHandler::CreatePendingConnection(Address addr,
59                                                    bool authenticate_on_connect,
60                                                    bool allow_role_switch) {
61   if (classic_connection_pending_) {
62     return false;
63   }
64   classic_connection_pending_ = true;
65   pending_connection_address_ = addr;
66   authenticate_pending_classic_connection_ = authenticate_on_connect;
67   pending_classic_connection_allow_role_switch_ = allow_role_switch;
68   return true;
69 }
70 
HasPendingConnection(Address addr) const71 bool AclConnectionHandler::HasPendingConnection(Address addr) const {
72   return classic_connection_pending_ && pending_connection_address_ == addr;
73 }
74 
AuthenticatePendingConnection() const75 bool AclConnectionHandler::AuthenticatePendingConnection() const {
76   return authenticate_pending_classic_connection_;
77 }
78 
CancelPendingConnection(Address addr)79 bool AclConnectionHandler::CancelPendingConnection(Address addr) {
80   if (!classic_connection_pending_ || pending_connection_address_ != addr) {
81     return false;
82   }
83   classic_connection_pending_ = false;
84   pending_connection_address_ = Address::kEmpty;
85   pending_le_connection_resolved_address_ = AddressWithType();
86   return true;
87 }
88 
CreatePendingLeConnection(AddressWithType peer,AddressWithType resolved_peer,AddressWithType local_address)89 bool AclConnectionHandler::CreatePendingLeConnection(
90     AddressWithType peer, AddressWithType resolved_peer,
91     AddressWithType local_address) {
92   for (auto pair : acl_connections_) {
93     auto connection = std::get<AclConnection>(pair);
94     if (connection.GetAddress() == peer ||
95         connection.GetResolvedAddress() == resolved_peer) {
96       LOG_INFO("%s: %s is already connected", __func__,
97                peer.ToString().c_str());
98       if (connection.GetResolvedAddress() == resolved_peer) {
99         LOG_INFO("%s: allowing a second connection with %s", __func__,
100                  resolved_peer.ToString().c_str());
101       } else {
102         return false;
103       }
104     }
105   }
106   if (le_connection_pending_) {
107     LOG_INFO("%s: connection already pending", __func__);
108     return false;
109   }
110   le_connection_pending_ = true;
111   pending_le_connection_address_ = peer;
112   pending_le_connection_own_address_ = local_address;
113   pending_le_connection_resolved_address_ = resolved_peer;
114   return true;
115 }
116 
HasPendingLeConnection(AddressWithType addr) const117 bool AclConnectionHandler::HasPendingLeConnection(AddressWithType addr) const {
118   return le_connection_pending_ && pending_le_connection_address_ == addr;
119 }
120 
CancelPendingLeConnection(AddressWithType addr)121 bool AclConnectionHandler::CancelPendingLeConnection(AddressWithType addr) {
122   if (!le_connection_pending_ || pending_le_connection_address_ != addr) {
123     return false;
124   }
125   le_connection_pending_ = false;
126   pending_le_connection_address_ =
127       AddressWithType{Address::kEmpty, AddressType::PUBLIC_DEVICE_ADDRESS};
128   pending_le_connection_resolved_address_ =
129       AddressWithType{Address::kEmpty, AddressType::PUBLIC_DEVICE_ADDRESS};
130   return true;
131 }
132 
CreateConnection(Address addr,Address own_addr)133 uint16_t AclConnectionHandler::CreateConnection(Address addr,
134                                                 Address own_addr) {
135   if (CancelPendingConnection(addr)) {
136     uint16_t handle = GetUnusedHandle();
137     acl_connections_.emplace(
138         handle,
139         AclConnection{
140             AddressWithType{addr, AddressType::PUBLIC_DEVICE_ADDRESS},
141             AddressWithType{own_addr, AddressType::PUBLIC_DEVICE_ADDRESS},
142             AddressWithType(), Phy::Type::BR_EDR,
143             bluetooth::hci::Role::CENTRAL});
144     return handle;
145   }
146   return kReservedHandle;
147 }
148 
CreateLeConnection(AddressWithType addr,AddressWithType own_addr,bluetooth::hci::Role role)149 uint16_t AclConnectionHandler::CreateLeConnection(AddressWithType addr,
150                                                   AddressWithType own_addr,
151                                                   bluetooth::hci::Role role) {
152   AddressWithType resolved_peer = pending_le_connection_resolved_address_;
153   if (CancelPendingLeConnection(addr)) {
154     uint16_t handle = GetUnusedHandle();
155     acl_connections_.emplace(handle,
156                              AclConnection{addr, own_addr, resolved_peer,
157                                            Phy::Type::LOW_ENERGY, role});
158     return handle;
159   }
160   return kReservedHandle;
161 }
162 
Disconnect(uint16_t handle,std::function<void (TaskId)> stopStream)163 bool AclConnectionHandler::Disconnect(uint16_t handle,
164                                       std::function<void(TaskId)> stopStream) {
165   if (HasScoHandle(handle)) {
166     sco_connections_.at(handle).StopStream(std::move(stopStream));
167     sco_connections_.erase(handle);
168     return true;
169   }
170   if (HasHandle(handle)) {
171     // It is the responsibility of the caller to remove SCO connections
172     // with connected peer first.
173     uint16_t sco_handle = GetScoHandle(GetAddress(handle).GetAddress());
174     ASSERT(!HasScoHandle(sco_handle));
175     acl_connections_.erase(handle);
176     return true;
177   }
178   return false;
179 }
180 
GetHandle(AddressWithType addr) const181 uint16_t AclConnectionHandler::GetHandle(AddressWithType addr) const {
182   for (auto pair : acl_connections_) {
183     if (std::get<AclConnection>(pair).GetAddress() == addr) {
184       return std::get<0>(pair);
185     }
186   }
187   return kReservedHandle;
188 }
189 
GetHandleOnlyAddress(bluetooth::hci::Address addr) const190 uint16_t AclConnectionHandler::GetHandleOnlyAddress(
191     bluetooth::hci::Address addr) const {
192   for (auto pair : acl_connections_) {
193     if (std::get<AclConnection>(pair).GetAddress().GetAddress() == addr) {
194       return std::get<0>(pair);
195     }
196   }
197   return kReservedHandle;
198 }
199 
GetAclConnection(uint16_t handle)200 AclConnection& AclConnectionHandler::GetAclConnection(uint16_t handle) {
201   ASSERT_LOG(HasHandle(handle), "Unknown handle %d", handle);
202   return acl_connections_.at(handle);
203 }
204 
GetAddress(uint16_t handle) const205 AddressWithType AclConnectionHandler::GetAddress(uint16_t handle) const {
206   ASSERT_LOG(HasHandle(handle), "Unknown handle %hd", handle);
207   return acl_connections_.at(handle).GetAddress();
208 }
209 
GetAddressSafe(uint16_t handle) const210 std::optional<AddressWithType> AclConnectionHandler::GetAddressSafe(
211     uint16_t handle) const {
212   return HasHandle(handle) ? acl_connections_.at(handle).GetAddress()
213                            : std::optional<AddressWithType>();
214 }
215 
GetScoAddress(uint16_t handle) const216 Address AclConnectionHandler::GetScoAddress(uint16_t handle) const {
217   ASSERT_LOG(HasScoHandle(handle), "Unknown SCO handle %hd", handle);
218   return sco_connections_.at(handle).GetAddress();
219 }
220 
GetOwnAddress(uint16_t handle) const221 AddressWithType AclConnectionHandler::GetOwnAddress(uint16_t handle) const {
222   ASSERT_LOG(HasHandle(handle), "Unknown handle %hd", handle);
223   return acl_connections_.at(handle).GetOwnAddress();
224 }
225 
GetResolvedAddress(uint16_t handle) const226 AddressWithType AclConnectionHandler::GetResolvedAddress(
227     uint16_t handle) const {
228   ASSERT_LOG(HasHandle(handle), "Unknown handle %hd", handle);
229   return acl_connections_.at(handle).GetResolvedAddress();
230 }
231 
Encrypt(uint16_t handle)232 void AclConnectionHandler::Encrypt(uint16_t handle) {
233   if (!HasHandle(handle)) {
234     return;
235   }
236   acl_connections_.at(handle).Encrypt();
237 }
238 
IsEncrypted(uint16_t handle) const239 bool AclConnectionHandler::IsEncrypted(uint16_t handle) const {
240   if (!HasHandle(handle)) {
241     return false;
242   }
243   return acl_connections_.at(handle).IsEncrypted();
244 }
245 
SetRssi(uint16_t handle,int8_t rssi)246 void AclConnectionHandler::SetRssi(uint16_t handle, int8_t rssi) {
247   if (HasHandle(handle)) {
248     acl_connections_.at(handle).SetRssi(rssi);
249   }
250 }
251 
GetRssi(uint16_t handle) const252 int8_t AclConnectionHandler::GetRssi(uint16_t handle) const {
253   return HasHandle(handle) ? acl_connections_.at(handle).GetRssi() : 0;
254 }
255 
GetPhyType(uint16_t handle) const256 Phy::Type AclConnectionHandler::GetPhyType(uint16_t handle) const {
257   if (!HasHandle(handle)) {
258     return Phy::Type::BR_EDR;
259   }
260   return acl_connections_.at(handle).GetPhyType();
261 }
262 
GetAclLinkPolicySettings(uint16_t handle) const263 uint16_t AclConnectionHandler::GetAclLinkPolicySettings(uint16_t handle) const {
264   return acl_connections_.at(handle).GetLinkPolicySettings();
265 };
266 
SetAclLinkPolicySettings(uint16_t handle,uint16_t settings)267 void AclConnectionHandler::SetAclLinkPolicySettings(uint16_t handle,
268                                                     uint16_t settings) {
269   acl_connections_.at(handle).SetLinkPolicySettings(settings);
270 }
271 
GetAclRole(uint16_t handle) const272 bluetooth::hci::Role AclConnectionHandler::GetAclRole(uint16_t handle) const {
273   return acl_connections_.at(handle).GetRole();
274 };
275 
SetAclRole(uint16_t handle,bluetooth::hci::Role role)276 void AclConnectionHandler::SetAclRole(uint16_t handle,
277                                       bluetooth::hci::Role role) {
278   acl_connections_.at(handle).SetRole(role);
279 }
280 
281 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 framing,uint16_t max_transport_latency_m_to_s,uint16_t max_transport_latency_s_to_m,std::vector<bluetooth::hci::CisParametersConfig> & streams)282 AclConnectionHandler::SetCigParameters(
283     uint8_t id, uint32_t sdu_interval_m_to_s, uint32_t sdu_interval_s_to_m,
284     bluetooth::hci::ClockAccuracy /* accuracy */,
285     bluetooth::hci::Packing packing, bluetooth::hci::Enable framing,
286     uint16_t max_transport_latency_m_to_s,
287     uint16_t max_transport_latency_s_to_m,
288     std::vector<bluetooth::hci::CisParametersConfig>& streams) {
289   std::vector<uint16_t> handles;
290   GroupParameters group_parameters{
291       .id = id,
292       .sdu_interval_m_to_s = sdu_interval_m_to_s,
293       .sdu_interval_s_to_m = sdu_interval_s_to_m,
294       .interleaved = packing == bluetooth::hci::Packing::INTERLEAVED,
295       .framed = framing == bluetooth::hci::Enable::ENABLED,
296       .max_transport_latency_m_to_s = max_transport_latency_m_to_s,
297       .max_transport_latency_s_to_m = max_transport_latency_s_to_m};
298   std::vector<StreamParameters> stream_parameters;
299   for (size_t i = 0; i < streams.size(); i++) {
300     auto handle = GetUnusedHandle();
301     StreamParameters a{.group_id = group_parameters.id,
302                        .stream_id = streams[i].cis_id_,
303                        .max_sdu_m_to_s = streams[i].max_sdu_m_to_s_,
304                        .max_sdu_s_to_m = streams[i].max_sdu_s_to_m_,
305                        .rtn_m_to_s = streams[i].rtn_m_to_s_,
306                        .rtn_s_to_m = streams[i].rtn_s_to_m_,
307                        .handle = handle};
308     handles.push_back(handle);
309     stream_parameters.push_back(std::move(a));
310   }
311 
312   return isochronous_connection_handler_.SetCigParameters(
313       group_parameters, stream_parameters, std::move(handles));
314 }
315 
CreatePendingCis(bluetooth::hci::CreateCisConfig config)316 void AclConnectionHandler::CreatePendingCis(
317     bluetooth::hci::CreateCisConfig config) {
318   CisHandles handles;
319   handles.cis_handle_ = config.cis_connection_handle_;
320   handles.acl_handle_ = config.acl_connection_handle_;
321   handles.remote_cis_handle_ = kReservedHandle;
322   pending_streams_.emplace_back(std::move(handles));
323 }
324 
ConnectCis(uint16_t handle)325 bool AclConnectionHandler::ConnectCis(uint16_t handle) {
326   size_t position;
327   CisHandles connection;
328   for (position = 0; position < pending_streams_.size(); position++) {
329     if (handle == pending_streams_[position].cis_handle_) {
330       LOG_INFO("Found handle 0x%04hx", handle);
331       connection = pending_streams_[position];
332       pending_streams_.erase(pending_streams_.begin() + position);
333       connected_streams_.push_back(connection);
334       ASSERT(connection.cis_handle_ != kReservedHandle);
335       ASSERT(connection.acl_handle_ != kReservedHandle);
336       ASSERT(connection.remote_cis_handle_ != kReservedHandle);
337       return true;
338     }
339   }
340 
341   LOG_INFO("No pending CIS connection with handle 0x%04hx", handle);
342   return false;
343 }
344 
SetRemoteCisHandle(uint16_t handle,uint16_t remote_handle)345 void AclConnectionHandler::SetRemoteCisHandle(uint16_t handle,
346                                               uint16_t remote_handle) {
347   for (size_t position = 0; position < pending_streams_.size(); position++) {
348     if (handle == pending_streams_[position].cis_handle_) {
349       LOG_INFO("Added remote handle 0x%04hx to handle 0x%04hx", remote_handle,
350                pending_streams_[position].cis_handle_);
351       pending_streams_[position].remote_cis_handle_ = remote_handle;
352       return;
353     }
354   }
355   LOG_INFO("Couldn't find CIS connection with handle 0x%04hx", handle);
356 }
357 
RejectCis(uint16_t handle)358 bool AclConnectionHandler::RejectCis(uint16_t handle) {
359   size_t position;
360   for (position = 0; position < pending_streams_.size(); position++) {
361     if (handle == pending_streams_[position].cis_handle_) {
362       pending_streams_.erase(pending_streams_.begin() + position);
363       break;
364     }
365   }
366   if (position == pending_streams_.size()) {
367     LOG_INFO("No pending connection with handle 0x%hx", handle);
368     return false;
369   }
370   return true;
371 }
372 
GetPendingAclHandle(uint16_t cis_handle) const373 uint16_t AclConnectionHandler::GetPendingAclHandle(uint16_t cis_handle) const {
374   size_t position;
375   uint16_t handle = 0xffff;
376   for (position = 0; position < pending_streams_.size(); position++) {
377     if (cis_handle == pending_streams_[position].cis_handle_) {
378       handle = pending_streams_[position].acl_handle_;
379       break;
380     }
381   }
382   if (position == pending_streams_.size()) {
383     LOG_INFO("No pending connection with handle 0x%hx", cis_handle);
384   }
385   return handle;
386 }
387 
DisconnectCis(uint16_t cis_handle)388 bool AclConnectionHandler::DisconnectCis(uint16_t cis_handle) {
389   size_t position;
390   for (position = 0; position < connected_streams_.size(); position++) {
391     if (cis_handle == connected_streams_[position].cis_handle_) {
392       connected_streams_.erase(connected_streams_.begin() + position);
393       break;
394     }
395   }
396   if (position == connected_streams_.size()) {
397     LOG_INFO("No connected stream 0x%hx", cis_handle);
398     return false;
399   }
400   return true;
401 }
402 
RemoveCig(uint8_t cig_id)403 bluetooth::hci::ErrorCode AclConnectionHandler::RemoveCig(uint8_t cig_id) {
404   for (const auto& stream : connected_streams_) {
405     if (isochronous_connection_handler_.GetGroupId(stream.cis_handle_) ==
406         cig_id) {
407       return bluetooth::hci::ErrorCode::COMMAND_DISALLOWED;
408     }
409   }
410   for (const auto& stream : pending_streams_) {
411     if (isochronous_connection_handler_.GetGroupId(stream.cis_handle_) ==
412         cig_id) {
413       return bluetooth::hci::ErrorCode::COMMAND_DISALLOWED;
414     }
415   }
416   auto status = isochronous_connection_handler_.RemoveCig(cig_id);
417   if (status == bluetooth::hci::ErrorCode::SUCCESS) {
418     // Clean up?
419   }
420   return status;
421 }
422 
HasPendingCisConnection(uint16_t handle) const423 bool AclConnectionHandler::HasPendingCisConnection(uint16_t handle) const {
424   for (const auto& config : pending_streams_) {
425     if (config.cis_handle_ == handle) {
426       return true;
427     }
428   }
429   return false;
430 }
431 
HasPendingCis() const432 bool AclConnectionHandler::HasPendingCis() const {
433   return !pending_streams_.empty();
434 }
435 
HasConnectedCis(uint16_t handle) const436 bool AclConnectionHandler::HasConnectedCis(uint16_t handle) const {
437   for (const auto& cs : connected_streams_) {
438     if (handle == cs.cis_handle_) {
439       return true;
440     }
441   }
442   return false;
443 }
444 
HasCisHandle(uint16_t handle) const445 bool AclConnectionHandler::HasCisHandle(uint16_t handle) const {
446   for (const auto& cs : pending_streams_) {
447     if (handle == cs.cis_handle_) {
448       return true;
449     }
450   }
451   for (const auto& cs : connected_streams_) {
452     if (handle == cs.cis_handle_) {
453       return true;
454     }
455   }
456   return isochronous_connection_handler_.HasHandle(handle);
457 }
458 
GetAclHandleForCisHandle(uint16_t cis_handle) const459 uint16_t AclConnectionHandler::GetAclHandleForCisHandle(
460     uint16_t cis_handle) const {
461   for (const auto& cs : connected_streams_) {
462     if (cis_handle == cs.cis_handle_) {
463       return cs.acl_handle_;
464     }
465   }
466   return kReservedHandle;
467 }
468 
GetRemoteCisHandleForCisHandle(uint16_t cis_handle) const469 uint16_t AclConnectionHandler::GetRemoteCisHandleForCisHandle(
470     uint16_t cis_handle) const {
471   for (const auto& cs : connected_streams_) {
472     if (cis_handle == cs.cis_handle_) {
473       return cs.remote_cis_handle_;
474     }
475   }
476   return kReservedHandle;
477 }
478 
GetGroupParameters(uint8_t id) const479 GroupParameters AclConnectionHandler::GetGroupParameters(uint8_t id) const {
480   return isochronous_connection_handler_.GetGroupParameters(id);
481 }
482 
GetStreamParameters(uint16_t handle) const483 StreamParameters AclConnectionHandler::GetStreamParameters(
484     uint16_t handle) const {
485   return isochronous_connection_handler_.GetStreamParameters(handle);
486 }
487 
CreateScoConnection(bluetooth::hci::Address addr,ScoConnectionParameters const & parameters,ScoState state,ScoDatapath datapath,bool legacy)488 void AclConnectionHandler::CreateScoConnection(
489     bluetooth::hci::Address addr, ScoConnectionParameters const& parameters,
490     ScoState state, ScoDatapath datapath, bool legacy) {
491   uint16_t sco_handle = GetUnusedHandle();
492   sco_connections_.emplace(
493       sco_handle, ScoConnection(addr, parameters, state, datapath, legacy));
494 }
495 
HasPendingScoConnection(bluetooth::hci::Address addr) const496 bool AclConnectionHandler::HasPendingScoConnection(
497     bluetooth::hci::Address addr) const {
498   for (const auto& pair : sco_connections_) {
499     if (std::get<ScoConnection>(pair).GetAddress() == addr) {
500       ScoState state = std::get<ScoConnection>(pair).GetState();
501       return state == SCO_STATE_PENDING ||
502              state == SCO_STATE_SENT_ESCO_CONNECTION_REQUEST ||
503              state == SCO_STATE_SENT_SCO_CONNECTION_REQUEST;
504     }
505   }
506   return false;
507 }
508 
GetScoConnectionState(bluetooth::hci::Address addr) const509 ScoState AclConnectionHandler::GetScoConnectionState(
510     bluetooth::hci::Address addr) const {
511   for (const auto& pair : sco_connections_) {
512     if (std::get<ScoConnection>(pair).GetAddress() == addr) {
513       return std::get<ScoConnection>(pair).GetState();
514     }
515   }
516   return SCO_STATE_CLOSED;
517 }
518 
IsLegacyScoConnection(bluetooth::hci::Address addr) const519 bool AclConnectionHandler::IsLegacyScoConnection(
520     bluetooth::hci::Address addr) const {
521   for (const auto& pair : sco_connections_) {
522     if (std::get<ScoConnection>(pair).GetAddress() == addr) {
523       return std::get<ScoConnection>(pair).IsLegacy();
524     }
525   }
526   return false;
527 }
528 
CancelPendingScoConnection(bluetooth::hci::Address addr)529 void AclConnectionHandler::CancelPendingScoConnection(
530     bluetooth::hci::Address addr) {
531   for (auto it = sco_connections_.begin(); it != sco_connections_.end(); it++) {
532     if (std::get<ScoConnection>(*it).GetAddress() == addr) {
533       sco_connections_.erase(it);
534       return;
535     }
536   }
537 }
538 
AcceptPendingScoConnection(bluetooth::hci::Address addr,ScoLinkParameters const & parameters,std::function<TaskId ()> startStream)539 bool AclConnectionHandler::AcceptPendingScoConnection(
540     bluetooth::hci::Address addr, ScoLinkParameters const& parameters,
541     std::function<TaskId()> startStream) {
542   for (auto& pair : sco_connections_) {
543     if (std::get<ScoConnection>(pair).GetAddress() == addr) {
544       std::get<ScoConnection>(pair).SetLinkParameters(parameters);
545       std::get<ScoConnection>(pair).SetState(ScoState::SCO_STATE_OPENED);
546       std::get<ScoConnection>(pair).StartStream(std::move(startStream));
547       return true;
548     }
549   }
550   return false;
551 }
552 
AcceptPendingScoConnection(bluetooth::hci::Address addr,ScoConnectionParameters const & parameters,std::function<TaskId ()> startStream)553 bool AclConnectionHandler::AcceptPendingScoConnection(
554     bluetooth::hci::Address addr, ScoConnectionParameters const& parameters,
555     std::function<TaskId()> startStream) {
556   for (auto& pair : sco_connections_) {
557     if (std::get<ScoConnection>(pair).GetAddress() == addr) {
558       bool ok =
559           std::get<ScoConnection>(pair).NegotiateLinkParameters(parameters);
560       std::get<ScoConnection>(pair).SetState(ok ? ScoState::SCO_STATE_OPENED
561                                                 : ScoState::SCO_STATE_CLOSED);
562       if (ok) {
563         std::get<ScoConnection>(pair).StartStream(std::move(startStream));
564       }
565       return ok;
566     }
567   }
568   return false;
569 }
570 
GetScoHandle(bluetooth::hci::Address addr) const571 uint16_t AclConnectionHandler::GetScoHandle(
572     bluetooth::hci::Address addr) const {
573   for (const auto& pair : sco_connections_) {
574     if (std::get<ScoConnection>(pair).GetAddress() == addr) {
575       return std::get<0>(pair);
576     }
577   }
578   return kReservedHandle;
579 }
580 
GetScoConnectionParameters(bluetooth::hci::Address addr) const581 ScoConnectionParameters AclConnectionHandler::GetScoConnectionParameters(
582     bluetooth::hci::Address addr) const {
583   for (const auto& pair : sco_connections_) {
584     if (std::get<ScoConnection>(pair).GetAddress() == addr) {
585       return std::get<ScoConnection>(pair).GetConnectionParameters();
586     }
587   }
588   return {};
589 }
590 
GetScoLinkParameters(bluetooth::hci::Address addr) const591 ScoLinkParameters AclConnectionHandler::GetScoLinkParameters(
592     bluetooth::hci::Address addr) const {
593   for (const auto& pair : sco_connections_) {
594     if (std::get<ScoConnection>(pair).GetAddress() == addr) {
595       return std::get<ScoConnection>(pair).GetLinkParameters();
596     }
597   }
598   return {};
599 }
600 
GetAclHandles() const601 std::vector<uint16_t> AclConnectionHandler::GetAclHandles() const {
602   std::vector<uint16_t> keys;
603 
604   for (const auto& pair : acl_connections_) {
605     keys.push_back(pair.first);
606   }
607   return keys;
608 }
609 
ResetLinkTimer(uint16_t handle)610 void AclConnectionHandler::ResetLinkTimer(uint16_t handle) {
611   acl_connections_.at(handle).ResetLinkTimer();
612 }
613 
614 std::chrono::steady_clock::duration
TimeUntilLinkNearExpiring(uint16_t handle) const615 AclConnectionHandler::TimeUntilLinkNearExpiring(uint16_t handle) const {
616   return acl_connections_.at(handle).TimeUntilNearExpiring();
617 }
618 
IsLinkNearExpiring(uint16_t handle) const619 bool AclConnectionHandler::IsLinkNearExpiring(uint16_t handle) const {
620   return acl_connections_.at(handle).IsNearExpiring();
621 }
622 
TimeUntilLinkExpired(uint16_t handle) const623 std::chrono::steady_clock::duration AclConnectionHandler::TimeUntilLinkExpired(
624     uint16_t handle) const {
625   return acl_connections_.at(handle).TimeUntilExpired();
626 }
627 
HasLinkExpired(uint16_t handle) const628 bool AclConnectionHandler::HasLinkExpired(uint16_t handle) const {
629   return acl_connections_.at(handle).HasExpired();
630 }
631 
IsRoleSwitchAllowedForPendingConnection() const632 bool AclConnectionHandler::IsRoleSwitchAllowedForPendingConnection() const {
633   return pending_classic_connection_allow_role_switch_;
634 }
635 
636 }  // namespace rootcanal
637