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 <lib/fit/function.h> 17 18 #include <atomic> 19 #include <climits> 20 #include <cstdint> 21 #include <list> 22 #include <memory> 23 #include <mutex> 24 #include <queue> 25 26 #include "pw_bluetooth/vendor.h" 27 #include "pw_bluetooth_sapphire/internal/host/common/byte_buffer.h" 28 #include "pw_bluetooth_sapphire/internal/host/common/inspect.h" 29 #include "pw_bluetooth_sapphire/internal/host/common/macros.h" 30 #include "pw_bluetooth_sapphire/internal/host/common/pipeline_monitor.h" 31 #include "pw_bluetooth_sapphire/internal/host/common/weak_self.h" 32 #include "pw_bluetooth_sapphire/internal/host/l2cap/a2dp_offload_manager.h" 33 #include "pw_bluetooth_sapphire/internal/host/l2cap/fragmenter.h" 34 #include "pw_bluetooth_sapphire/internal/host/l2cap/l2cap_defs.h" 35 #include "pw_bluetooth_sapphire/internal/host/l2cap/pdu.h" 36 #include "pw_bluetooth_sapphire/internal/host/l2cap/rx_engine.h" 37 #include "pw_bluetooth_sapphire/internal/host/l2cap/tx_engine.h" 38 #include "pw_bluetooth_sapphire/internal/host/l2cap/types.h" 39 #include "pw_bluetooth_sapphire/internal/host/sm/error.h" 40 #include "pw_bluetooth_sapphire/internal/host/sm/types.h" 41 #include "pw_bluetooth_sapphire/internal/host/transport/acl_data_channel.h" 42 #include "pw_bluetooth_sapphire/internal/host/transport/acl_data_packet.h" 43 #include "pw_bluetooth_sapphire/internal/host/transport/command_channel.h" 44 #include "pw_bluetooth_sapphire/internal/host/transport/error.h" 45 #include "pw_bluetooth_sapphire/internal/host/transport/link_type.h" 46 47 namespace bt::l2cap { 48 49 // Maximum count of packets a channel can queue before it must drop old packets 50 constexpr uint16_t kDefaultTxMaxQueuedCount = 500; 51 52 // Represents a L2CAP channel. Each instance is owned by a service 53 // implementation that operates on the corresponding channel. Instances can only 54 // be obtained from a ChannelManager. 55 // 56 // A Channel can operate in one of 6 L2CAP Modes of Operation (see Core Spec 57 // v5.0, Vol 3, Part A, Section 2.4). Only Basic Mode is currently supported. 58 // 59 // USAGE: 60 // 61 // Channel is an abstract base class. There are two concrete implementations: 62 // 63 // * internal::ChannelImpl (defined below) which implements a real L2CAP 64 // channel. Instances are obtained from ChannelManager and tied to 65 // internal::LogicalLink instances. 66 // 67 // * FakeChannel, which can be used for unit testing service-layer entities 68 // that operate on one or more L2CAP channel(s). 69 // 70 // Production instances are obtained from a ChannelManager. Channels are not 71 // thread safe. 72 // 73 // A Channel's owner must explicitly call Deactivate() and must not rely on 74 // dropping its reference to close the channel. 75 // 76 // When a LogicalLink closes, all of its active channels become deactivated 77 // when it closes and this is signaled by running the ClosedCallback passed to 78 // Activate(). 79 class Channel : public WeakSelf<Channel> { 80 public: 81 // TODO(fxbug.dev/42053109): define a preferred MTU somewhere 82 Channel(ChannelId id, 83 ChannelId remote_id, 84 bt::LinkType link_type, 85 hci_spec::ConnectionHandle link_handle, 86 ChannelInfo info, 87 uint16_t max_tx_queued); 88 virtual ~Channel() = default; 89 90 // Identifier for this channel's endpoint on this device. It can be prior- 91 // specified for fixed channels or allocated for dynamic channels per v5.0, 92 // Vol 3, Part A, Section 2.1 "Channel Identifiers." Channels on a link will 93 // have unique identifiers to each other. id()94 ChannelId id() const { return id_; } 95 96 // Identifier for this channel's endpoint on the remote peer. Same value as 97 // |id()| for fixed channels and allocated by the remote for dynamic channels. remote_id()98 ChannelId remote_id() const { return remote_id_; } 99 100 // The type of the logical link this channel operates on. link_type()101 bt::LinkType link_type() const { return link_type_; } 102 103 // The connection handle of the underlying logical link. link_handle()104 hci_spec::ConnectionHandle link_handle() const { return link_handle_; } 105 106 // Returns a value that's unique for any channel connected to this device. 107 // If two channels have different unique_ids, they represent different 108 // channels even if their ids match. 109 using UniqueId = uint32_t; unique_id()110 UniqueId unique_id() const { 111 static_assert(sizeof(UniqueId) >= 112 sizeof(hci_spec::ConnectionHandle) + sizeof(ChannelId), 113 "UniqueId needs to be large enough to make unique IDs"); 114 return (link_handle() << (sizeof(ChannelId) * CHAR_BIT)) | id(); 115 } 116 mode()117 const AnyChannelMode& mode() const { return info().mode; } 118 119 // These accessors define the concept of a Maximum Transmission Unit (MTU) as 120 // a maximum inbound (rx) and outbound (tx) packet size for the L2CAP 121 // implementation (see v5.2, Vol. 3, Part A 5.1). L2CAP requires that channel 122 // MTUs are at least 23 bytes for LE-U links and 48 bytes for ACL-U links. A 123 // further requirement is that "the minimum MTU for a channel is the larger 124 // of the L2CAP minimum [...] and any MTU explicitly required by the protocols 125 // and profiles using that channel." `max_rx_sdu_size` is always determined by 126 // the capabilities of the local implementation. For dynamic channels, 127 // `max_tx_sdu_size` is determined through a configuration procedure with the 128 // peer (v5.2 Vol. 3 Part A 7.1). For fixed channels, this is always the 129 // maximum allowable L2CAP packet size, not a protocol-specific MTU. max_rx_sdu_size()130 uint16_t max_rx_sdu_size() const { return info().max_rx_sdu_size; } max_tx_sdu_size()131 uint16_t max_tx_sdu_size() const { return info().max_tx_sdu_size; } 132 133 // Returns the current configuration parameters for this channel. info()134 const ChannelInfo& info() const { return info_; } 135 max_tx_queued()136 uint16_t max_tx_queued() const { return max_tx_queued_; } set_max_tx_queued(uint16_t count)137 void set_max_tx_queued(uint16_t count) { max_tx_queued_ = count; } 138 139 // Returns the current link security properties of the underlying link. 140 // Returns the lowest security level if the link is closed. 141 virtual const sm::SecurityProperties security() = 0; 142 143 // Callback invoked when this channel has been closed without an explicit 144 // request from the owner of this instance. For example, this can happen when 145 // the remote end closes a dynamically configured channel or when the 146 // underlying logical link is terminated through other means. 147 using ClosedCallback = fit::closure; 148 149 // Callback invoked when a new packet is received on this channel. Any 150 // previously buffered packets will be sent to |rx_cb| right away, provided 151 // that |rx_cb| is not empty and the underlying logical link is active. 152 using RxCallback = fit::function<void(ByteBufferPtr packet)>; 153 154 // Activates this channel to execute |rx_callback| and |closed_callback| 155 // immediately as L2CAP is notified of their underlying events. 156 // 157 // Any inbound data that has already been buffered for this channel will be 158 // drained by calling |rx_callback| repeatedly, before this call returns. 159 // 160 // Execution of |rx_callback| may block L2CAP data routing, so care should be 161 // taken to avoid introducing excessive latency. 162 // 163 // Each channel can be activated only once. 164 // 165 // Returns false if the channel's link has been closed. 166 // 167 // NOTE: Callers shouldn't assume that this method will succeed, as the 168 // underlying link can be removed at any time. 169 virtual bool Activate(RxCallback rx_callback, 170 ClosedCallback closed_callback) = 0; 171 172 // Deactivates this channel. No more packets can be sent or received after 173 // this is called. |rx_callback| may still be called if it has been already 174 // dispatched to its task runner. 175 // 176 // This method is idempotent. 177 virtual void Deactivate() = 0; 178 179 // Signals that the underlying link should be disconnected. This should be 180 // called when a service layer protocol error requires the connection to be 181 // severed. 182 // 183 // The link error callback (provided to L2CAP::Register* methods) is invoked 184 // as a result of this operation. The handler is responsible for actually 185 // disconnecting the link. 186 // 187 // This does not deactivate the channel, though the channel is expected to 188 // close when the link gets removed later. 189 virtual void SignalLinkError() = 0; 190 191 // Requests to upgrade the security properties of the underlying link to the 192 // requested |level| and reports the result via |callback|. Has no effect if 193 // the channel is not active. 194 virtual void UpgradeSecurity(sm::SecurityLevel level, 195 sm::ResultFunction<> callback) = 0; 196 197 // Queue the given SDU payload for transmission over this channel, taking 198 // ownership of |sdu|. Returns true if the SDU was queued successfully, and 199 // false otherwise. 200 // 201 // For reasons why queuing might fail, see the documentation for the relevant 202 // TxEngine's QueueSdu() method. Note: a successfully enqueued SDU may still 203 // fail to reach the receiver, due to asynchronous local errors, transmission 204 // failure, or remote errors. 205 virtual bool Send(ByteBufferPtr sdu) = 0; 206 207 // Request that the ACL priority of this channel be changed to |priority|. 208 // Calls |callback| with success if the request succeeded, or error otherwise. 209 // Requests may fail if the controller does not support changing the ACL 210 // priority or the indicated priority conflicts with another channel. 211 virtual void RequestAclPriority( 212 pw::bluetooth::AclPriority, 213 fit::callback<void(fit::result<fit::failed>)> callback) = 0; 214 215 // Sets an automatic flush timeout with duration |flush_timeout|. |callback| 216 // will be called with the result of the operation. This is only supported if 217 // the link type is kACL (BR/EDR). |flush_timeout| must be in the range [1ms - 218 // hci_spec::kMaxAutomaticFlushTimeoutDuration]. A flush timeout of 219 // pw::chrono::SystemClock::duration::max() indicates an infinite flush 220 // timeout (packets will be marked flushable, but there will be no automatic 221 // flush timeout). 222 virtual void SetBrEdrAutomaticFlushTimeout( 223 pw::chrono::SystemClock::duration flush_timeout, 224 hci::ResultCallback<> callback) = 0; 225 226 // Attach this channel as a child node of |parent| with the given |name|. 227 virtual void AttachInspect(inspect::Node& parent, std::string name) = 0; 228 229 // Request the start of A2DP source offloading. |callback| will be called with 230 // the result of the request. If offloading is already started or is pending, 231 // the request will fail and an error will be reported synchronously. 232 virtual void StartA2dpOffload(const A2dpOffloadManager::Configuration& config, 233 hci::ResultCallback<> callback) = 0; 234 235 // Request the stop of A2DP source offloading. |callback| will be called with 236 // the result of the request. If offloading is already stopped, report 237 // success. 238 virtual void StopA2dpOffload(hci::ResultCallback<> callback) = 0; 239 240 // The ACL priority that was both requested and accepted by the controller. requested_acl_priority()241 pw::bluetooth::AclPriority requested_acl_priority() const { 242 return requested_acl_priority_; 243 } 244 245 protected: 246 const ChannelId id_; 247 const ChannelId remote_id_; 248 const bt::LinkType link_type_; 249 const hci_spec::ConnectionHandle link_handle_; 250 ChannelInfo info_; 251 // Maximum number of PDUs in the channel queue 252 uint16_t max_tx_queued_; 253 // The ACL priority that was requested by a client and accepted by the 254 // controller. 255 pw::bluetooth::AclPriority requested_acl_priority_; 256 257 BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(Channel); 258 }; 259 260 namespace internal { 261 262 class LogicalLink; 263 using LogicalLinkWeakPtr = WeakSelf<LogicalLink>::WeakPtr; 264 265 // Channel implementation used in production. 266 class ChannelImpl : public Channel, public TxEngine::TxChannel { 267 public: 268 // Many core-spec protocols which operate over fixed channels (e.g. v5.2 Vol. 269 // 3 Parts F (ATT) and H (SMP)) define service-specific MTU values. Channels 270 // created with `CreateFixedChannel` do not check against these 271 // service-specific MTUs. Thus `bt-host` local services which operate over 272 // fixed channels are required to respect their MTU internally by: 273 // 1.) never sending packets larger than their spec-defined MTU. 274 // 2.) handling inbound PDUs which are larger than their spec-defined MTU 275 // appropriately. 276 static std::unique_ptr<ChannelImpl> CreateFixedChannel( 277 pw::async::Dispatcher& dispatcher, 278 ChannelId id, 279 internal::LogicalLinkWeakPtr link, 280 hci::CommandChannel::WeakPtr cmd_channel, 281 uint16_t max_acl_payload_size, 282 A2dpOffloadManager& a2dp_offload_manager, 283 uint16_t max_tx_queued = kDefaultTxMaxQueuedCount); 284 285 static std::unique_ptr<ChannelImpl> CreateDynamicChannel( 286 pw::async::Dispatcher& dispatcher, 287 ChannelId id, 288 ChannelId peer_id, 289 internal::LogicalLinkWeakPtr link, 290 ChannelInfo info, 291 hci::CommandChannel::WeakPtr cmd_channel, 292 uint16_t max_acl_payload_size, 293 A2dpOffloadManager& a2dp_offload_manager, 294 uint16_t max_tx_queued = kDefaultTxMaxQueuedCount); 295 296 ~ChannelImpl() override; 297 298 // Returns the next PDU fragment, or nullptr if none is available. 299 // Converts pending transmission PDUs to fragments 300 // Fragments of the same PDU must be sent before another channel in the same 301 // link can send packets 302 std::unique_ptr<hci::ACLDataPacket> GetNextOutboundPacket(); 303 304 // Called by |link_| to notify us when the channel can no longer process data. 305 void OnClosed(); 306 307 // Called by |link_| when a PDU targeting this channel has been received. 308 // Contents of |pdu| will be moved. 309 void HandleRxPdu(PDU&& pdu); 310 HasSDUs()311 bool HasSDUs() const { return !pending_tx_sdus_.empty(); } 312 HasPDUs()313 bool HasPDUs() const { return !pending_tx_pdus_.empty(); } 314 HasFragments()315 bool HasFragments() const { return !pending_tx_fragments_.empty(); } 316 317 // Channel overrides: 318 const sm::SecurityProperties security() override; 319 bool Activate(RxCallback rx_callback, 320 ClosedCallback closed_callback) override; 321 void Deactivate() override; 322 void SignalLinkError() override; 323 bool Send(ByteBufferPtr sdu) override; 324 void UpgradeSecurity(sm::SecurityLevel level, 325 sm::ResultFunction<> callback) override; 326 void RequestAclPriority( 327 pw::bluetooth::AclPriority priority, 328 fit::callback<void(fit::result<fit::failed>)> callback) override; 329 void SetBrEdrAutomaticFlushTimeout( 330 pw::chrono::SystemClock::duration flush_timeout, 331 hci::ResultCallback<> callback) override; 332 void AttachInspect(inspect::Node& parent, std::string name) override; 333 void StartA2dpOffload(const A2dpOffloadManager::Configuration& config, 334 hci::ResultCallback<> callback) override; 335 void StopA2dpOffload(hci::ResultCallback<> callback) override; 336 337 using WeakPtr = WeakSelf<ChannelImpl>::WeakPtr; GetWeakPtr()338 WeakPtr GetWeakPtr() { return weak_self_.GetWeakPtr(); } 339 340 private: 341 ChannelImpl(pw::async::Dispatcher& dispatcher, 342 ChannelId id, 343 ChannelId remote_id, 344 internal::LogicalLinkWeakPtr link, 345 ChannelInfo info, 346 hci::CommandChannel::WeakPtr cmd_channel, 347 uint16_t max_acl_payload_size, 348 A2dpOffloadManager& a2dp_offload_manager, 349 uint16_t max_tx_queued); 350 351 // Common channel closure logic. Called on Deactivate/OnClosed. 352 void CleanUp(); 353 354 // Called by |tx_engine_| to deliver a PDU to lower layers. 355 void SendFrame(ByteBufferPtr pdu) override; 356 357 // Called by |tx_engine_| to get a queued SDU for processing. 358 std::optional<ByteBufferPtr> GetNextQueuedSdu() override; 359 360 pw::async::Dispatcher& pw_dispatcher_; 361 362 bool active_; 363 RxCallback rx_cb_; 364 ClosedCallback closed_cb_; 365 366 // The LogicalLink that this channel is associated with. A channel is always 367 // created by a LogicalLink. 368 // 369 // |link_| is guaranteed to be valid as long as the link is active. This is 370 // because when a LogicalLink is torn down, it will notify all of its 371 // associated channels by calling OnLinkClosed() which sets |link_| to 372 // nullptr. 373 internal::LogicalLinkWeakPtr link_; 374 375 // Command channel used to transport A2DP offload configuration of vendor 376 // extensions. 377 hci::CommandChannel::WeakPtr cmd_channel_; 378 379 // The engine which processes received PDUs, and converts them to SDUs for 380 // upper layers. 381 std::unique_ptr<RxEngine> rx_engine_; 382 383 // The engine which accepts SDUs, and converts them to PDUs for lower layers. 384 std::unique_ptr<TxEngine> tx_engine_; 385 386 // The pending SDUs on this channel. Received PDUs are buffered if |rx_cb_| is 387 // currently not set. 388 // TODO(armansito): We should avoid STL containers for data packets as they 389 // all implicitly allocate. This is a reminder to fix this elsewhere 390 // (especially in the HCI layer). 391 std::queue<ByteBufferPtr, std::list<ByteBufferPtr>> pending_rx_sdus_; 392 393 // Contains outbound SDUs 394 std::queue<ByteBufferPtr> pending_tx_sdus_; 395 396 // Contains outbound PDUs 397 std::queue<ByteBufferPtr> pending_tx_pdus_; 398 399 // Contains outbound fragments 400 std::list<hci::ACLDataPacketPtr> pending_tx_fragments_; 401 402 // Fragmenter and Recombiner are always accessed on the L2CAP thread. 403 const Fragmenter fragmenter_; 404 405 uint8_t dropped_packets = 0; 406 407 struct InspectProperties { 408 inspect::Node node; 409 inspect::StringProperty psm; 410 inspect::StringProperty local_id; 411 inspect::StringProperty remote_id; 412 inspect::UintProperty dropped_packets; 413 }; 414 InspectProperties inspect_; 415 416 A2dpOffloadManager& a2dp_offload_manager_; 417 418 WeakSelf<ChannelImpl> weak_self_; 419 420 BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(ChannelImpl); 421 }; 422 423 } // namespace internal 424 } // namespace bt::l2cap 425