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