// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_L2CAP_FRAGMENTER_H_
#define SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_L2CAP_FRAGMENTER_H_

#include <fbl/macros.h>

#include "src/connectivity/bluetooth/core/bt-host/common/byte_buffer.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/hci.h"
#include "src/connectivity/bluetooth/core/bt-host/l2cap/pdu.h"

namespace bt::l2cap {

enum class FrameCheckSequenceOption {
  kNoFcs,      // FCS is not appended to the L2CAP frame
  kIncludeFcs  // FCS is appended to the L2CAP frame
};

// Represents an unfragmented view of a complete L2CAP frame, used to construct PDUs. Unlike PDU,
// this does not own its underlying data and is read-only. To avoid extraneous copies, the only way
// to access the view is to perform a copy from a slice of the view.
class OutboundFrame final {
 public:
  OutboundFrame(ChannelId channel_id, const ByteBuffer& data, FrameCheckSequenceOption fcs_option);

  // Returns the total size of the frame including the L2CAP Basic Header and Information payload.
  [[nodiscard]] size_t size() const;

  // Fills |fragment_payload| with frame data starting at |offset| into the frame, up to the
  // fragment's capacity or the end of this frame, whichever comes first.
  void WriteToFragment(MutableBufferView fragment_payload, size_t offset);

 private:
  using BasicHeaderBuffer = StaticByteBuffer<sizeof(BasicHeader)>;
  using FrameCheckSequenceBuffer = StaticByteBuffer<sizeof(FrameCheckSequence)>;

  bool include_fcs() const { return fcs_option_ == FrameCheckSequenceOption::kIncludeFcs; }

  // Build wire representation of Basic L2CAP header for this frame.
  BasicHeaderBuffer MakeBasicHeader() const;

  // Build wire representation of Frame Check Sequence for this frame.
  // Used to initialize |fcs_|. All other fields must have already been initialized.
  FrameCheckSequenceBuffer MakeFcs() const;

  const ChannelId channel_id_;
  const BufferView data_;
  const FrameCheckSequenceOption fcs_option_;
  const std::optional<FrameCheckSequenceBuffer> fcs_;

  DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(OutboundFrame);
};

// A Fragmenter is used to construct L2CAP PDUs composed of fragments that can
// be sent over the HCI ACL data channel. This is intended for building PDUs
// that will be sent in the host-to-controller direction only.
//
// Each instance of Fragmenter is intended to operate on a single logical link.
//
// THREAD-SAFETY:
//
// This class is not thread-safe. External locking should be provided if an
// instance will be accessed on multiple threads.
class Fragmenter final {
 public:
  // |max_acl_payload_size| is the maximum number of bytes that should be
  // allowed in a ACL data packet, exluding the header. |connection_handle|
  // represents the logical link that this Fragmenter operates on.
  //
  // NOTE: |max_acl_payload_size| is required by the spec to be at least 27 (see
  // Core Spec v5.0, Vol 2, Part E, Section 5.4.2). We do not enforce this here
  // as unit tests are allowed to pass a smaller number.
  Fragmenter(hci::ConnectionHandle connection_handle,
             uint16_t max_acl_payload_size = hci::kMaxACLPayloadSize);

  void set_max_acl_payload_size(size_t value) { max_acl_payload_size_ = value; }

  // Constructs and returns a PDU to be sent over the L2CAP channel |channel_id|. |data| will be
  // treated as the Information payload of a B-frame, i.e. the PDU will contain:
  //
  //   <Basic L2CAP header><data>[FCS]
  //
  // All L2CAP frames have a Basic L2CAP header and optionally an FCS footer and can be constructed
  // using this method.
  //
  // If |flushable| is true, then this will build an automatically flushable L2CAP PDU.
  // Automatically flushable packets are sent over ACL-U logical links based on the setting of an
  // automatic flush timer. Only non-automatically flushable PDUs can be sent over LE-U links (see
  // Core Spec v5.0, Vol 2, Part E, Section 5.4.2).
  [[nodiscard]] PDU BuildFrame(ChannelId channel_id, const ByteBuffer& data,
                               FrameCheckSequenceOption fcs_option, bool flushable = false) const;

 private:
  hci::ConnectionHandle connection_handle_;
  size_t max_acl_payload_size_;

  DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(Fragmenter);
};

}  // namespace bt::l2cap

#endif  // SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_L2CAP_FRAGMENTER_H_
