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