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 #pragma once
18 
19 #include <memory>
20 #include <variant>
21 
22 #include "hci/acl_manager/acl_connection.h"
23 #include "hci/acl_manager/le_connection_management_callbacks.h"
24 #include "hci/address_with_type.h"
25 #include "hci/hci_packets.h"
26 #include "hci/le_acl_connection_interface.h"
27 
28 namespace bluetooth {
29 namespace hci {
30 namespace acl_manager {
31 
32 struct DataAsCentral {
33   // the address used when initiating the connection
34   AddressWithType local_address;
35 };
36 
37 struct DataAsPeripheral {
38   // the address of the advertising set that the peer connected to
39   AddressWithType local_address;
40   // the advertising set ID that the peer connected to - in LE, our role is peripheral iff the peer
41   // initiated a connection to our advertisement
42   std::optional<uint8_t> advertising_set_id;
43   // whether the peripheral connected to a discoverable advertisement (this affects the readability
44   // of GAP characteristics)
45   bool connected_to_discoverable;
46 };
47 
48 // when we know it's a peripheral, but we don't yet have all the data about the set it connected to
49 // this state should never remain after the connection is fully populated
50 struct DataAsUninitializedPeripheral {};
51 
52 using RoleSpecificData =
53         std::variant<DataAsUninitializedPeripheral, DataAsCentral, DataAsPeripheral>;
54 
55 class LeAclConnection : public AclConnection {
56 public:
57   LeAclConnection();
58   LeAclConnection(std::shared_ptr<Queue> queue,
59                   LeAclConnectionInterface* le_acl_connection_interface, uint16_t handle,
60                   RoleSpecificData role_specific_data, AddressWithType remote_address);
61   LeAclConnection(const LeAclConnection&) = delete;
62   LeAclConnection& operator=(const LeAclConnection&) = delete;
63 
64   ~LeAclConnection();
65 
66   virtual AddressWithType GetLocalAddress() const;
67 
68   virtual Role GetRole() const;
69 
70   const RoleSpecificData& GetRoleSpecificData() const;
71 
UpdateRoleSpecificData(RoleSpecificData role_specific_data)72   void UpdateRoleSpecificData(RoleSpecificData role_specific_data) {
73     role_specific_data_ = role_specific_data;
74   }
75 
GetRemoteAddress()76   virtual AddressWithType GetRemoteAddress() const { return remote_address_; }
77 
78   // The peer address and type returned from the Connection Complete Event
79   AddressWithType peer_address_with_type_;
80 
81   // 5.2::7.7.65.10 Connection interval used on this connection.
82   // Range: 0x0006 to 0x0C80
83   // Time = N * 1.25 ms
84   // Time Range: 7.5 ms to 4000 ms.
85   uint16_t interval_;
86   // 5.2::7.7.65.10 Peripheral latency for the connection in number of connection events.
87   // Range: 0x0000 to 0x01F3
88   uint16_t latency_;
89   // 5.2::7.7.65.10 Connection supervision timeout.
90   // Range: 0x000A to 0x0C80
91   // Time = N * 10 ms
92   // Time Range: 100 ms to 32 s
93   uint16_t supervision_timeout_;
94 
95   // True if connection address was in the filter accept list, false otherwise
96   bool in_filter_accept_list_;
IsInFilterAcceptList()97   bool IsInFilterAcceptList() const { return in_filter_accept_list_; }
98 
99   Address local_resolvable_private_address_ = Address::kEmpty;
100   Address peer_resolvable_private_address_ = Address::kEmpty;
101 
GetPeerAddress()102   virtual AddressWithType GetPeerAddress() const { return peer_address_with_type_; }
103 
104   // This function return actual peer address which was used for the connection over the air.
GetPeerOtaAddress()105   virtual AddressWithType GetPeerOtaAddress() const {
106     if (peer_resolvable_private_address_ == Address::kEmpty) {
107       return GetPeerAddress();
108     }
109     return AddressWithType(peer_resolvable_private_address_, AddressType::RANDOM_DEVICE_ADDRESS);
110   }
111 
112   // This function return actual local address which was used for the connection over the air.
GetLocalOtaAddress()113   virtual AddressWithType GetLocalOtaAddress() const {
114     if (local_resolvable_private_address_ == Address::kEmpty) {
115       return GetLocalAddress();
116     }
117 
118     return AddressWithType(local_resolvable_private_address_, AddressType::RANDOM_DEVICE_ADDRESS);
119   }
120 
121   virtual void RegisterCallbacks(LeConnectionManagementCallbacks* callbacks, os::Handler* handler);
122   virtual void Disconnect(DisconnectReason reason);
123 
124   virtual bool LeConnectionUpdate(uint16_t conn_interval_min, uint16_t conn_interval_max,
125                                   uint16_t conn_latency, uint16_t supervision_timeout,
126                                   uint16_t min_ce_length, uint16_t max_ce_length);
127 
128   virtual bool ReadRemoteVersionInformation() override;
129   virtual bool LeReadRemoteFeatures();
130 
131   virtual void LeSubrateRequest(uint16_t subrate_min, uint16_t subrate_max, uint16_t max_latency,
132                                 uint16_t cont_num, uint16_t sup_tout);
133 
134   // TODO implement LeRemoteConnectionParameterRequestReply,
135   // LeRemoteConnectionParameterRequestNegativeReply
136 
137   // Called once before passing the connection to the client
138   virtual LeConnectionManagementCallbacks* GetEventCallbacks(
139           std::function<void(uint16_t)> invalidate_callbacks);
140 
141 protected:
142   AddressWithType remote_address_;
143   RoleSpecificData role_specific_data_;
144 
145 private:
146   void OnLeSubrateRequestStatus(CommandStatusView status);
147   virtual bool check_connection_parameters(uint16_t conn_interval_min, uint16_t conn_interval_max,
148                                            uint16_t expected_conn_latency,
149                                            uint16_t expected_supervision_timeout);
150   bool is_disconnecting_ = false;
151   struct impl;
152   struct impl* pimpl_ = nullptr;
153 };
154 
155 }  // namespace acl_manager
156 }  // namespace hci
157 }  // namespace bluetooth
158