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 17 #include "pw_bluetooth_sapphire/internal/host/gap/adapter_state.h" 18 #include "pw_bluetooth_sapphire/internal/host/gap/peer_cache.h" 19 #include "pw_bluetooth_sapphire/internal/host/hci/sequential_command_runner.h" 20 #include "pw_bluetooth_sapphire/internal/host/transport/transport.h" 21 22 namespace bt { 23 namespace hci { 24 class Transport; 25 } // namespace hci 26 27 namespace gap { 28 29 // LowEnergyInterrogator sends HCI commands that request the controller version 30 // and features of a peer and handles responses by updating the Peer. 31 // LowEnergyInterrogator must only be used with an LE or dual mode controller. 32 class LowEnergyInterrogator final { 33 public: 34 // |peer| must outlive this object. 35 // |sca_supported| indicates that the controller supports interrogation of 36 // peer sleep clock accuracy. 37 LowEnergyInterrogator(Peer::WeakPtr peer, 38 hci_spec::ConnectionHandle handle, 39 hci::CommandChannel::WeakPtr hci, 40 bool sca_supported); 41 42 // Destroying the LowEnergyInterrogator effectively abandons an in-flight 43 // interrogation, if there is one. The result callback will not be called. 44 ~LowEnergyInterrogator() = default; 45 46 // Starts interrogation. Calls |callback| when the sequence is completed or 47 // fails. Only 1 interrogation may be pending at a time. 48 using ResultCallback = hci::ResultCallback<>; 49 void Start(ResultCallback callback); 50 51 // Abandons interrogation. The result callbacks will be called with result of 52 // kCanceled. No-op if interrogation has already completed. 53 void Cancel(); 54 55 private: 56 void Complete(hci::Result<> result); 57 58 void QueueRequestPeerSca(); 59 void QueueReadLERemoteFeatures(); 60 void QueueReadRemoteVersionInformation(); 61 62 Peer::WeakPtr peer_; 63 // Cache of the PeerId to allow for debug logging even if the WeakPtr<Peer> is 64 // invalidated 65 const PeerId peer_id_; 66 const hci_spec::ConnectionHandle handle_; 67 68 ResultCallback callback_ = nullptr; 69 70 hci::SequentialCommandRunner cmd_runner_; 71 72 // Controller supports interrogation of peer sleep clock accuracy. 73 bool controller_supports_sca_; 74 75 // Keep this as the last member to make sure that all weak pointers are 76 // invalidated before other members get destroyed. 77 WeakSelf<LowEnergyInterrogator> weak_self_; 78 79 BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(LowEnergyInterrogator); 80 }; 81 82 } // namespace gap 83 } // namespace bt 84