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/async/dispatcher.h>
19 
20 #include "pw_bluetooth_sapphire/internal/host/common/byte_buffer.h"
21 #include "pw_bluetooth_sapphire/internal/host/iso/iso_common.h"
22 
23 namespace bt::fidl::testing {
24 
25 class FakeHciTransportServer final
26     : public ::fidl::Server<fuchsia_hardware_bluetooth::HciTransport> {
27  public:
28   FakeHciTransportServer(
29       ::fidl::ServerEnd<fuchsia_hardware_bluetooth::HciTransport> server_end,
30       async_dispatcher_t* dispatcher);
31 
Unbind()32   void Unbind() {
33     binding_.Unbind();
34     bound_ = false;
35   }
36 
bound()37   bool bound() const { return bound_; }
38 
39   zx_status_t SendEvent(const BufferView& event);
40   zx_status_t SendAcl(const BufferView& buffer);
41   zx_status_t SendSco(const BufferView& buffer);
42   zx_status_t SendIso(const BufferView& buffer);
43 
44   // Returns true if the SCO server was successfully unbound.
45   bool UnbindSco();
46 
acks_received()47   size_t acks_received() const { return ack_receive_count_; }
sco_acks_received()48   size_t sco_acks_received() const { return sco_ack_receive_count_; }
49 
commands_received()50   const std::vector<bt::DynamicByteBuffer>& commands_received() const {
51     return commands_received_;
52   }
acl_packets_received()53   const std::vector<bt::DynamicByteBuffer>& acl_packets_received() const {
54     return acl_packets_received_;
55   }
sco_packets_received()56   const std::vector<bt::DynamicByteBuffer>& sco_packets_received() const {
57     return sco_packets_received_;
58   }
iso_packets_received()59   const std::vector<bt::DynamicByteBuffer>& iso_packets_received() const {
60     return iso_packets_received_;
61   }
62 
63   // Use custom |ConfigureScoTestCallback| to manually verify configuration
64   // fields from tests
65   using ConfigureScoTestCallback =
66       fit::function<void(fuchsia_hardware_bluetooth::ScoCodingFormat,
67                          fuchsia_hardware_bluetooth::ScoEncoding,
68                          fuchsia_hardware_bluetooth::ScoSampleRate)>;
set_check_configure_sco(ConfigureScoTestCallback callback)69   void set_check_configure_sco(ConfigureScoTestCallback callback) {
70     check_configure_sco_ = std::move(callback);
71   }
72 
73   // Uee custom |ResetScoTestCallback| to manually perform reset actions from
74   // tests
75   using ResetScoTestCallback = fit::function<void()>;
set_reset_sco_callback(ResetScoTestCallback callback)76   void set_reset_sco_callback(ResetScoTestCallback callback) {
77     reset_sco_cb_ = std::move(callback);
78   }
79 
80  private:
81   class ScoConnectionServer
82       : public ::fidl::Server<fuchsia_hardware_bluetooth::ScoConnection> {
83    public:
84     ScoConnectionServer(
85         ::fidl::ServerEnd<fuchsia_hardware_bluetooth::ScoConnection> server_end,
86         async_dispatcher_t* dispatcher,
87         FakeHciTransportServer* hci_server);
88 
89     zx_status_t Send(const BufferView& buffer);
90 
91     void Unbind();
92 
93    private:
94     // Server<ScoConnection> overrides:
95     void Send(SendRequest& request, SendCompleter::Sync& completer) override;
96     void AckReceive(AckReceiveCompleter::Sync& completer) override;
97     void Stop(StopCompleter::Sync& completer) override;
98     void handle_unknown_method(
99         ::fidl::UnknownMethodMetadata<fuchsia_hardware_bluetooth::ScoConnection>
100             metadata,
101         ::fidl::UnknownMethodCompleter::Sync& completer) override;
102 
103     void OnUnbound(::fidl::UnbindInfo info,
104                    ::fidl::ServerEnd<fuchsia_hardware_bluetooth::ScoConnection>
105                        server_end);
106 
107     FakeHciTransportServer* hci_server_;
108     ::fidl::ServerBindingRef<fuchsia_hardware_bluetooth::ScoConnection>
109         binding_;
110   };
111 
112   // Server<HciTransport> overrides:
113   void Send(SendRequest& request, SendCompleter::Sync& completer) override;
114   void AckReceive(AckReceiveCompleter::Sync& completer) override;
115   void ConfigureSco(ConfigureScoRequest& request,
116                     ConfigureScoCompleter::Sync& completer) override;
117   void handle_unknown_method(
118       ::fidl::UnknownMethodMetadata<fuchsia_hardware_bluetooth::HciTransport>
119           metadata,
120       ::fidl::UnknownMethodCompleter::Sync& completer) override;
121 
122   void OnUnbound(
123       ::fidl::UnbindInfo info,
124       ::fidl::ServerEnd<fuchsia_hardware_bluetooth::HciTransport> server_end);
125 
126   std::vector<bt::DynamicByteBuffer> commands_received_;
127 
128   std::vector<bt::DynamicByteBuffer> acl_packets_received_;
129 
130   std::vector<bt::DynamicByteBuffer> sco_packets_received_;
131   ConfigureScoTestCallback check_configure_sco_;
132   ResetScoTestCallback reset_sco_cb_;
133 
134   std::vector<bt::DynamicByteBuffer> iso_packets_received_;
135 
136   std::optional<ScoConnectionServer> sco_server_;
137 
138   size_t ack_receive_count_ = 0u;
139   size_t sco_ack_receive_count_ = 0u;
140 
141   async_dispatcher_t* dispatcher_;
142   bool bound_ = true;
143   ::fidl::ServerBindingRef<fuchsia_hardware_bluetooth::HciTransport> binding_;
144 };
145 
146 }  // namespace bt::fidl::testing
147