1 // Copyright 2023 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 15 #pragma once 16 #include <cpp-string/string_printf.h> 17 #include <lib/fit/function.h> 18 19 #include <string> 20 21 #include "pw_bluetooth_sapphire/internal/host/sm/pairing_channel.h" 22 #include "pw_bluetooth_sapphire/internal/host/sm/pairing_phase.h" 23 #include "pw_bluetooth_sapphire/internal/host/sm/smp.h" 24 #include "pw_bluetooth_sapphire/internal/host/sm/types.h" 25 26 namespace bt::sm { 27 28 // SecurityRequestPhase is responsible for sending outbound Security Requests 29 // and handling the peer's response. As Security Requests can only be sent from 30 // an SMP responder, this class should only be instantiated when acting as the 31 // SMP responder. 32 // 33 // This class is not thread safe and is meant to be accessed on the thread it 34 // was created on. All callbacks will be run by the default dispatcher of an 35 // SecurityRequestPhase's creation thread. 36 37 class SecurityRequestPhase final : public PairingPhase, 38 public PairingChannelHandler { 39 public: 40 // Initializes this SecurityRequestPhase with the following parameters: 41 // - |chan|, |listener|: To construct the base PairingPhase 42 // - |desired_level|: The level of security requested by the SM client to 43 // cause this Security 44 // Request. 45 // - |bondable_mode|: The operating bondable mode of the device (v5.2 Vol. 3 46 // Part C 9.4). 47 // - |on_pairing_req|: Used to signal the owning class of an inbound Pairing 48 // Request triggered 49 // by this Security Request. 50 SecurityRequestPhase(PairingChannel::WeakPtr chan, 51 Listener::WeakPtr listener, 52 SecurityLevel desired_level, 53 BondableMode bondable_mode, 54 PairingRequestCallback on_pairing_req); 55 ~SecurityRequestPhase()56 ~SecurityRequestPhase() override { InvalidatePairingChannelHandler(); } 57 58 // PairingPhase override. 59 void Start() final; 60 pending_security_request()61 SecurityLevel pending_security_request() const { 62 return pending_security_request_; 63 } 64 65 private: 66 // Makes a Security Request to the peer per V5.0 Vol. 3 Part H 2.4.6. 67 // Providing SecurityLevel::kNoSecurity as |desired_level| is a client error 68 // and will assert. 69 void MakeSecurityRequest(SecurityLevel desired_level, 70 BondableMode bondable_mode); 71 72 // Handle pairing requests from the peer. 73 void OnPairingRequest(PairingRequestParams req_params); 74 75 // PairingChannelHandler overrides: 76 void OnRxBFrame(ByteBufferPtr sdu) override; OnChannelClosed()77 void OnChannelClosed() override { PairingPhase::HandleChannelClosed(); } 78 79 // PairingPhase overrides ToStringInternal()80 std::string ToStringInternal() override { 81 return bt_lib_cpp_string::StringPrintf( 82 "Security Request Phase - pending security request for %s", 83 LevelToString(pending_security_request_)); 84 } 85 86 BondableMode bondable_mode_; 87 SecurityLevel pending_security_request_; 88 89 PairingRequestCallback on_pairing_req_; 90 BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(SecurityRequestPhase); 91 }; 92 93 } // namespace bt::sm 94