// 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_RFCOMM_H_
#define GARNET_DRIVERS_BLUETOOTH_LIB_RFCOMM_RFCOMM_H_

#include <cstdint>

#include <lib/fxl/logging.h>

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

namespace btlib {
namespace rfcomm {

// C/R bit, used at both the frame level and the multiplexer channel command
// level. See RFCOMM 5.1.3 and 5.4.6.1/2.
enum class CommandResponse { kCommand, kResponse };

// Role assigned to this device's end of the RFCOMM session. Start-up procedure
// is described in RFCOMM 5.2.1; the device which starts up the multiplexer
// control channel is considered the initiator (see "RFCOMM initiator" in the
// glossary, RFCOMM 9).
// A value of kUnassigned indicates that the RFCOMM session has not started the
// start-up procedure, and thus no role has yet been assigned. A value of
// kNegotiating indicates that the start-up procedure has started, but not
// finished.
enum class Role { kUnassigned, kNegotiating, kInitiator, kResponder };

// Return the Role opposite to the one given in |role|. The opposite of the
// Unassigned role is Unassigned. This is used to get our peer's role when we
// know our own.
inline constexpr Role OppositeRole(Role role) {
  return role == Role::kUnassigned
             ? Role::kUnassigned
             : role == Role::kInitiator ? Role::kResponder : Role::kInitiator;
}

// This function defines what it means for a multiplexer to be started: namely,
// it has its role set to initiator or responder.
inline constexpr bool IsMultiplexerStarted(Role role) {
  return role == Role::kInitiator || role == Role::kResponder;
}

// DLCIs are 6 bits. See RFCOMM 5.4. Any DLCI value will be truncated to the
// least significant 6 bits.
using DLCI = uint8_t;
// DLCI 0 is internally used by RFCOMM as the multiplexer control channel, over
// which the two multiplexers communicate. DLCIs 2-61 correspond to user data
// channels, which can be used by applications.
constexpr DLCI kMuxControlDLCI = 0;
constexpr DLCI kMinUserDLCI = 2;
constexpr DLCI kMaxUserDLCI = 61;

constexpr bool IsUserDLCI(DLCI dlci) {
  return dlci >= kMinUserDLCI && dlci <= kMaxUserDLCI;
}

constexpr bool IsValidDLCI(DLCI dlci) {
  return dlci == kMuxControlDLCI || IsUserDLCI(dlci);
}

// Server Channels are 5 bits wide; they are the 5 most significant bits of the
// DLCI. Server Channels are exposed to the outside world; a user who is
// requesting to open a channel will know the Server Channel. DLCIs, on the
// other hand, are internal to RFCOMM.
using ServerChannel = uint8_t;
constexpr ServerChannel kMinServerChannel = 1;
constexpr ServerChannel kMaxServerChannel = 30;
// Used to indicate error.
constexpr ServerChannel kInvalidServerChannel = 0;

// Used to convert between Server Channel and DLCI. See RFCOMM 5.4 for the
// spec's description of Server Channels and how they relate to DLCIs.
constexpr size_t kServerChannelShift = 1;

inline constexpr ServerChannel DLCIToServerChannel(DLCI dlci) {
  FXL_DCHECK(IsUserDLCI(dlci));
  return dlci >> kServerChannelShift;
}

inline constexpr DLCI ServerChannelToDLCI(ServerChannel server_channel,
                                          Role role) {
  FXL_DCHECK(role == Role::kInitiator || role == Role::kResponder);
  FXL_DCHECK(server_channel >= kMinServerChannel &&
             server_channel <= kMaxServerChannel);
  return (server_channel << kServerChannelShift) |
         (role == Role::kInitiator ? 1 : 0);
}

// The length field encodes the length of the information (payload) field. The
// length field can be one or two octets, and can encode at most a 15-bit value.
using InformationLength = uint16_t;

// The maximum Length value which can be encoded in a single-octet length field.
// This constant is used to quickly determine whether two (or more) length
// octets will be needed to encode a length value. It is used by Frames and
// MuxCommands alike.
constexpr InformationLength kMaxSingleOctetLength = 127;

// Encodes the Control Field; see table 2, GSM 07.10 5.2.1.3 and RFCOMM 4.2.
// The P/F bit is set to 0 for all frame types.
// clang-format off
enum class FrameType : uint8_t {
  kSetAsynchronousBalancedMode  = 0b00101111,
  kUnnumberedAcknowledgement    = 0b01100011,
  kDisconnectedMode             = 0b00001111,
  kDisconnect                   = 0b01000011,
  kUnnumberedInfoHeaderCheck    = 0b11101111
};
// clang-format on

// Whether the frame is a valid multiplexer start-up frame. Valid multiplexer
// start-up frames are the only frames which are allowed to be sent before the
// multiplexer starts.
constexpr bool IsMuxStartupFrame(FrameType type, DLCI dlci) {
  return dlci == kMuxControlDLCI &&
         (type == FrameType::kSetAsynchronousBalancedMode ||
          type == FrameType::kUnnumberedAcknowledgement ||
          type == FrameType::kDisconnectedMode);
}

}  // namespace rfcomm
}  // namespace btlib

#endif  // GARNET_DRIVERS_BLUETOOTH_LIB_RFCOMM_RFCOMM_H_
