• 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_bluetooth_sapphire/internal/host/hci-spec/link_key.h"
17 #include "pw_bluetooth_sapphire/internal/host/hci/connection.h"
18 
19 namespace bt::hci {
20 
21 // Represents an ACL-U or LE-U link, both of which use the ACL data channel and
22 // support encryption procedures.
23 // Concrete implementations are found in BrEdrConnection and
24 // LowEnergyConnection.
25 class AclConnection : public Connection {
26  public:
27   ~AclConnection() override;
28 
29   // Authenticate (i.e. encrypt) this connection using its current link key.
30   // Returns false if the procedure cannot be initiated. The result of the
31   // authentication procedure will be reported via the encryption change
32   // callback.
33   //
34   // If the link layer procedure fails, the connection will be disconnected. The
35   // encryption change callback will be notified of the failure.
36   virtual bool StartEncryption() = 0;
37 
38   // Assigns a callback that will run when the encryption state of the
39   // underlying link changes. The bool value parameter represents the new state.
set_encryption_change_callback(ResultFunction<bool> callback)40   void set_encryption_change_callback(ResultFunction<bool> callback) {
41     encryption_change_callback_ = std::move(callback);
42   }
43 
44   // Returns the role of the local device in the established connection.
role()45   pw::bluetooth::emboss::ConnectionRole role() const { return role_; }
46 
47   // Update the role of the local device when a role change occurs.
set_role(pw::bluetooth::emboss::ConnectionRole role)48   void set_role(pw::bluetooth::emboss::ConnectionRole role) { role_ = role; }
49 
50   // The current long term key of the connection.
ltk()51   const std::optional<hci_spec::LinkKey>& ltk() const { return ltk_; }
52 
set_use_secure_connections(bool use_secure_connections)53   void set_use_secure_connections(bool use_secure_connections) {
54     use_secure_connections_ = use_secure_connections;
55   }
56 
encryption_status()57   pw::bluetooth::emboss::EncryptionStatus encryption_status() const {
58     return encryption_status_;
59   }
60 
61  protected:
62   AclConnection(hci_spec::ConnectionHandle handle,
63                 const DeviceAddress& local_address,
64                 const DeviceAddress& peer_address,
65                 pw::bluetooth::emboss::ConnectionRole role,
66                 const Transport::WeakPtr& hci);
67 
set_ltk(const hci_spec::LinkKey & link_key)68   void set_ltk(const hci_spec::LinkKey& link_key) { ltk_ = link_key; }
69 
70   // Notifies subclasses of a change in encryption status.
71   virtual void HandleEncryptionStatus(Result<bool /*enabled*/> result,
72                                       bool key_refreshed) = 0;
73 
encryption_change_callback()74   ResultFunction<bool>& encryption_change_callback() {
75     return encryption_change_callback_;
76   }
77 
78  private:
79   // This method must be static since it may be invoked after the connection
80   // associated with it is destroyed.
81   static void OnDisconnectionComplete(hci_spec::ConnectionHandle handle,
82                                       const Transport::WeakPtr& hci);
83 
84   // HCI event handlers.
85   CommandChannel::EventCallbackResult OnEncryptionChangeEvent(
86       const EmbossEventPacket& event);
87   CommandChannel::EventCallbackResult OnEncryptionKeyRefreshCompleteEvent(
88       const EmbossEventPacket& event);
89 
90   // IDs for encryption related HCI event handlers.
91   CommandChannel::EventHandlerId enc_change_id_;
92   CommandChannel::EventHandlerId enc_key_refresh_cmpl_id_;
93 
94   // This connection's current link key.
95   std::optional<hci_spec::LinkKey> ltk_;
96 
97   // Flag indicating if peer and local Secure Connections support are both
98   // present. Set in OnLinkKeyNotification in PairingState
99   bool use_secure_connections_ = false;
100 
101   pw::bluetooth::emboss::EncryptionStatus encryption_status_ =
102       pw::bluetooth::emboss::EncryptionStatus::OFF;
103 
104   pw::bluetooth::emboss::ConnectionRole role_;
105 
106   ResultFunction<bool> encryption_change_callback_;
107 
108   WeakSelf<AclConnection> weak_self_;
109 };
110 
111 }  // namespace bt::hci
112