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