// 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.

#include "fragmenter.h"

#include <endian.h>

#include "garnet/drivers/bluetooth/lib/hci/acl_data_packet.h"
#include "garnet/drivers/bluetooth/lib/l2cap/l2cap_defs.h"
#include "lib/fxl/logging.h"

namespace btlib {
namespace l2cap {

Fragmenter::Fragmenter(hci::ConnectionHandle connection_handle,
                       uint16_t max_acl_payload_size)
    : connection_handle_(connection_handle),
      max_acl_payload_size_(max_acl_payload_size) {
  FXL_DCHECK(connection_handle_);
  FXL_DCHECK(connection_handle_ <= hci::kConnectionHandleMax);
  FXL_DCHECK(max_acl_payload_size_);
  FXL_DCHECK(max_acl_payload_size_ >= sizeof(BasicHeader));
}

// NOTE(armansito): The following method copies the contents of |data| into ACL
// data packets. This copying is currently necessary because the complete HCI
// frame (ACL header + payload fragment) we send over the channel to the bt-hci
// driver need to be stored contiguously before the call to zx_channel_write.
// Plus, we perform the HCI flow-control on the host-stack side which requires
// ACL packets to be buffered.
//
// As our future driver architecture will remove the IPC between the HCI driver
// and the host stack, our new interface could support scatter-gather for the
// header and the payload. Then, the bt-hci driver could read the payload
// fragment directly out of |data| and we would only construct the headers,
// removing the extra copy.
//
// * Current theoretical number of data copies:
//     1. service -> L2CAP channel
//     2. channel -> fragmenter ->(move) HCI layer
//     3. HCI layer ->(zx_channel_write)
//     4. (zx_channel_read)-> bt-hci driver
//     5. bt-hci driver -> transport driver
//
// * Potential number of data copies
//     1. service -> L2CAP channel
//     2. channel -> fragmenter ->(move) HCI layer ->(move) bt-hci driver
//     if buffering is needed:
//       3. bt-hci driver -> transport driver
PDU Fragmenter::BuildBasicFrame(ChannelId channel_id,
                                const common::ByteBuffer& data,
                                bool flushable) {
  FXL_DCHECK(data.size() < kMaxBasicFramePayloadSize);
  FXL_DCHECK(channel_id);

  const size_t frame_size = data.size() + sizeof(BasicHeader);
  const size_t num_fragments = frame_size / max_acl_payload_size_ +
                               (frame_size % max_acl_payload_size_ ? 1 : 0);

  PDU pdu;
  size_t processed = 0;
  for (size_t i = 0; i < num_fragments; i++) {
    FXL_DCHECK(frame_size > processed);

    const size_t fragment_size = std::min(
        frame_size - processed, static_cast<size_t>(max_acl_payload_size_));
    auto pbf =
        (i ? hci::ACLPacketBoundaryFlag::kContinuingFragment
           : (flushable ? hci::ACLPacketBoundaryFlag::kFirstFlushable
                        : hci::ACLPacketBoundaryFlag::kFirstNonFlushable));

    // TODO(armansito): allow passing Active Slave Broadcast flag when we
    // support it.
    auto acl_packet = hci::ACLDataPacket::New(
        connection_handle_, pbf, hci::ACLBroadcastFlag::kPointToPoint,
        fragment_size);
    FXL_DCHECK(acl_packet);

    auto mut_payload = acl_packet->mutable_view()->mutable_payload_data();

    // Special-case the first fragment separately as it contains the basic
    // header.
    if (i == 0) {
      auto* header = acl_packet->mutable_view()->mutable_payload<BasicHeader>();

      // Write the Basic L2CAP header.
      header->length = htole16(static_cast<uint16_t>(data.size()));
      header->channel_id = htole16(channel_id);

      mut_payload.Write(data.data(), fragment_size - sizeof(BasicHeader),
                        sizeof(BasicHeader));
    } else {
      mut_payload.Write(data.data() + processed - sizeof(BasicHeader),
                        fragment_size);
    }

    processed += fragment_size;

    pdu.AppendFragment(std::move(acl_packet));
  }

  // The PDU should have been completely processed if we got here.
  FXL_DCHECK(processed == frame_size);

  return pdu;
}

}  // namespace l2cap
}  // namespace btlib
