/*
 *
 *    Copyright (c) 2020-2022 Project CHIP Authors
 *    Copyright (c) 2013-2017 Nest Labs, Inc.
 *    All rights reserved.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

/**
 *    @file
 *      Declaration of CHIP Device Controller, a common class
 *      that implements connecting and messaging and will later
 *      be expanded to support discovery, pairing and
 *      provisioning of CHIP  devices.
 *
 */

#pragma once

#include <app/AppConfig.h>
#include <app/CASEClientPool.h>
#include <app/CASESessionManager.h>
#include <app/ClusterStateCache.h>
#include <app/OperationalSessionSetup.h>
#include <app/OperationalSessionSetupPool.h>
#include <controller/AbstractDnssdDiscoveryController.h>
#include <controller/AutoCommissioner.h>
#include <controller/CHIPCluster.h>
#include <controller/CHIPDeviceControllerSystemState.h>
#include <controller/CommissioneeDeviceProxy.h>
#include <controller/CommissioningDelegate.h>
#include <controller/DevicePairingDelegate.h>
#include <controller/OperationalCredentialsDelegate.h>
#include <controller/SetUpCodePairer.h>
#include <credentials/FabricTable.h>
#include <credentials/attestation_verifier/DeviceAttestationDelegate.h>
#include <credentials/attestation_verifier/DeviceAttestationVerifier.h>
#include <crypto/CHIPCryptoPAL.h>
#include <inet/InetInterface.h>
#include <lib/core/CHIPConfig.h>
#include <lib/core/CHIPCore.h>
#include <lib/core/CHIPPersistentStorageDelegate.h>
#include <lib/core/DataModelTypes.h>
#include <lib/core/TLV.h>
#include <lib/support/DLLUtil.h>
#include <lib/support/Pool.h>
#include <lib/support/SafeInt.h>
#include <lib/support/Span.h>
#include <lib/support/ThreadOperationalDataset.h>
#include <messaging/ExchangeMgr.h>
#include <protocols/secure_channel/MessageCounterManager.h>
#include <protocols/secure_channel/RendezvousParameters.h>
#include <protocols/user_directed_commissioning/UserDirectedCommissioning.h>
#include <system/SystemClock.h>
#include <transport/SessionManager.h>
#include <transport/TransportMgr.h>
#include <transport/raw/UDP.h>

#if CONFIG_DEVICE_LAYER
#include <platform/CHIPDeviceLayer.h>
#endif

#if CONFIG_NETWORK_LAYER_BLE
#include <ble/Ble.h>
#endif
#include <controller/DeviceDiscoveryDelegate.h>

namespace chip {

namespace Controller {

inline constexpr uint16_t kNumMaxActiveDevices = CHIP_CONFIG_CONTROLLER_MAX_ACTIVE_DEVICES;

struct ControllerInitParams
{
    DeviceControllerSystemState * systemState                       = nullptr;
    DeviceDiscoveryDelegate * deviceDiscoveryDelegate               = nullptr;
    OperationalCredentialsDelegate * operationalCredentialsDelegate = nullptr;

    /* The following keypair must correspond to the public key used for generating
       controllerNOC. It's used by controller to establish CASE sessions with devices */
    Crypto::P256Keypair * operationalKeypair = nullptr;

    /**
     * Controls whether or not the operationalKeypair should be owned by the caller.
     * By default, this is false, but if the keypair cannot be serialized, then
     * setting this to true will allow the caller to manage this keypair's lifecycle.
     */
    bool hasExternallyOwnedOperationalKeypair = false;

    /* The following certificates must be in x509 DER format */
    ByteSpan controllerNOC;
    ByteSpan controllerICAC;
    ByteSpan controllerRCAC;

    /**
     * Controls whether we permit multiple DeviceController instances to exist
     * on the same logical fabric (identified by the tuple of the fabric's
     * root public key + fabric id).
     *
     * Each controller instance will be associated with its own FabricIndex.
     * This pivots the FabricTable to tracking identities instead of fabrics,
     * represented by FabricInfo instances that can have colliding logical fabrics.
     *
     */
    bool permitMultiControllerFabrics = false;

    //
    // Controls enabling server cluster interactions on a controller. This in turn
    // causes the following to get enabled:
    //
    //  - Advertisement of active controller operational identities.
    //
    bool enableServerInteractions = false;

    /**
     * Controls whether shutdown of the controller removes the corresponding
     * entry from the in-memory fabric table, but NOT from storage.
     *
     * Note that this means that after controller shutdown the storage and
     * in-memory versions of the fabric table will be out of sync.
     * For compatibility reasons this is the default behavior.
     *
     * @see deleteFromFabricTableOnShutdown
     */
    bool removeFromFabricTableOnShutdown = true;

    /**
     * Controls whether shutdown of the controller deletes the corresponding
     * entry from the fabric table (both in-memory and storage).
     *
     * If both `removeFromFabricTableOnShutdown` and this setting are true,
     * this setting will take precedence.
     *
     * @see removeFromFabricTableOnShutdown
     */
    bool deleteFromFabricTableOnShutdown = false;

    /**
     * Specifies whether to utilize the fabric table entry for the given FabricIndex
     * for initialization. If provided and neither the operational key pair nor the NOC
     * chain are provided, then attempt to locate a fabric corresponding to the given FabricIndex.
     */
    chip::Optional<FabricIndex> fabricIndex;

    chip::VendorId controllerVendorId;
};

struct CommissionerInitParams : public ControllerInitParams
{
    DevicePairingDelegate * pairingDelegate     = nullptr;
    CommissioningDelegate * defaultCommissioner = nullptr;
    // Device attestation verifier instance for the commissioning.
    // If null, the globally set attestation verifier (e.g. from GetDeviceAttestationVerifier()
    // singleton) will be used.
    Credentials::DeviceAttestationVerifier * deviceAttestationVerifier = nullptr;
};

/**
 * @brief
 *   Controller applications can use this class to communicate with already paired CHIP devices. The
 *   application is required to provide access to the persistent storage, where the paired device information
 *   is stored. This object of this class can be initialized with the data from the storage (List of devices,
 *   and device pairing information for individual devices). Alternatively, this class can retrieve the
 *   relevant information when the application tries to communicate with the device
 */
class DLL_EXPORT DeviceController : public AbstractDnssdDiscoveryController
{
public:
    DeviceController();
    ~DeviceController() override {}

