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