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

#pragma once

#include <cstddef>

#include "garnet/drivers/bluetooth/lib/common/byte_buffer.h"
#include "rfcomm.h"

namespace btlib {
namespace rfcomm {

// Defined in GSM 5.4.6.3.*.
// clang-format off
enum class MuxCommandType : uint8_t {
  kDLCParameterNegotiation      = 0b10000000,
  kTestCommand                  = 0b00100000,
  kFlowControlOnCommand         = 0b10100000,
  kFlowControlOffCommand        = 0b01100000,
  kModemStatusCommand           = 0b11100000,
  kNonSupportedCommandResponse  = 0b00010000,
  kRemotePortNegotiationCommand = 0b10010000,
  kRemoteLineStatusCommand      = 0b01010000
};
// clang-format on

// A MuxCommand represents an RFCOMM multiplexer command which is ready to be
// sent or which has been parsed from a ByteBuffer. Specifically, each
// MuxCommand can be seen as a collection of fields and their accessors, plus a
// function Write which knows how to write these fields into a buffer
// in the format defined by the RFCOMM/GSM specs.
//
// MuxCommands are used in two ways:
//  1. Parsing multiplexer commands out of a received buffer and reading their
//      fields
//  2. Constructing multiplexer commands and writing them into a buffer to send
//
// To use MuxCommands in the first way, use MuxCommand::Parse() on a received
// buffer. Check the type using command_type(), and cast the returned pointer
// to the appropriate subclass.
//
// TODO(gusss): this downcasting mechanism is non-ideal -- it is potentially
// very bug-prone. NET-1224 tracks the improvement of this mechanism.
//
// To use MuxCommands in the second way, construct the specific MuxCommand
// subtype which you are trying to send, allocate a buffer (using written_size()
// to calculate the needed size), and write into the buffer using Write().
//
// Supported commands are listed in RFCOMM 4.3.
class MuxCommand {
 public:
  // Parses a buffer and constructs the appropriate subclass of MuxCommand.
  // Users of Parse should read the resulting command type and cast the pointer
  // to the appropriate MuxCommand subclass.
  static std::unique_ptr<MuxCommand> Parse(const common::ByteBuffer& buffer);

  virtual ~MuxCommand() = default;

  // Writes this MuxCommand into |buffer|. |buffer| must be at least the size
  // indicated by written_size().
  virtual void Write(common::MutableBufferView buffer) const = 0;

  // The amount of space this command takes up when written. This is used when
  // allocating space for an RFCOMM frame which will hold a multiplexer command.
  virtual size_t written_size() const = 0;

  inline MuxCommandType command_type() const { return command_type_; }

  // The multiplexer-command-level C/R setting. This setting is described in GSM
  // 5.4.6.2.
  inline CommandResponse command_response() const { return command_response_; }

 protected:
  MuxCommand(MuxCommandType command_type, CommandResponse command_response);

  // Forms the type field octet for this multiplexer command by ORing:
  //  - the EA bit (which is always 1 for GSM/RFCOMM -- see GSM 5.4.6.1)
  //  - the C/R bit (whose value is defined in 5.4.6.2), and
  //  - the type octet for the command in question (see 5.4.6.3.*).
  inline uint8_t type_field_octet() const {
    return 1 | ((command_response_ == CommandResponse::kCommand ? 1 : 0) << 1) |
           (uint8_t)command_type_;
  }

  MuxCommandType command_type_;
  CommandResponse command_response_;
};

// This command is used to test the connection between two peers. The command
// contains an attached test pattern, which the peer must repeat back in full.
// See GSM 5.4.6.3.4.
//
// Multiplexer frames can encode an arbitrary number of length octets. In our
// implementation, the length of the pattern contained within the test command
// is limited by the system's max value of size_t.
class TestCommand : public MuxCommand {
 public:
  TestCommand(CommandResponse command_response,
              const common::ByteBuffer& test_pattern);

  // Returns nullptr if parse fails. |command_response| and |length| are
  // parameters which have already been parsed from |buffer|.
  static std::unique_ptr<TestCommand> Parse(CommandResponse command_response,
                                            size_t length,
                                            const common::ByteBuffer& buffer);

  inline common::BufferView test_pattern() const {
    return test_pattern_.view();
  }

