// Copyright 2017 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_HCI_CONNECTION_H_
#define GARNET_DRIVERS_BLUETOOTH_LIB_HCI_CONNECTION_H_

#include <lib/fit/function.h>
#include <zircon/assert.h>

#include "garnet/drivers/bluetooth/lib/common/device_address.h"
#include "garnet/drivers/bluetooth/lib/hci/connection_parameters.h"
#include "garnet/drivers/bluetooth/lib/hci/control_packets.h"
#include "garnet/drivers/bluetooth/lib/hci/hci.h"
#include "garnet/drivers/bluetooth/lib/hci/link_key.h"
#include "lib/fxl/macros.h"
#include "lib/fxl/memory/ref_ptr.h"
#include "lib/fxl/memory/weak_ptr.h"
#include "lib/fxl/synchronization/thread_checker.h"

namespace btlib {
namespace hci {

class Transport;

// A Connection represents a logical link connection to a remote device. It
// maintains link-specific configuration parameters (such as the connection
// handle, role, and connection parameters) and state (e.g. open/closed).
// Controller procedures that are related to managing a logical link are
// performed by a Connection, e.g. disconnecting the link and initiating link
// layer authentication.
//
// Connection instances are intended to be uniquely owned. The owner of an
// instance is also the owner of the underlying link and the lifetime of a
// Connection determines the lifetime of the link.
//
// Connection's public interface related to controller operations is abstract to
// enable the injection of a fake implementation for unit tests that don't need
// a real HCI transport. A production implementation can be obtained via static
// factory methods (see Create* below).
//
// It is possible for non-owning code to reference a Connection by a obtaining a
// WeakPtr.
//
// THREAD SAFETY:
//
// This class is not thread-safe. Instances should only be accessed on their
// creation thread.
class Connection {
 public:
  // This defines the various connection types. These do not exactly correspond
  // to the baseband logical/physical link types but instead provide a
  // high-level abstraction.
  enum class LinkType {
    // Represents a BR/EDR baseband link (ACL-U).
    kACL,

    // BR/EDR isochronous links (SCO-S, eSCO-S).
    kSCO,
    kESCO,

    // A LE logical link (LE-U).
    kLE,
  };

  // Role of the local device in the established connection.
  enum class Role {
    kMaster,
    kSlave,
  };

  // Initializes this as a LE connection.
  static std::unique_ptr<Connection> CreateLE(
      ConnectionHandle handle, Role role,
      const common::DeviceAddress& local_address,
      const common::DeviceAddress& peer_address,
      const LEConnectionParameters& params, fxl::RefPtr<Transport> hci);

  // Initializes this as a BR/EDR ACL connection.
  static std::unique_ptr<Connection> CreateACL(
      ConnectionHandle handle, Role role,
      const common::DeviceAddress& local_address,
      const common::DeviceAddress& peer_address, fxl::RefPtr<Transport> hci);

  // The destructor closes this connection.
  virtual ~Connection() = default;

  // Returns a weak pointer to this Connection. This must be implemented by
  // subclasses.
  virtual fxl::WeakPtr<Connection> WeakPtr() = 0;

  // Returns a string representation.
  std::string ToString() const;

  // The type of the connection.
  LinkType ll_type() const { return ll_type_; }

  // Returns the 12-bit connection handle of this connection. This handle is
  // used to identify an individual logical link maintained by the controller.
  ConnectionHandle handle() const { return handle_; }

  // Returns the role of the local device in the established connection.
  Role role() const { return role_; }

  // The active LE connection parameters of this connection. Must only be called
  // on a Connection with the LE link type.
  const LEConnectionParameters& low_energy_parameters() const {
    ZX_DEBUG_ASSERT(ll_type_ == LinkType::kLE);
    return le_params_;
  }

  // Sets the active LE parameters of this connection. Must only be called on a
  // Connection with the LE link type.
  void set_low_energy_parameters(const LEConnectionParameters& params) {
    ZX_DEBUG_ASSERT(ll_type_ == LinkType::kLE);
    le_params_ = params;
  }

  // The local device address used while establishing the connection.
  const common::DeviceAddress& local_address() const { return local_address_; }

  // The peer address used while establishing the connection.
  const common::DeviceAddress& peer_address() const { return peer_address_; }

  // Returns true if this connection is currently open.
  bool is_open() const { return is_open_; }
  void set_closed() { is_open_ = false; }

  // Assigns a link key to this connection. This will be used for all future
  // encryption procedures.
  void set_link_key(const LinkKey& ltk) { ltk_ = ltk; }

  // The current long term key of the connection.
  const std::optional<LinkKey>& ltk() const { return ltk_; }

  // Assigns a callback that will run when the encryption state of the
  // underlying link changes. The |enabled| parameter should be ignored if
  // |status| indicates an error.
  using EncryptionChangeCallback = fit::function<void(Status, bool enabled)>;
  void set_encryption_change_callback(EncryptionChangeCallback callback) {
    encryption_change_callback_ = std::move(callback);
  }

  // Closes this connection by sending the HCI_Disconnect command to the
  // controller. This method is a NOP if the connection is already closed.
  virtual void Close(
      StatusCode reason = StatusCode::kRemoteUserTerminatedConnection) = 0;

  // Authenticate (i.e. encrypt) this connection using its current link key.
  // Returns false if the procedure cannot be initiated. The result of the
  // authentication procedure will be reported via the encryption change
  // callback.
  //
  // If called on a LE connection and the link layer procedure fails, the
  // connection will be disconnected. The encryption change callback will be
  // notified of the failure.
  virtual bool StartEncryption() = 0;

 protected:
  Connection(ConnectionHandle handle, LinkType ll_type, Role role,
             const common::DeviceAddress& local_address,
             const common::DeviceAddress& peer_address);

  const EncryptionChangeCallback& encryption_change_callback() const {
    return encryption_change_callback_;
  }

 private:
  LinkType ll_type_;
  ConnectionHandle handle_;
  Role role_;
  bool is_open_;

  // Addresses used while creating the link.
  common::DeviceAddress local_address_;
  common::DeviceAddress peer_address_;

  // Connection parameters for a LE link. Not nullptr if the link type is LE.
  LEConnectionParameters le_params_;

  // This connection's current link key.
  std::optional<LinkKey> ltk_;

  EncryptionChangeCallback encryption_change_callback_;

  // TODO(armansito): Add a BREDRParameters struct.

  FXL_DISALLOW_COPY_AND_ASSIGN(Connection);
};

using ConnectionPtr = std::unique_ptr<Connection>;

}  // namespace hci
}  // namespace btlib

#endif  // GARNET_DRIVERS_BLUETOOTH_LIB_HCI_CONNECTION_H_
