xref: /aosp_15_r20/external/pigweed/pw_bluetooth/public/pw_bluetooth/host.h (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1 // Copyright 2022 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 <optional>
17 #include <string_view>
18 
19 #include "pw_bluetooth/controller.h"
20 #include "pw_bluetooth/gatt/client.h"
21 #include "pw_bluetooth/gatt/server.h"
22 #include "pw_bluetooth/low_energy/bond_data.h"
23 #include "pw_bluetooth/low_energy/central.h"
24 #include "pw_bluetooth/low_energy/peripheral.h"
25 #include "pw_bluetooth/low_energy/security_mode.h"
26 #include "pw_bluetooth/pairing_delegate.h"
27 #include "pw_bluetooth/peer.h"
28 #include "pw_bluetooth/types.h"
29 #include "pw_function/function.h"
30 #include "pw_span/span.h"
31 #include "pw_status/status.h"
32 
33 namespace pw::bluetooth {
34 
35 /// Host is the entrypoint API for interacting with a Bluetooth host stack. Host
36 /// is an abstract class that is implemented by a host stack implementation.
37 class Host {
38  public:
39   /// Represents the persistent configuration of a single Host instance. This is
40   /// used for identity representation in advertisements & bonding secrets
41   /// recall.
42   struct PersistentData {
43     /// The local Identity Resolving Key used by a Host to generate Resolvable
44     /// Private Addresses when privacy is enabled. May be absent for hosts that
45     /// do not use LE privacy, or that only use Non-Resolvable Private
46     /// Addresses.
47     ///
48     /// NOTE: This key is distributed to LE peers during pairing procedures. The
49     /// client must take care to assign an IRK that consistent with the local
50     /// Host identity.
51     std::optional<Key> identity_resolving_key;
52 
53     /// All bonds that use a public identity address must contain the same local
54     /// address.
55     span<const low_energy::BondData> bonds;
56   };
57 
58   /// The security level required for this pairing. This corresponds to the
59   /// security levels defined in the Security Manager Protocol in Core spec
60   /// v5.3, Vol 3, Part H, Section 2.3.1
61   enum class PairingSecurityLevel : uint8_t {
62     /// Encrypted without person-in-the-middle protection (unauthenticated)
63     kEncrypted,
64     /// Encrypted with person-in-the-middle protection (authenticated), although
65     /// this level of security does not fully protect against passive
66     /// eavesdroppers
67     kAuthenticated,
68     /// Encrypted with person-in-the-middle protection (authenticated).
69     /// This level of security fully protects against eavesdroppers.
70     kLeSecureConnections,
71   };
72 
73   /// Whether or not the device should form a bluetooth bond during the pairing
74   /// prodecure. As described in Core Spec v5.2, Vol 3, Part C, Sec 4.3
75   enum class BondableMode : uint8_t {
76     /// The device will form a bond during pairing with peers
77     kBondable,
78     /// The device will not form a bond during pairing with peers
79     kNonBondable,
80   };
81 
82   /// Parameters that give a caller more fine-grained control over the pairing
83   /// process.
84   struct PairingOptions {
85     /// Determines the Security Manager security level to pair with.
86     PairingSecurityLevel security_level = PairingSecurityLevel::kAuthenticated;
87 
88     /// Indicated whether the device should form a bond or not during pairing.
89     /// If not present, interpreted as bondable mode.
90     BondableMode bondable_mode = BondableMode::kBondable;
91   };
92 
93   /// `Close()` should complete before `Host` is destroyed.
94   virtual ~Host() = default;
95 
96   /// Initializes the host stack. Vendor specific controller initialization
97   /// (e.g. loading firmware) must be done before initializing `Host`.
98   ///
99   /// @param controller Pointer to a concrete `Controller` that the host stack
100   /// should use to communicate with the controller.
101   /// @param data Data to persist from a previous instance of `Host`.
102   /// @param on_initialization_complete Called when initialization is complete.
103   /// Other methods should not be called until initialization completes.
104   virtual void Initialize(
105       Controller* controller,
106       PersistentData data,
107       Function<void(Status)>&& on_initialization_complete) = 0;
108 
109   /// Safely shuts down the host, ending all active Bluetooth procedures:
110   /// - All objects/pointers associated with this host are destroyed/invalidated
111   ///   and all connections disconnected.
112   /// - All scanning and advertising procedures are stopped.
113   ///
114   /// The Host may send events or call callbacks as procedures get terminated.
115   /// @param callback Will be called once all procedures have terminated.
116   virtual void Close(Closure callback) = 0;
117 
118   /// Returns a pointer to the Central API, which is used to scan and connect to
119   /// peers.
120   virtual low_energy::Central* Central() = 0;
121 
122   /// Returns a pointer to the Peripheral API, which is used to advertise and
123   /// accept connections from peers.
124   virtual low_energy::Peripheral* Peripheral() = 0;
125 
126   /// Returns a pointer to the GATT Server API, which is used to publish GATT
127   /// services.
128   virtual gatt::Server* GattServer() = 0;
129 
130   /// Deletes a peer from the Bluetooth host. If the peer is connected, it will
131   /// be disconnected. `peer_id` will no longer refer to any peer.
132   ///
133   /// Returns `OK` after no peer exists that's identified by `peer_id` (even
134   /// if it didn't exist), `ABORTED` if the peer could not be disconnected or
135   /// deleted and still exists.
136   virtual Status ForgetPeer(PeerId peer_id) = 0;
137 
138   /// Enable or disable the LE privacy feature. When enabled, the host will use
139   /// a private device address in all LE procedures. When disabled, the public
140   /// identity address will be used instead (which is the default).
141   virtual void EnablePrivacy(bool enabled) = 0;
142 
143   /// Set the GAP LE Security Mode of the host. Only encrypted,
144   /// connection-based security modes are supported, i.e. Mode 1 and Secure
145   /// Connections Only mode. If the security mode is set to Secure Connections
146   /// Only, any existing encrypted connections which do not meet the security
147   /// requirements of Secure Connections Only mode will be disconnected.
148   virtual void SetSecurityMode(low_energy::SecurityMode security_mode) = 0;
149 
150   /// Assigns the pairing delegate that will respond to authentication
151   /// challenges using the given I/O capabilities. Calling this method cancels
152   /// any on-going pairing procedure started using a previous delegate. Pairing
153   /// requests will be rejected if no PairingDelegate has been assigned.
154   virtual void SetPairingDelegate(InputCapability input,
155                                   OutputCapability output,
156                                   PairingDelegate* pairing_delegate) = 0;
157 
158   /// NOTE: This is intended to satisfy test scenarios that require pairing
159   /// procedures to be initiated without relying on service access. In normal
160   /// operation, Bluetooth security is enforced during service access.
161   ///
162   /// Initiates pairing to the peer with the supplied `peer_id` and `options`.
163   /// Returns an error if no connected peer with `peer_id` is found or the
164   /// pairing procedure fails.
165   ///
166   /// If `options` specifies a higher security level than the current pairing,
167   /// this method attempts to raise the security level. Otherwise this method
168   /// has no effect and returns success.
169   ///
170   /// Returns the following errors via `callback`:
171   /// `NOT_FOUND` - The peer `peer_id` was not found.
172   /// `ABORTED` - The pairing procedure failed.
173   virtual void Pair(PeerId peer_id,
174                     PairingOptions options,
175                     Function<void(Status)>&& callback) = 0;
176 
177   /// Configures a callback to be called when new bond data for a peer has been
178   /// created. This data should be persisted and used to initialize Host in the
179   /// future. New bond data may be received for an already bonded peer, in which
180   /// case the new data should overwrite the old data.
181   virtual void SetBondDataCallback(
182       Function<void(low_energy::BondData)>&& callback) = 0;
183 
184   /// Looks up the `PeerId` corresponding to `address`. If `address` does not
185   /// correspond to a known peer, a new `PeerId` will be generated for the
186   /// address. If a `PeerId` cannot be generated, std::nullopt will be returned.
187   virtual std::optional<PeerId> PeerIdFromAddress(Address address) = 0;
188 
189   /// Looks up the Address corresponding to `peer_id`. Returns null if `peer_id`
190   /// does not correspond to a known peer.
191   virtual std::optional<Address> DeviceAddressFromPeerId(PeerId peer_id) = 0;
192 };
193 
194 }  // namespace pw::bluetooth
195