// Copyright 2018 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 "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/l2cap/bredr_signaling_channel.h"

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

namespace bt::l2cap::internal {

BrEdrSignalingChannel::BrEdrSignalingChannel(
    Channel::WeakPtr chan,
    pw::bluetooth::emboss::ConnectionRole role,
    pw::async::Dispatcher& dispatcher)
    : SignalingChannel(std::move(chan), role, dispatcher) {
  set_mtu(kDefaultMTU);

  // Add default handler for incoming Echo Request commands.
  ServeRequest(kEchoRequest,
               [](const ByteBuffer& req_payload, Responder* responder) {
                 responder->Send(req_payload);
               });
}

bool BrEdrSignalingChannel::TestLink(const ByteBuffer& data, DataCallback cb) {
  return SendRequest(
      kEchoRequest,
      data,
      [cb = std::move(cb)](Status status, const ByteBuffer& rsp_payload) {
        if (status == Status::kSuccess) {
          cb(rsp_payload);
        } else {
          cb(BufferView());
        }
        return ResponseHandlerAction::kCompleteOutboundTransaction;
      });
}

void BrEdrSignalingChannel::DecodeRxUnit(ByteBufferPtr sdu,
                                         const SignalingPacketHandler& cb) {
  // "Multiple commands may be sent in a single C-frame over Fixed Channel CID
  // 0x0001 (ACL-U) (v5.0, Vol 3, Part A, Section 4)"
  BT_DEBUG_ASSERT(sdu);
  if (sdu->size() < sizeof(CommandHeader)) {
    bt_log(DEBUG, "l2cap-bredr", "sig: dropped malformed ACL signaling packet");
    return;
  }

  size_t sdu_offset = 0;
  while (sdu_offset + sizeof(CommandHeader) <= sdu->size()) {
    const auto header_data = sdu->view(sdu_offset, sizeof(CommandHeader));
    SignalingPacket packet(&header_data);

    uint16_t expected_payload_length = le16toh(packet.header().length);
    size_t remaining_sdu_length =
        sdu->size() - sdu_offset - sizeof(CommandHeader);
    if (remaining_sdu_length < expected_payload_length) {
      bt_log(DEBUG,
             "l2cap-bredr",
             "sig: expected more bytes (%zu < %u); drop",
             remaining_sdu_length,
             expected_payload_length);
      SendCommandReject(
          packet.header().id, RejectReason::kNotUnderstood, BufferView());
      return;
    }

    const auto packet_data =
        sdu->view(sdu_offset, sizeof(CommandHeader) + expected_payload_length);
    cb(SignalingPacket(&packet_data, expected_payload_length));

    sdu_offset += packet_data.size();
  }

  if (sdu_offset != sdu->size()) {
    bt_log(DEBUG,
           "l2cap-bredr",
           "sig: incomplete packet header "
           "(expected: %zu, left: %zu)",
           sizeof(CommandHeader),
           sdu->size() - sdu_offset);
  }
}

bool BrEdrSignalingChannel::IsSupportedResponse(CommandCode code) const {
  switch (code) {
    case kCommandRejectCode:
    case kConnectionResponse:
    case kConfigurationResponse:
    case kDisconnectionResponse:
    case kEchoResponse:
    case kInformationResponse:
      return true;
  }

  // Other response-type commands are for AMP/LE and are not supported.
  return false;
}

}  // namespace bt::l2cap::internal
