xref: /aosp_15_r20/external/pigweed/pw_bluetooth/public/pw_bluetooth/low_energy/connection2.h (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1 // Copyright 2024 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 #pragma once
15 
16 #include "pw_async2/dispatcher.h"
17 #include "pw_bluetooth/gatt/client2.h"
18 #include "pw_bluetooth/internal/raii_ptr.h"
19 #include "pw_bluetooth/low_energy/channel.h"
20 #include "pw_bluetooth/types.h"
21 
22 namespace pw::bluetooth::low_energy {
23 
24 /// Class that represents a connection to a peer. This can be used to interact
25 /// with GATT services and establish LE L2CAP channels.
26 ///
27 /// The lifetime of this object is tied to that of the LE connection it
28 /// represents. Destroying the object results in a disconnection.
29 class Connection2 {
30  public:
31   /// Possible errors when updating the connection parameters.
32   enum class ConnectionParameterUpdateError : uint8_t {
33     kFailure,
34     kInvalidParameters,
35     kRejected,
36   };
37 
38   /// Possible reasons a connection was disconnected.
39   enum class DisconnectReason : uint8_t {
40     kFailure,
41     kRemoteUserTerminatedConnection,
42     /// This usually indicates that the link supervision timeout expired.
43     kConnectionTimeout,
44   };
45 
46   /// Actual connection parameters returned by the controller.
47   struct ConnectionParameters {
48     /// The connection interval indicates the frequency of link layer connection
49     /// events over which data channel PDUs can be transmitted. See Core Spec
50     /// v6, Vol 6, Part B, Section 4.5.1 for more information on the link
51     /// layer connection events.
52     /// - Range: 0x0006 to 0x0C80
53     /// - Time: N * 1.25 ms
54     /// - Time Range: 7.5 ms to 4 s.
55     uint16_t interval;
56 
57     /// The maximum allowed peripheral connection latency in number of
58     /// connection events. See Core Spec v5, Vol 6, Part B, Section 4.5.1.
59     /// - Range: 0x0000 to 0x01F3
60     uint16_t latency;
61 
62     /// This defines the maximum time between two received data packet PDUs
63     /// before the connection is considered lost. See Core Spec v6, Vol 6,
64     /// Part B, Section 4.5.2.
65     /// - Range: 0x000A to 0x0C80
66     /// - Time: N * 10 ms
67     /// - Time Range: 100 ms to 32 s
68     uint16_t supervision_timeout;
69   };
70 
71   /// Connection parameters that either the local device or a peer device are
72   /// requesting.
73   struct RequestedConnectionParameters {
74     /// Minimum value for the connection interval. This shall be less than or
75     /// equal to `max_interval`. The connection interval indicates the frequency
76     /// of link layer connection events over which data channel PDUs can be
77     /// transmitted. See Core Spec v6, Vol 6, Part B, Section 4.5.1 for more
78     /// information on the link layer connection events.
79     /// - Range: 0x0006 to 0x0C80
80     /// - Time: N * 1.25 ms
81     /// - Time Range: 7.5 ms to 4 s.
82     uint16_t min_interval;
83 
84     /// Maximum value for the connection interval. This shall be greater than or
85     /// equal to `min_interval`. The connection interval indicates the frequency
86     /// of link layer connection events over which data channel PDUs can be
87     /// transmitted.  See Core Spec v6, Vol 6, Part B, Section 4.5.1 for more
88     /// information on the link layer connection events.
89     /// - Range: 0x0006 to 0x0C80
90     /// - Time: N * 1.25 ms
91     /// - Time Range: 7.5 ms to 4 s.
92     uint16_t max_interval;
93 
94     /// Maximum peripheral latency for the connection in number of connection
95     /// events. See Core Spec v6, Vol 6, Part B, Section 4.5.1.
96     /// - Range: 0x0000 to 0x01F3
97     uint16_t max_latency;
98 
99     /// This defines the maximum time between two received data packet PDUs
100     /// before the connection is considered lost. See Core Spec v6, Vol 6,
101     /// Part B, Section 4.5.2.
102     /// - Range: 0x000A to 0x0C80
103     /// - Time: N * 10 ms
104     /// - Time Range: 100 ms to 32 s
105     uint16_t supervision_timeout;
106   };
107 
108   /// Represents parameters that are set on a per-connection basis.
109   struct ConnectionOptions {
110     /// When true, the connection operates in bondable mode. This means pairing
111     /// will form a bond, or persist across disconnections, if the peer is also
112     /// in bondable mode. When false, the connection operates in non-bondable
113     /// mode, which means the local device only allows pairing that does not
114     /// form a bond.
115     bool bondable_mode = true;
116 
117     /// When present, service discovery performed following the connection is
118     /// restricted to primary services that match this field. Otherwise, by
119     /// default all available services are discovered.
120     std::optional<Uuid> service_filter;
121 
122     /// When present, specifies the initial connection parameters. Otherwise,
123     /// the connection parameters will be selected by the implementation.
124     std::optional<RequestedConnectionParameters> parameters;
125 
126     /// When present, specifies the ATT MTU to request. The actual MTU used may
127     /// be smaller depending on peer and controller support. If none is
128     /// specified, the host implementation will select the ATT MTU. Note that an
129     /// MTU of 247 is the largest that can fit into a single LE data packet with
130     /// the Data Length Extension.
131     /// - LE ATT MTU Range: 23 to 517
132     /// - LE EATT MTU Range: 64 to 517
133     std::optional<uint16_t> att_mtu;
134   };
135 
136   struct ConnectL2capParameters {
137     /// The identifier of the service to connect to.
138     Psm psm;
139     /// Maximum supported packet size for receiving.
140     uint16_t max_receive_packet_size;
141     /// The security requirements that must be met before data is exchanged on
142     /// the channel. If the requirements cannot be met, channel establishment
143     /// will fail.
144     SecurityRequirements security_requirements;
145   };
146 
147   /// If a disconnection has not occurred, destroying this object will result in
148   /// disconnection.
149   virtual ~Connection2() = default;
150 
151   /// Returns Ready after the peer disconnects or there is a connection error
152   /// that caused a disconnection. Awakens `cx` on disconnect.
153   virtual async2::Poll<DisconnectReason> PendDisconnect(
154       async2::Context& cx) = 0;
155 
156   /// Returns a GATT client to the connected peer that is valid for the lifetime
157   /// of this `Connection2` object. `Connection2` is considered alive as long as
158   /// `PendDisconnect()` returns pending and the object hasn't been destroyed.
159   virtual gatt::Client2* GattClient() = 0;
160 
161   /// Returns the current ATT Maximum Transmission Unit. By subtracting ATT
162   /// headers from the MTU, the maximum payload size of messages can be
163   /// calculated.
164   virtual uint16_t AttMtu() = 0;
165 
166   /// Returns Pending until the ATT MTU changes, at which point `cx` will be
167   /// awoken. Returns Ready with the new ATT MTU once the ATT MTU has been
168   /// changed. The ATT MTU can only be changed once.
169   virtual async2::Poll<uint16_t> PendAttMtuChange(async2::Context& cx) = 0;
170 
171   /// Returns the current connection parameters.
172   virtual ConnectionParameters Parameters() = 0;
173 
174   /// Requests an update to the connection parameters.
175   /// @returns Asynchronously returns the result of the request.
176   virtual async2::OnceReceiver<
177       pw::expected<void, ConnectionParameterUpdateError>>
178   RequestParameterUpdate(RequestedConnectionParameters parameters) = 0;
179 
180   /// Connect to an L2CAP LE connection-oriented channel.
181   /// @param parameters The parameters to configure the channel with.
182   /// @return The result of the connection procedure. On success, contains a
183   /// `Channel` that can be used to exchange data.
184   virtual async2::OnceReceiver<pw::Result<Channel::Ptr>> ConnectL2cap(
185       ConnectL2capParameters parameters) = 0;
186 
187  private:
188   /// Request to disconnect this connection. This method is called by the
189   /// ~Connection::Ptr() when it goes out of scope, the API client should never
190   /// call this method.
191   virtual void Disconnect() = 0;
192 
193  public:
194   /// Movable `Connection2` smart pointer. When `Connection::Ptr` is destroyed
195   /// the `Connection2` will disconnect automatically.
196   using Ptr = internal::RaiiPtr<Connection2, &Connection2::Disconnect>;
197 };
198 
199 }  // namespace pw::bluetooth::low_energy
200