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 #pragma once
18 
19 #include <chrono>
20 #include <cstdint>
21 #include <functional>
22 #include <optional>
23 #include <unordered_map>
24 #include <vector>
25 
26 #include "hci/address.h"
27 #include "hci/address_with_type.h"
28 #include "model/controller/acl_connection.h"
29 #include "model/controller/sco_connection.h"
30 #include "packets/hci_packets.h"
31 #include "phy.h"
32 
33 namespace rootcanal {
34 static constexpr uint16_t kReservedHandle = 0xF00;
35 static constexpr uint16_t kCisHandleRangeStart = 0xE00;
36 static constexpr uint16_t kCisHandleRangeEnd = 0xEFE;
37 
38 class AclConnectionHandler {
39  public:
40   AclConnectionHandler() = default;
41   virtual ~AclConnectionHandler() = default;
42 
43   using TaskId = uint32_t;
44 
45   // Reset the connection manager state, stopping any pending
46   // SCO connections.
47   void Reset(std::function<void(TaskId)> stopStream);
48 
49   bool CreatePendingConnection(bluetooth::hci::Address addr,
50                                bool authenticate_on_connect,
51                                bool allow_role_switch);
52   bool HasPendingConnection(bluetooth::hci::Address addr) const;
53   bool CancelPendingConnection(bluetooth::hci::Address addr);
54   bool AuthenticatePendingConnection() const;
55 
56   bool HasPendingScoConnection(bluetooth::hci::Address addr) const;
57   ScoState GetScoConnectionState(bluetooth::hci::Address addr) const;
58   bool IsLegacyScoConnection(bluetooth::hci::Address addr) const;
59   void CreateScoConnection(bluetooth::hci::Address addr,
60                            ScoConnectionParameters const& parameters,
61                            ScoState state, ScoDatapath datapath,
62                            bool legacy = false);
63   void CancelPendingScoConnection(bluetooth::hci::Address addr);
64   bool AcceptPendingScoConnection(bluetooth::hci::Address addr,
65                                   ScoLinkParameters const& parameters,
66                                   std::function<TaskId()> startStream);
67   bool AcceptPendingScoConnection(bluetooth::hci::Address addr,
68                                   ScoConnectionParameters const& parameters,
69                                   std::function<TaskId()> startStream);
70   uint16_t GetScoHandle(bluetooth::hci::Address addr) const;
71   ScoConnectionParameters GetScoConnectionParameters(
72       bluetooth::hci::Address addr) const;
73   ScoLinkParameters GetScoLinkParameters(bluetooth::hci::Address addr) const;
74 
75   bool CreatePendingLeConnection(bluetooth::hci::AddressWithType peer,
76                                  bluetooth::hci::AddressWithType resolved_peer,
77                                  bluetooth::hci::AddressWithType local_address);
78   bool HasPendingLeConnection(bluetooth::hci::AddressWithType addr) const;
79   bool CancelPendingLeConnection(bluetooth::hci::AddressWithType addr);
80 
81   // \p pending is true if the connection is expected to be
82   // in pending state.
83   uint16_t CreateConnection(bluetooth::hci::Address addr,
84                             bluetooth::hci::Address own_addr,
85                             bool pending = true);
86   uint16_t CreateLeConnection(bluetooth::hci::AddressWithType addr,
87                               bluetooth::hci::AddressWithType own_addr,
88                               bluetooth::hci::Role role);
89   bool Disconnect(uint16_t handle, std::function<void(TaskId)> stopStream);
90   bool HasHandle(uint16_t handle) const;
91   bool HasScoHandle(uint16_t handle) const;
92 
93   // Return the connection handle for a classic ACL connection only.
94   // \p bd_addr is the peer address.
95   std::optional<uint16_t> GetAclConnectionHandle(
96       bluetooth::hci::Address bd_addr) const;
97 
98   uint16_t GetHandle(bluetooth::hci::AddressWithType addr) const;
99   uint16_t GetHandleOnlyAddress(bluetooth::hci::Address addr) const;
100   bluetooth::hci::AddressWithType GetAddress(uint16_t handle) const;
101   std::optional<AddressWithType> GetAddressSafe(uint16_t handle) const;
102   bluetooth::hci::Address GetScoAddress(uint16_t handle) const;
103   bluetooth::hci::AddressWithType GetOwnAddress(uint16_t handle) const;
104   bluetooth::hci::AddressWithType GetResolvedAddress(uint16_t handle) const;
105 
106   // Return the AclConnection for the selected connection handle, asserts
107   // if the handle is not currently used.
108   AclConnection& GetAclConnection(uint16_t handle);
109 
110   void Encrypt(uint16_t handle);
111   bool IsEncrypted(uint16_t handle) const;
112 
113   void SetRssi(uint16_t handle, int8_t rssi);
114   int8_t GetRssi(uint16_t handle) const;
115 
116   Phy::Type GetPhyType(uint16_t handle) const;
117 
118   uint16_t GetAclLinkPolicySettings(uint16_t handle) const;
119   void SetAclLinkPolicySettings(uint16_t handle, uint16_t settings);
120 
121   bluetooth::hci::Role GetAclRole(uint16_t handle) const;
122   void SetAclRole(uint16_t handle, bluetooth::hci::Role role);
123 
124   std::vector<uint16_t> GetAclHandles() const;
125 
126   void ResetLinkTimer(uint16_t handle);
127   std::chrono::steady_clock::duration TimeUntilLinkNearExpiring(
128       uint16_t handle) const;
129   bool IsLinkNearExpiring(uint16_t handle) const;
130   std::chrono::steady_clock::duration TimeUntilLinkExpired(
131       uint16_t handle) const;
132   bool HasLinkExpired(uint16_t handle) const;
133   bool IsRoleSwitchAllowedForPendingConnection() const;
134 
135  private:
136   std::unordered_map<uint16_t, AclConnection> acl_connections_;
137   std::unordered_map<uint16_t, ScoConnection> sco_connections_;
138 
139   bool classic_connection_pending_{false};
140   bluetooth::hci::Address pending_connection_address_{
141       bluetooth::hci::Address::kEmpty};
142   bool authenticate_pending_classic_connection_{false};
143   bool pending_classic_connection_allow_role_switch_{false};
144   bool le_connection_pending_{false};
145   bluetooth::hci::AddressWithType pending_le_connection_address_{
146       bluetooth::hci::Address::kEmpty,
147       bluetooth::hci::AddressType::PUBLIC_DEVICE_ADDRESS};
148   bluetooth::hci::AddressWithType pending_le_connection_own_address_{
149       bluetooth::hci::Address::kEmpty,
150       bluetooth::hci::AddressType::PUBLIC_DEVICE_ADDRESS};
151   bluetooth::hci::AddressWithType pending_le_connection_resolved_address_{
152       bluetooth::hci::Address::kEmpty,
153       bluetooth::hci::AddressType::PUBLIC_DEVICE_ADDRESS};
154 
155   uint16_t GetUnusedHandle();
156   uint16_t last_handle_{kReservedHandle - 2};
157 };
158 
159 }  // namespace rootcanal
160