  // MuxCommand overrides
  void Write(common::MutableBufferView buffer) const override;
  size_t written_size() const override;

 private:
  common::DynamicByteBuffer test_pattern_;
};

// This command is sent when our device is able to begin receiving messages. See
// GSM 5.4.6.3.5.
class FlowControlOnCommand : public MuxCommand {
 public:
  explicit FlowControlOnCommand(CommandResponse command_response);

  // Returns nullptr if parse fails. |command_response| is a parameter which has
  // already been parsed from |buffer|.
  static std::unique_ptr<FlowControlOnCommand> Parse(
      CommandResponse command_response);

  // MuxCommand overrides
  void Write(common::MutableBufferView buffer) const override;
  size_t written_size() const override;
};

// This command is sent when our device is not able to receive messages. See
// GSM 5.4.6.3.6.
class FlowControlOffCommand : public MuxCommand {
 public:
  explicit FlowControlOffCommand(CommandResponse command_response);

  // Returns nullptr if parse fails. |command_response| is a parameter which has
  // already been parsed from |buffer|.
  static std::unique_ptr<FlowControlOffCommand> Parse(
      CommandResponse command_response);

  // MuxCommand overrides
  void Write(common::MutableBufferView buffer) const override;
  size_t written_size() const override;
};

// These signals map to various V.24 signals as described in GSM tables 6 and 7.
struct ModemStatusCommandSignals {
  bool flow_control;
  bool ready_to_communicate;
  bool ready_to_receive;
  bool incoming_call;
  bool data_valid;
};

using BreakValue = uint8_t;
constexpr BreakValue kMinBreakValue = 0b0000;
constexpr BreakValue kMaxBreakValue = 0b1111;
constexpr BreakValue kDefaultInvalidBreakValue = 0xFF;

// This command conveys the virtual V.24 signals. See GSM 5.4.6.3.7.
class ModemStatusCommand : public MuxCommand {
 public:
  ModemStatusCommand(CommandResponse command_response, DLCI dlci,
                     ModemStatusCommandSignals signals,
                     BreakValue break_value = kDefaultInvalidBreakValue);

  // Returns nullptr if parse fails. |command_response| and |length| are
  // parameters which have already been parsed from |buffer|.
  static std::unique_ptr<ModemStatusCommand> Parse(
      CommandResponse command_response, size_t length,
      const common::ByteBuffer& buffer);

  // MuxCommand overrides
  void Write(common::MutableBufferView buffer) const override;

  size_t written_size() const override;

  inline DLCI dlci() const { return dlci_; }

  inline ModemStatusCommandSignals signals() const { return signals_; }

  // We only include a break signal if the break value is valid.
  bool has_break_signal() const {
    return break_value_ >= kMinBreakValue && break_value_ <= kMaxBreakValue;
  }

  inline BreakValue break_value() const { return break_value_; }

