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 <unordered_map> 19 20 #include "pw_bluetooth/controller.h" 21 #include "pw_bluetooth/vendor.h" 22 #include "pw_bluetooth_sapphire/internal/host/common/byte_buffer.h" 23 #include "pw_bluetooth_sapphire/internal/host/common/error.h" 24 #include "pw_bluetooth_sapphire/internal/host/common/inspect.h" 25 #include "pw_bluetooth_sapphire/internal/host/hci-spec/constants.h" 26 #include "pw_bluetooth_sapphire/internal/host/transport/acl_data_packet.h" 27 #include "pw_bluetooth_sapphire/internal/host/transport/command_channel.h" 28 #include "pw_bluetooth_sapphire/internal/host/transport/control_packets.h" 29 #include "pw_bluetooth_sapphire/internal/host/transport/data_buffer_info.h" 30 #include "pw_bluetooth_sapphire/internal/host/transport/link_type.h" 31 32 namespace bt::hci { 33 34 // Our ACL implementation allows specifying a Unique ChannelId for purposes of 35 // grouping packets so they can be dropped together when necessary. In practice, 36 // this channel id will always be equal to a given L2CAP ChannelId, as specified 37 // in the l2cap library 38 using UniqueChannelId = uint16_t; 39 40 class Transport; 41 42 // Represents the Bluetooth ACL Data channel and manages the Host<->Controller 43 // ACL data flow control. 44 // 45 // This currently only supports the Packet-based Data Flow Control as defined in 46 // Core Spec v5.0, Vol 2, Part E, Section 4.1.1. 47 class AclDataChannel { 48 public: 49 // This interface will be implemented by l2cap::LogicalLink 50 class ConnectionInterface { 51 public: 52 virtual ~ConnectionInterface() = default; 53 54 virtual hci_spec::ConnectionHandle handle() const = 0; 55 56 virtual bt::LinkType type() const = 0; 57 58 // Returns the next PDU fragment, or nullptr if none is available. 59 virtual std::unique_ptr<ACLDataPacket> GetNextOutboundPacket() = 0; 60 61 // Returns true if link has a queued packet 62 virtual bool HasAvailablePacket() const = 0; 63 }; 64 65 // Registers a connection. Failure to register a connection before sending 66 // packets will result in the packets being dropped immediately. A connection 67 // must not be registered again until after |UnregisterConnection| has been 68 // called on that connection. 69 virtual void RegisterConnection(WeakPtr<ConnectionInterface> connection) = 0; 70 71 // Unregister a connection when it is disconnected. Cleans up all outgoing 72 // data buffering state related to the logical link with the given |handle|. 73 // This must be called upon disconnection of a link to ensure that stale 74 // outbound packets are filtered out of the send queue. All future packets 75 // sent to this link will be dropped. 76 // 77 // |RegisterConnection| must be called before |UnregisterConnection| for the 78 // same handle. 79 // 80 // |UnregisterConnection| does not clear the controller packet count, so 81 // |ClearControllerPacketCount| must be called after |UnregisterConnection| 82 // and the HCI_Disconnection_Complete event has been received. 83 virtual void UnregisterConnection(hci_spec::ConnectionHandle handle) = 0; 84 85 // Called by LogicalLink when a packet is available 86 virtual void OnOutboundPacketAvailable() = 0; 87 88 enum class PacketPriority { kHigh, kLow }; 89 90 using AclPacketPredicate = fit::function<bool(const ACLDataPacketPtr& packet, 91 UniqueChannelId channel_id)>; 92 93 // Starts listening on the HCI ACL data channel and starts handling data flow 94 // control. |bredr_buffer_info| represents the controller's data buffering 95 // capacity for the BR/EDR transport and the |le_buffer_info| represents Low 96 // Energy buffers. At least one of these (BR/EDR vs LE) must contain non-zero 97 // values per Core Spec v5.0 Vol 2, Part E, Sec 4.1.1: 98 // 99 // - A LE only controller will have LE buffers only. 100 // - A BR/EDR-only controller will have BR/EDR buffers only. 101 // - A dual-mode controller will have BR/EDR buffers and MAY have LE buffers 102 // if the BR/EDR buffer is not shared between the transports. 103 // 104 // As this class is intended to support flow-control for both, this function 105 // should be called based on what is reported by the controller. 106 static std::unique_ptr<AclDataChannel> Create( 107 Transport* transport, 108 pw::bluetooth::Controller* hci, 109 const DataBufferInfo& bredr_buffer_info, 110 const DataBufferInfo& le_buffer_info); 111 112 virtual ~AclDataChannel() = default; 113 114 // Attach inspect node as a child node of |parent|. 115 static constexpr const char* const kInspectNodeName = "acl_data_channel"; 116 virtual void AttachInspect(inspect::Node& parent, 117 const std::string& name) = 0; 118 119 // Assigns a handler callback for received ACL data packets. |rx_callback| 120 // will shall take ownership of each packet received from the controller. 121 virtual void SetDataRxHandler(ACLPacketHandler rx_callback) = 0; 122 123 // Resets controller packet count for |handle| so that controller buffer 124 // credits can be reused. This must be called on the 125 // HCI_Disconnection_Complete event to notify ACLDataChannel that packets in 126 // the controller's buffer for |handle| have been flushed. See Core Spec v5.1, 127 // Vol 2, Part E, Section 4.3. This must be called after 128 // |UnregisterConnection|. 129 virtual void ClearControllerPacketCount( 130 hci_spec::ConnectionHandle handle) = 0; 131 132 // Returns the BR/EDR buffer information that the channel was initialized 133 // with. 134 virtual const DataBufferInfo& GetBufferInfo() const = 0; 135 136 // Returns the LE buffer information that the channel was initialized with. 137 // This defaults to the BR/EDR buffers if the controller does not have a 138 // dedicated LE buffer. 139 virtual const DataBufferInfo& GetLeBufferInfo() const = 0; 140 141 // Attempts to set the ACL |priority| of the connection indicated by |handle|. 142 // |callback| will be called with the result of the request. 143 virtual void RequestAclPriority( 144 pw::bluetooth::AclPriority priority, 145 hci_spec::ConnectionHandle handle, 146 fit::callback<void(fit::result<fit::failed>)> callback) = 0; 147 }; 148 149 } // namespace bt::hci 150