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 <list>
19 #include <memory>
20 #include <mutex>
21 #include <unordered_map>
22 
23 #include "pw_bluetooth/vendor.h"
24 #include "pw_bluetooth_sapphire/internal/host/common/inspectable.h"
25 #include "pw_bluetooth_sapphire/internal/host/common/macros.h"
26 #include "pw_bluetooth_sapphire/internal/host/hci-spec/protocol.h"
27 #include "pw_bluetooth_sapphire/internal/host/l2cap/a2dp_offload_manager.h"
28 #include "pw_bluetooth_sapphire/internal/host/l2cap/bredr_command_handler.h"
29 #include "pw_bluetooth_sapphire/internal/host/l2cap/channel.h"
30 #include "pw_bluetooth_sapphire/internal/host/l2cap/channel_manager.h"
31 #include "pw_bluetooth_sapphire/internal/host/l2cap/dynamic_channel_registry.h"
32 #include "pw_bluetooth_sapphire/internal/host/l2cap/fragmenter.h"
33 #include "pw_bluetooth_sapphire/internal/host/l2cap/l2cap_defs.h"
34 #include "pw_bluetooth_sapphire/internal/host/l2cap/low_energy_command_handler.h"
35 #include "pw_bluetooth_sapphire/internal/host/l2cap/recombiner.h"
36 #include "pw_bluetooth_sapphire/internal/host/transport/acl_data_packet.h"
37 #include "pw_bluetooth_sapphire/internal/host/transport/link_type.h"
38 
39 namespace bt::l2cap::internal {
40 
41 class ChannelImpl;
42 class LESignalingChannel;
43 class SignalingChannel;
44 
45 // Represents a controller logical link. Each instance aids in mapping L2CAP
46 // channels to their corresponding controller logical link and vice versa. This
47 // owns each link's signaling fixed channel and the dynamic channel logic that
48 // operates on that channel. A LogicalLink must be explicitly `Close`d before
49 // destruction, and will assert on this behavior in its destructor.
50 //
51 // Instances are created and owned by a ChannelManager.
52 class LogicalLink : public hci::AclDataChannel::ConnectionInterface {
53  public:
54   // Returns a function that accepts opened channels for a registered local
55   // service identified by |psm| on a given connection identified by |handle|,
56   // or nullptr if there is no service registered for that PSM.
57   using QueryServiceCallback =
58       fit::function<std::optional<ChannelManager::ServiceInfo>(
59           hci_spec::ConnectionHandle handle, Psm psm)>;
60 
61   // Constructs a new LogicalLink and initializes the signaling fixed channel.
62   // |max_payload_size| shall be the maximum "host to controller" data packet
63   // payload size for the link |type|, per Core Spec v5.0 Vol 2, Part E,
64   // Sec 4.1. Both |query_service_cb| and the inbound channel delivery callback
65   // that it returns will be executed on this object's creation thread. If
66   // |random_channel_ids| is true, assign dynamic channels randomly instead of
67   // starting at the beginning of the dynamic channel range.
68   // |a2dp_offload_manager| is a reference to A2dpOffloadManager that is passed
69   // to channels to use
70   LogicalLink(hci_spec::ConnectionHandle handle,
71               bt::LinkType type,
72               pw::bluetooth::emboss::ConnectionRole role,
73               uint16_t max_acl_payload_size,
74               QueryServiceCallback query_service_cb,
75               hci::AclDataChannel* acl_data_channel,
76               hci::CommandChannel* cmd_channel,
77               bool random_channel_ids,
78               A2dpOffloadManager& a2dp_offload_manager,
79               pw::async::Dispatcher& dispatcher);
80 
81   // When a logical link is destroyed it notifies all of its channels to close
82   // themselves. Data packets will no longer be routed to the associated
83   // channels.
84   ~LogicalLink() override;
85 
86   // Notifies and closes all open channels on this link. This must be called to
87   // cleanly shut down a LogicalLink.
88   //
89   // The link MUST not be closed when this is called.
90   void Close();
91 
92   // Opens the channel with |channel_id| over this logical link. See channel.h
93   // for documentation on |rx_callback| and |closed_callback|. Returns nullptr
94   // if a Channel for |channel_id| already exists.
95   //
96   // The link MUST not be closed when this is called.
97   Channel::WeakPtr OpenFixedChannel(ChannelId channel_id);
98 
99   // Opens a dynamic channel to the requested |psm| with the preferred
100   // parameters |params| and returns a channel asynchronously via |callback|.
101   //
102   // The link MUST not be closed when this is called.
103   void OpenChannel(Psm psm, ChannelParameters params, ChannelCallback callback);
104 
105   // Takes ownership of |packet| for PDU processing and routes it to its target
106   // channel. This must be called on this object's creation thread.
107   //
108   // The link MUST not be closed when this is called.
109   void HandleRxPacket(hci::ACLDataPacketPtr packet);
110 
111   // Called by l2cap::Channel when a packet is available.
112   void OnOutboundPacketAvailable();
113 
114   // Requests a security upgrade using the registered security upgrade callback.
115   // Invokes the |callback| argument with the result of the operation.
116   //
117   // Has no effect if the link is closed.
118   void UpgradeSecurity(sm::SecurityLevel level, sm::ResultFunction<> callback);
119 
120   // Assigns the security level of this link and resolves pending security
121   // upgrade requests. Has no effect if the link is closed.
122   void AssignSecurityProperties(const sm::SecurityProperties& security);
123 
124   // Send a Connection Parameter Update Request on the LE signaling channel.
125   // When the Connection Parameter Update Response is received, |request_cb|
126   // will be called with the result, |accepted|. NOTE: the local Host must be an
127   // LE peripheral.
128   void SendConnectionParameterUpdateRequest(
129       hci_spec::LEPreferredConnectionParameters params,
130       ConnectionParameterUpdateRequestCallback request_cb);
131 
132   // Request a change of this link's ACL priority to |priority|.
133   // |channel| must indicate the channel making the request, which must be
134   // alive. |callback| will be called with the result of the request. The
135   // request will fail if |priority| conflicts with another channel's priority
136   // or the controller does not support changing the ACL priority.
137   //
138   // Requests are queued and handled sequentially in order to prevent race
139   // conditions.
140   void RequestAclPriority(
141       Channel::WeakPtr channel,
142       pw::bluetooth::AclPriority priority,
143       fit::callback<void(fit::result<fit::failed>)> callback);
144 
145   // Sets an automatic flush timeout with duration |flush_timeout|. |callback|
146   // will be called with the result of the operation. This is only supported if
147   // the link type is kACL (BR/EDR). |flush_timeout| must be in the range [1ms -
148   // hci_spec::kMaxAutomaticFlushTimeoutDuration]. A flush timeout of
149   // pw::chrono::SystemClock::duration::max() indicates an infinite flush
150   // timeout (no automatic flush), the default.
151   void SetBrEdrAutomaticFlushTimeout(
152       pw::chrono::SystemClock::duration flush_timeout,
153       hci::ResultCallback<> callback);
154 
155   // Attach LogicalLink's inspect node as a child of |parent| with the given
156   // |name|.
157   void AttachInspect(inspect::Node& parent, std::string name);
158 
159   // Assigns the link error callback to be invoked when a channel signals a link
160   // error.
161   void set_error_callback(fit::closure callback);
162 
163   // Assigns the security upgrade delegate for this link.
164   void set_security_upgrade_callback(SecurityUpgradeCallback callback);
165 
166   // Assigns the callback to be invoked when a valid Connection Parameter Update
167   // Request is received on the signaling channel.
168   void set_connection_parameter_update_callback(
169       LEConnectionParameterUpdateCallback callback);
170 
security()171   const sm::SecurityProperties security() { return security_; }
172 
173   using WeakPtr = WeakSelf<LogicalLink>::WeakPtr;
GetWeakPtr()174   WeakPtr GetWeakPtr() { return weak_self_.GetWeakPtr(); }
175 
176   // ConnectionInterface overrides:
handle()177   hci_spec::ConnectionHandle handle() const override { return handle_; }
type()178   bt::LinkType type() const override { return type_; }
179   std::unique_ptr<hci::ACLDataPacket> GetNextOutboundPacket() override;
180   bool HasAvailablePacket() const override;
181 
182  private:
183   friend class ChannelImpl;
184 
185   // Returns true if |id| is valid and supported by the peer.
186   bool AllowsFixedChannel(ChannelId id);
187 
188   // Called by ChannelImpl::Deactivate(). Removes the channel from the given
189   // link. Calls |removed_cb| when the channel no longer exists.
190   void RemoveChannel(Channel* chan, fit::closure removed_cb);
191 
192   // Called by ChannelImpl::SignalLinkError() to disconnect all channels then
193   // signal an error to the lower layers (usually GAP, to request a link
194   // disconnection). Has no effect if the link is closed.
195   void SignalError();
196 
197   // If the service identified by |psm| can be opened, return a function to
198   // complete the channel open for a newly-opened DynamicChannel. Otherwise,
199   // return nullptr.
200   //
201   // This MUST not be called on a closed link.
202   std::optional<DynamicChannelRegistry::ServiceInfo> OnServiceRequest(Psm psm);
203 
204   // Called by |dynamic_registry_| when the peer requests the closure of a
205   // dynamic channel using a signaling PDU.
206   //
207   // This MUST not be called on a closed link.
208   void OnChannelDisconnectRequest(const DynamicChannel* dyn_chan);
209 
210   // Given a newly-opened dynamic channel as reported by this link's
211   // DynamicChannelRegistry, create a ChannelImpl for it to carry user data,
212   // then pass a pointer to it through |open_cb|. If |dyn_chan| is null, then
213   // pass nullptr into |open_cb|.
214   //
215   // This MUST not be called on a closed link.
216   void CompleteDynamicOpen(const DynamicChannel* dyn_chan,
217                            ChannelCallback open_cb);
218 
219   // Send an Information Request signaling packet of type Fixed Channels
220   // Supported.
221   void SendFixedChannelsSupportedInformationRequest();
222 
223   // Handler for Information Response signaling packet. This is used to handle
224   // the Fixed Channels Supported information response, which indicates which
225   // fixed channels the peer supports (Core Spec v5.1, Vol 3, Part A, Sec 4.13).
226   // Except for the signaling channels, fixed channels may not be created until
227   // this response has been received.
228   // TODO(fxbug.dev/42119997): save fixed channels mask and use to verify opened
229   // fixed channel ids are supported
230   void OnRxFixedChannelsSupportedInfoRsp(
231       const BrEdrCommandHandler::InformationResponse& rsp);
232 
233   // Start serving Connection Parameter Update Requests on the LE signaling
234   // channel.
235   void ServeConnectionParameterUpdateRequest();
236 
237   // Handler called when a Connection Parameter Update Request is received on
238   // the LE signaling channel.
239   void OnRxConnectionParameterUpdateRequest(
240       uint16_t interval_min,
241       uint16_t interval_max,
242       uint16_t peripheral_latency,
243       uint16_t timeout_multiplier,
244       LowEnergyCommandHandler::ConnectionParameterUpdateResponder* responder);
245 
246   // Processes the next ACL priority request in the  |pending_acl_requests_|
247   // queue. In order to optimize radio performance, ACL priority is downgraded
248   // whenever possible (i.e. when no more channels are requesting high
249   // priority).
250   void HandleNextAclPriorityRequest();
251 
252   // Return true if |current_channel_|'s next packet is part of a PDU that is
253   // already in the process of being sent
254   bool IsNextPacketContinuingFragment() const;
255 
256   // Round robins through channels in logical link to get next packet to send
257   // Returns nullptr if there are no connections with pending packets
258   void RoundRobinChannels();
259 
260   pw::async::Dispatcher& pw_dispatcher_;
261 
262   sm::SecurityProperties security_;
263 
264   // Information about the underlying controller logical link.
265   hci_spec::ConnectionHandle handle_;
266   bt::LinkType type_;
267   pw::bluetooth::emboss::ConnectionRole role_;
268 
269   // Maximum number of bytes that should be allowed in a ACL data packet,
270   // excluding the header
271   uint16_t max_acl_payload_size_;
272 
273   // The duration after which BR/EDR packets are flushed from the controller.
274   // By default, the flush timeout is pw::chrono::SystemClock::duration::max()
275   // (no automatic flush).
276   UintInspectable<pw::chrono::SystemClock::duration> flush_timeout_;
277 
278   fit::closure link_error_cb_;
279 
280   SecurityUpgradeCallback security_callback_;
281 
282   LEConnectionParameterUpdateCallback connection_parameter_update_callback_;
283 
284   // No data packets are processed once this gets set to true.
285   bool closed_;
286 
287   // Recombiner is always accessed on the L2CAP thread.
288   Recombiner recombiner_;
289 
290   // Channels that were created on this link. Channels notify the link for
291   // removal when deactivated.
292   using ChannelMap =
293       std::unordered_map<ChannelId, std::unique_ptr<ChannelImpl>>;
294   ChannelMap channels_;
295 
296   // Round robin iterator for sending packets from channels
297   ChannelMap::iterator current_channel_;
298 
299   // Channel that Logical Link is currently sending PDUs from
300   ChannelImpl::WeakPtr current_pdus_channel_;
301 
302   // Manages the L2CAP signaling channel on this logical link. Depending on
303   // |type_| this will either implement the LE or BR/EDR signaling commands.
304   std::unique_ptr<SignalingChannel> signaling_channel_;
305 
306   // Stores packets that have been received on a currently closed channel. We
307   // buffer these for fixed channels so that the data is available when the
308   // channel is opened.
309   using PendingPduMap = std::unordered_map<ChannelId, std::list<PDU>>;
310   PendingPduMap pending_pdus_;
311 
312   struct PendingAclRequest {
313     Channel::WeakPtr channel;
314     pw::bluetooth::AclPriority priority;
315     fit::callback<void(fit::result<fit::failed>)> callback;
316   };
317   std::queue<PendingAclRequest> pending_acl_requests_;
318 
319   // The current ACL priority of this link.
320   pw::bluetooth::AclPriority acl_priority_ =
321       pw::bluetooth::AclPriority::kNormal;
322 
323   // Dynamic channels opened with the remote. The registry is destroyed and all
324   // procedures terminated when this link gets closed.
325   std::unique_ptr<DynamicChannelRegistry> dynamic_registry_;
326 
327   hci::AclDataChannel* acl_data_channel_;
328   hci::CommandChannel* cmd_channel_;
329 
330   // Search function for inbound service requests. Returns handler that accepts
331   // opened channels.
332   QueryServiceCallback query_service_cb_;
333 
334   struct InspectProperties {
335     inspect::Node node;
336     inspect::Node channels_node;
337     inspect::StringProperty handle;
338     inspect::StringProperty link_type;
339   };
340   InspectProperties inspect_properties_;
341 
342   A2dpOffloadManager& a2dp_offload_manager_;
343 
344   WeakSelf<hci::AclDataChannel::ConnectionInterface> weak_conn_interface_;
345   WeakSelf<LogicalLink> weak_self_;
346 
347   BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(LogicalLink);
348 };
349 
350 }  // namespace bt::l2cap::internal
351