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 <lib/fit/function.h> 17 18 #include <memory> 19 20 #include "pw_bluetooth_sapphire/internal/host/common/macros.h" 21 #include "pw_bluetooth_sapphire/internal/host/gap/peer.h" 22 #include "pw_bluetooth_sapphire/internal/host/hci-spec/protocol.h" 23 #include "pw_bluetooth_sapphire/internal/host/hci/sequential_command_runner.h" 24 #include "pw_bluetooth_sapphire/internal/host/transport/command_channel.h" 25 26 namespace bt { 27 namespace hci { 28 class Transport; 29 } 30 31 namespace gap { 32 33 // A BrEdrInterrogator abstracts over the HCI commands and events involved 34 // immediately after connecting to a peer over BR/EDR. 35 class BrEdrInterrogator final { 36 public: 37 using ResultCallback = hci::ResultCallback<>; 38 39 // |peer| must live longer than this object. 40 BrEdrInterrogator(Peer::WeakPtr peer, 41 hci_spec::ConnectionHandle handle, 42 hci::CommandChannel::WeakPtr cmd_channel); 43 44 // Cancels the pending interrogation without calling the result callback. 45 ~BrEdrInterrogator() = default; 46 47 // Starts interrogation. Calls |callback| when the sequence is completed or 48 // fails. Only 1 interrogation may be pending at a time. 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 // Requests the name of the remote peer. 59 void QueueRemoteNameRequest(); 60 61 // Requests features of the peer, and asks for Extended Features if they 62 // exist. 63 void QueueReadRemoteFeatures(); 64 65 // Reads the extended feature page |page| of the peer. 66 void QueueReadRemoteExtendedFeatures(uint8_t page); 67 68 void QueueReadRemoteVersionInformation(); 69 70 Peer::WeakPtr peer_; 71 const PeerId peer_id_; 72 const hci_spec::ConnectionHandle handle_; 73 74 ResultCallback callback_ = nullptr; 75 76 hci::SequentialCommandRunner cmd_runner_; 77 78 // Keep this as the last member to make sure that all weak pointers are 79 // invalidated before other members get destroyed. 80 WeakSelf<BrEdrInterrogator> weak_self_; 81 82 BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(BrEdrInterrogator); 83 }; 84 85 } // namespace gap 86 } // namespace bt 87