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