    CHIP_ERROR Init(ControllerInitParams params);

    /**
     * @brief
     *  Tears down the entirety of the stack, including destructing key objects in the system.
     *  This expects to be called with external thread synchronization, and will not internally
     *  grab the CHIP stack lock.
     *
     *  This will also not stop the CHIP event queue / thread (if one exists).  Consumers are expected to
     *  ensure this happened before calling this method.
     */
    virtual void Shutdown();

    SessionManager * SessionMgr()
    {
        if (mSystemState)
        {
            return mSystemState->SessionMgr();
        }

        return nullptr;
    }

    CASESessionManager * CASESessionMgr()
    {
        if (mSystemState)
        {
            return mSystemState->CASESessionMgr();
        }

        return nullptr;
    }

    Messaging::ExchangeManager * ExchangeMgr()
    {
        if (mSystemState != nullptr)
        {
            return mSystemState->ExchangeMgr();
        }

        return nullptr;
    }

    CHIP_ERROR GetPeerAddressAndPort(NodeId peerId, Inet::IPAddress & addr, uint16_t & port);

    /**
     * @brief
     *   Looks up the PeerAddress for an established CASE session.
     *
     * @param[in] nodeId the NodeId of the target.
     * @param[out] addr the PeerAddress to be filled on success
     *
     * @return CHIP_ERROR CHIP_ERROR_NOT_CONNECTED if no CASE session exists for the device
     */
    CHIP_ERROR GetPeerAddress(NodeId nodeId, Transport::PeerAddress & addr);

    ScopedNodeId GetPeerScopedId(NodeId nodeId) { return ScopedNodeId(nodeId, GetFabricIndex()); }

    /**
     * This function finds the device corresponding to deviceId, and establishes
     * a CASE session with it.
     *
     * Once the CASE session is successfully established the `onConnection`
     * callback is called. This can happen before GetConnectedDevice returns if
     * there is an existing CASE session.
     *
     * If a CASE sessions fails to be established, the `onFailure` callback will
     * be called.  This can also happen before GetConnectedDevice returns.
     *
     * An error return from this function means that neither callback has been
     * called yet, and neither callback will be called in the future.
     */
    virtual CHIP_ERROR
    GetConnectedDevice(NodeId peerNodeId, Callback::Callback<OnDeviceConnected> * onConnection,
                       Callback::Callback<OnDeviceConnectionFailure> * onFailure,
                       TransportPayloadCapability transportPayloadCapability = TransportPayloadCapability::kMRPPayload)
    {
        VerifyOrReturnError(mState == State::Initialized, CHIP_ERROR_INCORRECT_STATE);
        mSystemState->CASESessionMgr()->FindOrEstablishSession(ScopedNodeId(peerNodeId, GetFabricIndex()), onConnection, onFailure,
#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
                                                               1, nullptr,
#endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
                                                               transportPayloadCapability);
        return CHIP_NO_ERROR;
    }

    /**
     * This function finds the device corresponding to deviceId, and establishes
     * a CASE session with it.
     *
     * Once the CASE session is successfully established the `onConnection`
     * callback is called. This can happen before GetConnectedDevice returns if
     * there is an existing CASE session.
     *
     * If a CASE sessions fails to be established, the `onSetupFailure` callback will
     * be called.  This can also happen before GetConnectedDevice returns.
     *
     * An error return from this function means that neither callback has been
     * called yet, and neither callback will be called in the future.
     */
    CHIP_ERROR
    GetConnectedDevice(NodeId peerNodeId, Callback::Callback<OnDeviceConnected> * onConnection,
                       chip::Callback::Callback<OperationalSessionSetup::OnSetupFailure> * onSetupFailure,
                       TransportPayloadCapability transportPayloadCapability = TransportPayloadCapability::kMRPPayload)
    {
        VerifyOrReturnError(mState == State::Initialized, CHIP_ERROR_INCORRECT_STATE);
        mSystemState->CASESessionMgr()->FindOrEstablishSession(ScopedNodeId(peerNodeId, GetFabricIndex()), onConnection,
                                                               onSetupFailure,
#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
                                                               1, nullptr,
#endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
                                                               transportPayloadCapability);
        return CHIP_NO_ERROR;
    }

    /**
     * @brief
     *   Compute a PASE verifier and passcode ID for the desired setup pincode.
     *
     *   This can be used to open a commissioning window on the device for
     *   additional administrator commissioning.
     *
     * @param[in] iterations      The number of iterations to use when generating the verifier
     * @param[in] setupPincode    The desired PIN code to use
     * @param[in] salt            The 16-byte salt for verifier computation
     * @param[out] outVerifier    The Spake2pVerifier to be populated on success
     *
     * @return CHIP_ERROR         CHIP_NO_ERROR on success, or corresponding error
     */
    CHIP_ERROR ComputePASEVerifier(uint32_t iterations, uint32_t setupPincode, const ByteSpan & salt,
                                   Crypto::Spake2pVerifier & outVerifier);

    void RegisterDeviceDiscoveryDelegate(DeviceDiscoveryDelegate * delegate) { mDeviceDiscoveryDelegate = delegate; }

    /**
     * @brief Get the Compressed Fabric ID assigned to the device.
     */
    uint64_t GetCompressedFabricId() const
    {
        const auto * fabricInfo = GetFabricInfo();
        return (fabricInfo != nullptr) ? static_cast<uint64_t>(fabricInfo->GetCompressedFabricId()) : kUndefinedCompressedFabricId;
    }

    /**
     * @brief Get the Compressed Fabric Id as a big-endian 64 bit octet string.
     *
     * Output span is resized to 8 bytes on success if it was larger.
     *
     * @param outBytes span to contain the compressed fabric ID, must be at least 8 bytes long
     * @return CHIP_ERROR_BUFFER_TOO_SMALL if `outBytes` is too small, CHIP_ERROR_INVALID_FABRIC_INDEX
     *         if the controller is somehow not associated with a fabric (internal error!) or
     *         CHIP_NO_ERROR on success.
     */
    CHIP_ERROR GetCompressedFabricIdBytes(MutableByteSpan & outBytes) const;

