• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "pw_bluetooth_sapphire/internal/host/common/assert.h"
19 #include "pw_bluetooth_sapphire/internal/host/common/byte_buffer.h"
20 #include "pw_bluetooth_sapphire/internal/host/l2cap/l2cap_defs.h"
21 
22 namespace bt::l2cap::internal {
23 
24 // The interface between a Channel, and the module implementing the
25 // mode-specific transmit logic. The primary purposes of an TxEngine are a) to
26 // transform SDUs into PDUs, and b) to transmit/retransmit the PDUs at the
27 // appropriate time. See Bluetooth Core Spec v5.0, Volume 3, Part A, Sec 2.4,
28 // "Modes of Operation" for more information about the possible modes.
29 class TxEngine {
30  public:
31   // Type defining the callback that a TxEngine uses to deliver a PDU to lower
32   // layers. The callee may assume that the ByteBufferPtr owns an instance of a
33   // DynamicByteBuffer or SlabBuffer.
34   using SendFrameCallback = fit::function<void(ByteBufferPtr pdu)>;
35 
36   // Creates a transmit engine, which will invoke |send_frame_callback|
37   // when a PDU is ready for transmission. This callback may be invoked
38   // synchronously from QueueSdu(), as well as asynchronously (e.g. when a
39   // retransmission timer expires).
40   //
41   // NOTE: The user of this class must ensure that a synchronous invocation of
42   // |send_frame_callback| does not deadlock. E.g., the callback must not
43   // attempt to lock the same mutex as the caller of QueueSdu().
TxEngine(ChannelId channel_id,uint16_t max_tx_sdu_size,SendFrameCallback send_frame_callback)44   TxEngine(ChannelId channel_id,
45            uint16_t max_tx_sdu_size,
46            SendFrameCallback send_frame_callback)
47       : channel_id_(channel_id),
48         max_tx_sdu_size_(max_tx_sdu_size),
49         send_frame_callback_(std::move(send_frame_callback)) {
50     BT_ASSERT(max_tx_sdu_size_);
51   }
52   virtual ~TxEngine() = default;
53 
54   // Queues an SDU for transmission, returning true on success.
55   //
56   // * As noted in the ctor documentation, this _may_ result in a synchronous
57   //   invocation of |send_frame_callback_|.
58   // * It is presumed that the ByteBufferPtr owns an instance of a
59   //   DynamicByteBuffer or SlabBuffer.
60   virtual bool QueueSdu(ByteBufferPtr) = 0;
61 
62  protected:
63   const ChannelId channel_id_;
64   const uint16_t max_tx_sdu_size_;
65   // Invoked when a PDU is ready for transmission.
66   const SendFrameCallback send_frame_callback_;
67 
68  private:
69   BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(TxEngine);
70 };
71 
72 }  // namespace bt::l2cap::internal
73