// 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 "recombiner.h"

#include <zircon/assert.h>

#include "src/connectivity/bluetooth/core/bt-host/common/log.h"

namespace bt {
namespace l2cap {
namespace {

const BasicHeader& GetBasicHeader(const hci::ACLDataPacket& fragment) {
  ZX_DEBUG_ASSERT(fragment.packet_boundary_flag() !=
                  hci::ACLPacketBoundaryFlag::kContinuingFragment);
  return fragment.view().payload<BasicHeader>();
}

}  // namespace

Recombiner::Recombiner() : ready_(false), frame_length_(0u), cur_length_(0u) {}

bool Recombiner::AddFragment(hci::ACLDataPacketPtr&& fragment) {
  ZX_DEBUG_ASSERT(fragment);
  TRACE_DURATION("bluetooth", "Recombiner::AddFragment");

  if (ready())
    return false;

  if (empty()) {
    if (!ProcessFirstFragment(*fragment))
      return false;
    ZX_DEBUG_ASSERT(!empty());
  } else {
    if (fragment->packet_boundary_flag() != hci::ACLPacketBoundaryFlag::kContinuingFragment) {
      bt_log(SPEW, "l2cap", "expected continuing fragment!");
      return false;
    }

    if (cur_length_ + fragment->view().payload_size() > frame_length_) {
      bt_log(SPEW, "l2cap", "continuing fragment too long!");
      return false;
    }
  }

  cur_length_ += fragment->view().payload_size();
  if (frame_length_ == cur_length_) {
    // The PDU is complete.
    ready_ = true;
  }
#ifndef NTRACE
  else {
    trace_flow_id_t flow_id = TRACE_NONCE();
    TRACE_FLOW_BEGIN("bluetooth", "Recombiner::AddFragment packet fragment", flow_id);
    trace_ids_.push_back(flow_id);
  }
#endif

  pdu_->AppendFragment(std::move(fragment));
  return true;
}

bool Recombiner::Release(PDU* out_pdu) {
  TRACE_DURATION("bluetooth", "Recombiner::Release");
  if (empty() || !ready())
    return false;

#ifndef NTRACE
  if (TRACE_ENABLED()) {
    for (auto flow_id : trace_ids_) {
      TRACE_FLOW_END("bluetooth", "Recombiner::AddFragment packet fragment", flow_id);
    }
    trace_ids_.clear();
  }
#endif

  ZX_DEBUG_ASSERT(out_pdu);

  *out_pdu = std::move(*pdu_);
  Drop();

  return true;
}

void Recombiner::Drop() {
  ready_ = false;
  frame_length_ = 0u;
  cur_length_ = 0u;
  pdu_.reset();
}

bool Recombiner::ProcessFirstFragment(const hci::ACLDataPacket& fragment) {
  ZX_DEBUG_ASSERT(!ready());
  ZX_DEBUG_ASSERT(!frame_length_);
  ZX_DEBUG_ASSERT(!cur_length_);

  // The first fragment needs to at least contain the Basic L2CAP header and
  // should not be a continuation fragment.
  if (fragment.packet_boundary_flag() == hci::ACLPacketBoundaryFlag::kContinuingFragment ||
      fragment.view().payload_size() < sizeof(BasicHeader)) {
    bt_log(SPEW, "l2cap", "bad first fragment");
    return false;
  }

  uint16_t frame_length = le16toh(GetBasicHeader(fragment).length) + sizeof(BasicHeader);

  if (fragment.view().payload_size() > frame_length) {
    bt_log(SPEW, "l2cap", "fragment too long!");
    return false;
  }

  pdu_ = PDU();
  frame_length_ = frame_length;

  return true;
}

}  // namespace l2cap
}  // namespace bt
