// 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 UnnumberedInfoHeaderCheckFrame;
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 AsUserDataFrame.
  // Otherwise, if the DLCI is 0, the frame should be cast to a MuxCommandFrame
  // using AsMuxCommandFrame.
  //
  // 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; }

  // Pointer to this Frame as a MuxCommandFrame.
  // Must only be called if the DLCI is 0.
  MuxCommandFrame* AsMuxCommandFrame();

  // Pointer to this Frame as a MuxCommandFrame.
  // Must only be called if the IsUserDLCI() for this frame is true.
  UserDataFrame* AsUserDataFrame();

  // Pointer to this Frame as a UnnumberedInfoHeaderCheckFrame
  // Must only be called if this frame is a UIH frame.
  UnnumberedInfoHeaderCheckFrame* AsUnnumberedInfoHeaderCheckFrame();

  // 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 IsUserDLCI() 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_ ? information_->size() : 0;
  }

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