 private:
  DLCI dlci_;
  ModemStatusCommandSignals signals_;
  BreakValue break_value_;
};

// GSM table 12
// clang-format off
enum class Baud : uint8_t {
  k2400   = 0,
  k4800   = 1,
  k7200   = 2,
  k9600   = 3,
  k19200  = 4,
  k38400  = 5,
  k57600  = 6,
  k115200 = 7,
  k230400 = 8
};
// clang-format on
constexpr Baud kDefaultBaud = Baud::k9600;

// GSM 5.4.6.3.9 (below table 12)
enum class DataBits : uint8_t {
  k5Bits = 0,
  k6Bits = 2,
  k7Bits = 1,
  k8Bits = 3
};
constexpr DataBits kDefaultDataBits = DataBits::k8Bits;

// GSM 5.4.6.3.9 (below table 12)
// clang-format off
enum class StopBits : bool {
  k1Bit         = 0,
  k1AndHalfBits = 1
};
// clang-format on
constexpr StopBits kDefaultStopBits = StopBits::k1Bit;

// GSM 5.4.6.3.9 (below table 12)
// clang-format off
enum class ParityType : uint8_t {
  kOdd    = 0,
  kMark   = 1,
  kEven   = 2,
  kSpace  = 3
};
// clang-format on
// No default is defined in the spec, so we choose even arbitrarily.
constexpr ParityType kDefaultParityType = ParityType::kEven;
// Whether parity is on or off by default. This is not defined in the spec.
constexpr bool kDefaultParity = true;

// GSM 5.4.6.3.9 (below table 12)
// clang-format off
enum FlowControlFlags : uint8_t {
  kXonXoffInputFlag   = 1 << 0,
  kXonXoffOutputFlag  = 1 << 1,
  kRTRInputFlag       = 1 << 2,
  kRTROutputFlag      = 1 << 3,
  kRTCInputFlag       = 1 << 4,
  kRTCOutputFlag      = 1 << 5
};
// clang-format on
using FlowControlFlagsBitfield = uint8_t;
// GSM 5.4.6.3.9 (below table 12)
constexpr FlowControlFlagsBitfield kDefaultFlowControlFlags = 0;

struct RemotePortNegotiationParams {
  Baud baud;
  DataBits data_bits;
  StopBits stop_bits;
  bool parity;
  ParityType parity_type;
  FlowControlFlagsBitfield flow_control;
  uint8_t xon_character;
  uint8_t xoff_character;
};
// GSM 5.4.6.3.9 (below table 12)
constexpr uint8_t kDefaultXONCharacter = 0x01;   // DC1
constexpr uint8_t kDefaultXOFFCharacter = 0x03;  // DC3
constexpr RemotePortNegotiationParams kDefaultRemotePortNegotiationParams = {
    kDefaultBaud,         kDefaultDataBits,     kDefaultStopBits,
    kDefaultParity,       kDefaultParityType,   kDefaultFlowControlFlags,
    kDefaultXONCharacter, kDefaultXOFFCharacter};

// GSM 5.4.6.3.9 (below table 12)
// clang-format off
enum RemotePortNegotiationMask : uint16_t {
  kXonXoffInput   = 1 << 0,
  kXonXoffOutput  = 1 << 1,
  kRTRInput       = 1 << 2,
  kRTROutput      = 1 << 3,
  kRTCInput       = 1 << 4,
  kRTCOutput      = 1 << 5,
  kBitRate        = 1 << 8,
  kDataBits       = 1 << 9,
  kStopBits       = 1 << 10,
  kParity         = 1 << 11,
  kParityType     = 1 << 12,
  kXONCharacter   = 1 << 13,
  kXOFFCharacter  = 1 << 14
};
// clang-format on
using RemotePortNegotiationMaskBitfield = uint16_t;
// This default is not defined in the spec.
constexpr RemotePortNegotiationMaskBitfield
    kDefaultRemotePortNegotiationMaskBitfield = 0;

// This command is used to negotiate port settings such as baud rate. See GSM
// 5.4.6.3.9.
class RemotePortNegotiationCommand : public MuxCommand {
 public:
  // Creates an RPN command with one value octet. This type of RPN command is
  // used to request the remote port settings.
  RemotePortNegotiationCommand(CommandResponse command_response, DLCI dlci);

  // Creates an RPN command with eight value octets. This type of RPN command is
  // used to negotiate port settings.
  RemotePortNegotiationCommand(CommandResponse command_response, DLCI dlci,
                               RemotePortNegotiationParams params,
                               RemotePortNegotiationMaskBitfield mask);

  // Returns nullptr if parse fails. |command_response| and |length| are
  // parameters which have already been parsed from |buffer|.
  static std::unique_ptr<RemotePortNegotiationCommand> Parse(
      CommandResponse command_response, size_t length,
      const common::ByteBuffer& buffer);

  // MuxCommand overrides
  void Write(common::MutableBufferView buffer) const override;
  size_t written_size() const override;

  // The DLCI which this RPN command is negotiating over.
  inline DLCI dlci() const { return dlci_; }

  // The Remote Port Negotiation parameters. These are described in detaul in
  // GSM 5.4.6.3.9.
  inline RemotePortNegotiationParams params() const { return params_; }

  // The mask used to indicate which parameters are being negotiated.
  inline RemotePortNegotiationMaskBitfield mask() const { return mask_; }

 private:
  // Indicates whether this is the short (1 value octet) or long (8 value
  // octets) version of the RPN command.
  bool short_RPN_command_;

  DLCI dlci_;

