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 "pw_bluetooth/peer.h" 17 #include "pw_function/function.h" 18 19 namespace pw::bluetooth { 20 21 // Input Capabilities for pairing exchanges. 22 // See Core Spec v5.3 Volume 3, Part C, Section 5.2.2.4, Table 5.3. 23 enum class InputCapability : uint8_t { kNone, kConfirmation, kKeyboard }; 24 25 // Output Capabilities for pairing exchanges. 26 // See Core Spec v5.3 Volume 3, Part C, Section 5.2.2.4, Table 5.4. 27 enum class OutputCapability : uint8_t { kNone, kDisplay }; 28 29 // Pairing event handler implemented by the API client. 30 class PairingDelegate { 31 public: 32 // Different types required by the Security Manager for pairing methods. 33 // Bluetooth SIG has different requirements for different device capabilities. 34 enum class PairingMethod : uint8_t { 35 // The user is asked to accept or reject pairing. 36 kConsent, 37 38 // The user is shown a 6-digit numerical passkey which they must enter on 39 // the 40 // peer device. 41 kPasskeyDisplay, 42 43 // The user is shown a 6-digit numerical passkey which will also shown on 44 // the 45 // peer device. The user must compare the passkeys and accept the pairing if 46 // the passkeys match. 47 kPasskeyComparison, 48 49 // The user is asked to enter a 6-digit passkey. 50 kPasskeyEntry 51 }; 52 53 enum class PairingKeypress : uint8_t { 54 // The user has entered a single digit. 55 kDigitEntered, 56 57 // The user has erased a single digit. 58 kDigitErased, 59 60 // The user has cleared the entire passkey. 61 kPasskeyCleared, 62 63 // The user has finished entering the passkey. 64 kPasskeyEntered 65 }; 66 67 // Callback for responding to pairing requests. 68 using ResponseCallback = 69 pw::Function<void(bool accept, uint32_t entered_passkey)>; 70 71 // Callback for signaling local keypresses to a peer. 72 using KeypressCallback = 73 pw::Function<void(PeerId peer_id, PairingKeypress keypress)>; 74 75 virtual ~PairingDelegate() = default; 76 77 // Called to initiate a pairing request. The delegate must respond with "true" 78 // or "false" in the callback to either accept or reject the pairing request. 79 // If the pairing method requires a passkey this is returned as well. It is OK 80 // to call `callback` synchronously in this method. 81 // 82 // Any response from this method will be ignored if the `OnPairingComplete` 83 // event has already been sent for `peer`. 84 // 85 // The `displayed_passkey` parameter should be displayed to the user if 86 // `method` equals `PairingMethod::kPasskeyDisplay` or 87 // `PairingMethod.kPasskeyComparison`. Otherwise, this parameter has no 88 // meaning and should be ignored. 89 // 90 // The `entered_passkey` parameter of `callback` only has meaning if `method` 91 // equals `PairingMethod.kPasskeyEntry`. It will be ignored otherwise. 92 virtual void OnPairingRequest(Peer peer, 93 PairingMethod method, 94 uint32_t displayed_passkey, 95 ResponseCallback&& callback) = 0; 96 97 // Called if the pairing procedure for the device with the given ID is 98 // completed. This can be due to successful completion or an error (e.g. due 99 // to cancellation by the peer, a timeout, or disconnection) which is 100 // indicated by `success`. 101 virtual void OnPairingComplete(PeerId peer_id, bool success) = 0; 102 103 // Called to notify keypresses from the peer device during pairing using 104 // `PairingMethod::kPasskeyDisplay`. 105 // 106 // This event is used to provide key press events to the delegate for a 107 // responsive user experience as the user types the passkey on the peer 108 // device. This event will be called once for each keypress. 109 virtual void OnRemoteKeypress(PeerId peer_id, PairingKeypress keypress) = 0; 110 111 // Sets a callback that the client may call on local passkey keypresses during 112 // a `PairingMethod::kPasskeyEntry` pairing request. Signaled keypresses may 113 // be used in the UI of the peer. This should be set immediately by the 114 // Bluetooth stack when the delegate is configured by the client unless 115 // sending local keypresses is not supported. 116 virtual void SetLocalKeypressCallback(KeypressCallback&& callback) = 0; 117 }; 118 119 } // namespace pw::bluetooth 120