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

#ifndef GARNET_DRIVERS_BLUETOOTH_LIB_RFCOMM_FRAMES_H_
#define GARNET_DRIVERS_BLUETOOTH_LIB_RFCOMM_FRAMES_H_

#include <cstdlib>

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

namespace btlib {
namespace rfcomm {

class UserDataFrame;
class MuxCommandFrame;

// Represents an RFCOMM frame.
// The Frame class has two primary uses:
//  1. Constructing RFCOMM frames with all necessary fields, with the possible
//     exception of the credits field; later, modifying the credits field and
//     writing the frame to a buffer.
//  2. Interpreting an RFCOMM frame written into a buffer, but not modifying the
//     underlying buffer or fields.
// The Frame class is designed to be heavily restricted to the above use cases.
//
// The Frame class hierarchy is as follows:
// Frame
//  - SetAsynchronousBalancedModeCommand
//  - DisconnectCommand
//  - UnnumberedAcknowledgementResponse
//  - DisconnectedModeResponse
//  - UnnumberedInfoHeaderCheckFrame (abstract)
//    - UserDataFrame
//    - MuxCommandFrame
//
// To use Frame in the first way (to write RFCOMM frames), construct the
// subclass of Frame corresponding to the type of RFCOMM frame you would like.
// If it is a UIH frame, modify the frame's credits field using set_credits() if
// needed. Allocate a buffer using written_size() to determine the size of the
// frame when written. Finally, use Write() to write the frame into a buffer.
//
// To use Frame in the second way (as a frame parser), use Frame::Parse(). If
// needed, cast the returned Frame pointer to a specific subclass (see the
// documentation of Parse()). Read values using the accessors. Finally, if the
// frame contains user data or a multiplexer command, use the Take...()
// functions to take ownership of the frame's information (payload). This
// payload can then be passed to the next layer.
class Frame {
 public:
  // |role| is the local RFCOMM role. This is used to determine how to set the
  // C/R bit. |control| is the control octet. Generally, this will be passed by
  // casting a FrameType to a uint8_t. We take a uint8_t instead of a FrameType
  // because Frame can represent frames of unsupported frame type (whose frame
  // types are not enumerated in FrameType).
  inline Frame(Role role, CommandResponse command_response, DLCI dlci,
               uint8_t control, bool poll_final);

  virtual ~Frame() = default;

  // Parse a frame out of a ByteBuffer. If parsing fails, returns nullptr.
  // Copies the payload from |buffer|. Does not take ownership of |buffer|.
  // |credit_based_flow| indicates whether credit-based flow is turned on for
  // this session. |role| is the RFCOMM role of the session on which the frame
  // was formed. Thus, if the frame was formed by the remote peer and sent to
  // the local session, Parse() should be called with the opposite role of the
  // local session.
  //
  // The Frame returned by Parse should first have its type inspected. If it is
  // not a UIH frame, it can be used as-is. No casting needs to be done to get
  // all of the useful information out of the Frame; simply use the Frame
  // accessors to read information about the frame. If the frame type is UIH,
  // then the DLCI should be inspected. If the DLCI is a user data DLCI, the
  // Frame should be converted to a UserDataFrame using ToUserDataFrame.
  // Otherwise, if the DLCI is 0, the frame should be cast to a MuxCommandFrame
  // using ToMuxCommandFrame.
  //
  // For UIH frames, this function will copy from |buffer|.
  static std::unique_ptr<Frame> Parse(bool credit_based_flow, Role role,
                                      const common::ByteBuffer& buffer);

  // Write this into a buffer. The base implementation of Write() will simply
  // write the address, control, length(=0), and FCS octets into a buffer. This
  // is adequate for non-UIH frames.
  virtual void Write(common::MutableBufferView buffer) const;

  // The amount of space this frame takes up when written. Used to allocate the
  // correct size for Write().
  virtual inline size_t written_size() const {
    // Address, control, length, FCS octets.
    return 4 * sizeof(uint8_t);
  }

  // See GSM 5.2 to understand how we extract different fields from the frame.

  // Returns Data Link Connection Identifier (DLCI) used to identify the
  // specific DLC/channel which this frame pertains to.
  inline DLCI dlci() const { return dlci_; }

  // Returns whether this is a Command or a Response frame.
  inline CommandResponse command_response() const { return command_response_; }

  // Returns Control field with the Poll/Final bit set to 0. See GSM Table 2.
  // The Control field encodes the frame type. This octet can be cast to a
  // FrameType; however, this octet may not correspond to any of the octets in
  // the FrameType enum, if the peer sent an unrecognized/unsupported frame
  // type.
  inline uint8_t control() const { return control_; }

  // Returns the Poll/Final (P/F) bit. See RFCOMM 5.1.2, which indicates the
  // various uses of the P/F bit in RFCOMM.
  inline bool poll_final() const { return poll_final_; }

  // Returns the length of the information field of this frame. This is the
  // value which will be encoded in the length field of the frame, when the
  // frame is written. For the default Frame implementation, returns 0, as there
  // is no payload. This is overridden for UIH frames.
  inline virtual InformationLength length() const { return 0; }

  // Downcast this Frame to a Frame subclass. It is expected that the caller
  // will first check that the frame is of the subclass they are downcasting to;
  // for example, by checking that the DLCI is 0 for MuxCommandFrames, or
  // checking that the DLCI is in [kMinUserDLCI, kMaxUserDLCI] for
  // UserDataFrames.
  //
  // TODO(NET-1224): find a cleaner and less bug-prone way to do downcasting.
  template <typename T>
  static inline std::unique_ptr<T> DowncastFrame(std::unique_ptr<Frame> frame) {
    static_assert(std::is_base_of<Frame, T>::value,
                  "Must be downcasting to a Frame subclass");
    return std::unique_ptr<T>(static_cast<T*>(frame.release()));
  }

