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, bool authenticate_on_connect,
50                                bool allow_role_switch);
51   bool HasPendingConnection(bluetooth::hci::Address addr) const;
52   bool CancelPendingConnection(bluetooth::hci::Address addr);
53   bool AuthenticatePendingConnection() const;
54 
55   bool HasPendingScoConnection(bluetooth::hci::Address addr) const;
56   ScoState GetScoConnectionState(bluetooth::hci::Address addr) const;
57   bool IsLegacyScoConnection(bluetooth::hci::Address addr) const;
58   void CreateScoConnection(bluetooth::hci::Address addr, ScoConnectionParameters const& parameters,
59                            ScoState state, ScoDatapath datapath, bool legacy = false);
60   void CancelPendingScoConnection(bluetooth::hci::Address addr);
61   bool AcceptPendingScoConnection(bluetooth::hci::Address addr, ScoLinkParameters const& parameters,
62                                   std::function<TaskId()> startStream);
63   bool AcceptPendingScoConnection(bluetooth::hci::Address addr,
64                                   ScoConnectionParameters const& parameters,
65                                   std::function<TaskId()> startStream);
66   uint16_t GetScoHandle(bluetooth::hci::Address addr) const;
67   ScoConnectionParameters GetScoConnectionParameters(bluetooth::hci::Address addr) const;
68   ScoLinkParameters GetScoLinkParameters(bluetooth::hci::Address addr) const;
69 
70   bool CreatePendingLeConnection(bluetooth::hci::AddressWithType peer,
71                                  bluetooth::hci::AddressWithType resolved_peer,
72                                  bluetooth::hci::AddressWithType local_address);
73   bool HasPendingLeConnection(bluetooth::hci::AddressWithType addr) const;
74   bool CancelPendingLeConnection(bluetooth::hci::AddressWithType addr);
75 
76   // \p pending is true if the connection is expected to be
77   // in pending state.
78   uint16_t CreateConnection(bluetooth::hci::Address addr, bluetooth::hci::Address own_addr,
79                             bool pending = true);
80   uint16_t CreateLeConnection(bluetooth::hci::AddressWithType addr,
81                               bluetooth::hci::AddressWithType own_addr, bluetooth::hci::Role role);
82   bool Disconnect(uint16_t handle, std::function<void(TaskId)> stopStream);
83   bool HasHandle(uint16_t handle) const;
84   bool HasScoHandle(uint16_t handle) const;
85 
86   // Return the connection handle for a classic ACL connection only.
87   // \p bd_addr is the peer address.
88   std::optional<uint16_t> GetAclConnectionHandle(bluetooth::hci::Address bd_addr) const;
89 
90   uint16_t GetHandle(bluetooth::hci::AddressWithType addr) const;
91   uint16_t GetHandleOnlyAddress(bluetooth::hci::Address addr) const;
92   bluetooth::hci::AddressWithType GetAddress(uint16_t handle) const;
93   std::optional<AddressWithType> GetAddressSafe(uint16_t handle) const;
94   bluetooth::hci::Address GetScoAddress(uint16_t handle) const;
95   bluetooth::hci::AddressWithType GetOwnAddress(uint16_t handle) const;
96   bluetooth::hci::AddressWithType GetResolvedAddress(uint16_t handle) const;
97 
98   // Return the AclConnection for the selected connection handle, asserts
99   // if the handle is not currently used.
100   AclConnection& GetAclConnection(uint16_t handle);
101 
102   void Encrypt(uint16_t handle);
103   bool IsEncrypted(uint16_t handle) const;
104 
105   void SetRssi(uint16_t handle, int8_t rssi);
106   int8_t GetRssi(uint16_t handle) const;
107 
108   Phy::Type GetPhyType(uint16_t handle) const;
109 
110   uint16_t GetAclLinkPolicySettings(uint16_t handle) const;
111   void SetAclLinkPolicySettings(uint16_t handle, uint16_t settings);
112 
113   bluetooth::hci::Role GetAclRole(uint16_t handle) const;
114   void SetAclRole(uint16_t handle, bluetooth::hci::Role role);
115 
116   std::vector<uint16_t> GetAclHandles() const;
117 
118   void ResetLinkTimer(uint16_t handle);
119   std::chrono::steady_clock::duration TimeUntilLinkNearExpiring(uint16_t handle) const;
120   bool IsLinkNearExpiring(uint16_t handle) const;
121   std::chrono::steady_clock::duration TimeUntilLinkExpired(uint16_t handle) const;
122   bool HasLinkExpired(uint16_t handle) const;
123   bool IsRoleSwitchAllowedForPendingConnection() const;
124 
125 private:
126   std::unordered_map<uint16_t, AclConnection> acl_connections_;
127   std::unordered_map<uint16_t, ScoConnection> sco_connections_;
128 
129   bool classic_connection_pending_{false};
130   bluetooth::hci::Address pending_connection_address_{bluetooth::hci::Address::kEmpty};
131   bool authenticate_pending_classic_connection_{false};
132   bool pending_classic_connection_allow_role_switch_{false};
133   bool le_connection_pending_{false};
134   bluetooth::hci::AddressWithType pending_le_connection_address_{
135           bluetooth::hci::Address::kEmpty, bluetooth::hci::AddressType::PUBLIC_DEVICE_ADDRESS};
136   bluetooth::hci::AddressWithType pending_le_connection_own_address_{
137           bluetooth::hci::Address::kEmpty, bluetooth::hci::AddressType::PUBLIC_DEVICE_ADDRESS};
138   bluetooth::hci::AddressWithType pending_le_connection_resolved_address_{
139           bluetooth::hci::Address::kEmpty, bluetooth::hci::AddressType::PUBLIC_DEVICE_ADDRESS};
140 
141   uint16_t GetUnusedHandle();
142   uint16_t last_handle_{kReservedHandle - 2};
143 };
144 
145 }  // namespace rootcanal
146