aboutsummaryrefslogtreecommitdiff
path: root/pw_bluetooth/public/pw_bluetooth/host.h
blob: d5f3f30111aca788395ff695e6064f168b7f1b31 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
// Copyright 2022 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
#pragma once

#include <optional>
#include <string_view>

#include "pw_bluetooth/controller.h"
#include "pw_bluetooth/gatt/client.h"
#include "pw_bluetooth/gatt/server.h"
#include "pw_bluetooth/low_energy/bond_data.h"
#include "pw_bluetooth/low_energy/central.h"
#include "pw_bluetooth/low_energy/peripheral.h"
#include "pw_bluetooth/low_energy/security_mode.h"
#include "pw_bluetooth/pairing_delegate.h"
#include "pw_bluetooth/peer.h"
#include "pw_bluetooth/types.h"
#include "pw_function/function.h"
#include "pw_span/span.h"
#include "pw_status/status.h"

namespace pw::bluetooth {

/// Host is the entrypoint API for interacting with a Bluetooth host stack. Host
/// is an abstract class that is implemented by a host stack implementation.
class Host {
 public:
  /// Represents the persistent configuration of a single Host instance. This is
  /// used for identity representation in advertisements & bonding secrets
  /// recall.
  struct PersistentData {
    /// The local Identity Resolving Key used by a Host to generate Resolvable
    /// Private Addresses when privacy is enabled. May be absent for hosts that
    /// do not use LE privacy, or that only use Non-Resolvable Private
    /// Addresses.
    ///
    /// NOTE: This key is distributed to LE peers during pairing procedures. The
    /// client must take care to assign an IRK that consistent with the local
    /// Host identity.
    std::optional<Key> identity_resolving_key;

    /// All bonds that use a public identity address must contain the same local
    /// address.
    span<const low_energy::BondData> bonds;
  };

  /// The security level required for this pairing. This corresponds to the
  /// security levels defined in the Security Manager Protocol in Core spec
  /// v5.3, Vol 3, Part H, Section 2.3.1
  enum class PairingSecurityLevel : uint8_t {
    /// Encrypted without person-in-the-middle protection (unauthenticated)
    kEncrypted,
    /// Encrypted with person-in-the-middle protection (authenticated), although
    /// this level of security does not fully protect against passive
    /// eavesdroppers
    kAuthenticated,
    /// Encrypted with person-in-the-middle protection (authenticated).
    /// This level of security fully protects against eavesdroppers.
    kLeSecureConnections,
  };

  /// Whether or not the device should form a bluetooth bond during the pairing
  /// prodecure. As described in Core Spec v5.2, Vol 3, Part C, Sec 4.3
  enum class BondableMode : uint8_t {
    /// The device will form a bond during pairing with peers
    kBondable,
    /// The device will not form a bond during pairing with peers
    kNonBondable,
  };

  /// Parameters that give a caller more fine-grained control over the pairing
  /// process.
  struct PairingOptions {
    /// Determines the Security Manager security level to pair with.
    PairingSecurityLevel security_level = PairingSecurityLevel::kAuthenticated;

    /// Indicated whether the device should form a bond or not during pairing.
    /// If not present, interpreted as bondable mode.
    BondableMode bondable_mode = BondableMode::kBondable;
  };

  /// `Close()` should complete before `Host` is destroyed.
  virtual ~Host() = default;

  /// Initializes the host stack. Vendor specific controller initialization
  /// (e.g. loading firmware) must be done before initializing `Host`.
  ///
  /// @param controller Pointer to a concrete `Controller` that the host stack
  /// should use to communicate with the controller.
  /// @param data Data to persist from a previous instance of `Host`.
  /// @param on_initialization_complete Called when initialization is complete.
  /// Other methods should not be called until initialization completes.
  virtual void Initialize(
      Controller* controller,
      PersistentData data,
      Function<void(Status)>&& on_initialization_complete) = 0;