 protected:
  // The size of the header. We consider the header to be the address octet,
  // control octet, and and length octet(s).
  virtual size_t header_size() const;

  // Write the header of this frame into a buffer.
  virtual void WriteHeader(common::MutableBufferView buffer) const;

  // RFCOMM session parameters.
  Role role_;

  // Frame fields.
  CommandResponse command_response_;
  DLCI dlci_;
  uint8_t control_;
  bool poll_final_;
};

// Set Asynchronous Balanced Mode (SABM) command, described in GSM 5.3.1. Used
// to start up channels.
class SetAsynchronousBalancedModeCommand : public Frame {
 public:
  SetAsynchronousBalancedModeCommand(Role role, DLCI dlci);
};

// Disconnect (DISC) command, described in GSM 5.3.3. Used to close down
// channels, or the multiplexer session as a whole.
class DisconnectCommand : public Frame {
 public:
  DisconnectCommand(Role role, DLCI dlci);
};

// Unnumbered Acknowledgement (UA) response, described in GSM 5.3.2. Used as an
// acknowledgement to SABM and DISC commands.
class UnnumberedAcknowledgementResponse : public Frame {
 public:
  UnnumberedAcknowledgementResponse(Role role, DLCI dlci);
};

// Disconnected Mode (DM) response, described in GSM 5.3.3. This response is
// sent when commands are sent along a disconnected channel.
class DisconnectedModeResponse : public Frame {
 public:
  DisconnectedModeResponse(Role role, DLCI dlci);
};

// Unnumbered Information with Header Check frame. This abstract class is the
// superclass of both MuxCommandFrame (sent along DLCI 0) and UserDataFrame
// (sent along DLCIs 2-61).
//
// |credit_based_flow| is a session parameter specifying whether credit-based
// flow control is turned on or off for this session. It determines whether a
// credit field can appear in this frame; if it is set to true and set_credits()
// is used to set the credits to a nonzero amount, a credits field will appear.
// Note that, with this class, we cannot encode a frame with a credits field
// equal to 0. This isn't an issue, as sending a frame with credits=0 is
// functionally equivalent to a frame without a credits field.
class UnnumberedInfoHeaderCheckFrame : public Frame {
 public:
  UnnumberedInfoHeaderCheckFrame(Role role, bool credit_based_flow, DLCI dlci);

  virtual ~UnnumberedInfoHeaderCheckFrame() = default;

  // Frame overrides
  virtual void Write(common::MutableBufferView buffer) const override = 0;
  virtual size_t written_size() const override = 0;
  virtual InformationLength length() const override = 0;

  // Returns the number of credits contained in the credits field of this frame.
  // See RFCOMM 6.5.2. If this frame does not contain a credits field, returns
  // 0.
  inline uint8_t credits() const { return has_credit_octet() ? credits_ : 0; }

  // Sets the credits. This is the only field that may need to be changed
  // after frame creation. This function should not be called if credit-based
  // flow is off; if credit-based flow is off, then |credits_| should remain 0.
  // This function also changes the poll/final bit to reflect the new amount of
  // credits; P/F=0 iff credits=0. See RFCOMM 6.5.2.
  void set_credits(uint8_t credits);

 protected:
  // Whether or not this frame contains the optional credit octet.
  inline bool has_credit_octet() const {
    return credit_based_flow_ && credits_;
  }

  // The size of the header. In this case, we define the header to be the
  // address octet, control octet, length octet(s), and optional credits octets.
  virtual size_t header_size() const override;

  // Write the header of this frame, including the optional credits octet.
  virtual void WriteHeader(common::MutableBufferView buffer) const override;

  bool credit_based_flow_;
  uint8_t credits_;
};

class UserDataFrame : public UnnumberedInfoHeaderCheckFrame {
 public:
  // |information| is the payload; "information" is RFCOMM/GSM's term for the
  // payload of a frame. Frame takes ownership of |information|.
  UserDataFrame(Role role, bool credit_based_flow, DLCI dlci,
                common::ByteBufferPtr information);

  // UnnumberedInfoHeaderCheckFrame overrides
  void Write(common::MutableBufferView buffer) const override;
  size_t written_size() const override;
  inline InformationLength length() const override {
    return information_->size();
  }

  // Transfers ownership of the information field (aka the payload) from this
  // Frame to the caller. Future calls to TakeInformation() will return nullptr.
  // It is expected that the Frame will be destructed soon after this call.
  common::ByteBufferPtr TakeInformation();

 private:
  common::ByteBufferPtr information_;
};

// Represents a UIH frame encapsulating a multiplexer control channel command.
// These frames will always have DLCI=0 (the multiplexer control channel).
class MuxCommandFrame : public UnnumberedInfoHeaderCheckFrame {
 public:
  MuxCommandFrame(Role role, bool credit_based_flow,
                  std::unique_ptr<MuxCommand> mux_command);

  // UnnumberedInfoHeaderCheckFrame overrides
  void Write(common::MutableBufferView buffer) const override;
  size_t written_size() const override;
  inline InformationLength length() const override {
    return mux_command_->written_size();
  }

  // Transfers ownership of the MuxCommand owned by this MuxCommandFrame. In the
  // common usage of MuxCommandFrame, this will be called just before
  // MuxCommandFrame is destructed. However, a call to TakeMuxCommand() before
  // destruction is not necessary.
  std::unique_ptr<MuxCommand> TakeMuxCommand();

 private:
  std::unique_ptr<MuxCommand> mux_command_;
};

}  // namespace rfcomm
}  // namespace btlib

#endif  // GARNET_DRIVERS_BLUETOOTH_LIB_RFCOMM_FRAMES_H_