    /**
     * @brief Get the raw Fabric ID assigned to the device.
     */
    uint64_t GetFabricId() const
    {
        const auto * fabricInfo = GetFabricInfo();
        return (fabricInfo != nullptr) ? static_cast<uint64_t>(fabricInfo->GetFabricId()) : kUndefinedFabricId;
    }

    /**
     * @brief Get the Node ID of this instance.
     */
    NodeId GetNodeId() const
    {
        const auto * fabricInfo = GetFabricInfo();
        return (fabricInfo != nullptr) ? static_cast<uint64_t>(fabricInfo->GetNodeId()) : kUndefinedNodeId;
    }

    /**
     * @brief Get the root public key for the fabric
     *
     * @param outRootPublicKey reference to public key object that gets updated on success.
     *
     * @return CHIP_NO_ERROR on success, CHIP_ERROR_INCORRECT_STATE if fabric table is unset, or another internal error
     *         on storage access failure.
     */
    CHIP_ERROR GetRootPublicKey(Crypto::P256PublicKey & outRootPublicKey) const;

    FabricIndex GetFabricIndex() const { return mFabricIndex; }

    const FabricTable * GetFabricTable() const
    {
        if (mSystemState == nullptr)
        {
            return nullptr;
        }
        return mSystemState->Fabrics();
    }

    OperationalCredentialsDelegate * GetOperationalCredentialsDelegate() { return mOperationalCredentialsDelegate; }

    /**
     * @brief
     *   Reconfigures a new set of operational credentials to be used with this
     *   controller given ControllerInitParams state.
     *
     * WARNING: This is a low-level method that should only be called directly
     *          if you know exactly how this will interact with controller state,
     *          since there are several integrations that do this call for you.
     *          It can be used for fine-grained dependency injection of a controller's
     *          NOC and operational keypair.
     */
    CHIP_ERROR InitControllerNOCChain(const ControllerInitParams & params);

    /**
     * @brief Update the NOC chain of controller.
     *
     * @param[in] noc                                NOC in CHIP certificate format.
     * @param[in] icac                               ICAC in CHIP certificate format. If no icac is present, an empty
     *                                               ByteSpan should be passed.
     * @param[in] operationalKeypair                 External operational keypair. If null, use keypair in OperationalKeystore.
     * @param[in] operationalKeypairExternalOwned    If true, external operational keypair must outlive the fabric.
     *                                               If false, the keypair is copied and owned in heap of a FabricInfo.
     *
     * @return CHIP_ERROR                            CHIP_NO_ERROR on success.
     */
    CHIP_ERROR UpdateControllerNOCChain(const ByteSpan & noc, const ByteSpan & icac, Crypto::P256Keypair * operationalKeypair,
                                        bool operationalKeypairExternalOwned);

protected:
    enum class State
    {
        NotInitialized,
        Initialized
    };

    // This is not public to avoid users of DeviceController relying on "innards" access to
    // the raw fabric table. Everything needed should be available with getters on DeviceController.
    const FabricInfo * GetFabricInfo() const
    {
        VerifyOrReturnError((mState == State::Initialized) && (mFabricIndex != kUndefinedFabricIndex), nullptr);
        VerifyOrReturnError(GetFabricTable() != nullptr, nullptr);

        return GetFabricTable()->FindFabricWithIndex(mFabricIndex);
    }

    State mState;

    FabricIndex mFabricIndex = kUndefinedFabricIndex;

    bool mRemoveFromFabricTableOnShutdown = true;
    bool mDeleteFromFabricTableOnShutdown = false;

    FabricTable::AdvertiseIdentity mAdvertiseIdentity = FabricTable::AdvertiseIdentity::Yes;

    // TODO(cecille): Make this configuarable.
    static constexpr int kMaxCommissionableNodes = 10;
    Dnssd::CommissionNodeData mCommissionableNodes[kMaxCommissionableNodes];
    DeviceControllerSystemState * mSystemState = nullptr;

    ControllerDeviceInitParams GetControllerDeviceInitParams();

    OperationalCredentialsDelegate * mOperationalCredentialsDelegate;

    chip::VendorId mVendorId;

