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