• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <pw_assert/check.h>
17 
18 #include <optional>
19 
20 #include "pw_bluetooth_sapphire/internal/host/common/identifier.h"
21 #include "pw_bluetooth_sapphire/internal/host/gap/bredr_connection_request.h"
22 #include "pw_bluetooth_sapphire/internal/host/gap/bredr_interrogator.h"
23 #include "pw_bluetooth_sapphire/internal/host/gap/gap.h"
24 #include "pw_bluetooth_sapphire/internal/host/gap/pairing_state_manager.h"
25 #include "pw_bluetooth_sapphire/internal/host/gap/peer.h"
26 #include "pw_bluetooth_sapphire/internal/host/hci/bredr_connection.h"
27 #include "pw_bluetooth_sapphire/internal/host/l2cap/channel_manager.h"
28 #include "pw_bluetooth_sapphire/internal/host/l2cap/l2cap_defs.h"
29 #include "pw_bluetooth_sapphire/internal/host/sco/sco_connection_manager.h"
30 #include "pw_bluetooth_sapphire/internal/host/sm/security_manager.h"
31 #include "pw_bluetooth_sapphire/internal/host/sm/types.h"
32 
33 namespace bt::gap {
34 
35 class PeerCache;
36 class SecureSimplePairingState;
37 
38 // Represents an ACL connection that is currently open with the controller (i.e.
39 // after receiving a Connection Complete and before either user disconnection or
40 // Disconnection Complete).
41 class BrEdrConnection final {
42  public:
43   // |send_auth_request_cb| is called during pairing, and should send the
44   // authenticaion request HCI command. |disconnect_cb| is called when an error
45   // occurs and the link should be disconnected. |on_peer_disconnect_cb| is
46   // called when the peer disconnects and this connection should be destroyed.
47   BrEdrConnection(Peer::WeakPtr peer,
48                   std::unique_ptr<hci::BrEdrConnection> link,
49                   fit::closure send_auth_request_cb,
50                   fit::callback<void()> disconnect_cb,
51                   fit::closure on_peer_disconnect_cb,
52                   l2cap::ChannelManager* l2cap,
53                   hci::Transport::WeakPtr transport,
54                   std::optional<BrEdrConnectionRequest> request,
55                   hci::LocalAddressDelegate* low_energy_address_delegate,
56                   bool controller_remote_public_key_validation_supported,
57                   sm::BrEdrSecurityManagerFactory security_manager_factory,
58                   pw::async::Dispatcher& pw_dispatcher);
59 
60   ~BrEdrConnection();
61 
62   BrEdrConnection(BrEdrConnection&&) = default;
63 
64   void Interrogate(BrEdrInterrogator::ResultCallback callback);
65 
66   // Called after interrogation completes to mark this connection as available
67   // for upper layers, i.e. L2CAP. Also signals any requesters with a successful
68   // status and this connection. If not called and this connection is deleted
69   // (e.g. by disconnection), requesters will be signaled with
70   // |HostError::kNotSupported| (to indicate interrogation error).
71   void OnInterrogationComplete();
72 
73   // Add a request callback that will be called when OnInterrogationComplete()
74   // is called (or immediately if OnInterrogationComplete() has already been
75   // called).
76   void AddRequestCallback(BrEdrConnectionRequest::OnComplete cb);
77 
78   // Create a SecureSimplePairingState or LegacyPairingState object based on
79   // |type|. If the object for corresponding |type| has already been created,
80   // this method does nothing.
81   void CreateOrUpdatePairingState(
82       PairingStateType type,
83       const PairingDelegate::WeakPtr& pairing_delegate,
84       BrEdrSecurityMode security_mode);
85 
86   // If |OnInterrogationComplete| has been called, opens an L2CAP channel using
87   // the preferred parameters |params| on the L2cap provided. Otherwise, calls
88   // |cb| with a nullptr.
89   void OpenL2capChannel(l2cap::Psm psm,
90                         l2cap::ChannelParameters params,
91                         l2cap::ChannelCallback cb);
92 
93   // See ScoConnectionManager for documentation.
94   using ScoRequestHandle = sco::ScoConnectionManager::RequestHandle;
95   ScoRequestHandle OpenScoConnection(
96       bt::StaticPacket<
97           pw::bluetooth::emboss::SynchronousConnectionParametersWriter>,
98       sco::ScoConnectionManager::OpenConnectionCallback callback);
99   ScoRequestHandle AcceptScoConnection(
100       std::vector<bt::StaticPacket<
101           pw::bluetooth::emboss::SynchronousConnectionParametersWriter>>
102           parameters,
103       sco::ScoConnectionManager::AcceptConnectionCallback callback);
104 
105   // Attach connection inspect node as a child of |parent| named |name|.
106   void AttachInspect(inspect::Node& parent, std::string name);
107 
link()108   const hci::Connection& link() const { return *link_; }
link()109   hci::BrEdrConnection& link() { return *link_; }
peer_id()110   PeerId peer_id() const { return peer_id_; }
pairing_state_manager()111   PairingStateManager& pairing_state_manager() {
112     return *pairing_state_manager_;
113   }
114 
115   // Returns the duration that this connection has been alive.
116   pw::chrono::SystemClock::duration duration() const;
117 
interrogation_complete()118   bool interrogation_complete() const { return !request_.has_value(); }
119 
security_properties()120   sm::SecurityProperties security_properties() const {
121     PW_CHECK(pairing_state_manager_);
122     return pairing_state_manager_->security_properties();
123   }
124 
set_security_mode(BrEdrSecurityMode mode)125   void set_security_mode(BrEdrSecurityMode mode) {
126     PW_CHECK(pairing_state_manager_);
127     pairing_state_manager_->set_security_mode(mode);
128   }
129 
130   void SetSecurityManagerChannel(
131       l2cap::Channel::WeakPtr security_manager_channel);
132 
133  private:
134   // |conn_token| is a token received from Peer::MutBrEdr::RegisterConnection().
135   void set_peer_connection_token(Peer::ConnectionToken conn_token);
136 
137   // Called by |pairing_state_manager_| when pairing completes with |status|.
138   void OnPairingStateStatus(hci_spec::ConnectionHandle handle,
139                             hci::Result<> status);
140 
141   PeerId peer_id_;
142   Peer::WeakPtr peer_;
143   std::unique_ptr<hci::BrEdrConnection> link_;
144   std::optional<BrEdrConnectionRequest> request_;
145   bool controller_remote_public_key_validation_supported_;
146   sm::BrEdrSecurityManagerFactory security_manager_factory_;
147   std::unique_ptr<PairingStateManager> pairing_state_manager_;
148   l2cap::Channel::WeakPtr security_manager_channel_;
149   l2cap::ChannelManager* l2cap_;
150   std::unique_ptr<sco::ScoConnectionManager> sco_manager_;
151   std::unique_ptr<BrEdrInterrogator> interrogator_;
152   // Time this object was constructed.
153   pw::chrono::SystemClock::time_point create_time_;
154   // Called when an error occurs and this connection should be disconnected.
155   fit::callback<void()> disconnect_cb_;
156 
157   struct InspectProperties {
158     inspect::StringProperty peer_id;
159   };
160   InspectProperties inspect_properties_;
161   inspect::Node inspect_node_;
162 
163   std::optional<Peer::InitializingConnectionToken> peer_init_token_;
164   // Ensures that this peer is marked "connected" once pairing completes.
165   // Unregisters the connection from PeerCache when this connection is
166   // destroyed.
167   Peer::ConnectionToken peer_conn_token_;
168 
169   pw::async::Dispatcher& dispatcher_;
170 
171   BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(BrEdrConnection);
172 };
173 
174 }  // namespace bt::gap
175