  /// Safely shuts down the host, ending all active Bluetooth procedures:
  /// - All objects/pointers associated with this host are destroyed/invalidated
  ///   and all connections disconnected.
  /// - All scanning and advertising procedures are stopped.
  ///
  /// The Host may send events or call callbacks as procedures get terminated.
  /// @param callback Will be called once all procedures have terminated.
  virtual void Close(Closure callback) = 0;

  /// Returns a pointer to the Central API, which is used to scan and connect to
  /// peers.
  virtual low_energy::Central* Central() = 0;

  /// Returns a pointer to the Peripheral API, which is used to advertise and
  /// accept connections from peers.
  virtual low_energy::Peripheral* Peripheral() = 0;

  /// Returns a pointer to the GATT Server API, which is used to publish GATT
  /// services.
  virtual gatt::Server* GattServer() = 0;

  /// Deletes a peer from the Bluetooth host. If the peer is connected, it will
  /// be disconnected. `peer_id` will no longer refer to any peer.
  ///
  /// Returns `OK` after no peer exists that's identified by `peer_id` (even
  /// if it didn't exist), `ABORTED` if the peer could not be disconnected or
  /// deleted and still exists.
  virtual Status ForgetPeer(PeerId peer_id) = 0;

  /// Enable or disable the LE privacy feature. When enabled, the host will use
  /// a private device address in all LE procedures. When disabled, the public
  /// identity address will be used instead (which is the default).
  virtual void EnablePrivacy(bool enabled) = 0;

  /// Set the GAP LE Security Mode of the host. Only encrypted,
  /// connection-based security modes are supported, i.e. Mode 1 and Secure
  /// Connections Only mode. If the security mode is set to Secure Connections
  /// Only, any existing encrypted connections which do not meet the security
  /// requirements of Secure Connections Only mode will be disconnected.
  virtual void SetSecurityMode(low_energy::SecurityMode security_mode) = 0;

  /// Assigns the pairing delegate that will respond to authentication
  /// challenges using the given I/O capabilities. Calling this method cancels
  /// any on-going pairing procedure started using a previous delegate. Pairing
  /// requests will be rejected if no PairingDelegate has been assigned.
  virtual void SetPairingDelegate(InputCapability input,
                                  OutputCapability output,
                                  PairingDelegate* pairing_delegate) = 0;

  /// NOTE: This is intended to satisfy test scenarios that require pairing
  /// procedures to be initiated without relying on service access. In normal
  /// operation, Bluetooth security is enforced during service access.
  ///
  /// Initiates pairing to the peer with the supplied `peer_id` and `options`.
  /// Returns an error if no connected peer with `peer_id` is found or the
  /// pairing procedure fails.
  ///
  /// If `options` specifies a higher security level than the current pairing,
  /// this method attempts to raise the security level. Otherwise this method
  /// has no effect and returns success.
  ///
  /// Returns the following errors via `callback`:
  /// `NOT_FOUND` - The peer `peer_id` was not found.
  /// `ABORTED` - The pairing procedure failed.
  virtual void Pair(PeerId peer_id,
                    PairingOptions options,
                    Function<void(Status)>&& callback) = 0;

  /// Configures a callback to be called when new bond data for a peer has been
  /// created. This data should be persisted and used to initialize Host in the
  /// future. New bond data may be received for an already bonded peer, in which
  /// case the new data should overwrite the old data.
  virtual void SetBondDataCallback(
      Function<void(low_energy::BondData)>&& callback) = 0;

  /// Looks up the `PeerId` corresponding to `address`. If `address` does not
  /// correspond to a known peer, a new `PeerId` will be generated for the
  /// address. If a `PeerId` cannot be generated, std::nullopt will be returned.
  virtual std::optional<PeerId> PeerIdFromAddress(Address address) = 0;

  /// Looks up the Address corresponding to `peer_id`. Returns null if `peer_id`
  /// does not correspond to a known peer.
  virtual std::optional<Address> DeviceAddressFromPeerId(PeerId peer_id) = 0;
};

}  // namespace pw::bluetooth