• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
95   // Channel overrides:
security()96   const sm::SecurityProperties security() override { return security_; }
97   bool Activate(RxCallback rx_callback,
98                 ClosedCallback closed_callback) override;
99   void Deactivate() override;
100   void SignalLinkError() override;
101   bool Send(ByteBufferPtr sdu) override;
102   void UpgradeSecurity(sm::SecurityLevel level,
103                        sm::ResultFunction<> callback) override;
104   void RequestAclPriority(
105       pw::bluetooth::AclPriority priority,
106       fit::callback<void(fit::result<fit::failed>)> cb) override;
107   void SetBrEdrAutomaticFlushTimeout(
108       pw::chrono::SystemClock::duration flush_timeout,
109       hci::ResultCallback<> callback) override;
AttachInspect(inspect::Node & parent,std::string name)110   void AttachInspect(inspect::Node& parent, std::string name) override {}
111   void StartA2dpOffload(const A2dpOffloadManager::Configuration& config,
112                         hci::ResultCallback<> callback) override;
113   void StopA2dpOffload(hci::ResultCallback<> callback) override;
114 
115  private:
116   hci_spec::ConnectionHandle handle_;
117   Fragmenter fragmenter_;
118 
119   sm::SecurityProperties security_;
120   SecurityUpgradeCallback security_cb_;
121   std::optional<pw::async::HeapDispatcher> security_dispatcher_;
122 
123   ClosedCallback closed_cb_;
124   RxCallback rx_cb_;
125 
126   SendCallback send_cb_;
127   std::optional<pw::async::HeapDispatcher> send_dispatcher_;
128 
129   LinkErrorCallback link_err_cb_;
130 
131   bool activate_fails_;
132   bool link_error_;
133 
134   bool acl_priority_fails_;
135   bool flush_timeout_succeeds_ = true;
136 
137   std::optional<HostError> a2dp_offload_error_;
138 
139   // The pending SDUs on this channel. Received PDUs are buffered if |rx_cb_| is
140   // currently not set.
141   std::queue<ByteBufferPtr> pending_rx_sdus_;
142 
143   WeakSelf<FakeChannel> weak_fake_chan_;
144 
145   BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(FakeChannel);
146 };
147 
148 }  // namespace bt::l2cap::testing
149