• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2024 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 <fidl/fuchsia.hardware.bluetooth/cpp/fidl.h>
18 #include <lib/fpromise/result.h>
19 
20 #include <vector>
21 
22 #include "pw_bluetooth_sapphire/internal/host/testing/fake_controller.h"
23 #include "pw_bluetooth_sapphire/internal/host/testing/fake_peer.h"
24 
25 namespace bt_hci_virtual {
26 
27 // Responsible for processing FIDL messages to/from an emulated peer instance.
28 // This class is not thread-safe.
29 //
30 // When the remote end of the FIDL channel gets closed the underlying FakePeer
31 // will be removed from the fake controller and the |closed_callback| that is
32 // passed to the constructor will get notified. The owner of this object should
33 // act on this by destroying this Peer instance.
34 class EmulatedPeer : public fidl::Server<fuchsia_hardware_bluetooth::Peer> {
35  public:
36   using Result =
37       fpromise::result<std::unique_ptr<EmulatedPeer>,
38                        fuchsia_hardware_bluetooth::EmulatorPeerError>;
39 
40   // Registers a peer with the FakeController using the provided LE parameters.
41   // Returns the peer on success or an error reporting the failure.
42   static Result NewLowEnergy(
43       fuchsia_hardware_bluetooth::PeerParameters parameters,
44       bt::testing::FakeController* fake_controller,
45       async_dispatcher_t* dispatcher);
46 
47   // Registers a peer with the FakeController using the provided BR/EDR
48   // parameters. Returns the peer on success or an error reporting the failure.
49   static Result NewBredr(fuchsia_hardware_bluetooth::PeerParameters parameters,
50                          bt::testing::FakeController* fake_controller,
51                          async_dispatcher_t* dispatcher);
52 
53   // The destructor unregisters the Peer if initialized.
54   ~EmulatedPeer();
55 
56   // Rerturns the device address that this instance was initialized with based
57   // on the FIDL parameters.
address()58   const bt::DeviceAddress& address() const { return address_; }
59 
60   // Assign a callback that will run when the Peer handle gets closed.
set_closed_callback(fit::callback<void ()> closed_callback)61   void set_closed_callback(fit::callback<void()> closed_callback) {
62     closed_callback_ = std::move(closed_callback);
63   }
64 
65   // fuchsia_hardware_bluetooth::Peer overrides:
66   void AssignConnectionStatus(
67       AssignConnectionStatusRequest& request,
68       AssignConnectionStatusCompleter::Sync& completer) override;
69   void EmulateLeConnectionComplete(
70       EmulateLeConnectionCompleteRequest& request,
71       EmulateLeConnectionCompleteCompleter::Sync& completer) override;
72   void EmulateDisconnectionComplete(
73       EmulateDisconnectionCompleteCompleter::Sync& completer) override;
74   void WatchConnectionStates(
75       WatchConnectionStatesCompleter::Sync& completer) override;
76   void SetDeviceClass(SetDeviceClassRequest& request,
77                       SetDeviceClassCompleter::Sync& completer) override;
78   void SetServiceDefinitions(
79       SetServiceDefinitionsRequest& request,
80       SetServiceDefinitionsCompleter::Sync& completer) override;
81   void SetLeAdvertisement(
82       SetLeAdvertisementRequest& request,
83       SetLeAdvertisementCompleter::Sync& completer) override;
84   void handle_unknown_method(
85       fidl::UnknownMethodMetadata<fuchsia_hardware_bluetooth::Peer> metadata,
86       fidl::UnknownMethodCompleter::Sync& completer) override;
87 
88   // Updates this peer with the current connection state which is used to notify
89   // its FIDL client of state changes that it is observing.
90   void UpdateConnectionState(bool connected);
91   void MaybeUpdateConnectionStates();
92 
93  private:
94   EmulatedPeer(bt::DeviceAddress address,
95                fidl::ServerEnd<fuchsia_hardware_bluetooth::Peer> request,
96                bt::testing::FakeController* fake_controller,
97                async_dispatcher_t* dispatcher);
98 
99   void OnChannelClosed(fidl::UnbindInfo info);
100   void CleanUp();
101   void NotifyChannelClosed();
102 
103   bt::DeviceAddress address_;
104   bt::testing::FakeController* fake_controller_;
105   fidl::ServerBinding<fuchsia_hardware_bluetooth::Peer> binding_;
106   fit::callback<void()> closed_callback_;
107 
108   std::mutex connection_states_lock_;
109   std::vector<fuchsia_hardware_bluetooth::ConnectionState> connection_states_;
110   std::queue<WatchConnectionStatesCompleter::Async>
111       connection_states_completers_ __TA_GUARDED(connection_states_lock_);
112 };
113 
114 }  // namespace bt_hci_virtual
115