// 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 SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_GAP_LOW_ENERGY_ADDRESS_MANAGER_H_
#define SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_GAP_LOW_ENERGY_ADDRESS_MANAGER_H_

#include <lib/async/cpp/task.h>

#include <optional>
#include <queue>

#include <fbl/macros.h>

#include "src/connectivity/bluetooth/core/bt-host/common/device_address.h"
#include "src/connectivity/bluetooth/core/bt-host/common/uint128.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/local_address_delegate.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/status.h"
#include "src/lib/fxl/memory/ref_ptr.h"
#include "src/lib/fxl/memory/weak_ptr.h"

namespace bt {

namespace hci {
class Transport;
}  // namespace hci

namespace gap {

// Manages the local LE device address used in scan, legacy advertising, and
// connection initiation procedures. The primary purpose of this class is to
// defer updating the random device address if we believe that doing so is
// disallowed by the controller. This is the case when scanning or legacy
// advertising is enabled, according to Vol 2, Part E, 7.8.4.
//
// Procedures that need to know the value of the local address (both connection
// and advertising procedures need to assign this to any resultant
// hci::Connection object for SMP pairing to function correctly) should call the
// EnsureLocalAddress() method to obtain it and to lazily refresh the address
// if required.
//
// The type and value of the local address depends on whether or not the privacy
// feature is in use. The potential states are as follows:
//
//   * When privacy is DISABLED, the local address type and its value match
//     the public device address that this object gets initialized with.
//
//   * When privacy is ENABLED, the exact type and value depends on the state of
//     link layer procedures at that time. The "HCI LE Set Random Address"
//     command is used to assign the controller a random address, which it will
//     use for the next active scan, legacy advertising, or initiation command
//     with a random address type. A new local random address will be generated
//     at a regular interval (see kPrivateAddressTimeout in gap.h).
//
//     According to Vol 2, Part E, 7.8.4 the "HCI LE Set Random Address"
//     command is disallowed when scanning or legacy advertising are enabled.
//     Before any one of these procedures gets started, the EnsureLocalAddress()
//     method should be called to update the random address if it is allowed by
//     the controller (and the address needs a refresh). This function
//     asynchronously returns the device address that should be used by the
//     procedure.
//
// The state requested by EnablePrivacy() (enabled or disabled) may not take
// effect immediately if a scan, advertising, or connection procedure is in
// progress. The requested address type (public or private) will apply
// eventually when the controller allows it.
class LowEnergyAddressManager final : public hci::LocalAddressDelegate {
 public:
  // Function called when privacy is in use to determine if it is allowed to
  // assign a new random address to the controller. This must return false if
  // if scan, legacy advertising, and/or initiation procedures are in progress.
  using StateQueryDelegate = fit::function<bool()>;

  LowEnergyAddressManager(const DeviceAddress& public_address, StateQueryDelegate delegate,
                          fxl::WeakPtr<hci::Transport> hci);
  ~LowEnergyAddressManager();

  // Assigns the IRK to generate a RPA for the next address refresh when privacy
  // is enabled.
  void set_irk(const std::optional<UInt128>& irk) { irk_ = irk; }

  // Enable or disable the privacy feature. When enabled, the controller will be
  // configured to use a new random address if it is currently allowed to do so.
  // If setting the random address is not allowed the update will be deferred
  // until the the next successful attempt triggered by a call to
  // TryRefreshRandomAddress().
  //
  // If an IRK has been assigned and |enabled| is true, then the generated
  // random addresses will each be a Resolvable Private Address that can be
  // resolved with the IRK. Otherwise, Non-resolvable Private Addresses will be
  // used.
  void EnablePrivacy(bool enabled);

  // LocalAddressDelegate overrides:
  std::optional<UInt128> irk() const override { return irk_; }
  DeviceAddress identity_address() const override { return public_; }
  void EnsureLocalAddress(AddressCallback callback) override;

 private:
  // Return the current address.
  const DeviceAddress& current_address() const {
    return (privacy_enabled_ && random_) ? *random_ : public_;
  }

  // Attempt to reconfigure the current random device address.
  void TryRefreshRandomAddress();

  // Clears all privacy related state such that the random address will not be
  // refreshed until privacy is re-enabled. |random_| is not modified and
  // continues to reflect the most recently configured random address.
  void CleanUpPrivacyState();

  void CancelExpiry();
  bool CanUpdateRandomAddress() const;
  void ResolveAddressRequests();

  StateQueryDelegate delegate_;
  fxl::WeakPtr<hci::Transport> hci_;
  bool privacy_enabled_;

  // The public device address (i.e. BD_ADDR) that is assigned to the
  // controller.
  const DeviceAddress public_;

  // The random device address assigned to the controller by the most recent
  // successful HCI_LE_Set_Random_Address command. std::nullopt if the command
  // was never run successfully.
  std::optional<DeviceAddress> random_;

  // True if the random address needs a refresh. This is the case when
  //   a. Privacy is enabled and the random device address needs to get rotated;
  //      or
  //   b. Privacy has recently been enabled and the controller hasn't been
  //      programmed with the new address yet
  bool needs_refresh_;

  // True if a HCI command to update the random address is in progress.
  bool refreshing_;

  // The local identity resolving key. If present, it is used to generate RPAs
  // when privacy is enabled.
  std::optional<UInt128> irk_;

  // Callbacks waiting to be notified of the local address.
  std::queue<AddressCallback> address_callbacks_;

  // The task that executes when a random address expires and needs to be
  // refreshed.
  async::Task random_address_expiry_task_;

  fxl::WeakPtrFactory<LowEnergyAddressManager> weak_ptr_factory_;

  DISALLOW_COPY_ASSIGN_AND_MOVE(LowEnergyAddressManager);
};

}  // namespace gap
}  // namespace bt

#endif  // SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_GAP_LOW_ENERGY_ADDRESS_MANAGER_H_
