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 <pw_async/heap_dispatcher.h>
17 
18 #include <memory>
19 
20 #include "pw_bluetooth_sapphire/internal/host/common/byte_buffer.h"
21 #include "pw_bluetooth_sapphire/internal/host/common/macros.h"
22 #include "pw_bluetooth_sapphire/internal/host/hci-spec/protocol.h"
23 #include "pw_bluetooth_sapphire/internal/host/l2cap/channel.h"
24 #include "pw_bluetooth_sapphire/internal/host/l2cap/fragmenter.h"
25 #include "pw_bluetooth_sapphire/internal/host/l2cap/l2cap_defs.h"
26 #include "pw_bluetooth_sapphire/internal/host/l2cap/types.h"
27 
28 namespace bt::l2cap::testing {
29 
30 // FakeChannel is a simple pass-through Channel implementation that is intended
31 // for L2CAP service level unit tests where data is transmitted over a L2CAP
32 // channel.
33 class FakeChannel : public Channel {
34  public:
35   FakeChannel(ChannelId id,
36               ChannelId remote_id,
37               hci_spec::ConnectionHandle handle,
38               bt::LinkType link_type,
39               ChannelInfo info = ChannelInfo::MakeBasicMode(kDefaultMTU,
40                                                             kDefaultMTU),
41               uint16_t max_tx_queued = 1);
42   ~FakeChannel() override = default;
43 
44   // Routes the given data over to the rx handler as if it were received from
45   // the controller.
46   void Receive(const ByteBuffer& data);
47 
48   // Sets a delegate to notify when a frame was sent over the channel.
49   // If a |dispatcher| is specified, |callback| will be invoked asynchronously.
50   using SendCallback = fit::function<void(ByteBufferPtr)>;
51   void SetSendCallback(SendCallback callback);
52   void SetSendCallback(SendCallback callback,
53                        pw::async::Dispatcher& dispatcher);
54 
55   // Sets a callback to emulate the result of "SignalLinkError()". In
56   // production, this callback is invoked by the link.
57   void SetLinkErrorCallback(LinkErrorCallback callback);
58 
59   // Sets a callback to emulate the result of "UpgradeSecurity()".
60   void SetSecurityCallback(SecurityUpgradeCallback callback,
61                            pw::async::Dispatcher& dispatcher);
62 
63   // Emulates channel closure.
64   void Close();
65 
66   using WeakPtr = WeakSelf<FakeChannel>::WeakPtr;
AsWeakPtr()67   FakeChannel::WeakPtr AsWeakPtr() { return weak_fake_chan_.GetWeakPtr(); }
68 
69   // Activating always fails if true.
set_activate_fails(bool value)70   void set_activate_fails(bool value) { activate_fails_ = value; }
71 
72   // True if SignalLinkError() has been called.
link_error()73   bool link_error() const { return link_error_; }
74 
75   // True if Deactivate has yet not been called after Activate.
activated()76   bool activated() const { return static_cast<bool>(rx_cb_); }
77 
78   // Assigns a link security level.
set_security(const sm::SecurityProperties & sec_props)79   void set_security(const sm::SecurityProperties& sec_props) {
80     security_ = sec_props;
81   }
82 
83   // RequestAclPriority always fails if true.
set_acl_priority_fails(bool fail)84   void set_acl_priority_fails(bool fail) { acl_priority_fails_ = fail; }
85 
set_flush_timeout_succeeds(bool succeed)86   void set_flush_timeout_succeeds(bool succeed) {
87     flush_timeout_succeeds_ = succeed;
88   }
89 
90   // StartA2dpOffload() and StopA2dpOffload() fail with given |error_code|.
set_a2dp_offload_fails(HostError error_code)91   void set_a2dp_offload_fails(HostError error_code) {
92     a2dp_offload_error_ = error_code;
93   }
94 
a2dp_offload_status()95   A2dpOffloadStatus a2dp_offload_status() { return audio_offloading_status_; }
96 
97   // Channel overrides:
security()98   const sm::SecurityProperties security() override { return security_; }
99   bool Activate(RxCallback rx_callback,
100                 ClosedCallback closed_callback) override;
101   void Deactivate() override;
102   void SignalLinkError() override;
103   bool Send(ByteBufferPtr sdu) override;
104   void UpgradeSecurity(sm::SecurityLevel level,
105                        sm::ResultFunction<> callback) override;
106   void RequestAclPriority(
107       pw::bluetooth::AclPriority priority,
108       fit::callback<void(fit::result<fit::failed>)> cb) override;
109   void SetBrEdrAutomaticFlushTimeout(
110       pw::chrono::SystemClock::duration flush_timeout,
111       hci::ResultCallback<> callback) override;
AttachInspect(inspect::Node &,std::string)112   void AttachInspect(inspect::Node&, std::string) override {}
113   void StartA2dpOffload(const A2dpOffloadManager::Configuration& config,
114                         hci::ResultCallback<> callback) override;
115   void StopA2dpOffload(hci::ResultCallback<> callback) override;
116 
117  private:
118   hci_spec::ConnectionHandle handle_;
119   Fragmenter fragmenter_;
120 
121   sm::SecurityProperties security_;
122   SecurityUpgradeCallback security_cb_;
123   std::optional<pw::async::HeapDispatcher> security_dispatcher_;
124 
125   ClosedCallback closed_cb_;
126   RxCallback rx_cb_;
127 
128   SendCallback send_cb_;
129   std::optional<pw::async::HeapDispatcher> send_dispatcher_;
130 
131   LinkErrorCallback link_err_cb_;
132 
133   bool activate_fails_;
134   bool link_error_;
135 
136   bool acl_priority_fails_;
137   bool flush_timeout_succeeds_ = true;
138 
139   A2dpOffloadStatus audio_offloading_status_ = A2dpOffloadStatus::kStopped;
140 
141   std::optional<HostError> a2dp_offload_error_;
142 
143   // The pending SDUs on this channel. Received PDUs are buffered if |rx_cb_| is
144   // currently not set.
145   std::queue<ByteBufferPtr> pending_rx_sdus_;
146 
147   WeakSelf<FakeChannel> weak_fake_chan_;
148 
149   BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(FakeChannel);
150 };
151 
152 }  // namespace bt::l2cap::testing
153