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

#include <zircon/assert.h>

#include "slab_allocators.h"

namespace bt {
namespace hci {
namespace slab_allocators {

// Slab-allocator traits for command packets.
using LargeCommandTraits = PacketTraits<CommandHeader, kLargeControlPacketSize,
                                        kNumLargeControlPackets>;
using SmallCommandTraits = PacketTraits<CommandHeader, kSmallControlPacketSize,
                                        kNumSmallControlPackets>;

// Slab-allocator traits for event packets. Since event packets are only
// received (and not sent) and because the packet size cannot be determined
// before the contents are read from the underlying channel, CommandChannel
// always allocates the largest possible buffer for events. Thus, a small buffer
// allocator is not needed.
using EventTraits =
    PacketTraits<EventHeader, kLargeControlPacketSize, kNumLargeControlPackets>;

using LargeCommandAllocator = fbl::SlabAllocator<LargeCommandTraits>;
using SmallCommandAllocator = fbl::SlabAllocator<SmallCommandTraits>;
using EventAllocator = fbl::SlabAllocator<EventTraits>;

}  // namespace slab_allocators

namespace {

std::unique_ptr<CommandPacket> NewCommandPacket(size_t payload_size) {
  ZX_DEBUG_ASSERT(payload_size <= slab_allocators::kLargeControlPayloadSize);

  if (payload_size <= slab_allocators::kSmallControlPayloadSize) {
    auto buffer = slab_allocators::SmallCommandAllocator::New(payload_size);
    if (buffer)
      return buffer;

    // We failed to allocate a small buffer; fall back to the large allocator.
  }

  return slab_allocators::LargeCommandAllocator::New(payload_size);
}

// Returns true and populates the |out_code| field with the status parameter.
// Returns false if |event|'s payload is too small to hold a T. T must have a
// |status| member of type hci::StatusCode for this to compile.
template <typename T>
bool StatusCodeFromEvent(const EventPacket& event, hci::StatusCode* out_code) {
  ZX_DEBUG_ASSERT(out_code);

  if (event.view().payload_size() < sizeof(T))
    return false;

  *out_code = event.view().payload<T>().status;
  return true;
}

// Specialization for the CommandComplete event.
template <>
bool StatusCodeFromEvent<CommandCompleteEventParams>(
    const EventPacket& event, hci::StatusCode* out_code) {
  ZX_DEBUG_ASSERT(out_code);

  const auto* params = event.return_params<SimpleReturnParams>();
  if (!params)
    return false;

  *out_code = params->status;
  return true;
}

}  // namespace

// static
std::unique_ptr<CommandPacket> CommandPacket::New(OpCode opcode,
                                                  size_t payload_size) {
  auto packet = NewCommandPacket(payload_size);
  if (!packet)
    return nullptr;

  packet->WriteHeader(opcode);
  return packet;
}

void CommandPacket::WriteHeader(OpCode opcode) {
  mutable_view()->mutable_header()->opcode = htole16(opcode);
  mutable_view()->mutable_header()->parameter_total_size =
      view().payload_size();
}

// static
std::unique_ptr<EventPacket> EventPacket::New(size_t payload_size) {
  return slab_allocators::EventAllocator::New(payload_size);
}

bool EventPacket::ToStatusCode(StatusCode* out_code) const {
#define CASE_EVENT_STATUS(event_name) \
  case k##event_name##EventCode:      \
    return StatusCodeFromEvent<event_name##EventParams>(*this, out_code)

  switch (event_code()) {
    CASE_EVENT_STATUS(CommandComplete);
    CASE_EVENT_STATUS(CommandStatus);
    CASE_EVENT_STATUS(ConnectionComplete);
    CASE_EVENT_STATUS(DisconnectionComplete);
    CASE_EVENT_STATUS(InquiryComplete);
    CASE_EVENT_STATUS(EncryptionChange);
    CASE_EVENT_STATUS(RemoteNameRequestComplete);
    CASE_EVENT_STATUS(ReadRemoteVersionInfoComplete);
    CASE_EVENT_STATUS(ReadRemoteSupportedFeaturesComplete);
    CASE_EVENT_STATUS(ReadRemoteExtendedFeaturesComplete);

      // TODO(armansito): Complete this list.

    default:
      ZX_PANIC("event (%#.2x) not implemented!", event_code());
      break;
  }
  return false;

#undef CASE_EVENT_STATUS
}

Status EventPacket::ToStatus() const {
  StatusCode code;
  if (!ToStatusCode(&code)) {
    return Status(HostError::kPacketMalformed);
  }
  return Status(code);
}

void EventPacket::InitializeFromBuffer() {
  mutable_view()->Resize(view().header().parameter_total_size);
}

}  // namespace hci
}  // namespace bt

DECLARE_STATIC_SLAB_ALLOCATOR_STORAGE(
    bt::hci::slab_allocators::LargeCommandTraits,
    bt::hci::slab_allocators::kMaxNumSlabs, true);
DECLARE_STATIC_SLAB_ALLOCATOR_STORAGE(
    bt::hci::slab_allocators::SmallCommandTraits,
    bt::hci::slab_allocators::kMaxNumSlabs, true);
DECLARE_STATIC_SLAB_ALLOCATOR_STORAGE(bt::hci::slab_allocators::EventTraits,
                                      bt::hci::slab_allocators::kMaxNumSlabs,
                                      true);
