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 } set_encryption_status(pw::bluetooth::emboss::EncryptionStatus status)60 void set_encryption_status(pw::bluetooth::emboss::EncryptionStatus status) { 61 encryption_status_ = status; 62 } 63 64 protected: 65 AclConnection(hci_spec::ConnectionHandle handle, 66 const DeviceAddress& local_address, 67 const DeviceAddress& peer_address, 68 pw::bluetooth::emboss::ConnectionRole role, 69 const Transport::WeakPtr& hci); 70 set_ltk(const hci_spec::LinkKey & link_key)71 void set_ltk(const hci_spec::LinkKey& link_key) { ltk_ = link_key; } 72 73 // Notifies subclasses of a change in encryption status. 74 virtual void HandleEncryptionStatus(Result<bool /*enabled*/> result, 75 bool key_refreshed) = 0; 76 encryption_change_callback()77 ResultFunction<bool>& encryption_change_callback() { 78 return encryption_change_callback_; 79 } 80 81 private: 82 // This method must be static since it may be invoked after the connection 83 // associated with it is destroyed. 84 static void OnDisconnectionComplete(hci_spec::ConnectionHandle handle, 85 const Transport::WeakPtr& hci); 86 87 // HCI event handlers. 88 CommandChannel::EventCallbackResult OnEncryptionChangeEvent( 89 const EventPacket& event); 90 CommandChannel::EventCallbackResult OnEncryptionKeyRefreshCompleteEvent( 91 const EventPacket& event); 92 93 // IDs for encryption related HCI event handlers. 94 CommandChannel::EventHandlerId enc_change_id_; 95 CommandChannel::EventHandlerId enc_key_refresh_cmpl_id_; 96 97 // This connection's current link key. 98 std::optional<hci_spec::LinkKey> ltk_; 99 100 // Flag indicating if peer and local Secure Connections support are both 101 // present. Set in OnLinkKeyNotification in SecureSimplePairingState 102 bool use_secure_connections_ = false; 103 104 pw::bluetooth::emboss::EncryptionStatus encryption_status_ = 105 pw::bluetooth::emboss::EncryptionStatus::OFF; 106 107 pw::bluetooth::emboss::ConnectionRole role_; 108 109 ResultFunction<bool> encryption_change_callback_; 110 111 WeakSelf<AclConnection> weak_self_; 112 }; 113 114 } // namespace bt::hci 115