    DiscoveredNodeList GetDiscoveredNodes() override { return DiscoveredNodeList(mCommissionableNodes); }
};

#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY
using UdcTransportMgr = TransportMgr<Transport::UDP /* IPv6 */
#if INET_CONFIG_ENABLE_IPV4
                                     ,
                                     Transport::UDP /* IPv4 */
#endif
                                     >;
#endif

/**
 * @brief Callback prototype for ExtendArmFailSafe command.
 */
typedef void (*OnExtendFailsafeSuccess)(
    void * context, const app::Clusters::GeneralCommissioning::Commands::ArmFailSafeResponse::DecodableType & data);
typedef void (*OnExtendFailsafeFailure)(void * context, CHIP_ERROR error);

/**
 * @brief
 *   The commissioner applications can use this class to pair new/unpaired CHIP devices. The application is
 *   required to provide write access to the persistent storage, where the paired device information
 *   will be stored.
 */
class DLL_EXPORT DeviceCommissioner : public DeviceController,
#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY // make this commissioner discoverable
                                      public Protocols::UserDirectedCommissioning::InstanceNameResolver,
#endif
#if CHIP_CONFIG_ENABLE_READ_CLIENT
                                      public app::ClusterStateCache::Callback,
#endif
                                      public SessionEstablishmentDelegate
{
public:
    DeviceCommissioner();
    ~DeviceCommissioner() override;

#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY // make this commissioner discoverable
    /**
     * Set port for User Directed Commissioning
     */
    CHIP_ERROR SetUdcListenPort(uint16_t listenPort);
#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY

    /**
     * Commissioner-specific initialization, includes parameters such as the pairing delegate.
     */
    CHIP_ERROR Init(CommissionerInitParams params);

    /**
     * @brief
     *  Tears down the entirety of the stack, including destructing key objects in the system.
     *  This is not a thread-safe API, and should be called with external synchronization.
     *
     *  Please see implementation for more details.
     */
    void Shutdown() override;

    // ----- Connection Management -----
    /**
     * @brief
     *   Pair a CHIP device with the provided code. The code can be either a QRCode
     *   or a Manual Setup Code.
     *   Use registered DevicePairingDelegate object to receive notifications on
     *   pairing status updates.
     *
     *   Note: Pairing process requires that the caller has registered PersistentStorageDelegate
     *         in the Init() call.
     *
     * @param[in] remoteDeviceId        The remote device Id.
     * @param[in] setUpCode             The setup code for connecting to the device
     * @param[in] discoveryType         The network discovery type, defaults to DiscoveryType::kAll.
     * @param[in] resolutionData        Optional resolution data previously discovered on the network for the target device.
     */
    CHIP_ERROR PairDevice(NodeId remoteDeviceId, const char * setUpCode, DiscoveryType discoveryType = DiscoveryType::kAll,
                          Optional<Dnssd::CommonResolutionData> resolutionData = NullOptional);
    CHIP_ERROR PairDevice(NodeId remoteDeviceId, const char * setUpCode, const CommissioningParameters & CommissioningParameters,
                          DiscoveryType discoveryType                          = DiscoveryType::kAll,
                          Optional<Dnssd::CommonResolutionData> resolutionData = NullOptional);

    /**
     * @brief
     *   Pair a CHIP device with the provided Rendezvous connection parameters.
     *   Use registered DevicePairingDelegate object to receive notifications on
     *   pairing status updates.
     *
     *   Note: Pairing process requires that the caller has registered PersistentStorageDelegate
     *         in the Init() call.
     *
     * @param[in] remoteDeviceId        The remote device Id.
     * @param[in] rendezvousParams      The Rendezvous connection parameters
     */
    CHIP_ERROR PairDevice(NodeId remoteDeviceId, RendezvousParameters & rendezvousParams);

    /**
     * @overload
     * @param[in] remoteDeviceId        The remote device Id.
     * @param[in] rendezvousParams      The Rendezvous connection parameters
     * @param[in] commissioningParams    The commissioning parameters (uses default if not supplied)
     */
    CHIP_ERROR PairDevice(NodeId remoteDeviceId, RendezvousParameters & rendezvousParams,
                          CommissioningParameters & commissioningParams);

    /**
     * @brief
     *   Start establishing a PASE connection with a node for the purposes of commissioning.
     *   Commissioners that wish to use the auto-commissioning functions should use the
     *   supplied "PairDevice" functions above to automatically establish a connection then
     *   perform commissioning. This function is intended to be use by commissioners that
     *   are not using the supplied auto-commissioner.
     *
     *   This function is non-blocking. PASE is established once the DevicePairingDelegate
     *   receives the OnPairingComplete call.
     *
     *   PASE connections can only be established with nodes that have their commissioning
     *   window open. The PASE connection will fail if this window is not open and the
     *   OnPairingComplete will be called with an error.
     *
     * @param[in] remoteDeviceId        The remote device Id.
     * @param[in] params                The Rendezvous connection parameters
     */
    CHIP_ERROR EstablishPASEConnection(NodeId remoteDeviceId, RendezvousParameters & params);

    /**
     * @brief
     *   Start establishing a PASE connection with a node for the purposes of commissioning.
     *   Commissioners that wish to use the auto-commissioning functions should use the
     *   supplied "PairDevice" functions above to automatically establish a connection then
     *   perform commissioning. This function is intended to be used by commissioners that
     *   are not using the supplied auto-commissioner.
     *
     *   This function is non-blocking. PASE is established once the DevicePairingDelegate
     *   receives the OnPairingComplete call.
     *
     *   PASE connections can only be established with nodes that have their commissioning
     *   window open. The PASE connection will fail if this window is not open and in that case
     *   OnPairingComplete will be called with an error.
     *
     * @param[in] remoteDeviceId        The remote device Id.
     * @param[in] setUpCode             The setup code for connecting to the device
     * @param[in] discoveryType         The network discovery type, defaults to DiscoveryType::kAll.
     * @param[in] resolutionData        Optional resolution data previously discovered on the network for the target device.
     */
    CHIP_ERROR EstablishPASEConnection(NodeId remoteDeviceId, const char * setUpCode,
                                       DiscoveryType discoveryType                          = DiscoveryType::kAll,
                                       Optional<Dnssd::CommonResolutionData> resolutionData = NullOptional);

    /**
     * @brief
     *   Start the auto-commissioning process on a node after establishing a PASE connection.
     *   This function is intended to be used in conjunction with the EstablishPASEConnection
     *   function. It can be called either before or after the DevicePairingDelegate receives
     *   the OnPairingComplete call. Commissioners that want to perform simple auto-commissioning
     *   should use the supplied "PairDevice" functions above, which will establish the PASE
     *   connection and commission automatically.
     *
     * @param[in] remoteDeviceId        The remote device Id.
     * @param[in] params                The commissioning parameters
     */
    CHIP_ERROR Commission(NodeId remoteDeviceId, CommissioningParameters & params);
    CHIP_ERROR Commission(NodeId remoteDeviceId);

    /**
     * @brief
     *   This function instructs the commissioner to proceed to the next stage of commissioning after
     *   attestation is reported to an installed attestation delegate.
     *
     * @param[in] device                The device being commissioned.
     * @param[in] attestationResult     The attestation result to use instead of whatever the device
     *                                  attestation verifier came up with. May be a success or an error result.
     */
    CHIP_ERROR
    ContinueCommissioningAfterDeviceAttestation(DeviceProxy * device, Credentials::AttestationVerificationResult attestationResult);

    CHIP_ERROR GetDeviceBeingCommissioned(NodeId deviceId, CommissioneeDeviceProxy ** device);

    /**
     * @brief
     *   This function stops a pairing or commissioning process that is in progress.
     *   It does not delete the pairing of a previously paired device.
     *
     *   Note that cancelling an ongoing commissioning process is an asynchronous operation.
     *   The pairing delegate (if any) will receive OnCommissioningComplete and OnCommissioningFailure
     *   failure callbacks with a status code of CHIP_ERROR_CANCELLED once cancellation is complete.
     *
     * @param[in] remoteDeviceId        The remote device Id.
     *
     * @return CHIP_ERROR               CHIP_NO_ERROR on success, or corresponding error
     */
    CHIP_ERROR StopPairing(NodeId remoteDeviceId);

    /**
     * @brief
     *   Remove pairing for a paired device. If the device is currently being paired, it'll stop the pairing process.
     *
     * @param[in] remoteDeviceId        The remote device Id.
     *
     * @return CHIP_ERROR               CHIP_NO_ERROR on success, or corresponding error
     */
    CHIP_ERROR UnpairDevice(NodeId remoteDeviceId);

    //////////// SessionEstablishmentDelegate Implementation ///////////////
    void OnSessionEstablishmentError(CHIP_ERROR error) override;
    void OnSessionEstablished(const SessionHandle & session) override;

    void RendezvousCleanup(CHIP_ERROR status);

    void PerformCommissioningStep(DeviceProxy * device, CommissioningStage step, CommissioningParameters & params,
                                  CommissioningDelegate * delegate, EndpointId endpoint, Optional<System::Clock::Timeout> timeout);

    /**
     * @brief
     *   This function validates the Attestation Information sent by the device.
     *
     * @param[in] info Structure containing all the required information for validating the device attestation.
     */
    CHIP_ERROR ValidateAttestationInfo(const Credentials::DeviceAttestationVerifier::AttestationInfo & info);

    /**
     * @brief
     * Sends CommissioningStepComplete report to the commissioning delegate. Function will fill in current step.
     * @params[in] err      error from the current step
     * @params[in] report   report to send. Current step will be filled in automatically
     */
    void
    CommissioningStageComplete(CHIP_ERROR err,
                               CommissioningDelegate::CommissioningReport report = CommissioningDelegate::CommissioningReport());

    /**
     * @brief
     *   This function is called by the DevicePairingDelegate to indicate that network credentials have been set
     * on the CommissioningParameters of the CommissioningDelegate using CommissioningDelegate.SetCommissioningParameters().
     * As a result, commissioning can advance to the next stage.
     *
     * The DevicePairingDelegate may call this method from the OnScanNetworksSuccess and OnScanNetworksFailure callbacks,
     * or it may call this method after obtaining network credentials using asynchronous methods (prompting user, cloud API call,
     * etc).
     *
     * If an error happens in the subsequent network commissioning step (either NetworkConfig or ConnectNetwork commands)
     * then the DevicePairingDelegate will receive the error in completionStatus.networkCommissioningStatus and the
     * commissioning stage will return to kNeedsNetworkCreds so that the DevicePairingDelegate can re-attempt with new
     * network information. The DevicePairingDelegate can exit the commissioning process by calling StopPairing.
     *
     * @return CHIP_ERROR   The return status. Returns CHIP_ERROR_INCORRECT_STATE if not in the correct state (kNeedsNetworkCreds).
     */
    CHIP_ERROR NetworkCredentialsReady();

    /**
     * @brief
     *   This function is called by the DevicePairingDelegate to indicate that ICD registration info (ICDSymmetricKey,
     * ICDCheckInNodeId and ICDMonitoredSubject) have been set on the CommissioningParameters of the CommissioningDelegate
     * using CommissioningDelegate.SetCommissioningParameters(). As a result, commissioning can advance to the next stage.
     *
     * The DevicePairingDelegate may call this method from the OnICDRegistrationInfoRequired callback, or it may call this
     * method after obtaining required parameters for ICD registration using asynchronous methods (like RPC call etc).
     *
     * When the ICD Registration completes, OnICDRegistrationComplete will be called.
     *
     * @return CHIP_ERROR   The return status. Returns CHIP_ERROR_INCORRECT_STATE if not in the correct state
     * (kICDGetRegistrationInfo).
     */
    CHIP_ERROR ICDRegistrationInfoReady();

    /**
     * @brief
     *  This function returns the current CommissioningStage for this commissioner.
     */
    CommissioningStage GetCommissioningStage() { return mCommissioningStage; }

#if CONFIG_NETWORK_LAYER_BLE
#if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE
    /**
     * @brief
     *   Prior to commissioning, the Controller should make sure the BleLayer transport
     *   is set to the Commissioner transport and not the Server transport.
     */
    void ConnectBleTransportToSelf();
#endif // CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE

    /**
     * @brief
     *   Once we have finished all commissioning work, the Controller should close the BLE
     *   connection to the device and establish CASE session / another PASE session to the device
     *   if needed.
     */
    void CloseBleConnection();
#endif
    /**
     * @brief
     *   Discover all devices advertising as commissionable.
     *   Should be called on main loop thread.
     * * @param[in] filter  Browse filter - controller will look for only the specified subtype.
     * @return CHIP_ERROR   The return status
     */
    CHIP_ERROR DiscoverCommissionableNodes(Dnssd::DiscoveryFilter filter);

    /**
     * Stop commissionable discovery triggered by a previous
     * DiscoverCommissionableNodes call.
     */
    CHIP_ERROR StopCommissionableDiscovery();

    /**
     * @brief
     *   Returns information about discovered devices.
     *   Should be called on main loop thread.
     * @return const DiscoveredNodeData* info about the selected device. May be nullptr if no information has been returned yet.
     */
    const Dnssd::CommissionNodeData * GetDiscoveredDevice(int idx);

    /**
     * @brief
     *   Returns the max number of commissionable nodes this commissioner can track mdns information for.
     * @return int  The max number of commissionable nodes supported
     */
    int GetMaxCommissionableNodesSupported() { return kMaxCommissionableNodes; }

#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY // make this commissioner discoverable
    /**
     * @brief
     *   Called when a UDC message is received specifying the given instanceName
     * This method indicates that UDC Server needs the Commissionable Node corresponding to
     * the given instance name to be found. UDC Server will wait for OnCommissionableNodeFound.
     *
     * @param instanceName DNS-SD instance name for the client requesting commissioning
     *
     */
    void FindCommissionableNode(char * instanceName) override;

    /**
     * @brief
     *   Return the UDC Server instance
     *
     */
    Protocols::UserDirectedCommissioning::UserDirectedCommissioningServer * GetUserDirectedCommissioningServer()
    {
        return mUdcServer;
    }
#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY

    /**
     * @brief
     *   Overrides method from AbstractDnssdDiscoveryController
     *
     * @param nodeData DNS-SD node information
     *
     */
    void OnNodeDiscovered(const chip::Dnssd::DiscoveredNodeData & nodeData) override;

    void RegisterPairingDelegate(DevicePairingDelegate * pairingDelegate) { mPairingDelegate = pairingDelegate; }
    DevicePairingDelegate * GetPairingDelegate() const { return mPairingDelegate; }

#if CHIP_CONFIG_ENABLE_READ_CLIENT
    // ClusterStateCache::Callback impl
    void OnDone(app::ReadClient *) override;
#endif // CHIP_CONFIG_ENABLE_READ_CLIENT

    // Issue an NOC chain using the associated OperationalCredentialsDelegate. The NOC chain will
    // be provided in X509 DER format.
    // NOTE: This is only valid assuming that `mOperationalCredentialsDelegate` is what is desired
    // to issue the NOC chain.
    CHIP_ERROR IssueNOCChain(const ByteSpan & NOCSRElements, NodeId nodeId,
                             chip::Callback::Callback<OnNOCChainGeneration> * callback);

    void SetDeviceAttestationVerifier(Credentials::DeviceAttestationVerifier * deviceAttestationVerifier)
    {
        mDeviceAttestationVerifier = deviceAttestationVerifier;
    }

    Credentials::DeviceAttestationVerifier * GetDeviceAttestationVerifier() const { return mDeviceAttestationVerifier; }

    Optional<CommissioningParameters> GetCommissioningParameters()
    {
        return mDefaultCommissioner == nullptr ? NullOptional : MakeOptional(mDefaultCommissioner->GetCommissioningParameters());
    }

    // Reset the arm failsafe timer during commissioning.  If this returns
    // false, that means that the timer was already set for a longer time period
    // than the new time we are trying to set.  In this case, neither
    // onSuccess nor onFailure will be called.
    bool ExtendArmFailSafe(DeviceProxy * proxy, CommissioningStage step, uint16_t armFailSafeTimeout,
                           Optional<System::Clock::Timeout> commandTimeout, OnExtendFailsafeSuccess onSuccess,
                           OnExtendFailsafeFailure onFailure)
    {
        // If this method is called directly by a client, assume it's fire-and-forget (not a commissioning stage)
        return ExtendArmFailSafeInternal(proxy, step, armFailSafeTimeout, commandTimeout, onSuccess, onFailure,
                                         /* fireAndForget = */ true);
    }

private:
    DevicePairingDelegate * mPairingDelegate = nullptr;

    DeviceProxy * mDeviceBeingCommissioned               = nullptr;
    CommissioneeDeviceProxy * mDeviceInPASEEstablishment = nullptr;

    CommissioningStage mCommissioningStage = CommissioningStage::kSecurePairing;
    bool mRunCommissioningAfterConnection  = false;
    Internal::InvokeCancelFn mInvokeCancelFn;
    Internal::WriteCancelFn mWriteCancelFn;

    ObjectPool<CommissioneeDeviceProxy, kNumMaxActiveDevices> mCommissioneeDevicePool;

#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY // make this commissioner discoverable
    Protocols::UserDirectedCommissioning::UserDirectedCommissioningServer * mUdcServer = nullptr;
    // mUdcTransportMgr is for insecure communication (ex. user directed commissioning)
    UdcTransportMgr * mUdcTransportMgr = nullptr;
    uint16_t mUdcListenPort            = CHIP_UDC_PORT;
#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY

#if CONFIG_NETWORK_LAYER_BLE
    static void OnDiscoveredDeviceOverBleSuccess(void * appState, BLE_CONNECTION_OBJECT connObj);
    static void OnDiscoveredDeviceOverBleError(void * appState, CHIP_ERROR err);
    RendezvousParameters mRendezvousParametersForDeviceDiscoveredOverBle;
#endif
#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
    static void OnWiFiPAFSubscribeComplete(void * appState);
    static void OnWiFiPAFSubscribeError(void * appState, CHIP_ERROR err);
    RendezvousParameters mRendezvousParametersForDeviceDiscoveredOverWiFiPAF;
#endif

    static void OnBasicFailure(void * context, CHIP_ERROR err);
    static void OnBasicSuccess(void * context, const chip::app::DataModel::NullObjectType &);

    /* This function sends a Device Attestation Certificate chain request to the device.
       The function does not hold a reference to the device object.
     */
    CHIP_ERROR SendCertificateChainRequestCommand(DeviceProxy * device, Credentials::CertificateType certificateType,
                                                  Optional<System::Clock::Timeout> timeout);
    /* This function sends an Attestation request to the device.
       The function does not hold a reference to the device object.
     */
    CHIP_ERROR SendAttestationRequestCommand(DeviceProxy * device, const ByteSpan & attestationNonce,
                                             Optional<System::Clock::Timeout> timeout);
    /* This function sends an CSR request to the device.
       The function does not hold a reference to the device object.
     */
    CHIP_ERROR SendOperationalCertificateSigningRequestCommand(DeviceProxy * device, const ByteSpan & csrNonce,
                                                               Optional<System::Clock::Timeout> timeout);
    /* This function sends the operational credentials to the device.
       The function does not hold a reference to the device object.
     */
    CHIP_ERROR SendOperationalCertificate(DeviceProxy * device, const ByteSpan & nocCertBuf, const Optional<ByteSpan> & icaCertBuf,
                                          Crypto::IdentityProtectionKeySpan ipk, NodeId adminSubject,
                                          Optional<System::Clock::Timeout> timeout);
    /* This function sends the trusted root certificate to the device.
       The function does not hold a reference to the device object.
     */
    CHIP_ERROR SendTrustedRootCertificate(DeviceProxy * device, const ByteSpan & rcac, Optional<System::Clock::Timeout> timeout);

    /* This function is called by the commissioner code when the device completes
       the operational credential provisioning process.
       The function does not hold a reference to the device object.
       */
    CHIP_ERROR OnOperationalCredentialsProvisioningCompletion(DeviceProxy * device);

    /* Callback when the previously sent CSR request results in failure */
    static void OnCSRFailureResponse(void * context, CHIP_ERROR error);

    void ExtendArmFailSafeForDeviceAttestation(const Credentials::DeviceAttestationVerifier::AttestationInfo & info,
                                               Credentials::AttestationVerificationResult result);
    static void OnCertificateChainFailureResponse(void * context, CHIP_ERROR error);
    static void OnCertificateChainResponse(
        void * context, const app::Clusters::OperationalCredentials::Commands::CertificateChainResponse::DecodableType & response);

    static void OnAttestationFailureResponse(void * context, CHIP_ERROR error);
    static void
    OnAttestationResponse(void * context,
                          const app::Clusters::OperationalCredentials::Commands::AttestationResponse::DecodableType & data);

    /**
     * @brief
     *   This function is called by the IM layer when the commissioner receives the CSR from the device.
     *   (Reference: Specifications section 11.18.5.6. NOCSR Elements)
     *
     * @param[in] context               The context provided while registering the callback.
     * @param[in] data                  The response struct containing the following fields:
     *                                    NOCSRElements: CSR elements as per specifications section 11.22.5.6. NOCSR Elements.
     *                                    AttestationSignature: Cryptographic signature generated for the fields in the response
     * message.
     */
    static void OnOperationalCertificateSigningRequest(
        void * context, const app::Clusters::OperationalCredentials::Commands::CSRResponse::DecodableType & data);

    /* Callback when adding operational certs to device results in failure */
    static void OnAddNOCFailureResponse(void * context, CHIP_ERROR errro);
    /* Callback when the device confirms that it has added the operational certificates */
    static void
    OnOperationalCertificateAddResponse(void * context,
                                        const app::Clusters::OperationalCredentials::Commands::NOCResponse::DecodableType & data);

    /* Callback when the device confirms that it has added the root certificate */
    static void OnRootCertSuccessResponse(void * context, const chip::app::DataModel::NullObjectType &);
    /* Callback called when adding root cert to device results in failure */
    static void OnRootCertFailureResponse(void * context, CHIP_ERROR error);

    static void OnDeviceConnectedFn(void * context, Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle);
    static void OnDeviceConnectionFailureFn(void * context, const ScopedNodeId & peerId, CHIP_ERROR error);
#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
    static void OnDeviceConnectionRetryFn(void * context, const ScopedNodeId & peerId, CHIP_ERROR error,
                                          System::Clock::Seconds16 retryTimeout);
#endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES

    static void OnDeviceAttestationInformationVerification(void * context,
                                                           const Credentials::DeviceAttestationVerifier::AttestationInfo & info,
                                                           Credentials::AttestationVerificationResult result);

    static void OnDeviceNOCChainGeneration(void * context, CHIP_ERROR status, const ByteSpan & noc, const ByteSpan & icac,
                                           const ByteSpan & rcac, Optional<Crypto::IdentityProtectionKeySpan> ipk,
                                           Optional<NodeId> adminSubject);
    static void OnArmFailSafe(void * context,
                              const chip::app::Clusters::GeneralCommissioning::Commands::ArmFailSafeResponse::DecodableType & data);
    static void OnSetRegulatoryConfigResponse(
        void * context,
        const chip::app::Clusters::GeneralCommissioning::Commands::SetRegulatoryConfigResponse::DecodableType & data);
    static void OnSetUTCError(void * context, CHIP_ERROR error);
    static void
    OnSetTimeZoneResponse(void * context,
                          const chip::app::Clusters::TimeSynchronization::Commands::SetTimeZoneResponse::DecodableType & data);

    static void
    OnScanNetworksResponse(void * context,
                           const app::Clusters::NetworkCommissioning::Commands::ScanNetworksResponse::DecodableType & data);
    static void OnScanNetworksFailure(void * context, CHIP_ERROR err);
    static void
    OnNetworkConfigResponse(void * context,
                            const app::Clusters::NetworkCommissioning::Commands::NetworkConfigResponse::DecodableType & data);
    static void OnConnectNetworkResponse(
        void * context, const chip::app::Clusters::NetworkCommissioning::Commands::ConnectNetworkResponse::DecodableType & data);
    static void OnCommissioningCompleteResponse(
        void * context,
        const chip::app::Clusters::GeneralCommissioning::Commands::CommissioningCompleteResponse::DecodableType & data);
    static void OnDisarmFailsafe(void * context,
                                 const app::Clusters::GeneralCommissioning::Commands::ArmFailSafeResponse::DecodableType & data);
    static void OnDisarmFailsafeFailure(void * context, CHIP_ERROR error);
    void CleanupDoneAfterError();
    static void OnArmFailSafeExtendedForDeviceAttestation(
        void * context, const chip::app::Clusters::GeneralCommissioning::Commands::ArmFailSafeResponse::DecodableType & data);
    static void OnFailedToExtendedArmFailSafeDeviceAttestation(void * context, CHIP_ERROR error);
    void HandleDeviceAttestationCompleted();

    static void OnICDManagementRegisterClientResponse(
        void * context, const app::Clusters::IcdManagement::Commands::RegisterClientResponse::DecodableType & data);

    static void
    OnICDManagementStayActiveResponse(void * context,
                                      const app::Clusters::IcdManagement::Commands::StayActiveResponse::DecodableType & data);

    /**
     * @brief
     *   This function processes the CSR sent by the device.
     *   (Reference: Specifications section 11.18.5.6. NOCSR Elements)
     *
     * @param[in] proxy           device proxy
     * @param[in] NOCSRElements   CSR elements as per specifications section 11.22.5.6. NOCSR Elements.
     * @param[in] AttestationSignature       Cryptographic signature generated for all the above fields.
     * @param[in] dac               device attestation certificate
     * @param[in] pai               Product Attestation Intermediate certificate
     * @param[in] csrNonce          certificate signing request nonce
     */
    CHIP_ERROR ProcessCSR(DeviceProxy * proxy, const ByteSpan & NOCSRElements, const ByteSpan & AttestationSignature,
                          const ByteSpan & dac, const ByteSpan & pai, const ByteSpan & csrNonce);

    /**
     * @brief
     *   This function validates the CSR information from the device.
     *   (Reference: Specifications section 11.18.5.6. NOCSR Elements)
     *
     * @param[in] proxy           device proxy
     * @param[in] NOCSRElements   CSR elements as per specifications section 11.22.5.6. NOCSR Elements.
     * @param[in] AttestationSignature       Cryptographic signature generated for all the above fields.
     * @param[in] dac               device attestation certificate
     * @param[in] csrNonce          certificate signing request nonce
     */
    CHIP_ERROR ValidateCSR(DeviceProxy * proxy, const ByteSpan & NOCSRElements, const ByteSpan & AttestationSignature,
                           const ByteSpan & dac, const ByteSpan & csrNonce);

    /**
     * @brief
     *   This function validates the revocation status of the DAC Chain sent by the device.
     *
     * @param[in] info Structure containing all the required information for validating the device attestation.
     */
    CHIP_ERROR CheckForRevokedDACChain(const Credentials::DeviceAttestationVerifier::AttestationInfo & info);

    CommissioneeDeviceProxy * FindCommissioneeDevice(NodeId id);
    CommissioneeDeviceProxy * FindCommissioneeDevice(const Transport::PeerAddress & peerAddress);
    void ReleaseCommissioneeDevice(CommissioneeDeviceProxy * device);

    bool ExtendArmFailSafeInternal(DeviceProxy * proxy, CommissioningStage step, uint16_t armFailSafeTimeout,
                                   Optional<System::Clock::Timeout> commandTimeout, OnExtendFailsafeSuccess onSuccess,
                                   OnExtendFailsafeFailure onFailure, bool fireAndForget);

    template <typename RequestObjectT>
    CHIP_ERROR SendCommissioningCommand(DeviceProxy * device, const RequestObjectT & request,
                                        CommandResponseSuccessCallback<typename RequestObjectT::ResponseType> successCb,
                                        CommandResponseFailureCallback failureCb, EndpointId endpoint,
                                        Optional<System::Clock::Timeout> timeout = NullOptional, bool fireAndForget = false);
    void SendCommissioningReadRequest(DeviceProxy * proxy, Optional<System::Clock::Timeout> timeout,
                                      app::AttributePathParams * readPaths, size_t readPathsSize);
    template <typename AttrType>
    CHIP_ERROR SendCommissioningWriteRequest(DeviceProxy * device, EndpointId endpoint, ClusterId cluster, AttributeId attribute,
                                             const AttrType & requestData, WriteResponseSuccessCallback successCb,
                                             WriteResponseFailureCallback failureCb);
    void CancelCommissioningInteractions();
    void CancelCASECallbacks();

#if CHIP_CONFIG_ENABLE_READ_CLIENT
    void ParseCommissioningInfo();
    // Parsing attributes read in kReadCommissioningInfo stage.
    CHIP_ERROR ParseCommissioningInfo1(ReadCommissioningInfo & info);
    // Parsing attributes read in kReadCommissioningInfo2 stage.
    CHIP_ERROR ParseCommissioningInfo2(ReadCommissioningInfo & info);
    // Called by ParseCommissioningInfo2
    CHIP_ERROR ParseFabrics(ReadCommissioningInfo & info);
    CHIP_ERROR ParseICDInfo(ReadCommissioningInfo & info);
    // Called by ParseCommissioningInfo
    void ParseTimeSyncInfo(ReadCommissioningInfo & info);
#endif // CHIP_CONFIG_ENABLE_READ_CLIENT

    static CHIP_ERROR
    ConvertFromOperationalCertStatus(chip::app::Clusters::OperationalCredentials::NodeOperationalCertStatusEnum err);

    // Sends commissioning complete callbacks to the delegate depending on the status. Sends
    // OnCommissioningComplete and either OnCommissioningSuccess or OnCommissioningFailure depending on the given completion status.
    void SendCommissioningCompleteCallbacks(NodeId nodeId, const CompletionStatus & completionStatus);

    // Cleans up and resets failsafe as appropriate depending on the error and the failed stage.
    // For success, sends completion report with the CommissioningDelegate and sends callbacks to the PairingDelegate
    // For failures after AddNOC succeeds, sends completion report with the CommissioningDelegate and sends callbacks to the
    // PairingDelegate. In this case, it does not disarm the failsafe or close the pase connection. For failures up through AddNOC,
    // sends a command to immediately expire the failsafe, then sends completion report with the CommissioningDelegate and callbacks
    // to the PairingDelegate upon arm failsafe command completion.
    void CleanupCommissioning(DeviceProxy * proxy, NodeId nodeId, const CompletionStatus & completionStatus);

    // Extend the fail-safe before trying to do network-enable (since after that
    // point, for non-concurrent-commissioning devices, we may not have a way to
    // extend it).
    void ExtendFailsafeBeforeNetworkEnable(DeviceProxy * device, CommissioningParameters & params, CommissioningStage step);

    bool IsAttestationInformationMissing(const CommissioningParameters & params);

    chip::Callback::Callback<OnDeviceConnected> mOnDeviceConnectedCallback;
    chip::Callback::Callback<OnDeviceConnectionFailure> mOnDeviceConnectionFailureCallback;
#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
    chip::Callback::Callback<OnDeviceConnectionRetry> mOnDeviceConnectionRetryCallback;
#endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES

    chip::Callback::Callback<Credentials::DeviceAttestationVerifier::OnAttestationInformationVerification>
        mDeviceAttestationInformationVerificationCallback;

    chip::Callback::Callback<OnNOCChainGeneration> mDeviceNOCChainCallback;
    SetUpCodePairer mSetUpCodePairer;
    AutoCommissioner mAutoCommissioner;
    CommissioningDelegate * mDefaultCommissioner =
        nullptr; // Commissioning delegate to call when PairDevice / Commission functions are used
    CommissioningDelegate * mCommissioningDelegate =
        nullptr; // Commissioning delegate that issued the PerformCommissioningStep command
    CompletionStatus mCommissioningCompletionStatus;

#if CHIP_CONFIG_ENABLE_READ_CLIENT
    Platform::UniquePtr<app::ClusterStateCache> mAttributeCache;
    Platform::UniquePtr<app::ReadClient> mReadClient;
#endif
    Credentials::AttestationVerificationResult mAttestationResult;
    Platform::UniquePtr<Credentials::DeviceAttestationVerifier::AttestationDeviceInfo> mAttestationDeviceInfo;
    Credentials::DeviceAttestationVerifier * mDeviceAttestationVerifier = nullptr;
};

} // namespace Controller
} // namespace chip