  RemotePortNegotiationParams params_;
  RemotePortNegotiationMaskBitfield mask_;
};

// GSM 5.4.6.3.10 (below table 15)
// clang-format off
enum class LineError : uint8_t {
  kOverrunError = (1 << 0),
  kParityError  = (1 << 1),
  kFramingError = (1 << 2)
};
// clang-format on

// This command is used to convey changes in the status of the line. See GSM
// 5.4.6.3.10.
class RemoteLineStatusCommand : public MuxCommand {
 public:
  RemoteLineStatusCommand(CommandResponse command_response, DLCI dlci,
                          bool error_occurred, LineError error);

  // Returns nullptr if parse fails. |command_response| is a parameter which has
  // already been parsed from |buffer|.
  static std::unique_ptr<RemoteLineStatusCommand> Parse(
      CommandResponse command_response, const common::ByteBuffer& buffer);

  // MuxCommand overrides
  void Write(common::MutableBufferView buffer) const override;
  size_t written_size() const override;

  // The DLCI which this command pertains to.
  inline DLCI dlci() const { return dlci_; }

  // Whether or not this frame contains an error.
  inline bool error_occurred() const { return error_occurred_; }

  // The type of error which occured. See GSM 5.4.6.3.10 for an explanation of
  // the errors.
  inline LineError error() const { return error_; }

 private:
  DLCI dlci_;
  bool error_occurred_;
  LineError error_;
};

// RFCOMM table 5.3.
enum class CreditBasedFlowHandshake : uint8_t {
  kUnsupported = 0x0,
  kSupportedRequest = 0xF,
  kSupportedResponse = 0xE
};

using Priority = uint8_t;
constexpr Priority kMinPriority = 0;
constexpr Priority kMaxPriority = 63;

using InitialCredits = uint8_t;
constexpr InitialCredits kMinInitialCredits = 0;
constexpr InitialCredits kMaxInitialCredits = 7;

// See GSM 5.4.6.3.1 and the modifications presented in RFCOMM 5.5.3.
struct ParameterNegotiationParams {
  // 6 bits wide.
  DLCI dlci;
  CreditBasedFlowHandshake credit_based_flow_handshake;
  Priority priority;
  uint16_t maximum_frame_size;
  InitialCredits initial_credits;
};

// This command is used prior to opening a DLC. It is used to set up the
// parameters of the DLC. See GSM 5.4.6.3.1 and the modifications described in
// RFCOMM 5.5.3.
class DLCParameterNegotiationCommand : public MuxCommand {
 public:
  DLCParameterNegotiationCommand(CommandResponse command_response,
                                 ParameterNegotiationParams params);

  // Returns nullptr if parse fails. |command_response| is a parameter which has
  // already been parsed from |buffer|.
  static std::unique_ptr<DLCParameterNegotiationCommand> Parse(
      CommandResponse command_response, const common::ByteBuffer& buffer);

  // MuxCommand overrides
  void Write(common::MutableBufferView buffer) const override;
  size_t written_size() const override;

  inline ParameterNegotiationParams params() const { return params_; }

 private:
  ParameterNegotiationParams params_;
};

// This response is sent when we receive a command which we do not recognize or
// support. See GSM 5.4.6.3.8.
class NonSupportedCommandResponse : public MuxCommand {
 public:
  // Note that NSC is always a response.
  // |incoming_non_supported_command| is 6 bits.
  NonSupportedCommandResponse(CommandResponse incoming_command_response,
                              uint8_t incoming_non_supported_command);

  // Returns nullptr if parse fails. |command_response| is a parameter which has
  // already been parsed from |buffer|.
  static std::unique_ptr<NonSupportedCommandResponse> Parse(
      CommandResponse command_response, const common::ByteBuffer& buffer);

  // MuxCommand overrides
  void Write(common::MutableBufferView buffer) const override;
  size_t written_size() const override;

  inline CommandResponse incoming_command_response() const {
    return incoming_command_response_;
  }
  inline uint8_t incoming_non_supported_command() const {
    return incoming_non_supported_command_;
  }

 private:
  CommandResponse incoming_command_response_;
  uint8_t incoming_non_supported_command_;
};

}  // namespace rfcomm
}  // namespace btlib
