// Copyright 2019 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 "test_packets.h"

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

namespace bt {
namespace testing {

// clang-format off
#define COMMAND_STATUS_RSP(opcode, statuscode)                       \
CreateStaticByteBuffer(hci::kCommandStatusEventCode, 0x04,         \
                                (statuscode), 0xF0,                 \
                                LowerBits((opcode)), UpperBits((opcode)))
// clang-format on

DynamicByteBuffer AcceptConnectionRequestPacket(DeviceAddress address) {
  const auto addr = address.value().bytes();
  return DynamicByteBuffer(CreateStaticByteBuffer(
      LowerBits(hci::kAcceptConnectionRequest), UpperBits(hci::kAcceptConnectionRequest),
      0x07,                                                  // parameter_total_size (7 bytes)
      addr[0], addr[1], addr[2], addr[3], addr[4], addr[5],  // peer address
      0x00                                                   // role (become master)
      ));
}

DynamicByteBuffer AuthenticationRequestedPacket(hci::ConnectionHandle conn) {
  return DynamicByteBuffer(CreateStaticByteBuffer(
      LowerBits(hci::kAuthenticationRequested), UpperBits(hci::kAuthenticationRequested),
      0x02,                             // parameter_total_size (2 bytes)
      LowerBits(conn), UpperBits(conn)  // Connection_Handle
      ));
}

DynamicByteBuffer ConnectionRequestPacket(DeviceAddress address) {
  const auto addr = address.value().bytes();
  return DynamicByteBuffer(CreateStaticByteBuffer(
      hci::kConnectionRequestEventCode,
      0x0A,  // parameter_total_size (10 byte payload)
      addr[0], addr[1], addr[2], addr[3], addr[4], addr[5],  // peer address
      0x00, 0x1F, 0x00,                                      // class_of_device (unspecified)
      0x01                                                   // link_type (ACL)
      ));
}

DynamicByteBuffer CreateConnectionPacket(DeviceAddress address) {
  auto addr = address.value().bytes();
  return DynamicByteBuffer(CreateStaticByteBuffer(
      LowerBits(hci::kCreateConnection), UpperBits(hci::kCreateConnection),
      0x0d,                                                  // parameter_total_size (13 bytes)
      addr[0], addr[1], addr[2], addr[3], addr[4], addr[5],  // peer address
      LowerBits(hci::kEnableAllPacketTypes),                 // allowable packet types
      UpperBits(hci::kEnableAllPacketTypes),                 // allowable packet types
      0x02,                                                  // page_scan_repetition_mode (R2)
      0x00,                                                  // reserved
      0x00, 0x00,                                            // clock_offset
      0x00                                                   // allow_role_switch (don't)
      ));
}

DynamicByteBuffer ConnectionCompletePacket(DeviceAddress address, hci::ConnectionHandle conn) {
  auto addr = address.value().bytes();
  return DynamicByteBuffer(CreateStaticByteBuffer(
      hci::kConnectionCompleteEventCode,
      0x0B,                              // parameter_total_size (11 byte payload)
      hci::StatusCode::kSuccess,         // status
      LowerBits(conn), UpperBits(conn),  // Little-Endian Connection_handle
      addr[0], addr[1], addr[2], addr[3], addr[4], addr[5],  // peer address
      0x01,                                                  // link_type (ACL)
      0x00                                                   // encryption not enabled
      ));
}

DynamicByteBuffer DisconnectPacket(hci::ConnectionHandle conn, hci::StatusCode reason) {
  return DynamicByteBuffer(CreateStaticByteBuffer(
      LowerBits(hci::kDisconnect), UpperBits(hci::kDisconnect),
      0x03,                              // parameter_total_size (3 bytes)
      LowerBits(conn), UpperBits(conn),  // Little-Endian Connection_handle
      reason                             // Reason
      ));
}

DynamicByteBuffer DisconnectStatusResponsePacket() {
  return DynamicByteBuffer(COMMAND_STATUS_RSP(hci::kDisconnect, hci::StatusCode::kSuccess));
}

DynamicByteBuffer DisconnectionCompletePacket(hci::ConnectionHandle conn, hci::StatusCode reason) {
  return DynamicByteBuffer(CreateStaticByteBuffer(
      hci::kDisconnectionCompleteEventCode,
      0x04,                              // parameter_total_size (4 bytes)
      hci::StatusCode::kSuccess,         // status
      LowerBits(conn), UpperBits(conn),  // Little-Endian Connection_handle
      reason                             // Reason
      ));
}

DynamicByteBuffer EncryptionChangeEventPacket(hci::StatusCode status_code,
                                              hci::ConnectionHandle conn,
                                              hci::EncryptionStatus encryption_enabled) {
  return DynamicByteBuffer(CreateStaticByteBuffer(
      hci::kEncryptionChangeEventCode,
      0x04,                                     // parameter_total_size (4 bytes)
      status_code,                              // status
      LowerBits(conn), UpperBits(conn),         // Little-Endian Connection_Handle
      static_cast<uint8_t>(encryption_enabled)  // Encryption_Enabled
      ));
}

DynamicByteBuffer NumberOfCompletedPacketsPacket(hci::ConnectionHandle conn, uint16_t num_packets) {
  return DynamicByteBuffer(CreateStaticByteBuffer(
      0x13, 0x05,  // Number Of Completed Packet HCI event header, parameters length
      0x01,        // Number of handles
      LowerBits(conn), UpperBits(conn), LowerBits(num_packets), UpperBits(num_packets)));
}

DynamicByteBuffer CommandStatusPacket(hci::OpCode op_code, hci::StatusCode status_code) {
  return DynamicByteBuffer(StaticByteBuffer(
      hci::kCommandStatusEventCode,
      0x04,  // parameter size (4 bytes)
      status_code,
      0xF0,  // number of HCI command packets allowed to be sent to controller (240)
      LowerBits(op_code), UpperBits(op_code)));
}

DynamicByteBuffer RemoteNameRequestPacket(DeviceAddress address) {
  auto addr = address.value().bytes();
  return DynamicByteBuffer(CreateStaticByteBuffer(
      LowerBits(hci::kRemoteNameRequest), UpperBits(hci::kRemoteNameRequest),
      0x0a,                                                  // parameter_total_size (10 bytes)
      addr[0], addr[1], addr[2], addr[3], addr[4], addr[5],  // peer address
      0x00,                                                  // page_scan_repetition_mode (R0)
      0x00,                                                  // reserved
      0x00, 0x00                                             // clock_offset
      ));
}

DynamicByteBuffer RemoteNameRequestCompletePacket(DeviceAddress address) {
  auto addr = address.value().bytes();
  return DynamicByteBuffer(CreateStaticByteBuffer(
      hci::kRemoteNameRequestCompleteEventCode,
      0x20,                                                  // parameter_total_size (32)
      hci::StatusCode::kSuccess,                             // status
      addr[0], addr[1], addr[2], addr[3], addr[4], addr[5],  // peer address
      'F', 'u', 'c', 'h', 's', 'i', 'a', 0xF0, 0x9F, 0x92, 0x96, 0x00, 0x14, 0x15, 0x16, 0x17, 0x18,
      0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20
      // remote name (Fuchsia 💖)
      // Everything after the 0x00 should be ignored.
      ));
}

DynamicByteBuffer ReadRemoteVersionInfoPacket(hci::ConnectionHandle conn) {
  return DynamicByteBuffer(CreateStaticByteBuffer(
      LowerBits(hci::kReadRemoteVersionInfo), UpperBits(hci::kReadRemoteVersionInfo),
      0x02,                             // Parameter_total_size (2 bytes)
      LowerBits(conn), UpperBits(conn)  // Little-Endian Connection_handle
      ));
}

DynamicByteBuffer ReadRemoteVersionInfoCompletePacket(hci::ConnectionHandle conn) {
  return DynamicByteBuffer(CreateStaticByteBuffer(
      hci::kReadRemoteVersionInfoCompleteEventCode,
      0x08,                              // parameter_total_size (8 bytes)
      hci::StatusCode::kSuccess,         // status
      LowerBits(conn), UpperBits(conn),  // Little-Endian Connection_handle
      hci::HCIVersion::k4_2,             // lmp_version
      0xE0, 0x00,                        // manufacturer_name (Google)
      0xAD, 0xDE                         // lmp_subversion (anything)
      ));
}

DynamicByteBuffer ReadRemoteSupportedFeaturesPacket(hci::ConnectionHandle conn) {
  return DynamicByteBuffer(CreateStaticByteBuffer(
      LowerBits(hci::kReadRemoteSupportedFeatures), UpperBits(hci::kReadRemoteSupportedFeatures),
      0x02,             // parameter_total_size (2 bytes)
      LowerBits(conn),  // Little-Endian Connection_handle
      UpperBits(conn)));
}

DynamicByteBuffer ReadRemoteSupportedFeaturesCompletePacket(hci::ConnectionHandle conn,
                                                            bool extended_features) {
  return DynamicByteBuffer(CreateStaticByteBuffer(
      hci::kReadRemoteSupportedFeaturesCompleteEventCode,
      0x0B,                              // parameter_total_size (11 bytes)
      hci::StatusCode::kSuccess,         // status
      LowerBits(conn), UpperBits(conn),  // Little-Endian Connection_handle
      0xFF, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, (extended_features ? 0x80 : 0x00)
      // lmp_features
      // Set: 3 slot packets, 5 slot packets, Encryption, Timing Accuracy,
      // Role Switch, Hold Mode, Sniff Mode, LE Supported
      // Extended Features if enabled
      ));
}

DynamicByteBuffer LEReadRemoteFeaturesPacket(hci::ConnectionHandle conn) {
  return DynamicByteBuffer(CreateStaticByteBuffer(
      LowerBits(hci::kLEReadRemoteFeatures), UpperBits(hci::kLEReadRemoteFeatures),
      0x02,             // parameter_total_size (2 bytes)
      LowerBits(conn),  // Little-Endian Connection_handle
      UpperBits(conn)));
}

DynamicByteBuffer LEReadRemoteFeaturesCompletePacket(hci::ConnectionHandle conn,
                                                     hci::LESupportedFeatures le_features) {
  const BufferView features(&le_features, sizeof(le_features));
  return DynamicByteBuffer(StaticByteBuffer(hci::kLEMetaEventCode,
                                            0x0c,  // parameter total size (12 bytes)
                                            hci::kLEReadRemoteFeaturesCompleteSubeventCode,
                                            hci::StatusCode::kSuccess,  // status
                                            // Little-Endian connection handle
                                            LowerBits(conn), UpperBits(conn),
                                            // bit mask of LE features
                                            features[0], features[1], features[2], features[3],
                                            features[4], features[5], features[6], features[7]));
}

DynamicByteBuffer ReadRemoteExtended1Packet(hci::ConnectionHandle conn) {
  return DynamicByteBuffer(CreateStaticByteBuffer(
      LowerBits(hci::kReadRemoteExtendedFeatures), UpperBits(hci::kReadRemoteExtendedFeatures),
      0x03,             // parameter_total_size (3 bytes)
      LowerBits(conn),  // Little-Endian Connection_handle
      UpperBits(conn),
      0x01  // page_number (1)
      ));
}

DynamicByteBuffer ReadRemoteExtended1CompletePacket(hci::ConnectionHandle conn) {
  return DynamicByteBuffer(CreateStaticByteBuffer(
      hci::kReadRemoteExtendedFeaturesCompleteEventCode,
      0x0D,                              // parameter_total_size (13 bytes)
      hci::StatusCode::kSuccess,         // status
      LowerBits(conn), UpperBits(conn),  // Little-Endian Connection_handle
      0x01,                              // page_number
      0x03,                              // max_page_number (3 pages)
      0x0F, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00
      // lmp_features (page 1)
      // Set: Secure Simple Pairing (Host Support), LE Supported (Host),
      //  SimultaneousLEAndBREDR, Secure Connections (Host Support)
      ));
}

DynamicByteBuffer ReadRemoteExtended2Packet(hci::ConnectionHandle conn) {
  return DynamicByteBuffer(CreateStaticByteBuffer(
      LowerBits(hci::kReadRemoteExtendedFeatures), UpperBits(hci::kReadRemoteExtendedFeatures),
      0x03,                              // parameter_total_size (3 bytes)
      LowerBits(conn), UpperBits(conn),  // Little-Endian Connection_handle
      0x02                               // page_number (2)
      ));
}

DynamicByteBuffer ReadRemoteExtended2CompletePacket(hci::ConnectionHandle conn) {
  return DynamicByteBuffer(CreateStaticByteBuffer(
      hci::kReadRemoteExtendedFeaturesCompleteEventCode,
      0x0D,                              // parameter_total_size (13 bytes)
      hci::StatusCode::kSuccess,         // status
      LowerBits(conn), UpperBits(conn),  // Little-Endian Connection_handle
      0x02,                              // page_number
      0x03,                              // max_page_number (3 pages)
      0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xFF, 0x00
      // lmp_features  - All the bits should be ignored.
      ));
}

}  // namespace testing
}  // namespace bt
