/*
 *
 *    Copyright (c) 2021 Project CHIP Authors
 *
 *    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.
 */

// THIS FILE IS GENERATED BY ZAP
#include "CHIPClusters.h"

#include <cstdint>

#include "chip-zcl-zpro-codec-api.h"
#include <gen/CHIPClientCallbacks.h>
#include <lib/support/Span.h>

namespace chip {
namespace Controller {

// TODO(#4502): onCompletion is not used by IM for now.
// TODO(#4503): length should be passed to commands when byte string is in argument list.
// TODO(#4503): Commands should take group id as an argument.

// AccountLogin Cluster Commands
CHIP_ERROR AccountLoginCluster::GetSetupPIN(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                            chip::ByteSpan tempAccountIdentifier)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kGetSetupPINCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // tempAccountIdentifier: charString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), tempAccountIdentifier));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR AccountLoginCluster::Login(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                      chip::ByteSpan tempAccountIdentifier, chip::ByteSpan setupPIN)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kLoginCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // tempAccountIdentifier: charString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), tempAccountIdentifier));
    // setupPIN: charString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), setupPIN));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

// AccountLogin Cluster Attributes
CHIP_ERROR AccountLoginCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback,
                                                   Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeAccountLoginClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR AccountLoginCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                             Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// ApplicationBasic Cluster Commands
CHIP_ERROR ApplicationBasicCluster::ChangeStatus(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                                 uint8_t status)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kChangeStatusCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // status: applicationBasicStatus
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), status));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

// ApplicationBasic Cluster Attributes
CHIP_ERROR ApplicationBasicCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback,
                                                       Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeApplicationBasicClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR ApplicationBasicCluster::ReadAttributeVendorName(Callback::Cancelable * onSuccessCallback,
                                                            Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0000;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<StringAttributeCallback>);
}

CHIP_ERROR ApplicationBasicCluster::ReadAttributeVendorId(Callback::Cancelable * onSuccessCallback,
                                                          Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0001;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ApplicationBasicCluster::ReadAttributeApplicationName(Callback::Cancelable * onSuccessCallback,
                                                                 Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0002;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<StringAttributeCallback>);
}

CHIP_ERROR ApplicationBasicCluster::ReadAttributeProductId(Callback::Cancelable * onSuccessCallback,
                                                           Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0003;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ApplicationBasicCluster::ReadAttributeApplicationId(Callback::Cancelable * onSuccessCallback,
                                                               Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0005;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<StringAttributeCallback>);
}

CHIP_ERROR ApplicationBasicCluster::ReadAttributeCatalogVendorId(Callback::Cancelable * onSuccessCallback,
                                                                 Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0006;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ApplicationBasicCluster::ReadAttributeApplicationStatus(Callback::Cancelable * onSuccessCallback,
                                                                   Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0007;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR ApplicationBasicCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                                 Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// ApplicationLauncher Cluster Commands
CHIP_ERROR ApplicationLauncherCluster::LaunchApp(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                                 chip::ByteSpan data, uint16_t catalogVendorId, chip::ByteSpan applicationId)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kLaunchAppCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // data: charString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), data));
    // catalogVendorId: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), catalogVendorId));
    // applicationId: charString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), applicationId));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

// ApplicationLauncher Cluster Attributes
CHIP_ERROR ApplicationLauncherCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback,
                                                          Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeApplicationLauncherClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR ApplicationLauncherCluster::ReadAttributeApplicationLauncherList(Callback::Cancelable * onSuccessCallback,
                                                                            Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0000;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             ApplicationLauncherClusterApplicationLauncherListListAttributeFilter);
}

CHIP_ERROR ApplicationLauncherCluster::ReadAttributeCatalogVendorId(Callback::Cancelable * onSuccessCallback,
                                                                    Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0001;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR ApplicationLauncherCluster::ReadAttributeApplicationId(Callback::Cancelable * onSuccessCallback,
                                                                  Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0002;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR ApplicationLauncherCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                                    Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// AudioOutput Cluster Commands
CHIP_ERROR AudioOutputCluster::RenameOutput(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                            uint8_t index, chip::ByteSpan name)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kRenameOutputCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // index: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), index));
    // name: charString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), name));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR AudioOutputCluster::SelectOutput(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                            uint8_t index)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kSelectOutputCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // index: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), index));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

// AudioOutput Cluster Attributes
CHIP_ERROR AudioOutputCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback,
                                                  Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeAudioOutputClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR AudioOutputCluster::ReadAttributeAudioOutputList(Callback::Cancelable * onSuccessCallback,
                                                            Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0000;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             AudioOutputClusterAudioOutputListListAttributeFilter);
}

CHIP_ERROR AudioOutputCluster::ReadAttributeCurrentAudioOutput(Callback::Cancelable * onSuccessCallback,
                                                               Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0001;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR AudioOutputCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                            Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// BarrierControl Cluster Commands
CHIP_ERROR BarrierControlCluster::BarrierControlGoToPercent(Callback::Cancelable * onSuccessCallback,
                                                            Callback::Cancelable * onFailureCallback, uint8_t percentOpen)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kBarrierControlGoToPercentCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // percentOpen: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), percentOpen));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR BarrierControlCluster::BarrierControlStop(Callback::Cancelable * onSuccessCallback,
                                                     Callback::Cancelable * onFailureCallback)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kBarrierControlStopCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    // Command takes no arguments.

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

// BarrierControl Cluster Attributes
CHIP_ERROR BarrierControlCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback,
                                                     Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeBarrierControlClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR BarrierControlCluster::ReadAttributeBarrierMovingState(Callback::Cancelable * onSuccessCallback,
                                                                  Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0001;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR BarrierControlCluster::ReadAttributeBarrierSafetyStatus(Callback::Cancelable * onSuccessCallback,
                                                                   Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0002;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR BarrierControlCluster::ReadAttributeBarrierCapabilities(Callback::Cancelable * onSuccessCallback,
                                                                   Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0003;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR BarrierControlCluster::ReadAttributeBarrierPosition(Callback::Cancelable * onSuccessCallback,
                                                               Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x000A;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR BarrierControlCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                               Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// Basic Cluster Commands
CHIP_ERROR BasicCluster::MfgSpecificPing(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kMfgSpecificPingCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    // Command takes no arguments.

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

// Basic Cluster Attributes
CHIP_ERROR BasicCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeBasicClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR BasicCluster::ReadAttributeInteractionModelVersion(Callback::Cancelable * onSuccessCallback,
                                                              Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0000;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR BasicCluster::ReadAttributeVendorName(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0001;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<StringAttributeCallback>);
}

CHIP_ERROR BasicCluster::ReadAttributeVendorID(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0002;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR BasicCluster::ReadAttributeProductName(Callback::Cancelable * onSuccessCallback,
                                                  Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0003;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<StringAttributeCallback>);
}

CHIP_ERROR BasicCluster::ReadAttributeProductID(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0004;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR BasicCluster::ReadAttributeUserLabel(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0005;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<StringAttributeCallback>);
}

CHIP_ERROR BasicCluster::WriteAttributeUserLabel(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                                 chip::ByteSpan value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeBasicClusterWriteUserLabelAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR BasicCluster::ReadAttributeLocation(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0006;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<StringAttributeCallback>);
}

CHIP_ERROR BasicCluster::WriteAttributeLocation(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                                chip::ByteSpan value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeBasicClusterWriteLocationAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR BasicCluster::ReadAttributeHardwareVersion(Callback::Cancelable * onSuccessCallback,
                                                      Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0007;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR BasicCluster::ReadAttributeHardwareVersionString(Callback::Cancelable * onSuccessCallback,
                                                            Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0008;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<StringAttributeCallback>);
}

CHIP_ERROR BasicCluster::ReadAttributeSoftwareVersion(Callback::Cancelable * onSuccessCallback,
                                                      Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0009;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR BasicCluster::ReadAttributeSoftwareVersionString(Callback::Cancelable * onSuccessCallback,
                                                            Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x000A;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<StringAttributeCallback>);
}

CHIP_ERROR BasicCluster::ReadAttributeManufacturingDate(Callback::Cancelable * onSuccessCallback,
                                                        Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x000B;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<StringAttributeCallback>);
}

CHIP_ERROR BasicCluster::ReadAttributePartNumber(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x000C;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<StringAttributeCallback>);
}

CHIP_ERROR BasicCluster::ReadAttributeProductURL(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x000D;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<StringAttributeCallback>);
}

CHIP_ERROR BasicCluster::ReadAttributeProductLabel(Callback::Cancelable * onSuccessCallback,
                                                   Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x000E;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<StringAttributeCallback>);
}

CHIP_ERROR BasicCluster::ReadAttributeSerialNumber(Callback::Cancelable * onSuccessCallback,
                                                   Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x000F;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<StringAttributeCallback>);
}

CHIP_ERROR BasicCluster::ReadAttributeLocalConfigDisabled(Callback::Cancelable * onSuccessCallback,
                                                          Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0010;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<BooleanAttributeCallback>);
}

CHIP_ERROR BasicCluster::WriteAttributeLocalConfigDisabled(Callback::Cancelable * onSuccessCallback,
                                                           Callback::Cancelable * onFailureCallback, uint8_t value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeBasicClusterWriteLocalConfigDisabledAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR BasicCluster::ReadAttributeReachable(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0011;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<BooleanAttributeCallback>);
}

CHIP_ERROR BasicCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                      Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// BinaryInputBasic Cluster Commands
// BinaryInputBasic Cluster Attributes
CHIP_ERROR BinaryInputBasicCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback,
                                                       Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeBinaryInputBasicClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR BinaryInputBasicCluster::ReadAttributeOutOfService(Callback::Cancelable * onSuccessCallback,
                                                              Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0051;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<BooleanAttributeCallback>);
}

CHIP_ERROR BinaryInputBasicCluster::WriteAttributeOutOfService(Callback::Cancelable * onSuccessCallback,
                                                               Callback::Cancelable * onFailureCallback, uint8_t value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeBinaryInputBasicClusterWriteOutOfServiceAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR BinaryInputBasicCluster::ReadAttributePresentValue(Callback::Cancelable * onSuccessCallback,
                                                              Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0055;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<BooleanAttributeCallback>);
}

CHIP_ERROR BinaryInputBasicCluster::WriteAttributePresentValue(Callback::Cancelable * onSuccessCallback,
                                                               Callback::Cancelable * onFailureCallback, uint8_t value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeBinaryInputBasicClusterWritePresentValueAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR BinaryInputBasicCluster::ConfigureAttributePresentValue(Callback::Cancelable * onSuccessCallback,
                                                                   Callback::Cancelable * onFailureCallback, uint16_t minInterval,
                                                                   uint16_t maxInterval)
{
    uint8_t seqNum = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand =
        encodeBinaryInputBasicClusterConfigurePresentValueAttribute(seqNum, mEndpoint, minInterval, maxInterval);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR BinaryInputBasicCluster::ReportAttributePresentValue(Callback::Cancelable * onReportCallback)
{
    return RequestAttributeReporting(0x0055, onReportCallback);
}

CHIP_ERROR BinaryInputBasicCluster::ReadAttributeStatusFlags(Callback::Cancelable * onSuccessCallback,
                                                             Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x006F;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR BinaryInputBasicCluster::ConfigureAttributeStatusFlags(Callback::Cancelable * onSuccessCallback,
                                                                  Callback::Cancelable * onFailureCallback, uint16_t minInterval,
                                                                  uint16_t maxInterval)
{
    uint8_t seqNum = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand =
        encodeBinaryInputBasicClusterConfigureStatusFlagsAttribute(seqNum, mEndpoint, minInterval, maxInterval);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR BinaryInputBasicCluster::ReportAttributeStatusFlags(Callback::Cancelable * onReportCallback)
{
    return RequestAttributeReporting(0x006F, onReportCallback);
}

CHIP_ERROR BinaryInputBasicCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                                 Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// Binding Cluster Commands
CHIP_ERROR BindingCluster::Bind(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                chip::NodeId nodeId, chip::GroupId groupId, chip::EndpointId endpointId, chip::ClusterId clusterId)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kBindCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // nodeId: nodeId
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), nodeId));
    // groupId: groupId
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), groupId));
    // endpointId: endpointNo
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), endpointId));
    // clusterId: clusterId
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), clusterId));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR BindingCluster::Unbind(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                  chip::NodeId nodeId, chip::GroupId groupId, chip::EndpointId endpointId,
                                  chip::ClusterId clusterId)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kUnbindCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // nodeId: nodeId
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), nodeId));
    // groupId: groupId
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), groupId));
    // endpointId: endpointNo
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), endpointId));
    // clusterId: clusterId
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), clusterId));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

// Binding Cluster Attributes
CHIP_ERROR BindingCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeBindingClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR BindingCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                        Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// BridgedDeviceBasic Cluster Commands
// BridgedDeviceBasic Cluster Attributes
CHIP_ERROR BridgedDeviceBasicCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback,
                                                         Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeBridgedDeviceBasicClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR BridgedDeviceBasicCluster::ReadAttributeVendorName(Callback::Cancelable * onSuccessCallback,
                                                              Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0001;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<StringAttributeCallback>);
}

CHIP_ERROR BridgedDeviceBasicCluster::ReadAttributeVendorID(Callback::Cancelable * onSuccessCallback,
                                                            Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0002;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR BridgedDeviceBasicCluster::ReadAttributeProductName(Callback::Cancelable * onSuccessCallback,
                                                               Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0003;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<StringAttributeCallback>);
}

CHIP_ERROR BridgedDeviceBasicCluster::ReadAttributeUserLabel(Callback::Cancelable * onSuccessCallback,
                                                             Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0005;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<StringAttributeCallback>);
}

CHIP_ERROR BridgedDeviceBasicCluster::WriteAttributeUserLabel(Callback::Cancelable * onSuccessCallback,
                                                              Callback::Cancelable * onFailureCallback, chip::ByteSpan value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeBridgedDeviceBasicClusterWriteUserLabelAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR BridgedDeviceBasicCluster::ReadAttributeHardwareVersion(Callback::Cancelable * onSuccessCallback,
                                                                   Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0007;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR BridgedDeviceBasicCluster::ReadAttributeHardwareVersionString(Callback::Cancelable * onSuccessCallback,
                                                                         Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0008;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<StringAttributeCallback>);
}

CHIP_ERROR BridgedDeviceBasicCluster::ReadAttributeSoftwareVersion(Callback::Cancelable * onSuccessCallback,
                                                                   Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0009;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR BridgedDeviceBasicCluster::ReadAttributeSoftwareVersionString(Callback::Cancelable * onSuccessCallback,
                                                                         Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x000A;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<StringAttributeCallback>);
}

CHIP_ERROR BridgedDeviceBasicCluster::ReadAttributeManufacturingDate(Callback::Cancelable * onSuccessCallback,
                                                                     Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x000B;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<StringAttributeCallback>);
}

CHIP_ERROR BridgedDeviceBasicCluster::ReadAttributePartNumber(Callback::Cancelable * onSuccessCallback,
                                                              Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x000C;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<StringAttributeCallback>);
}

CHIP_ERROR BridgedDeviceBasicCluster::ReadAttributeProductURL(Callback::Cancelable * onSuccessCallback,
                                                              Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x000D;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<StringAttributeCallback>);
}

CHIP_ERROR BridgedDeviceBasicCluster::ReadAttributeProductLabel(Callback::Cancelable * onSuccessCallback,
                                                                Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x000E;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<StringAttributeCallback>);
}

CHIP_ERROR BridgedDeviceBasicCluster::ReadAttributeSerialNumber(Callback::Cancelable * onSuccessCallback,
                                                                Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x000F;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<StringAttributeCallback>);
}

CHIP_ERROR BridgedDeviceBasicCluster::ReadAttributeReachable(Callback::Cancelable * onSuccessCallback,
                                                             Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0011;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<BooleanAttributeCallback>);
}

CHIP_ERROR BridgedDeviceBasicCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                                   Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// ColorControl Cluster Commands
CHIP_ERROR ColorControlCluster::ColorLoopSet(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                             uint8_t updateFlags, uint8_t action, uint8_t direction, uint16_t time,
                                             uint16_t startHue, uint8_t optionsMask, uint8_t optionsOverride)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kColorLoopSetCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // updateFlags: colorLoopUpdateFlags
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), updateFlags));
    // action: colorLoopAction
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), action));
    // direction: colorLoopDirection
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), direction));
    // time: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), time));
    // startHue: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), startHue));
    // optionsMask: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionsMask));
    // optionsOverride: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionsOverride));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR ColorControlCluster::EnhancedMoveHue(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                                uint8_t moveMode, uint16_t rate, uint8_t optionsMask, uint8_t optionsOverride)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kEnhancedMoveHueCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // moveMode: hueMoveMode
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), moveMode));
    // rate: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), rate));
    // optionsMask: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionsMask));
    // optionsOverride: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionsOverride));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR ColorControlCluster::EnhancedMoveToHue(Callback::Cancelable * onSuccessCallback,
                                                  Callback::Cancelable * onFailureCallback, uint16_t enhancedHue, uint8_t direction,
                                                  uint16_t transitionTime, uint8_t optionsMask, uint8_t optionsOverride)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kEnhancedMoveToHueCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // enhancedHue: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), enhancedHue));
    // direction: hueDirection
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), direction));
    // transitionTime: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), transitionTime));
    // optionsMask: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionsMask));
    // optionsOverride: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionsOverride));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR ColorControlCluster::EnhancedMoveToHueAndSaturation(Callback::Cancelable * onSuccessCallback,
                                                               Callback::Cancelable * onFailureCallback, uint16_t enhancedHue,
                                                               uint8_t saturation, uint16_t transitionTime, uint8_t optionsMask,
                                                               uint8_t optionsOverride)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kEnhancedMoveToHueAndSaturationCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // enhancedHue: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), enhancedHue));
    // saturation: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), saturation));
    // transitionTime: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), transitionTime));
    // optionsMask: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionsMask));
    // optionsOverride: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionsOverride));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR ColorControlCluster::EnhancedStepHue(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                                uint8_t stepMode, uint16_t stepSize, uint16_t transitionTime, uint8_t optionsMask,
                                                uint8_t optionsOverride)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kEnhancedStepHueCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // stepMode: hueStepMode
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), stepMode));
    // stepSize: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), stepSize));
    // transitionTime: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), transitionTime));
    // optionsMask: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionsMask));
    // optionsOverride: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionsOverride));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR ColorControlCluster::MoveColor(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                          int16_t rateX, int16_t rateY, uint8_t optionsMask, uint8_t optionsOverride)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kMoveColorCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // rateX: int16s
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), rateX));
    // rateY: int16s
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), rateY));
    // optionsMask: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionsMask));
    // optionsOverride: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionsOverride));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR ColorControlCluster::MoveColorTemperature(Callback::Cancelable * onSuccessCallback,
                                                     Callback::Cancelable * onFailureCallback, uint8_t moveMode, uint16_t rate,
                                                     uint16_t colorTemperatureMinimum, uint16_t colorTemperatureMaximum,
                                                     uint8_t optionsMask, uint8_t optionsOverride)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kMoveColorTemperatureCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // moveMode: hueMoveMode
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), moveMode));
    // rate: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), rate));
    // colorTemperatureMinimum: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), colorTemperatureMinimum));
    // colorTemperatureMaximum: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), colorTemperatureMaximum));
    // optionsMask: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionsMask));
    // optionsOverride: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionsOverride));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR ColorControlCluster::MoveHue(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                        uint8_t moveMode, uint8_t rate, uint8_t optionsMask, uint8_t optionsOverride)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kMoveHueCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // moveMode: hueMoveMode
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), moveMode));
    // rate: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), rate));
    // optionsMask: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionsMask));
    // optionsOverride: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionsOverride));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR ColorControlCluster::MoveSaturation(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                               uint8_t moveMode, uint8_t rate, uint8_t optionsMask, uint8_t optionsOverride)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kMoveSaturationCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // moveMode: saturationMoveMode
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), moveMode));
    // rate: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), rate));
    // optionsMask: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionsMask));
    // optionsOverride: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionsOverride));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR ColorControlCluster::MoveToColor(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                            uint16_t colorX, uint16_t colorY, uint16_t transitionTime, uint8_t optionsMask,
                                            uint8_t optionsOverride)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kMoveToColorCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // colorX: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), colorX));
    // colorY: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), colorY));
    // transitionTime: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), transitionTime));
    // optionsMask: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionsMask));
    // optionsOverride: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionsOverride));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR ColorControlCluster::MoveToColorTemperature(Callback::Cancelable * onSuccessCallback,
                                                       Callback::Cancelable * onFailureCallback, uint16_t colorTemperature,
                                                       uint16_t transitionTime, uint8_t optionsMask, uint8_t optionsOverride)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kMoveToColorTemperatureCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // colorTemperature: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), colorTemperature));
    // transitionTime: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), transitionTime));
    // optionsMask: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionsMask));
    // optionsOverride: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionsOverride));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR ColorControlCluster::MoveToHue(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                          uint8_t hue, uint8_t direction, uint16_t transitionTime, uint8_t optionsMask,
                                          uint8_t optionsOverride)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kMoveToHueCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // hue: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), hue));
    // direction: hueDirection
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), direction));
    // transitionTime: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), transitionTime));
    // optionsMask: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionsMask));
    // optionsOverride: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionsOverride));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR ColorControlCluster::MoveToHueAndSaturation(Callback::Cancelable * onSuccessCallback,
                                                       Callback::Cancelable * onFailureCallback, uint8_t hue, uint8_t saturation,
                                                       uint16_t transitionTime, uint8_t optionsMask, uint8_t optionsOverride)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kMoveToHueAndSaturationCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // hue: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), hue));
    // saturation: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), saturation));
    // transitionTime: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), transitionTime));
    // optionsMask: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionsMask));
    // optionsOverride: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionsOverride));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR ColorControlCluster::MoveToSaturation(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                                 uint8_t saturation, uint16_t transitionTime, uint8_t optionsMask,
                                                 uint8_t optionsOverride)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kMoveToSaturationCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // saturation: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), saturation));
    // transitionTime: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), transitionTime));
    // optionsMask: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionsMask));
    // optionsOverride: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionsOverride));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR ColorControlCluster::StepColor(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                          int16_t stepX, int16_t stepY, uint16_t transitionTime, uint8_t optionsMask,
                                          uint8_t optionsOverride)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kStepColorCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // stepX: int16s
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), stepX));
    // stepY: int16s
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), stepY));
    // transitionTime: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), transitionTime));
    // optionsMask: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionsMask));
    // optionsOverride: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionsOverride));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR ColorControlCluster::StepColorTemperature(Callback::Cancelable * onSuccessCallback,
                                                     Callback::Cancelable * onFailureCallback, uint8_t stepMode, uint16_t stepSize,
                                                     uint16_t transitionTime, uint16_t colorTemperatureMinimum,
                                                     uint16_t colorTemperatureMaximum, uint8_t optionsMask, uint8_t optionsOverride)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kStepColorTemperatureCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // stepMode: hueStepMode
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), stepMode));
    // stepSize: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), stepSize));
    // transitionTime: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), transitionTime));
    // colorTemperatureMinimum: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), colorTemperatureMinimum));
    // colorTemperatureMaximum: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), colorTemperatureMaximum));
    // optionsMask: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionsMask));
    // optionsOverride: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionsOverride));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR ColorControlCluster::StepHue(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                        uint8_t stepMode, uint8_t stepSize, uint8_t transitionTime, uint8_t optionsMask,
                                        uint8_t optionsOverride)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kStepHueCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // stepMode: hueStepMode
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), stepMode));
    // stepSize: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), stepSize));
    // transitionTime: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), transitionTime));
    // optionsMask: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionsMask));
    // optionsOverride: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionsOverride));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR ColorControlCluster::StepSaturation(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                               uint8_t stepMode, uint8_t stepSize, uint8_t transitionTime, uint8_t optionsMask,
                                               uint8_t optionsOverride)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kStepSaturationCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // stepMode: saturationStepMode
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), stepMode));
    // stepSize: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), stepSize));
    // transitionTime: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), transitionTime));
    // optionsMask: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionsMask));
    // optionsOverride: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionsOverride));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR ColorControlCluster::StopMoveStep(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                             uint8_t optionsMask, uint8_t optionsOverride)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kStopMoveStepCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // optionsMask: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionsMask));
    // optionsOverride: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionsOverride));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

// ColorControl Cluster Attributes
CHIP_ERROR ColorControlCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback,
                                                   Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeColorControlClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR ColorControlCluster::ReadAttributeCurrentHue(Callback::Cancelable * onSuccessCallback,
                                                        Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0000;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::ConfigureAttributeCurrentHue(Callback::Cancelable * onSuccessCallback,
                                                             Callback::Cancelable * onFailureCallback, uint16_t minInterval,
                                                             uint16_t maxInterval, uint8_t change)
{
    uint8_t seqNum = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand =
        encodeColorControlClusterConfigureCurrentHueAttribute(seqNum, mEndpoint, minInterval, maxInterval, change);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR ColorControlCluster::ReportAttributeCurrentHue(Callback::Cancelable * onReportCallback)
{
    return RequestAttributeReporting(0x0000, onReportCallback);
}

CHIP_ERROR ColorControlCluster::ReadAttributeCurrentSaturation(Callback::Cancelable * onSuccessCallback,
                                                               Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0001;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::ConfigureAttributeCurrentSaturation(Callback::Cancelable * onSuccessCallback,
                                                                    Callback::Cancelable * onFailureCallback, uint16_t minInterval,
                                                                    uint16_t maxInterval, uint8_t change)
{
    uint8_t seqNum = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand =
        encodeColorControlClusterConfigureCurrentSaturationAttribute(seqNum, mEndpoint, minInterval, maxInterval, change);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR ColorControlCluster::ReportAttributeCurrentSaturation(Callback::Cancelable * onReportCallback)
{
    return RequestAttributeReporting(0x0001, onReportCallback);
}

CHIP_ERROR ColorControlCluster::ReadAttributeRemainingTime(Callback::Cancelable * onSuccessCallback,
                                                           Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0002;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::ReadAttributeCurrentX(Callback::Cancelable * onSuccessCallback,
                                                      Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0003;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::ConfigureAttributeCurrentX(Callback::Cancelable * onSuccessCallback,
                                                           Callback::Cancelable * onFailureCallback, uint16_t minInterval,
                                                           uint16_t maxInterval, uint16_t change)
{
    uint8_t seqNum = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand =
        encodeColorControlClusterConfigureCurrentXAttribute(seqNum, mEndpoint, minInterval, maxInterval, change);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR ColorControlCluster::ReportAttributeCurrentX(Callback::Cancelable * onReportCallback)
{
    return RequestAttributeReporting(0x0003, onReportCallback);
}

CHIP_ERROR ColorControlCluster::ReadAttributeCurrentY(Callback::Cancelable * onSuccessCallback,
                                                      Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0004;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::ConfigureAttributeCurrentY(Callback::Cancelable * onSuccessCallback,
                                                           Callback::Cancelable * onFailureCallback, uint16_t minInterval,
                                                           uint16_t maxInterval, uint16_t change)
{
    uint8_t seqNum = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand =
        encodeColorControlClusterConfigureCurrentYAttribute(seqNum, mEndpoint, minInterval, maxInterval, change);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR ColorControlCluster::ReportAttributeCurrentY(Callback::Cancelable * onReportCallback)
{
    return RequestAttributeReporting(0x0004, onReportCallback);
}

CHIP_ERROR ColorControlCluster::ReadAttributeDriftCompensation(Callback::Cancelable * onSuccessCallback,
                                                               Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0005;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::ReadAttributeCompensationText(Callback::Cancelable * onSuccessCallback,
                                                              Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0006;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<StringAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::ReadAttributeColorTemperature(Callback::Cancelable * onSuccessCallback,
                                                              Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0007;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::ConfigureAttributeColorTemperature(Callback::Cancelable * onSuccessCallback,
                                                                   Callback::Cancelable * onFailureCallback, uint16_t minInterval,
                                                                   uint16_t maxInterval, uint16_t change)
{
    uint8_t seqNum = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand =
        encodeColorControlClusterConfigureColorTemperatureAttribute(seqNum, mEndpoint, minInterval, maxInterval, change);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR ColorControlCluster::ReportAttributeColorTemperature(Callback::Cancelable * onReportCallback)
{
    return RequestAttributeReporting(0x0007, onReportCallback);
}

CHIP_ERROR ColorControlCluster::ReadAttributeColorMode(Callback::Cancelable * onSuccessCallback,
                                                       Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0008;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::ReadAttributeColorControlOptions(Callback::Cancelable * onSuccessCallback,
                                                                 Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x000F;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::WriteAttributeColorControlOptions(Callback::Cancelable * onSuccessCallback,
                                                                  Callback::Cancelable * onFailureCallback, uint8_t value)
{
    uint8_t seqNum = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand =
        encodeColorControlClusterWriteColorControlOptionsAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR ColorControlCluster::ReadAttributeNumberOfPrimaries(Callback::Cancelable * onSuccessCallback,
                                                               Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0010;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::ReadAttributePrimary1X(Callback::Cancelable * onSuccessCallback,
                                                       Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0011;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::ReadAttributePrimary1Y(Callback::Cancelable * onSuccessCallback,
                                                       Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0012;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::ReadAttributePrimary1Intensity(Callback::Cancelable * onSuccessCallback,
                                                               Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0013;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::ReadAttributePrimary2X(Callback::Cancelable * onSuccessCallback,
                                                       Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0015;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::ReadAttributePrimary2Y(Callback::Cancelable * onSuccessCallback,
                                                       Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0016;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::ReadAttributePrimary2Intensity(Callback::Cancelable * onSuccessCallback,
                                                               Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0017;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::ReadAttributePrimary3X(Callback::Cancelable * onSuccessCallback,
                                                       Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0019;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::ReadAttributePrimary3Y(Callback::Cancelable * onSuccessCallback,
                                                       Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x001A;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::ReadAttributePrimary3Intensity(Callback::Cancelable * onSuccessCallback,
                                                               Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x001B;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::ReadAttributePrimary4X(Callback::Cancelable * onSuccessCallback,
                                                       Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0020;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::ReadAttributePrimary4Y(Callback::Cancelable * onSuccessCallback,
                                                       Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0021;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::ReadAttributePrimary4Intensity(Callback::Cancelable * onSuccessCallback,
                                                               Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0022;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::ReadAttributePrimary5X(Callback::Cancelable * onSuccessCallback,
                                                       Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0024;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::ReadAttributePrimary5Y(Callback::Cancelable * onSuccessCallback,
                                                       Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0025;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::ReadAttributePrimary5Intensity(Callback::Cancelable * onSuccessCallback,
                                                               Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0026;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::ReadAttributePrimary6X(Callback::Cancelable * onSuccessCallback,
                                                       Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0028;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::ReadAttributePrimary6Y(Callback::Cancelable * onSuccessCallback,
                                                       Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0029;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::ReadAttributePrimary6Intensity(Callback::Cancelable * onSuccessCallback,
                                                               Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x002A;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::ReadAttributeWhitePointX(Callback::Cancelable * onSuccessCallback,
                                                         Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0030;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::WriteAttributeWhitePointX(Callback::Cancelable * onSuccessCallback,
                                                          Callback::Cancelable * onFailureCallback, uint16_t value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeColorControlClusterWriteWhitePointXAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR ColorControlCluster::ReadAttributeWhitePointY(Callback::Cancelable * onSuccessCallback,
                                                         Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0031;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::WriteAttributeWhitePointY(Callback::Cancelable * onSuccessCallback,
                                                          Callback::Cancelable * onFailureCallback, uint16_t value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeColorControlClusterWriteWhitePointYAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR ColorControlCluster::ReadAttributeColorPointRX(Callback::Cancelable * onSuccessCallback,
                                                          Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0032;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::WriteAttributeColorPointRX(Callback::Cancelable * onSuccessCallback,
                                                           Callback::Cancelable * onFailureCallback, uint16_t value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeColorControlClusterWriteColorPointRXAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR ColorControlCluster::ReadAttributeColorPointRY(Callback::Cancelable * onSuccessCallback,
                                                          Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0033;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::WriteAttributeColorPointRY(Callback::Cancelable * onSuccessCallback,
                                                           Callback::Cancelable * onFailureCallback, uint16_t value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeColorControlClusterWriteColorPointRYAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR ColorControlCluster::ReadAttributeColorPointRIntensity(Callback::Cancelable * onSuccessCallback,
                                                                  Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0034;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::WriteAttributeColorPointRIntensity(Callback::Cancelable * onSuccessCallback,
                                                                   Callback::Cancelable * onFailureCallback, uint8_t value)
{
    uint8_t seqNum = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand =
        encodeColorControlClusterWriteColorPointRIntensityAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR ColorControlCluster::ReadAttributeColorPointGX(Callback::Cancelable * onSuccessCallback,
                                                          Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0036;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::WriteAttributeColorPointGX(Callback::Cancelable * onSuccessCallback,
                                                           Callback::Cancelable * onFailureCallback, uint16_t value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeColorControlClusterWriteColorPointGXAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR ColorControlCluster::ReadAttributeColorPointGY(Callback::Cancelable * onSuccessCallback,
                                                          Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0037;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::WriteAttributeColorPointGY(Callback::Cancelable * onSuccessCallback,
                                                           Callback::Cancelable * onFailureCallback, uint16_t value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeColorControlClusterWriteColorPointGYAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR ColorControlCluster::ReadAttributeColorPointGIntensity(Callback::Cancelable * onSuccessCallback,
                                                                  Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0038;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::WriteAttributeColorPointGIntensity(Callback::Cancelable * onSuccessCallback,
                                                                   Callback::Cancelable * onFailureCallback, uint8_t value)
{
    uint8_t seqNum = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand =
        encodeColorControlClusterWriteColorPointGIntensityAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR ColorControlCluster::ReadAttributeColorPointBX(Callback::Cancelable * onSuccessCallback,
                                                          Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x003A;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::WriteAttributeColorPointBX(Callback::Cancelable * onSuccessCallback,
                                                           Callback::Cancelable * onFailureCallback, uint16_t value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeColorControlClusterWriteColorPointBXAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR ColorControlCluster::ReadAttributeColorPointBY(Callback::Cancelable * onSuccessCallback,
                                                          Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x003B;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::WriteAttributeColorPointBY(Callback::Cancelable * onSuccessCallback,
                                                           Callback::Cancelable * onFailureCallback, uint16_t value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeColorControlClusterWriteColorPointBYAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR ColorControlCluster::ReadAttributeColorPointBIntensity(Callback::Cancelable * onSuccessCallback,
                                                                  Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x003C;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::WriteAttributeColorPointBIntensity(Callback::Cancelable * onSuccessCallback,
                                                                   Callback::Cancelable * onFailureCallback, uint8_t value)
{
    uint8_t seqNum = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand =
        encodeColorControlClusterWriteColorPointBIntensityAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR ColorControlCluster::ReadAttributeEnhancedCurrentHue(Callback::Cancelable * onSuccessCallback,
                                                                Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x4000;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::ReadAttributeEnhancedColorMode(Callback::Cancelable * onSuccessCallback,
                                                               Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x4001;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::ReadAttributeColorLoopActive(Callback::Cancelable * onSuccessCallback,
                                                             Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x4002;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::ReadAttributeColorLoopDirection(Callback::Cancelable * onSuccessCallback,
                                                                Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x4003;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::ReadAttributeColorLoopTime(Callback::Cancelable * onSuccessCallback,
                                                           Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x4004;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::ReadAttributeColorCapabilities(Callback::Cancelable * onSuccessCallback,
                                                               Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x400A;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::ReadAttributeColorTempPhysicalMin(Callback::Cancelable * onSuccessCallback,
                                                                  Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x400B;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::ReadAttributeColorTempPhysicalMax(Callback::Cancelable * onSuccessCallback,
                                                                  Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x400C;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::ReadAttributeCoupleColorTempToLevelMinMireds(Callback::Cancelable * onSuccessCallback,
                                                                             Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x400D;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::ReadAttributeStartUpColorTemperatureMireds(Callback::Cancelable * onSuccessCallback,
                                                                           Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x4010;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ColorControlCluster::WriteAttributeStartUpColorTemperatureMireds(Callback::Cancelable * onSuccessCallback,
                                                                            Callback::Cancelable * onFailureCallback,
                                                                            uint16_t value)
{
    uint8_t seqNum = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand =
        encodeColorControlClusterWriteStartUpColorTemperatureMiredsAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR ColorControlCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                             Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// ContentLauncher Cluster Commands
CHIP_ERROR ContentLauncherCluster::LaunchContent(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                                 uint8_t autoPlay, chip::ByteSpan data)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kLaunchContentCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // autoPlay: boolean
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), autoPlay));
    // data: charString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), data));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR ContentLauncherCluster::LaunchURL(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                             chip::ByteSpan contentURL, chip::ByteSpan displayString)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kLaunchURLCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // contentURL: charString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), contentURL));
    // displayString: charString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), displayString));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

// ContentLauncher Cluster Attributes
CHIP_ERROR ContentLauncherCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback,
                                                      Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeContentLauncherClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR ContentLauncherCluster::ReadAttributeAcceptsHeaderList(Callback::Cancelable * onSuccessCallback,
                                                                  Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0000;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             ContentLauncherClusterAcceptsHeaderListListAttributeFilter);
}

CHIP_ERROR ContentLauncherCluster::ReadAttributeSupportedStreamingTypes(Callback::Cancelable * onSuccessCallback,
                                                                        Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0001;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             ContentLauncherClusterSupportedStreamingTypesListAttributeFilter);
}

CHIP_ERROR ContentLauncherCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                                Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// Descriptor Cluster Commands
// Descriptor Cluster Attributes
CHIP_ERROR DescriptorCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeDescriptorClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR DescriptorCluster::ReadAttributeDeviceList(Callback::Cancelable * onSuccessCallback,
                                                      Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0000;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             DescriptorClusterDeviceListListAttributeFilter);
}

CHIP_ERROR DescriptorCluster::ReadAttributeServerList(Callback::Cancelable * onSuccessCallback,
                                                      Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0001;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             DescriptorClusterServerListListAttributeFilter);
}

CHIP_ERROR DescriptorCluster::ReadAttributeClientList(Callback::Cancelable * onSuccessCallback,
                                                      Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0002;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             DescriptorClusterClientListListAttributeFilter);
}

CHIP_ERROR DescriptorCluster::ReadAttributePartsList(Callback::Cancelable * onSuccessCallback,
                                                     Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0003;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             DescriptorClusterPartsListListAttributeFilter);
}

CHIP_ERROR DescriptorCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                           Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// DiagnosticLogs Cluster Commands
CHIP_ERROR DiagnosticLogsCluster::RetrieveLogsRequest(Callback::Cancelable * onSuccessCallback,
                                                      Callback::Cancelable * onFailureCallback, uint8_t intent,
                                                      uint8_t requestedProtocol, chip::ByteSpan transferFileDesignator)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kRetrieveLogsRequestCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // intent: logsIntent
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), intent));
    // requestedProtocol: logsTransferProtocol
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), requestedProtocol));
    // transferFileDesignator: octetString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), transferFileDesignator));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

// DiagnosticLogs Cluster Attributes
CHIP_ERROR DiagnosticLogsCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback,
                                                     Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeDiagnosticLogsClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

// DoorLock Cluster Commands
CHIP_ERROR DoorLockCluster::ClearAllPins(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kClearAllPinsCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    // Command takes no arguments.

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR DoorLockCluster::ClearAllRfids(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kClearAllRfidsCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    // Command takes no arguments.

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR DoorLockCluster::ClearHolidaySchedule(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                                 uint8_t scheduleId)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kClearHolidayScheduleCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // scheduleId: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), scheduleId));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR DoorLockCluster::ClearPin(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                     uint16_t userId)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kClearPinCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // userId: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), userId));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR DoorLockCluster::ClearRfid(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                      uint16_t userId)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kClearRfidCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // userId: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), userId));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR DoorLockCluster::ClearWeekdaySchedule(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                                 uint8_t scheduleId, uint16_t userId)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kClearWeekdayScheduleCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // scheduleId: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), scheduleId));
    // userId: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), userId));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR DoorLockCluster::ClearYeardaySchedule(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                                 uint8_t scheduleId, uint16_t userId)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kClearYeardayScheduleCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // scheduleId: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), scheduleId));
    // userId: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), userId));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR DoorLockCluster::GetHolidaySchedule(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                               uint8_t scheduleId)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kGetHolidayScheduleCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // scheduleId: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), scheduleId));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR DoorLockCluster::GetLogRecord(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                         uint16_t logIndex)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kGetLogRecordCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // logIndex: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), logIndex));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR DoorLockCluster::GetPin(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                   uint16_t userId)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kGetPinCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // userId: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), userId));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR DoorLockCluster::GetRfid(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                    uint16_t userId)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kGetRfidCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // userId: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), userId));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR DoorLockCluster::GetUserType(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                        uint16_t userId)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kGetUserTypeCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // userId: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), userId));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR DoorLockCluster::GetWeekdaySchedule(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                               uint8_t scheduleId, uint16_t userId)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kGetWeekdayScheduleCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // scheduleId: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), scheduleId));
    // userId: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), userId));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR DoorLockCluster::GetYeardaySchedule(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                               uint8_t scheduleId, uint16_t userId)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kGetYeardayScheduleCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // scheduleId: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), scheduleId));
    // userId: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), userId));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR DoorLockCluster::LockDoor(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                     chip::ByteSpan pin)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kLockDoorCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // pin: charString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), pin));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR DoorLockCluster::SetHolidaySchedule(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                               uint8_t scheduleId, uint32_t localStartTime, uint32_t localEndTime,
                                               uint8_t operatingModeDuringHoliday)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kSetHolidayScheduleCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // scheduleId: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), scheduleId));
    // localStartTime: int32u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), localStartTime));
    // localEndTime: int32u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), localEndTime));
    // operatingModeDuringHoliday: enum8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), operatingModeDuringHoliday));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR DoorLockCluster::SetPin(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                   uint16_t userId, uint8_t userStatus, uint8_t userType, chip::ByteSpan pin)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kSetPinCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // userId: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), userId));
    // userStatus: doorLockUserStatus
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), userStatus));
    // userType: doorLockUserType
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), userType));
    // pin: charString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), pin));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR DoorLockCluster::SetRfid(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                    uint16_t userId, uint8_t userStatus, uint8_t userType, chip::ByteSpan id)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kSetRfidCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // userId: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), userId));
    // userStatus: doorLockUserStatus
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), userStatus));
    // userType: doorLockUserType
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), userType));
    // id: charString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), id));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR DoorLockCluster::SetUserType(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                        uint16_t userId, uint8_t userType)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kSetUserTypeCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // userId: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), userId));
    // userType: doorLockUserType
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), userType));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR DoorLockCluster::SetWeekdaySchedule(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                               uint8_t scheduleId, uint16_t userId, uint8_t daysMask, uint8_t startHour,
                                               uint8_t startMinute, uint8_t endHour, uint8_t endMinute)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kSetWeekdayScheduleCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // scheduleId: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), scheduleId));
    // userId: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), userId));
    // daysMask: doorLockDayOfWeek
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), daysMask));
    // startHour: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), startHour));
    // startMinute: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), startMinute));
    // endHour: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), endHour));
    // endMinute: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), endMinute));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR DoorLockCluster::SetYeardaySchedule(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                               uint8_t scheduleId, uint16_t userId, uint32_t localStartTime, uint32_t localEndTime)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kSetYeardayScheduleCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // scheduleId: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), scheduleId));
    // userId: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), userId));
    // localStartTime: int32u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), localStartTime));
    // localEndTime: int32u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), localEndTime));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR DoorLockCluster::UnlockDoor(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                       chip::ByteSpan pin)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kUnlockDoorCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // pin: charString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), pin));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR DoorLockCluster::UnlockWithTimeout(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                              uint16_t timeoutInSeconds, chip::ByteSpan pin)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kUnlockWithTimeoutCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // timeoutInSeconds: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), timeoutInSeconds));
    // pin: charString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), pin));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

// DoorLock Cluster Attributes
CHIP_ERROR DoorLockCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeDoorLockClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR DoorLockCluster::ReadAttributeLockState(Callback::Cancelable * onSuccessCallback,
                                                   Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0000;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR DoorLockCluster::ConfigureAttributeLockState(Callback::Cancelable * onSuccessCallback,
                                                        Callback::Cancelable * onFailureCallback, uint16_t minInterval,
                                                        uint16_t maxInterval)
{
    uint8_t seqNum = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand =
        encodeDoorLockClusterConfigureLockStateAttribute(seqNum, mEndpoint, minInterval, maxInterval);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR DoorLockCluster::ReportAttributeLockState(Callback::Cancelable * onReportCallback)
{
    return RequestAttributeReporting(0x0000, onReportCallback);
}

CHIP_ERROR DoorLockCluster::ReadAttributeLockType(Callback::Cancelable * onSuccessCallback,
                                                  Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0001;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR DoorLockCluster::ReadAttributeActuatorEnabled(Callback::Cancelable * onSuccessCallback,
                                                         Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0002;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<BooleanAttributeCallback>);
}

CHIP_ERROR DoorLockCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                         Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// ElectricalMeasurement Cluster Commands
// ElectricalMeasurement Cluster Attributes
CHIP_ERROR ElectricalMeasurementCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback,
                                                            Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeElectricalMeasurementClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR ElectricalMeasurementCluster::ReadAttributeMeasurementType(Callback::Cancelable * onSuccessCallback,
                                                                      Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0000;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR ElectricalMeasurementCluster::ReadAttributeTotalActivePower(Callback::Cancelable * onSuccessCallback,
                                                                       Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0304;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32sAttributeCallback>);
}

CHIP_ERROR ElectricalMeasurementCluster::ReadAttributeRmsVoltage(Callback::Cancelable * onSuccessCallback,
                                                                 Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0505;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ElectricalMeasurementCluster::ReadAttributeRmsVoltageMin(Callback::Cancelable * onSuccessCallback,
                                                                    Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0506;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ElectricalMeasurementCluster::ReadAttributeRmsVoltageMax(Callback::Cancelable * onSuccessCallback,
                                                                    Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0507;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ElectricalMeasurementCluster::ReadAttributeRmsCurrent(Callback::Cancelable * onSuccessCallback,
                                                                 Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0508;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ElectricalMeasurementCluster::ReadAttributeRmsCurrentMin(Callback::Cancelable * onSuccessCallback,
                                                                    Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0509;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ElectricalMeasurementCluster::ReadAttributeRmsCurrentMax(Callback::Cancelable * onSuccessCallback,
                                                                    Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x050A;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ElectricalMeasurementCluster::ReadAttributeActivePower(Callback::Cancelable * onSuccessCallback,
                                                                  Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x050B;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16sAttributeCallback>);
}

CHIP_ERROR ElectricalMeasurementCluster::ReadAttributeActivePowerMin(Callback::Cancelable * onSuccessCallback,
                                                                     Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x050C;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16sAttributeCallback>);
}

CHIP_ERROR ElectricalMeasurementCluster::ReadAttributeActivePowerMax(Callback::Cancelable * onSuccessCallback,
                                                                     Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x050D;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16sAttributeCallback>);
}

CHIP_ERROR ElectricalMeasurementCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                                      Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// EthernetNetworkDiagnostics Cluster Commands
CHIP_ERROR EthernetNetworkDiagnosticsCluster::ResetCounts(Callback::Cancelable * onSuccessCallback,
                                                          Callback::Cancelable * onFailureCallback)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kResetCountsCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    // Command takes no arguments.

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

// EthernetNetworkDiagnostics Cluster Attributes
CHIP_ERROR EthernetNetworkDiagnosticsCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback,
                                                                 Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeEthernetNetworkDiagnosticsClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR EthernetNetworkDiagnosticsCluster::ReadAttributePacketRxCount(Callback::Cancelable * onSuccessCallback,
                                                                         Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0002;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int64uAttributeCallback>);
}

CHIP_ERROR EthernetNetworkDiagnosticsCluster::ReadAttributePacketTxCount(Callback::Cancelable * onSuccessCallback,
                                                                         Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0003;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int64uAttributeCallback>);
}

CHIP_ERROR EthernetNetworkDiagnosticsCluster::ReadAttributeTxErrCount(Callback::Cancelable * onSuccessCallback,
                                                                      Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0004;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int64uAttributeCallback>);
}

CHIP_ERROR EthernetNetworkDiagnosticsCluster::ReadAttributeCollisionCount(Callback::Cancelable * onSuccessCallback,
                                                                          Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0005;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int64uAttributeCallback>);
}

CHIP_ERROR EthernetNetworkDiagnosticsCluster::ReadAttributeOverrunCount(Callback::Cancelable * onSuccessCallback,
                                                                        Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0006;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int64uAttributeCallback>);
}

CHIP_ERROR EthernetNetworkDiagnosticsCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                                           Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// FixedLabel Cluster Commands
// FixedLabel Cluster Attributes
CHIP_ERROR FixedLabelCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeFixedLabelClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR FixedLabelCluster::ReadAttributeLabelList(Callback::Cancelable * onSuccessCallback,
                                                     Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0000;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             FixedLabelClusterLabelListListAttributeFilter);
}

CHIP_ERROR FixedLabelCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                           Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// FlowMeasurement Cluster Commands
// FlowMeasurement Cluster Attributes
CHIP_ERROR FlowMeasurementCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback,
                                                      Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeFlowMeasurementClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR FlowMeasurementCluster::ReadAttributeMeasuredValue(Callback::Cancelable * onSuccessCallback,
                                                              Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0000;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16sAttributeCallback>);
}

CHIP_ERROR FlowMeasurementCluster::ReadAttributeMinMeasuredValue(Callback::Cancelable * onSuccessCallback,
                                                                 Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0001;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16sAttributeCallback>);
}

CHIP_ERROR FlowMeasurementCluster::ReadAttributeMaxMeasuredValue(Callback::Cancelable * onSuccessCallback,
                                                                 Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0002;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16sAttributeCallback>);
}

CHIP_ERROR FlowMeasurementCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                                Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// GeneralCommissioning Cluster Commands
CHIP_ERROR GeneralCommissioningCluster::ArmFailSafe(Callback::Cancelable * onSuccessCallback,
                                                    Callback::Cancelable * onFailureCallback, uint16_t expiryLengthSeconds,
                                                    uint64_t breadcrumb, uint32_t timeoutMs)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kArmFailSafeCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // expiryLengthSeconds: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), expiryLengthSeconds));
    // breadcrumb: int64u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), breadcrumb));
    // timeoutMs: int32u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), timeoutMs));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR GeneralCommissioningCluster::CommissioningComplete(Callback::Cancelable * onSuccessCallback,
                                                              Callback::Cancelable * onFailureCallback)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kCommissioningCompleteCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    // Command takes no arguments.

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR GeneralCommissioningCluster::SetRegulatoryConfig(Callback::Cancelable * onSuccessCallback,
                                                            Callback::Cancelable * onFailureCallback, uint8_t location,
                                                            chip::ByteSpan countryCode, uint64_t breadcrumb, uint32_t timeoutMs)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kSetRegulatoryConfigCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // location: regulatoryLocationType
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), location));
    // countryCode: charString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), countryCode));
    // breadcrumb: int64u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), breadcrumb));
    // timeoutMs: int32u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), timeoutMs));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

// GeneralCommissioning Cluster Attributes
CHIP_ERROR GeneralCommissioningCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback,
                                                           Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeGeneralCommissioningClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR GeneralCommissioningCluster::ReadAttributeFabricId(Callback::Cancelable * onSuccessCallback,
                                                              Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0000;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<StringAttributeCallback>);
}

CHIP_ERROR GeneralCommissioningCluster::ReadAttributeBreadcrumb(Callback::Cancelable * onSuccessCallback,
                                                                Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0001;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int64uAttributeCallback>);
}

CHIP_ERROR GeneralCommissioningCluster::WriteAttributeBreadcrumb(Callback::Cancelable * onSuccessCallback,
                                                                 Callback::Cancelable * onFailureCallback, uint64_t value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeGeneralCommissioningClusterWriteBreadcrumbAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR GeneralCommissioningCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                                     Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// GeneralDiagnostics Cluster Commands
// GeneralDiagnostics Cluster Attributes
CHIP_ERROR GeneralDiagnosticsCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback,
                                                         Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeGeneralDiagnosticsClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR GeneralDiagnosticsCluster::ReadAttributeNetworkInterfaces(Callback::Cancelable * onSuccessCallback,
                                                                     Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0000;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             GeneralDiagnosticsClusterNetworkInterfacesListAttributeFilter);
}

CHIP_ERROR GeneralDiagnosticsCluster::ReadAttributeRebootCount(Callback::Cancelable * onSuccessCallback,
                                                               Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0001;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR GeneralDiagnosticsCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                                   Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// GroupKeyManagement Cluster Commands
// GroupKeyManagement Cluster Attributes
CHIP_ERROR GroupKeyManagementCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback,
                                                         Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeGroupKeyManagementClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR GroupKeyManagementCluster::ReadAttributeGroups(Callback::Cancelable * onSuccessCallback,
                                                          Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0000;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             GroupKeyManagementClusterGroupsListAttributeFilter);
}

CHIP_ERROR GroupKeyManagementCluster::ReadAttributeGroupKeys(Callback::Cancelable * onSuccessCallback,
                                                             Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0001;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             GroupKeyManagementClusterGroupKeysListAttributeFilter);
}

CHIP_ERROR GroupKeyManagementCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                                   Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// Groups Cluster Commands
CHIP_ERROR GroupsCluster::AddGroup(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                   uint16_t groupId, chip::ByteSpan groupName)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kAddGroupCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // groupId: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), groupId));
    // groupName: charString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), groupName));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR GroupsCluster::AddGroupIfIdentifying(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                                uint16_t groupId, chip::ByteSpan groupName)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kAddGroupIfIdentifyingCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // groupId: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), groupId));
    // groupName: charString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), groupName));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR GroupsCluster::GetGroupMembership(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                             uint8_t groupCount, uint16_t groupList)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kGetGroupMembershipCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // groupCount: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), groupCount));
    // groupList: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), groupList));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR GroupsCluster::RemoveAllGroups(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kRemoveAllGroupsCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    // Command takes no arguments.

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR GroupsCluster::RemoveGroup(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                      uint16_t groupId)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kRemoveGroupCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // groupId: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), groupId));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR GroupsCluster::ViewGroup(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                    uint16_t groupId)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kViewGroupCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // groupId: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), groupId));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

// Groups Cluster Attributes
CHIP_ERROR GroupsCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeGroupsClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR GroupsCluster::ReadAttributeNameSupport(Callback::Cancelable * onSuccessCallback,
                                                   Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0000;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR GroupsCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                       Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// Identify Cluster Commands
CHIP_ERROR IdentifyCluster::Identify(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                     uint16_t identifyTime)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kIdentifyCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // identifyTime: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), identifyTime));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR IdentifyCluster::IdentifyQuery(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kIdentifyQueryCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    // Command takes no arguments.

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

// Identify Cluster Attributes
CHIP_ERROR IdentifyCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeIdentifyClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR IdentifyCluster::ReadAttributeIdentifyTime(Callback::Cancelable * onSuccessCallback,
                                                      Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0000;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR IdentifyCluster::WriteAttributeIdentifyTime(Callback::Cancelable * onSuccessCallback,
                                                       Callback::Cancelable * onFailureCallback, uint16_t value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeIdentifyClusterWriteIdentifyTimeAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR IdentifyCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                         Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// KeypadInput Cluster Commands
CHIP_ERROR KeypadInputCluster::SendKey(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                       uint8_t keyCode)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kSendKeyCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // keyCode: keypadInputCecKeyCode
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), keyCode));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

// KeypadInput Cluster Attributes
CHIP_ERROR KeypadInputCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback,
                                                  Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeKeypadInputClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR KeypadInputCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                            Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// LevelControl Cluster Commands
CHIP_ERROR LevelControlCluster::Move(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                     uint8_t moveMode, uint8_t rate, uint8_t optionMask, uint8_t optionOverride)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kMoveCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // moveMode: moveMode
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), moveMode));
    // rate: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), rate));
    // optionMask: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionMask));
    // optionOverride: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionOverride));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR LevelControlCluster::MoveToLevel(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                            uint8_t level, uint16_t transitionTime, uint8_t optionMask, uint8_t optionOverride)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kMoveToLevelCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // level: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), level));
    // transitionTime: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), transitionTime));
    // optionMask: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionMask));
    // optionOverride: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionOverride));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR LevelControlCluster::MoveToLevelWithOnOff(Callback::Cancelable * onSuccessCallback,
                                                     Callback::Cancelable * onFailureCallback, uint8_t level,
                                                     uint16_t transitionTime)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kMoveToLevelWithOnOffCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // level: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), level));
    // transitionTime: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), transitionTime));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR LevelControlCluster::MoveWithOnOff(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                              uint8_t moveMode, uint8_t rate)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kMoveWithOnOffCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // moveMode: moveMode
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), moveMode));
    // rate: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), rate));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR LevelControlCluster::Step(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                     uint8_t stepMode, uint8_t stepSize, uint16_t transitionTime, uint8_t optionMask,
                                     uint8_t optionOverride)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kStepCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // stepMode: stepMode
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), stepMode));
    // stepSize: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), stepSize));
    // transitionTime: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), transitionTime));
    // optionMask: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionMask));
    // optionOverride: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionOverride));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR LevelControlCluster::StepWithOnOff(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                              uint8_t stepMode, uint8_t stepSize, uint16_t transitionTime)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kStepWithOnOffCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // stepMode: stepMode
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), stepMode));
    // stepSize: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), stepSize));
    // transitionTime: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), transitionTime));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR LevelControlCluster::Stop(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                     uint8_t optionMask, uint8_t optionOverride)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kStopCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // optionMask: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionMask));
    // optionOverride: bitmap8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), optionOverride));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR LevelControlCluster::StopWithOnOff(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kStopWithOnOffCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    // Command takes no arguments.

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

// LevelControl Cluster Attributes
CHIP_ERROR LevelControlCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback,
                                                   Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeLevelControlClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR LevelControlCluster::ReadAttributeCurrentLevel(Callback::Cancelable * onSuccessCallback,
                                                          Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0000;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR LevelControlCluster::ConfigureAttributeCurrentLevel(Callback::Cancelable * onSuccessCallback,
                                                               Callback::Cancelable * onFailureCallback, uint16_t minInterval,
                                                               uint16_t maxInterval, uint8_t change)
{
    uint8_t seqNum = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand =
        encodeLevelControlClusterConfigureCurrentLevelAttribute(seqNum, mEndpoint, minInterval, maxInterval, change);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR LevelControlCluster::ReportAttributeCurrentLevel(Callback::Cancelable * onReportCallback)
{
    return RequestAttributeReporting(0x0000, onReportCallback);
}

CHIP_ERROR LevelControlCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                             Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// LowPower Cluster Commands
CHIP_ERROR LowPowerCluster::Sleep(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kSleepCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    // Command takes no arguments.

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

// LowPower Cluster Attributes
CHIP_ERROR LowPowerCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeLowPowerClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR LowPowerCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                         Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// MediaInput Cluster Commands
CHIP_ERROR MediaInputCluster::HideInputStatus(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kHideInputStatusCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    // Command takes no arguments.

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR MediaInputCluster::RenameInput(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                          uint8_t index, chip::ByteSpan name)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kRenameInputCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // index: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), index));
    // name: charString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), name));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR MediaInputCluster::SelectInput(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                          uint8_t index)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kSelectInputCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // index: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), index));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR MediaInputCluster::ShowInputStatus(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kShowInputStatusCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    // Command takes no arguments.

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

// MediaInput Cluster Attributes
CHIP_ERROR MediaInputCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeMediaInputClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR MediaInputCluster::ReadAttributeMediaInputList(Callback::Cancelable * onSuccessCallback,
                                                          Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0000;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             MediaInputClusterMediaInputListListAttributeFilter);
}

CHIP_ERROR MediaInputCluster::ReadAttributeCurrentMediaInput(Callback::Cancelable * onSuccessCallback,
                                                             Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0001;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR MediaInputCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                           Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// MediaPlayback Cluster Commands
CHIP_ERROR MediaPlaybackCluster::MediaFastForward(Callback::Cancelable * onSuccessCallback,
                                                  Callback::Cancelable * onFailureCallback)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kMediaFastForwardCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    // Command takes no arguments.

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR MediaPlaybackCluster::MediaNext(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kMediaNextCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    // Command takes no arguments.

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR MediaPlaybackCluster::MediaPause(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kMediaPauseCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    // Command takes no arguments.

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR MediaPlaybackCluster::MediaPlay(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kMediaPlayCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    // Command takes no arguments.

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR MediaPlaybackCluster::MediaPrevious(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kMediaPreviousCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    // Command takes no arguments.

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR MediaPlaybackCluster::MediaRewind(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kMediaRewindCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    // Command takes no arguments.

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR MediaPlaybackCluster::MediaSeek(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                           uint64_t position)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kMediaSeekCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // position: int64u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), position));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR MediaPlaybackCluster::MediaSkipBackward(Callback::Cancelable * onSuccessCallback,
                                                   Callback::Cancelable * onFailureCallback, uint64_t deltaPositionMilliseconds)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kMediaSkipBackwardCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // deltaPositionMilliseconds: int64u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), deltaPositionMilliseconds));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR MediaPlaybackCluster::MediaSkipForward(Callback::Cancelable * onSuccessCallback,
                                                  Callback::Cancelable * onFailureCallback, uint64_t deltaPositionMilliseconds)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kMediaSkipForwardCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // deltaPositionMilliseconds: int64u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), deltaPositionMilliseconds));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR MediaPlaybackCluster::MediaStartOver(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kMediaStartOverCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    // Command takes no arguments.

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR MediaPlaybackCluster::MediaStop(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kMediaStopCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    // Command takes no arguments.

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

// MediaPlayback Cluster Attributes
CHIP_ERROR MediaPlaybackCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback,
                                                    Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeMediaPlaybackClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR MediaPlaybackCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                              Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// NetworkCommissioning Cluster Commands
CHIP_ERROR NetworkCommissioningCluster::AddThreadNetwork(Callback::Cancelable * onSuccessCallback,
                                                         Callback::Cancelable * onFailureCallback,
                                                         chip::ByteSpan operationalDataset, uint64_t breadcrumb, uint32_t timeoutMs)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kAddThreadNetworkCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // operationalDataset: octetString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), operationalDataset));
    // breadcrumb: int64u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), breadcrumb));
    // timeoutMs: int32u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), timeoutMs));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR NetworkCommissioningCluster::AddWiFiNetwork(Callback::Cancelable * onSuccessCallback,
                                                       Callback::Cancelable * onFailureCallback, chip::ByteSpan ssid,
                                                       chip::ByteSpan credentials, uint64_t breadcrumb, uint32_t timeoutMs)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kAddWiFiNetworkCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // ssid: octetString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), ssid));
    // credentials: octetString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), credentials));
    // breadcrumb: int64u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), breadcrumb));
    // timeoutMs: int32u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), timeoutMs));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR NetworkCommissioningCluster::DisableNetwork(Callback::Cancelable * onSuccessCallback,
                                                       Callback::Cancelable * onFailureCallback, chip::ByteSpan networkID,
                                                       uint64_t breadcrumb, uint32_t timeoutMs)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kDisableNetworkCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // networkID: octetString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), networkID));
    // breadcrumb: int64u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), breadcrumb));
    // timeoutMs: int32u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), timeoutMs));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR NetworkCommissioningCluster::EnableNetwork(Callback::Cancelable * onSuccessCallback,
                                                      Callback::Cancelable * onFailureCallback, chip::ByteSpan networkID,
                                                      uint64_t breadcrumb, uint32_t timeoutMs)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kEnableNetworkCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // networkID: octetString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), networkID));
    // breadcrumb: int64u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), breadcrumb));
    // timeoutMs: int32u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), timeoutMs));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR NetworkCommissioningCluster::GetLastNetworkCommissioningResult(Callback::Cancelable * onSuccessCallback,
                                                                          Callback::Cancelable * onFailureCallback,
                                                                          uint32_t timeoutMs)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kGetLastNetworkCommissioningResultCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // timeoutMs: int32u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), timeoutMs));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR NetworkCommissioningCluster::RemoveNetwork(Callback::Cancelable * onSuccessCallback,
                                                      Callback::Cancelable * onFailureCallback, chip::ByteSpan networkID,
                                                      uint64_t breadcrumb, uint32_t timeoutMs)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kRemoveNetworkCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // networkID: octetString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), networkID));
    // breadcrumb: int64u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), breadcrumb));
    // timeoutMs: int32u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), timeoutMs));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR NetworkCommissioningCluster::ScanNetworks(Callback::Cancelable * onSuccessCallback,
                                                     Callback::Cancelable * onFailureCallback, chip::ByteSpan ssid,
                                                     uint64_t breadcrumb, uint32_t timeoutMs)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kScanNetworksCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // ssid: octetString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), ssid));
    // breadcrumb: int64u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), breadcrumb));
    // timeoutMs: int32u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), timeoutMs));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR NetworkCommissioningCluster::UpdateThreadNetwork(Callback::Cancelable * onSuccessCallback,
                                                            Callback::Cancelable * onFailureCallback,
                                                            chip::ByteSpan operationalDataset, uint64_t breadcrumb,
                                                            uint32_t timeoutMs)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kUpdateThreadNetworkCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // operationalDataset: octetString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), operationalDataset));
    // breadcrumb: int64u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), breadcrumb));
    // timeoutMs: int32u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), timeoutMs));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR NetworkCommissioningCluster::UpdateWiFiNetwork(Callback::Cancelable * onSuccessCallback,
                                                          Callback::Cancelable * onFailureCallback, chip::ByteSpan ssid,
                                                          chip::ByteSpan credentials, uint64_t breadcrumb, uint32_t timeoutMs)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kUpdateWiFiNetworkCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // ssid: octetString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), ssid));
    // credentials: octetString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), credentials));
    // breadcrumb: int64u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), breadcrumb));
    // timeoutMs: int32u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), timeoutMs));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

// NetworkCommissioning Cluster Attributes
CHIP_ERROR NetworkCommissioningCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback,
                                                           Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeNetworkCommissioningClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR NetworkCommissioningCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                                     Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// OtaSoftwareUpdateProvider Cluster Commands
CHIP_ERROR OtaSoftwareUpdateProviderCluster::ApplyUpdateRequest(Callback::Cancelable * onSuccessCallback,
                                                                Callback::Cancelable * onFailureCallback,
                                                                chip::ByteSpan updateToken, uint32_t newVersion)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kApplyUpdateRequestCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // updateToken: octetString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), updateToken));
    // newVersion: int32u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), newVersion));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR OtaSoftwareUpdateProviderCluster::NotifyUpdateApplied(Callback::Cancelable * onSuccessCallback,
                                                                 Callback::Cancelable * onFailureCallback,
                                                                 chip::ByteSpan updateToken, uint32_t currentVersion)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kNotifyUpdateAppliedCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // updateToken: octetString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), updateToken));
    // currentVersion: int32u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), currentVersion));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR OtaSoftwareUpdateProviderCluster::QueryImage(Callback::Cancelable * onSuccessCallback,
                                                        Callback::Cancelable * onFailureCallback, uint16_t vendorId,
                                                        uint16_t productId, uint16_t imageType, uint16_t hardwareVersion,
                                                        uint32_t currentVersion, uint8_t protocolsSupported,
                                                        chip::ByteSpan location, uint8_t requestorCanConsent,
                                                        chip::ByteSpan metadataForProvider)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kQueryImageCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // vendorId: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), vendorId));
    // productId: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), productId));
    // imageType: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), imageType));
    // hardwareVersion: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), hardwareVersion));
    // currentVersion: int32u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), currentVersion));
    // protocolsSupported: oTADownloadProtocol
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), protocolsSupported));
    // location: charString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), location));
    // requestorCanConsent: boolean
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), requestorCanConsent));
    // metadataForProvider: octetString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), metadataForProvider));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

// OtaSoftwareUpdateProvider Cluster Attributes
CHIP_ERROR OtaSoftwareUpdateProviderCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback,
                                                                Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeOtaSoftwareUpdateProviderClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR OtaSoftwareUpdateProviderCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                                          Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// OccupancySensing Cluster Commands
// OccupancySensing Cluster Attributes
CHIP_ERROR OccupancySensingCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback,
                                                       Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeOccupancySensingClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR OccupancySensingCluster::ReadAttributeOccupancy(Callback::Cancelable * onSuccessCallback,
                                                           Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0000;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR OccupancySensingCluster::ConfigureAttributeOccupancy(Callback::Cancelable * onSuccessCallback,
                                                                Callback::Cancelable * onFailureCallback, uint16_t minInterval,
                                                                uint16_t maxInterval)
{
    uint8_t seqNum = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand =
        encodeOccupancySensingClusterConfigureOccupancyAttribute(seqNum, mEndpoint, minInterval, maxInterval);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR OccupancySensingCluster::ReportAttributeOccupancy(Callback::Cancelable * onReportCallback)
{
    return RequestAttributeReporting(0x0000, onReportCallback);
}

CHIP_ERROR OccupancySensingCluster::ReadAttributeOccupancySensorType(Callback::Cancelable * onSuccessCallback,
                                                                     Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0001;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR OccupancySensingCluster::ReadAttributeOccupancySensorTypeBitmap(Callback::Cancelable * onSuccessCallback,
                                                                           Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0002;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR OccupancySensingCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                                 Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// OnOff Cluster Commands
CHIP_ERROR OnOffCluster::Off(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kOffCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    // Command takes no arguments.

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR OnOffCluster::OffWithEffect(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                       uint8_t effectId, uint8_t effectVariant)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kOffWithEffectCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // effectId: onOffEffectIdentifier
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), effectId));
    // effectVariant: enum8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), effectVariant));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR OnOffCluster::On(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kOnCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    // Command takes no arguments.

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR OnOffCluster::OnWithRecallGlobalScene(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kOnWithRecallGlobalSceneCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    // Command takes no arguments.

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR OnOffCluster::OnWithTimedOff(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                        uint8_t onOffControl, uint16_t onTime, uint16_t offWaitTime)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kOnWithTimedOffCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // onOffControl: onOffControl
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), onOffControl));
    // onTime: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), onTime));
    // offWaitTime: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), offWaitTime));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR OnOffCluster::Toggle(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kToggleCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    // Command takes no arguments.

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

// OnOff Cluster Attributes
CHIP_ERROR OnOffCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeOnOffClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR OnOffCluster::ReadAttributeOnOff(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0000;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<BooleanAttributeCallback>);
}

CHIP_ERROR OnOffCluster::ConfigureAttributeOnOff(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                                 uint16_t minInterval, uint16_t maxInterval)
{
    uint8_t seqNum = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand =
        encodeOnOffClusterConfigureOnOffAttribute(seqNum, mEndpoint, minInterval, maxInterval);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR OnOffCluster::ReportAttributeOnOff(Callback::Cancelable * onReportCallback)
{
    return RequestAttributeReporting(0x0000, onReportCallback);
}

CHIP_ERROR OnOffCluster::ReadAttributeGlobalSceneControl(Callback::Cancelable * onSuccessCallback,
                                                         Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x4000;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<BooleanAttributeCallback>);
}

CHIP_ERROR OnOffCluster::ReadAttributeOnTime(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x4001;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR OnOffCluster::WriteAttributeOnTime(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                              uint16_t value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeOnOffClusterWriteOnTimeAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR OnOffCluster::ReadAttributeOffWaitTime(Callback::Cancelable * onSuccessCallback,
                                                  Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x4002;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR OnOffCluster::WriteAttributeOffWaitTime(Callback::Cancelable * onSuccessCallback,
                                                   Callback::Cancelable * onFailureCallback, uint16_t value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeOnOffClusterWriteOffWaitTimeAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR OnOffCluster::ReadAttributeStartUpOnOff(Callback::Cancelable * onSuccessCallback,
                                                   Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x4003;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR OnOffCluster::WriteAttributeStartUpOnOff(Callback::Cancelable * onSuccessCallback,
                                                    Callback::Cancelable * onFailureCallback, uint8_t value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeOnOffClusterWriteStartUpOnOffAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR OnOffCluster::ReadAttributeFeatureMap(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFC;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR OnOffCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                      Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// OperationalCredentials Cluster Commands
CHIP_ERROR OperationalCredentialsCluster::AddOpCert(Callback::Cancelable * onSuccessCallback,
                                                    Callback::Cancelable * onFailureCallback, chip::ByteSpan nOCArray,
                                                    chip::ByteSpan iPKValue, chip::NodeId caseAdminNode, uint16_t adminVendorId)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kAddOpCertCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // nOCArray: octetString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), nOCArray));
    // iPKValue: octetString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), iPKValue));
    // caseAdminNode: nodeId
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), caseAdminNode));
    // adminVendorId: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), adminVendorId));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR OperationalCredentialsCluster::AddTrustedRootCertificate(Callback::Cancelable * onSuccessCallback,
                                                                    Callback::Cancelable * onFailureCallback,
                                                                    chip::ByteSpan rootCertificate)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kAddTrustedRootCertificateCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // rootCertificate: octetString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), rootCertificate));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR OperationalCredentialsCluster::OpCSRRequest(Callback::Cancelable * onSuccessCallback,
                                                       Callback::Cancelable * onFailureCallback, chip::ByteSpan cSRNonce)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kOpCSRRequestCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // cSRNonce: octetString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), cSRNonce));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR OperationalCredentialsCluster::RemoveAllFabrics(Callback::Cancelable * onSuccessCallback,
                                                           Callback::Cancelable * onFailureCallback)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kRemoveAllFabricsCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    // Command takes no arguments.

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR OperationalCredentialsCluster::RemoveFabric(Callback::Cancelable * onSuccessCallback,
                                                       Callback::Cancelable * onFailureCallback, chip::FabricId fabricId,
                                                       chip::NodeId nodeId, uint16_t vendorId)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kRemoveFabricCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // fabricId: fabricId
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), fabricId));
    // nodeId: nodeId
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), nodeId));
    // vendorId: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), vendorId));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR OperationalCredentialsCluster::RemoveTrustedRootCertificate(Callback::Cancelable * onSuccessCallback,
                                                                       Callback::Cancelable * onFailureCallback,
                                                                       chip::ByteSpan trustedRootIdentifier)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kRemoveTrustedRootCertificateCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // trustedRootIdentifier: octetString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), trustedRootIdentifier));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR OperationalCredentialsCluster::SetFabric(Callback::Cancelable * onSuccessCallback,
                                                    Callback::Cancelable * onFailureCallback, uint16_t vendorId)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kSetFabricCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // vendorId: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), vendorId));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR OperationalCredentialsCluster::UpdateFabricLabel(Callback::Cancelable * onSuccessCallback,
                                                            Callback::Cancelable * onFailureCallback, chip::ByteSpan label)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kUpdateFabricLabelCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // label: charString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), label));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

// OperationalCredentials Cluster Attributes
CHIP_ERROR OperationalCredentialsCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback,
                                                             Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeOperationalCredentialsClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR OperationalCredentialsCluster::ReadAttributeFabricsList(Callback::Cancelable * onSuccessCallback,
                                                                   Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0001;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             OperationalCredentialsClusterFabricsListListAttributeFilter);
}

CHIP_ERROR OperationalCredentialsCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                                       Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// PressureMeasurement Cluster Commands
// PressureMeasurement Cluster Attributes
CHIP_ERROR PressureMeasurementCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback,
                                                          Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodePressureMeasurementClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR PressureMeasurementCluster::ReadAttributeMeasuredValue(Callback::Cancelable * onSuccessCallback,
                                                                  Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0000;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16sAttributeCallback>);
}

CHIP_ERROR PressureMeasurementCluster::ConfigureAttributeMeasuredValue(Callback::Cancelable * onSuccessCallback,
                                                                       Callback::Cancelable * onFailureCallback,
                                                                       uint16_t minInterval, uint16_t maxInterval, int16_t change)
{
    uint8_t seqNum = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand =
        encodePressureMeasurementClusterConfigureMeasuredValueAttribute(seqNum, mEndpoint, minInterval, maxInterval, change);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR PressureMeasurementCluster::ReportAttributeMeasuredValue(Callback::Cancelable * onReportCallback)
{
    return RequestAttributeReporting(0x0000, onReportCallback);
}

CHIP_ERROR PressureMeasurementCluster::ReadAttributeMinMeasuredValue(Callback::Cancelable * onSuccessCallback,
                                                                     Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0001;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16sAttributeCallback>);
}

CHIP_ERROR PressureMeasurementCluster::ReadAttributeMaxMeasuredValue(Callback::Cancelable * onSuccessCallback,
                                                                     Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0002;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16sAttributeCallback>);
}

CHIP_ERROR PressureMeasurementCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                                    Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// PumpConfigurationAndControl Cluster Commands
// PumpConfigurationAndControl Cluster Attributes
CHIP_ERROR PumpConfigurationAndControlCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback,
                                                                  Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodePumpConfigurationAndControlClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR PumpConfigurationAndControlCluster::ReadAttributeMaxPressure(Callback::Cancelable * onSuccessCallback,
                                                                        Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0000;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16sAttributeCallback>);
}

CHIP_ERROR PumpConfigurationAndControlCluster::ReadAttributeMaxSpeed(Callback::Cancelable * onSuccessCallback,
                                                                     Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0001;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR PumpConfigurationAndControlCluster::ReadAttributeMaxFlow(Callback::Cancelable * onSuccessCallback,
                                                                    Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0002;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR PumpConfigurationAndControlCluster::ReadAttributeEffectiveOperationMode(Callback::Cancelable * onSuccessCallback,
                                                                                   Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0011;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR PumpConfigurationAndControlCluster::ReadAttributeEffectiveControlMode(Callback::Cancelable * onSuccessCallback,
                                                                                 Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0012;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR PumpConfigurationAndControlCluster::ReadAttributeCapacity(Callback::Cancelable * onSuccessCallback,
                                                                     Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0013;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16sAttributeCallback>);
}

CHIP_ERROR PumpConfigurationAndControlCluster::ConfigureAttributeCapacity(Callback::Cancelable * onSuccessCallback,
                                                                          Callback::Cancelable * onFailureCallback,
                                                                          uint16_t minInterval, uint16_t maxInterval,
                                                                          int16_t change)
{
    uint8_t seqNum = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand =
        encodePumpConfigurationAndControlClusterConfigureCapacityAttribute(seqNum, mEndpoint, minInterval, maxInterval, change);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR PumpConfigurationAndControlCluster::ReportAttributeCapacity(Callback::Cancelable * onReportCallback)
{
    return RequestAttributeReporting(0x0013, onReportCallback);
}

CHIP_ERROR PumpConfigurationAndControlCluster::ReadAttributeOperationMode(Callback::Cancelable * onSuccessCallback,
                                                                          Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0020;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR PumpConfigurationAndControlCluster::WriteAttributeOperationMode(Callback::Cancelable * onSuccessCallback,
                                                                           Callback::Cancelable * onFailureCallback, uint8_t value)
{
    uint8_t seqNum = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand =
        encodePumpConfigurationAndControlClusterWriteOperationModeAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR PumpConfigurationAndControlCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                                            Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// RelativeHumidityMeasurement Cluster Commands
// RelativeHumidityMeasurement Cluster Attributes
CHIP_ERROR RelativeHumidityMeasurementCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback,
                                                                  Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeRelativeHumidityMeasurementClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR RelativeHumidityMeasurementCluster::ReadAttributeMeasuredValue(Callback::Cancelable * onSuccessCallback,
                                                                          Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0000;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR RelativeHumidityMeasurementCluster::ConfigureAttributeMeasuredValue(Callback::Cancelable * onSuccessCallback,
                                                                               Callback::Cancelable * onFailureCallback,
                                                                               uint16_t minInterval, uint16_t maxInterval,
                                                                               uint16_t change)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeRelativeHumidityMeasurementClusterConfigureMeasuredValueAttribute(
        seqNum, mEndpoint, minInterval, maxInterval, change);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR RelativeHumidityMeasurementCluster::ReportAttributeMeasuredValue(Callback::Cancelable * onReportCallback)
{
    return RequestAttributeReporting(0x0000, onReportCallback);
}

CHIP_ERROR RelativeHumidityMeasurementCluster::ReadAttributeMinMeasuredValue(Callback::Cancelable * onSuccessCallback,
                                                                             Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0001;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR RelativeHumidityMeasurementCluster::ReadAttributeMaxMeasuredValue(Callback::Cancelable * onSuccessCallback,
                                                                             Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0002;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR RelativeHumidityMeasurementCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                                            Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// Scenes Cluster Commands
CHIP_ERROR ScenesCluster::AddScene(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                   uint16_t groupId, uint8_t sceneId, uint16_t transitionTime, chip::ByteSpan sceneName,
                                   chip::ClusterId clusterId, uint8_t length, uint8_t value)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kAddSceneCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // groupId: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), groupId));
    // sceneId: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), sceneId));
    // transitionTime: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), transitionTime));
    // sceneName: charString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), sceneName));
    // clusterId: clusterId
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), clusterId));
    // length: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), length));
    // value: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), value));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR ScenesCluster::GetSceneMembership(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                             uint16_t groupId)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kGetSceneMembershipCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // groupId: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), groupId));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR ScenesCluster::RecallScene(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                      uint16_t groupId, uint8_t sceneId, uint16_t transitionTime)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kRecallSceneCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // groupId: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), groupId));
    // sceneId: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), sceneId));
    // transitionTime: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), transitionTime));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR ScenesCluster::RemoveAllScenes(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                          uint16_t groupId)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kRemoveAllScenesCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // groupId: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), groupId));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR ScenesCluster::RemoveScene(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                      uint16_t groupId, uint8_t sceneId)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kRemoveSceneCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // groupId: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), groupId));
    // sceneId: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), sceneId));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR ScenesCluster::StoreScene(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                     uint16_t groupId, uint8_t sceneId)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kStoreSceneCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // groupId: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), groupId));
    // sceneId: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), sceneId));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR ScenesCluster::ViewScene(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                    uint16_t groupId, uint8_t sceneId)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kViewSceneCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // groupId: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), groupId));
    // sceneId: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), sceneId));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

// Scenes Cluster Attributes
CHIP_ERROR ScenesCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeScenesClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR ScenesCluster::ReadAttributeSceneCount(Callback::Cancelable * onSuccessCallback,
                                                  Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0000;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR ScenesCluster::ReadAttributeCurrentScene(Callback::Cancelable * onSuccessCallback,
                                                    Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0001;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR ScenesCluster::ReadAttributeCurrentGroup(Callback::Cancelable * onSuccessCallback,
                                                    Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0002;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ScenesCluster::ReadAttributeSceneValid(Callback::Cancelable * onSuccessCallback,
                                                  Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0003;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<BooleanAttributeCallback>);
}

CHIP_ERROR ScenesCluster::ReadAttributeNameSupport(Callback::Cancelable * onSuccessCallback,
                                                   Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0004;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR ScenesCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                       Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// SoftwareDiagnostics Cluster Commands
CHIP_ERROR SoftwareDiagnosticsCluster::ResetWatermarks(Callback::Cancelable * onSuccessCallback,
                                                       Callback::Cancelable * onFailureCallback)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kResetWatermarksCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    // Command takes no arguments.

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

// SoftwareDiagnostics Cluster Attributes
CHIP_ERROR SoftwareDiagnosticsCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback,
                                                          Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeSoftwareDiagnosticsClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR SoftwareDiagnosticsCluster::ReadAttributeCurrentHeapHighWatermark(Callback::Cancelable * onSuccessCallback,
                                                                             Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0003;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int64uAttributeCallback>);
}

CHIP_ERROR SoftwareDiagnosticsCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                                    Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// Switch Cluster Commands
// Switch Cluster Attributes
CHIP_ERROR SwitchCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeSwitchClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR SwitchCluster::ReadAttributeNumberOfPositions(Callback::Cancelable * onSuccessCallback,
                                                         Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0000;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR SwitchCluster::ReadAttributeCurrentPosition(Callback::Cancelable * onSuccessCallback,
                                                       Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0001;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR SwitchCluster::ConfigureAttributeCurrentPosition(Callback::Cancelable * onSuccessCallback,
                                                            Callback::Cancelable * onFailureCallback, uint16_t minInterval,
                                                            uint16_t maxInterval, uint8_t change)
{
    uint8_t seqNum = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand =
        encodeSwitchClusterConfigureCurrentPositionAttribute(seqNum, mEndpoint, minInterval, maxInterval, change);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR SwitchCluster::ReportAttributeCurrentPosition(Callback::Cancelable * onReportCallback)
{
    return RequestAttributeReporting(0x0001, onReportCallback);
}

CHIP_ERROR SwitchCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                       Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// TvChannel Cluster Commands
CHIP_ERROR TvChannelCluster::ChangeChannel(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                           chip::ByteSpan match)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kChangeChannelCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // match: charString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), match));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR TvChannelCluster::ChangeChannelByNumber(Callback::Cancelable * onSuccessCallback,
                                                   Callback::Cancelable * onFailureCallback, uint16_t majorNumber,
                                                   uint16_t minorNumber)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kChangeChannelByNumberCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // majorNumber: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), majorNumber));
    // minorNumber: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), minorNumber));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR TvChannelCluster::SkipChannel(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                         uint16_t count)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kSkipChannelCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // count: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), count));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

// TvChannel Cluster Attributes
CHIP_ERROR TvChannelCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeTvChannelClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR TvChannelCluster::ReadAttributeTvChannelList(Callback::Cancelable * onSuccessCallback,
                                                        Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0000;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             TvChannelClusterTvChannelListListAttributeFilter);
}

CHIP_ERROR TvChannelCluster::ReadAttributeTvChannelLineup(Callback::Cancelable * onSuccessCallback,
                                                          Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0001;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<StringAttributeCallback>);
}

CHIP_ERROR TvChannelCluster::ReadAttributeCurrentTvChannel(Callback::Cancelable * onSuccessCallback,
                                                           Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0002;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<StringAttributeCallback>);
}

CHIP_ERROR TvChannelCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                          Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// TargetNavigator Cluster Commands
CHIP_ERROR TargetNavigatorCluster::NavigateTarget(Callback::Cancelable * onSuccessCallback,
                                                  Callback::Cancelable * onFailureCallback, uint8_t target, chip::ByteSpan data)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kNavigateTargetCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // target: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), target));
    // data: charString
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), data));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

// TargetNavigator Cluster Attributes
CHIP_ERROR TargetNavigatorCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback,
                                                      Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeTargetNavigatorClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR TargetNavigatorCluster::ReadAttributeTargetNavigatorList(Callback::Cancelable * onSuccessCallback,
                                                                    Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0000;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             TargetNavigatorClusterTargetNavigatorListListAttributeFilter);
}

CHIP_ERROR TargetNavigatorCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                                Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// TemperatureMeasurement Cluster Commands
// TemperatureMeasurement Cluster Attributes
CHIP_ERROR TemperatureMeasurementCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback,
                                                             Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeTemperatureMeasurementClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR TemperatureMeasurementCluster::ReadAttributeMeasuredValue(Callback::Cancelable * onSuccessCallback,
                                                                     Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0000;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16sAttributeCallback>);
}

CHIP_ERROR TemperatureMeasurementCluster::ConfigureAttributeMeasuredValue(Callback::Cancelable * onSuccessCallback,
                                                                          Callback::Cancelable * onFailureCallback,
                                                                          uint16_t minInterval, uint16_t maxInterval,
                                                                          int16_t change)
{
    uint8_t seqNum = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand =
        encodeTemperatureMeasurementClusterConfigureMeasuredValueAttribute(seqNum, mEndpoint, minInterval, maxInterval, change);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR TemperatureMeasurementCluster::ReportAttributeMeasuredValue(Callback::Cancelable * onReportCallback)
{
    return RequestAttributeReporting(0x0000, onReportCallback);
}

CHIP_ERROR TemperatureMeasurementCluster::ReadAttributeMinMeasuredValue(Callback::Cancelable * onSuccessCallback,
                                                                        Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0001;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16sAttributeCallback>);
}

CHIP_ERROR TemperatureMeasurementCluster::ReadAttributeMaxMeasuredValue(Callback::Cancelable * onSuccessCallback,
                                                                        Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0002;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16sAttributeCallback>);
}

CHIP_ERROR TemperatureMeasurementCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                                       Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// TestCluster Cluster Commands
CHIP_ERROR TestClusterCluster::Test(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kTestCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    // Command takes no arguments.

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR TestClusterCluster::TestNotHandled(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kTestNotHandledCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    // Command takes no arguments.

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR TestClusterCluster::TestSpecific(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kTestSpecificCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    // Command takes no arguments.

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR TestClusterCluster::TestUnknownCommand(Callback::Cancelable * onSuccessCallback,
                                                  Callback::Cancelable * onFailureCallback)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kTestUnknownCommandCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    // Command takes no arguments.

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

// TestCluster Cluster Attributes
CHIP_ERROR TestClusterCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback,
                                                  Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeTestClusterClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR TestClusterCluster::ReadAttributeBoolean(Callback::Cancelable * onSuccessCallback,
                                                    Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0000;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<BooleanAttributeCallback>);
}

CHIP_ERROR TestClusterCluster::WriteAttributeBoolean(Callback::Cancelable * onSuccessCallback,
                                                     Callback::Cancelable * onFailureCallback, uint8_t value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeTestClusterClusterWriteBooleanAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR TestClusterCluster::ReadAttributeBitmap8(Callback::Cancelable * onSuccessCallback,
                                                    Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0001;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR TestClusterCluster::WriteAttributeBitmap8(Callback::Cancelable * onSuccessCallback,
                                                     Callback::Cancelable * onFailureCallback, uint8_t value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeTestClusterClusterWriteBitmap8Attribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR TestClusterCluster::ReadAttributeBitmap16(Callback::Cancelable * onSuccessCallback,
                                                     Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0002;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR TestClusterCluster::WriteAttributeBitmap16(Callback::Cancelable * onSuccessCallback,
                                                      Callback::Cancelable * onFailureCallback, uint16_t value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeTestClusterClusterWriteBitmap16Attribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR TestClusterCluster::ReadAttributeBitmap32(Callback::Cancelable * onSuccessCallback,
                                                     Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0003;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR TestClusterCluster::WriteAttributeBitmap32(Callback::Cancelable * onSuccessCallback,
                                                      Callback::Cancelable * onFailureCallback, uint32_t value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeTestClusterClusterWriteBitmap32Attribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR TestClusterCluster::ReadAttributeBitmap64(Callback::Cancelable * onSuccessCallback,
                                                     Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0004;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int64uAttributeCallback>);
}

CHIP_ERROR TestClusterCluster::WriteAttributeBitmap64(Callback::Cancelable * onSuccessCallback,
                                                      Callback::Cancelable * onFailureCallback, uint64_t value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeTestClusterClusterWriteBitmap64Attribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR TestClusterCluster::ReadAttributeInt8u(Callback::Cancelable * onSuccessCallback,
                                                  Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0005;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR TestClusterCluster::WriteAttributeInt8u(Callback::Cancelable * onSuccessCallback,
                                                   Callback::Cancelable * onFailureCallback, uint8_t value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeTestClusterClusterWriteInt8uAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR TestClusterCluster::ReadAttributeInt16u(Callback::Cancelable * onSuccessCallback,
                                                   Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0006;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR TestClusterCluster::WriteAttributeInt16u(Callback::Cancelable * onSuccessCallback,
                                                    Callback::Cancelable * onFailureCallback, uint16_t value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeTestClusterClusterWriteInt16uAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR TestClusterCluster::ReadAttributeInt32u(Callback::Cancelable * onSuccessCallback,
                                                   Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0008;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR TestClusterCluster::WriteAttributeInt32u(Callback::Cancelable * onSuccessCallback,
                                                    Callback::Cancelable * onFailureCallback, uint32_t value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeTestClusterClusterWriteInt32uAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR TestClusterCluster::ReadAttributeInt64u(Callback::Cancelable * onSuccessCallback,
                                                   Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x000C;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int64uAttributeCallback>);
}

CHIP_ERROR TestClusterCluster::WriteAttributeInt64u(Callback::Cancelable * onSuccessCallback,
                                                    Callback::Cancelable * onFailureCallback, uint64_t value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeTestClusterClusterWriteInt64uAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR TestClusterCluster::ReadAttributeInt8s(Callback::Cancelable * onSuccessCallback,
                                                  Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x000D;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8sAttributeCallback>);
}

CHIP_ERROR TestClusterCluster::WriteAttributeInt8s(Callback::Cancelable * onSuccessCallback,
                                                   Callback::Cancelable * onFailureCallback, int8_t value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeTestClusterClusterWriteInt8sAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR TestClusterCluster::ReadAttributeInt16s(Callback::Cancelable * onSuccessCallback,
                                                   Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x000E;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16sAttributeCallback>);
}

CHIP_ERROR TestClusterCluster::WriteAttributeInt16s(Callback::Cancelable * onSuccessCallback,
                                                    Callback::Cancelable * onFailureCallback, int16_t value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeTestClusterClusterWriteInt16sAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR TestClusterCluster::ReadAttributeInt32s(Callback::Cancelable * onSuccessCallback,
                                                   Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0010;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32sAttributeCallback>);
}

CHIP_ERROR TestClusterCluster::WriteAttributeInt32s(Callback::Cancelable * onSuccessCallback,
                                                    Callback::Cancelable * onFailureCallback, int32_t value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeTestClusterClusterWriteInt32sAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR TestClusterCluster::ReadAttributeInt64s(Callback::Cancelable * onSuccessCallback,
                                                   Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0014;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int64sAttributeCallback>);
}

CHIP_ERROR TestClusterCluster::WriteAttributeInt64s(Callback::Cancelable * onSuccessCallback,
                                                    Callback::Cancelable * onFailureCallback, int64_t value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeTestClusterClusterWriteInt64sAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR TestClusterCluster::ReadAttributeEnum8(Callback::Cancelable * onSuccessCallback,
                                                  Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0015;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR TestClusterCluster::WriteAttributeEnum8(Callback::Cancelable * onSuccessCallback,
                                                   Callback::Cancelable * onFailureCallback, uint8_t value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeTestClusterClusterWriteEnum8Attribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR TestClusterCluster::ReadAttributeEnum16(Callback::Cancelable * onSuccessCallback,
                                                   Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0016;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR TestClusterCluster::WriteAttributeEnum16(Callback::Cancelable * onSuccessCallback,
                                                    Callback::Cancelable * onFailureCallback, uint16_t value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeTestClusterClusterWriteEnum16Attribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR TestClusterCluster::ReadAttributeOctetString(Callback::Cancelable * onSuccessCallback,
                                                        Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0019;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<StringAttributeCallback>);
}

CHIP_ERROR TestClusterCluster::WriteAttributeOctetString(Callback::Cancelable * onSuccessCallback,
                                                         Callback::Cancelable * onFailureCallback, chip::ByteSpan value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeTestClusterClusterWriteOctetStringAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR TestClusterCluster::ReadAttributeListInt8u(Callback::Cancelable * onSuccessCallback,
                                                      Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x001A;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             TestClusterClusterListInt8uListAttributeFilter);
}

CHIP_ERROR TestClusterCluster::ReadAttributeListOctetString(Callback::Cancelable * onSuccessCallback,
                                                            Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x001B;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             TestClusterClusterListOctetStringListAttributeFilter);
}

CHIP_ERROR TestClusterCluster::ReadAttributeListStructOctetString(Callback::Cancelable * onSuccessCallback,
                                                                  Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x001C;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             TestClusterClusterListStructOctetStringListAttributeFilter);
}

CHIP_ERROR TestClusterCluster::ReadAttributeLongOctetString(Callback::Cancelable * onSuccessCallback,
                                                            Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x001D;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<StringAttributeCallback>);
}

CHIP_ERROR TestClusterCluster::WriteAttributeLongOctetString(Callback::Cancelable * onSuccessCallback,
                                                             Callback::Cancelable * onFailureCallback, chip::ByteSpan value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeTestClusterClusterWriteLongOctetStringAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR TestClusterCluster::ReadAttributeCharString(Callback::Cancelable * onSuccessCallback,
                                                       Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x001E;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<StringAttributeCallback>);
}

CHIP_ERROR TestClusterCluster::WriteAttributeCharString(Callback::Cancelable * onSuccessCallback,
                                                        Callback::Cancelable * onFailureCallback, chip::ByteSpan value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeTestClusterClusterWriteCharStringAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR TestClusterCluster::ReadAttributeLongCharString(Callback::Cancelable * onSuccessCallback,
                                                           Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x001F;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<StringAttributeCallback>);
}

CHIP_ERROR TestClusterCluster::WriteAttributeLongCharString(Callback::Cancelable * onSuccessCallback,
                                                            Callback::Cancelable * onFailureCallback, chip::ByteSpan value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeTestClusterClusterWriteLongCharStringAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR TestClusterCluster::ReadAttributeUnsupported(Callback::Cancelable * onSuccessCallback,
                                                        Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x00FF;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<BooleanAttributeCallback>);
}

CHIP_ERROR TestClusterCluster::WriteAttributeUnsupported(Callback::Cancelable * onSuccessCallback,
                                                         Callback::Cancelable * onFailureCallback, uint8_t value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeTestClusterClusterWriteUnsupportedAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR TestClusterCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                            Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// Thermostat Cluster Commands
CHIP_ERROR ThermostatCluster::ClearWeeklySchedule(Callback::Cancelable * onSuccessCallback,
                                                  Callback::Cancelable * onFailureCallback)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kClearWeeklyScheduleCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    // Command takes no arguments.

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR ThermostatCluster::GetRelayStatusLog(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kGetRelayStatusLogCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    // Command takes no arguments.

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR ThermostatCluster::GetWeeklySchedule(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                                uint8_t daysToReturn, uint8_t modeToReturn)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kGetWeeklyScheduleCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // daysToReturn: dayOfWeek
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), daysToReturn));
    // modeToReturn: modeForSequence
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), modeToReturn));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR ThermostatCluster::SetWeeklySchedule(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                                uint8_t numberOfTransitionsForSequence, uint8_t dayOfWeekForSequence,
                                                uint8_t modeForSequence, uint8_t payload)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kSetWeeklyScheduleCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // numberOfTransitionsForSequence: enum8
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), numberOfTransitionsForSequence));
    // dayOfWeekForSequence: dayOfWeek
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), dayOfWeekForSequence));
    // modeForSequence: modeForSequence
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), modeForSequence));
    // payload: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), payload));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR ThermostatCluster::SetpointRaiseLower(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                                 uint8_t mode, int8_t amount)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kSetpointRaiseLowerCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // mode: setpointAdjustMode
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), mode));
    // amount: int8s
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), amount));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

// Thermostat Cluster Attributes
CHIP_ERROR ThermostatCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeThermostatClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR ThermostatCluster::ReadAttributeLocalTemperature(Callback::Cancelable * onSuccessCallback,
                                                            Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0000;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16sAttributeCallback>);
}

CHIP_ERROR ThermostatCluster::ConfigureAttributeLocalTemperature(Callback::Cancelable * onSuccessCallback,
                                                                 Callback::Cancelable * onFailureCallback, uint16_t minInterval,
                                                                 uint16_t maxInterval, int16_t change)
{
    uint8_t seqNum = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand =
        encodeThermostatClusterConfigureLocalTemperatureAttribute(seqNum, mEndpoint, minInterval, maxInterval, change);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR ThermostatCluster::ReportAttributeLocalTemperature(Callback::Cancelable * onReportCallback)
{
    return RequestAttributeReporting(0x0000, onReportCallback);
}

CHIP_ERROR ThermostatCluster::ReadAttributeOccupiedCoolingSetpoint(Callback::Cancelable * onSuccessCallback,
                                                                   Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0011;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16sAttributeCallback>);
}

CHIP_ERROR ThermostatCluster::WriteAttributeOccupiedCoolingSetpoint(Callback::Cancelable * onSuccessCallback,
                                                                    Callback::Cancelable * onFailureCallback, int16_t value)
{
    uint8_t seqNum = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand =
        encodeThermostatClusterWriteOccupiedCoolingSetpointAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR ThermostatCluster::ReadAttributeOccupiedHeatingSetpoint(Callback::Cancelable * onSuccessCallback,
                                                                   Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0012;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16sAttributeCallback>);
}

CHIP_ERROR ThermostatCluster::WriteAttributeOccupiedHeatingSetpoint(Callback::Cancelable * onSuccessCallback,
                                                                    Callback::Cancelable * onFailureCallback, int16_t value)
{
    uint8_t seqNum = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand =
        encodeThermostatClusterWriteOccupiedHeatingSetpointAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR ThermostatCluster::ReadAttributeControlSequenceOfOperation(Callback::Cancelable * onSuccessCallback,
                                                                      Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x001B;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR ThermostatCluster::WriteAttributeControlSequenceOfOperation(Callback::Cancelable * onSuccessCallback,
                                                                       Callback::Cancelable * onFailureCallback, uint8_t value)
{
    uint8_t seqNum = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand =
        encodeThermostatClusterWriteControlSequenceOfOperationAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR ThermostatCluster::ReadAttributeSystemMode(Callback::Cancelable * onSuccessCallback,
                                                      Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x001C;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR ThermostatCluster::WriteAttributeSystemMode(Callback::Cancelable * onSuccessCallback,
                                                       Callback::Cancelable * onFailureCallback, uint8_t value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeThermostatClusterWriteSystemModeAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR ThermostatCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                           Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// ThreadNetworkDiagnostics Cluster Commands
CHIP_ERROR ThreadNetworkDiagnosticsCluster::ResetCounts(Callback::Cancelable * onSuccessCallback,
                                                        Callback::Cancelable * onFailureCallback)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kResetCountsCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    // Command takes no arguments.

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

// ThreadNetworkDiagnostics Cluster Attributes
CHIP_ERROR ThreadNetworkDiagnosticsCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback,
                                                               Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeThreadNetworkDiagnosticsClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeChannel(Callback::Cancelable * onSuccessCallback,
                                                                 Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0000;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeRoutingRole(Callback::Cancelable * onSuccessCallback,
                                                                     Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0001;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeNetworkName(Callback::Cancelable * onSuccessCallback,
                                                                     Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0002;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<StringAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributePanId(Callback::Cancelable * onSuccessCallback,
                                                               Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0003;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeExtendedPanId(Callback::Cancelable * onSuccessCallback,
                                                                       Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0004;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int64uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeMeshLocalPrefix(Callback::Cancelable * onSuccessCallback,
                                                                         Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0005;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<StringAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeOverrunCount(Callback::Cancelable * onSuccessCallback,
                                                                      Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0006;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int64uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeNeighborTableList(Callback::Cancelable * onSuccessCallback,
                                                                           Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0007;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             ThreadNetworkDiagnosticsClusterNeighborTableListListAttributeFilter);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeRouteTableList(Callback::Cancelable * onSuccessCallback,
                                                                        Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0008;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             ThreadNetworkDiagnosticsClusterRouteTableListListAttributeFilter);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributePartitionId(Callback::Cancelable * onSuccessCallback,
                                                                     Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0009;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeWeighting(Callback::Cancelable * onSuccessCallback,
                                                                   Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x000A;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeDataVersion(Callback::Cancelable * onSuccessCallback,
                                                                     Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x000B;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeStableDataVersion(Callback::Cancelable * onSuccessCallback,
                                                                           Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x000C;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeLeaderRouterId(Callback::Cancelable * onSuccessCallback,
                                                                        Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x000D;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeDetachedRoleCount(Callback::Cancelable * onSuccessCallback,
                                                                           Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x000E;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeChildRoleCount(Callback::Cancelable * onSuccessCallback,
                                                                        Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x000F;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeRouterRoleCount(Callback::Cancelable * onSuccessCallback,
                                                                         Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0010;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeLeaderRoleCount(Callback::Cancelable * onSuccessCallback,
                                                                         Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0011;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeAttachAttemptCount(Callback::Cancelable * onSuccessCallback,
                                                                            Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0012;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributePartitionIdChangeCount(Callback::Cancelable * onSuccessCallback,
                                                                                Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0013;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeBetterPartitionAttachAttemptCount(Callback::Cancelable * onSuccessCallback,
                                                                                           Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0014;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeParentChangeCount(Callback::Cancelable * onSuccessCallback,
                                                                           Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0015;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeTxTotalCount(Callback::Cancelable * onSuccessCallback,
                                                                      Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0016;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeTxUnicastCount(Callback::Cancelable * onSuccessCallback,
                                                                        Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0017;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeTxBroadcastCount(Callback::Cancelable * onSuccessCallback,
                                                                          Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0018;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeTxAckRequestedCount(Callback::Cancelable * onSuccessCallback,
                                                                             Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0019;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeTxAckedCount(Callback::Cancelable * onSuccessCallback,
                                                                      Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x001A;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeTxNoAckRequestedCount(Callback::Cancelable * onSuccessCallback,
                                                                               Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x001B;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeTxDataCount(Callback::Cancelable * onSuccessCallback,
                                                                     Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x001C;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeTxDataPollCount(Callback::Cancelable * onSuccessCallback,
                                                                         Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x001D;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeTxBeaconCount(Callback::Cancelable * onSuccessCallback,
                                                                       Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x001E;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeTxBeaconRequestCount(Callback::Cancelable * onSuccessCallback,
                                                                              Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x001F;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeTxOtherCount(Callback::Cancelable * onSuccessCallback,
                                                                      Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0020;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeTxRetryCount(Callback::Cancelable * onSuccessCallback,
                                                                      Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0021;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeTxDirectMaxRetryExpiryCount(Callback::Cancelable * onSuccessCallback,
                                                                                     Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0022;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeTxIndirectMaxRetryExpiryCount(Callback::Cancelable * onSuccessCallback,
                                                                                       Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0023;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeTxErrCcaCount(Callback::Cancelable * onSuccessCallback,
                                                                       Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0024;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeTxErrAbortCount(Callback::Cancelable * onSuccessCallback,
                                                                         Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0025;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeTxErrBusyChannelCount(Callback::Cancelable * onSuccessCallback,
                                                                               Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0026;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeRxTotalCount(Callback::Cancelable * onSuccessCallback,
                                                                      Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0027;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeRxUnicastCount(Callback::Cancelable * onSuccessCallback,
                                                                        Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0028;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeRxBroadcastCount(Callback::Cancelable * onSuccessCallback,
                                                                          Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0029;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeRxDataCount(Callback::Cancelable * onSuccessCallback,
                                                                     Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x002A;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeRxDataPollCount(Callback::Cancelable * onSuccessCallback,
                                                                         Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x002B;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeRxBeaconCount(Callback::Cancelable * onSuccessCallback,
                                                                       Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x002C;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeRxBeaconRequestCount(Callback::Cancelable * onSuccessCallback,
                                                                              Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x002D;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeRxOtherCount(Callback::Cancelable * onSuccessCallback,
                                                                      Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x002E;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeRxAddressFilteredCount(Callback::Cancelable * onSuccessCallback,
                                                                                Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x002F;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeRxDestAddrFilteredCount(Callback::Cancelable * onSuccessCallback,
                                                                                 Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0030;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeRxDuplicatedCount(Callback::Cancelable * onSuccessCallback,
                                                                           Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0031;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeRxErrNoFrameCount(Callback::Cancelable * onSuccessCallback,
                                                                           Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0032;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeRxErrUnknownNeighborCount(Callback::Cancelable * onSuccessCallback,
                                                                                   Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0033;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeRxErrInvalidSrcAddrCount(Callback::Cancelable * onSuccessCallback,
                                                                                  Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0034;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeRxErrSecCount(Callback::Cancelable * onSuccessCallback,
                                                                       Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0035;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeRxErrFcsCount(Callback::Cancelable * onSuccessCallback,
                                                                       Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0036;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeRxErrOtherCount(Callback::Cancelable * onSuccessCallback,
                                                                         Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0037;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int32uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeSecurityPolicy(Callback::Cancelable * onSuccessCallback,
                                                                        Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x003B;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             ThreadNetworkDiagnosticsClusterSecurityPolicyListAttributeFilter);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeChannelMask(Callback::Cancelable * onSuccessCallback,
                                                                     Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x003C;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeOperationalDatasetComponents(Callback::Cancelable * onSuccessCallback,
                                                                                      Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x003D;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             ThreadNetworkDiagnosticsClusterOperationalDatasetComponentsListAttributeFilter);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeActiveNetworkFaultsList(Callback::Cancelable * onSuccessCallback,
                                                                                 Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x003E;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             ThreadNetworkDiagnosticsClusterActiveNetworkFaultsListListAttributeFilter);
}

CHIP_ERROR ThreadNetworkDiagnosticsCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                                         Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// WakeOnLan Cluster Commands
// WakeOnLan Cluster Attributes
CHIP_ERROR WakeOnLanCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeWakeOnLanClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR WakeOnLanCluster::ReadAttributeWakeOnLanMacAddress(Callback::Cancelable * onSuccessCallback,
                                                              Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0000;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<StringAttributeCallback>);
}

CHIP_ERROR WakeOnLanCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                          Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// WiFiNetworkDiagnostics Cluster Commands
// WiFiNetworkDiagnostics Cluster Attributes
CHIP_ERROR WiFiNetworkDiagnosticsCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback,
                                                             Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeWiFiNetworkDiagnosticsClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR WiFiNetworkDiagnosticsCluster::ReadAttributeBssid(Callback::Cancelable * onSuccessCallback,
                                                             Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0000;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<StringAttributeCallback>);
}

CHIP_ERROR WiFiNetworkDiagnosticsCluster::ReadAttributeSecurityType(Callback::Cancelable * onSuccessCallback,
                                                                    Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0001;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR WiFiNetworkDiagnosticsCluster::ReadAttributeWiFiVersion(Callback::Cancelable * onSuccessCallback,
                                                                   Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0002;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR WiFiNetworkDiagnosticsCluster::ReadAttributeChannelNumber(Callback::Cancelable * onSuccessCallback,
                                                                     Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0003;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR WiFiNetworkDiagnosticsCluster::ReadAttributeRssi(Callback::Cancelable * onSuccessCallback,
                                                            Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0004;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8sAttributeCallback>);
}

CHIP_ERROR WiFiNetworkDiagnosticsCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                                       Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

// WindowCovering Cluster Commands
CHIP_ERROR WindowCoveringCluster::DownOrClose(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kDownOrCloseCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    // Command takes no arguments.

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR WindowCoveringCluster::GoToLiftPercentage(Callback::Cancelable * onSuccessCallback,
                                                     Callback::Cancelable * onFailureCallback, uint8_t liftPercentageValue,
                                                     uint16_t liftPercent100thsValue)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kGoToLiftPercentageCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // liftPercentageValue: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), liftPercentageValue));
    // liftPercent100thsValue: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), liftPercent100thsValue));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR WindowCoveringCluster::GoToLiftValue(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                                uint16_t liftValue)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kGoToLiftValueCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // liftValue: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), liftValue));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR WindowCoveringCluster::GoToTiltPercentage(Callback::Cancelable * onSuccessCallback,
                                                     Callback::Cancelable * onFailureCallback, uint8_t tiltPercentageValue,
                                                     uint16_t tiltPercent100thsValue)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kGoToTiltPercentageCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // tiltPercentageValue: int8u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), tiltPercentageValue));
    // tiltPercent100thsValue: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), tiltPercent100thsValue));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR WindowCoveringCluster::GoToTiltValue(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
                                                uint16_t tiltValue)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kGoToTiltValueCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    // tiltValue: int16u
    SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), tiltValue));

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR WindowCoveringCluster::StopMotion(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kStopMotionCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    // Command takes no arguments.

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

CHIP_ERROR WindowCoveringCluster::UpOrOpen(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    app::CommandSender * sender = nullptr;
    TLV::TLVWriter * writer     = nullptr;
    uint8_t argSeqNumber        = 0;

    // Used when encoding non-empty command. Suppress error message when encoding empty commands.
    (void) writer;
    (void) argSeqNumber;

    VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

    app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kUpOrOpenCommandId,
                                         (chip::app::CommandPathFlags::kEndpointIdValid) };

    SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

    SuccessOrExit(err = sender->PrepareCommand(cmdParams));

    // Command takes no arguments.

    SuccessOrExit(err = sender->FinishCommand());

    // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
    mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

    err = mDevice->SendCommands(sender);

exit:
    // On error, we are responsible to close the sender.
    if (err != CHIP_NO_ERROR && sender != nullptr)
    {
        sender->Shutdown();
    }
    return err;
}

// WindowCovering Cluster Attributes
CHIP_ERROR WindowCoveringCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback,
                                                     Callback::Cancelable * onFailureCallback)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeWindowCoveringClusterDiscoverAttributes(seqNum, mEndpoint);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}
CHIP_ERROR WindowCoveringCluster::ReadAttributeType(Callback::Cancelable * onSuccessCallback,
                                                    Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0000;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR WindowCoveringCluster::ReadAttributeCurrentPositionLift(Callback::Cancelable * onSuccessCallback,
                                                                   Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0003;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR WindowCoveringCluster::ReadAttributeCurrentPositionTilt(Callback::Cancelable * onSuccessCallback,
                                                                   Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0004;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR WindowCoveringCluster::ReadAttributeConfigStatus(Callback::Cancelable * onSuccessCallback,
                                                            Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0007;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR WindowCoveringCluster::ReadAttributeCurrentPositionLiftPercentage(Callback::Cancelable * onSuccessCallback,
                                                                             Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0008;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR WindowCoveringCluster::ConfigureAttributeCurrentPositionLiftPercentage(Callback::Cancelable * onSuccessCallback,
                                                                                  Callback::Cancelable * onFailureCallback,
                                                                                  uint16_t minInterval, uint16_t maxInterval,
                                                                                  uint8_t change)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeWindowCoveringClusterConfigureCurrentPositionLiftPercentageAttribute(
        seqNum, mEndpoint, minInterval, maxInterval, change);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR WindowCoveringCluster::ReportAttributeCurrentPositionLiftPercentage(Callback::Cancelable * onReportCallback)
{
    return RequestAttributeReporting(0x0008, onReportCallback);
}

CHIP_ERROR WindowCoveringCluster::ReadAttributeCurrentPositionTiltPercentage(Callback::Cancelable * onSuccessCallback,
                                                                             Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0009;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR WindowCoveringCluster::ConfigureAttributeCurrentPositionTiltPercentage(Callback::Cancelable * onSuccessCallback,
                                                                                  Callback::Cancelable * onFailureCallback,
                                                                                  uint16_t minInterval, uint16_t maxInterval,
                                                                                  uint8_t change)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeWindowCoveringClusterConfigureCurrentPositionTiltPercentageAttribute(
        seqNum, mEndpoint, minInterval, maxInterval, change);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR WindowCoveringCluster::ReportAttributeCurrentPositionTiltPercentage(Callback::Cancelable * onReportCallback)
{
    return RequestAttributeReporting(0x0009, onReportCallback);
}

CHIP_ERROR WindowCoveringCluster::ReadAttributeOperationalStatus(Callback::Cancelable * onSuccessCallback,
                                                                 Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x000A;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR WindowCoveringCluster::ConfigureAttributeOperationalStatus(Callback::Cancelable * onSuccessCallback,
                                                                      Callback::Cancelable * onFailureCallback,
                                                                      uint16_t minInterval, uint16_t maxInterval)
{
    uint8_t seqNum = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand =
        encodeWindowCoveringClusterConfigureOperationalStatusAttribute(seqNum, mEndpoint, minInterval, maxInterval);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR WindowCoveringCluster::ReportAttributeOperationalStatus(Callback::Cancelable * onReportCallback)
{
    return RequestAttributeReporting(0x000A, onReportCallback);
}

CHIP_ERROR WindowCoveringCluster::ReadAttributeTargetPositionLiftPercent100ths(Callback::Cancelable * onSuccessCallback,
                                                                               Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x000B;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR WindowCoveringCluster::ConfigureAttributeTargetPositionLiftPercent100ths(Callback::Cancelable * onSuccessCallback,
                                                                                    Callback::Cancelable * onFailureCallback,
                                                                                    uint16_t minInterval, uint16_t maxInterval,
                                                                                    uint16_t change)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeWindowCoveringClusterConfigureTargetPositionLiftPercent100thsAttribute(
        seqNum, mEndpoint, minInterval, maxInterval, change);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR WindowCoveringCluster::ReportAttributeTargetPositionLiftPercent100ths(Callback::Cancelable * onReportCallback)
{
    return RequestAttributeReporting(0x000B, onReportCallback);
}

CHIP_ERROR WindowCoveringCluster::ReadAttributeTargetPositionTiltPercent100ths(Callback::Cancelable * onSuccessCallback,
                                                                               Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x000C;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR WindowCoveringCluster::ConfigureAttributeTargetPositionTiltPercent100ths(Callback::Cancelable * onSuccessCallback,
                                                                                    Callback::Cancelable * onFailureCallback,
                                                                                    uint16_t minInterval, uint16_t maxInterval,
                                                                                    uint16_t change)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeWindowCoveringClusterConfigureTargetPositionTiltPercent100thsAttribute(
        seqNum, mEndpoint, minInterval, maxInterval, change);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR WindowCoveringCluster::ReportAttributeTargetPositionTiltPercent100ths(Callback::Cancelable * onReportCallback)
{
    return RequestAttributeReporting(0x000C, onReportCallback);
}

CHIP_ERROR WindowCoveringCluster::ReadAttributeEndProductType(Callback::Cancelable * onSuccessCallback,
                                                              Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x000D;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR WindowCoveringCluster::ReadAttributeCurrentPositionLiftPercent100ths(Callback::Cancelable * onSuccessCallback,
                                                                                Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x000E;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR WindowCoveringCluster::ConfigureAttributeCurrentPositionLiftPercent100ths(Callback::Cancelable * onSuccessCallback,
                                                                                     Callback::Cancelable * onFailureCallback,
                                                                                     uint16_t minInterval, uint16_t maxInterval,
                                                                                     uint16_t change)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeWindowCoveringClusterConfigureCurrentPositionLiftPercent100thsAttribute(
        seqNum, mEndpoint, minInterval, maxInterval, change);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR WindowCoveringCluster::ReportAttributeCurrentPositionLiftPercent100ths(Callback::Cancelable * onReportCallback)
{
    return RequestAttributeReporting(0x000E, onReportCallback);
}

CHIP_ERROR WindowCoveringCluster::ReadAttributeCurrentPositionTiltPercent100ths(Callback::Cancelable * onSuccessCallback,
                                                                                Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x000F;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR WindowCoveringCluster::ConfigureAttributeCurrentPositionTiltPercent100ths(Callback::Cancelable * onSuccessCallback,
                                                                                     Callback::Cancelable * onFailureCallback,
                                                                                     uint16_t minInterval, uint16_t maxInterval,
                                                                                     uint16_t change)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeWindowCoveringClusterConfigureCurrentPositionTiltPercent100thsAttribute(
        seqNum, mEndpoint, minInterval, maxInterval, change);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR WindowCoveringCluster::ReportAttributeCurrentPositionTiltPercent100ths(Callback::Cancelable * onReportCallback)
{
    return RequestAttributeReporting(0x000F, onReportCallback);
}

CHIP_ERROR WindowCoveringCluster::ReadAttributeInstalledOpenLimitLift(Callback::Cancelable * onSuccessCallback,
                                                                      Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0010;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR WindowCoveringCluster::ReadAttributeInstalledClosedLimitLift(Callback::Cancelable * onSuccessCallback,
                                                                        Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0011;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR WindowCoveringCluster::ReadAttributeInstalledOpenLimitTilt(Callback::Cancelable * onSuccessCallback,
                                                                      Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0012;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR WindowCoveringCluster::ReadAttributeInstalledClosedLimitTilt(Callback::Cancelable * onSuccessCallback,
                                                                        Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0013;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR WindowCoveringCluster::ReadAttributeMode(Callback::Cancelable * onSuccessCallback,
                                                    Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x0017;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int8uAttributeCallback>);
}

CHIP_ERROR WindowCoveringCluster::WriteAttributeMode(Callback::Cancelable * onSuccessCallback,
                                                     Callback::Cancelable * onFailureCallback, uint8_t value)
{
    uint8_t seqNum                            = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand = encodeWindowCoveringClusterWriteModeAttribute(seqNum, mEndpoint, value);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR WindowCoveringCluster::ReadAttributeSafetyStatus(Callback::Cancelable * onSuccessCallback,
                                                            Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0x001A;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

CHIP_ERROR WindowCoveringCluster::ConfigureAttributeSafetyStatus(Callback::Cancelable * onSuccessCallback,
                                                                 Callback::Cancelable * onFailureCallback, uint16_t minInterval,
                                                                 uint16_t maxInterval)
{
    uint8_t seqNum = mDevice->GetNextSequenceNumber();
    System::PacketBufferHandle encodedCommand =
        encodeWindowCoveringClusterConfigureSafetyStatusAttribute(seqNum, mEndpoint, minInterval, maxInterval);
    return SendCommand(seqNum, std::move(encodedCommand), onSuccessCallback, onFailureCallback);
}

CHIP_ERROR WindowCoveringCluster::ReportAttributeSafetyStatus(Callback::Cancelable * onReportCallback)
{
    return RequestAttributeReporting(0x001A, onReportCallback);
}

CHIP_ERROR WindowCoveringCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback,
                                                               Callback::Cancelable * onFailureCallback)
{
    chip::app::AttributePathParams attributePath;
    attributePath.mEndpointId = mEndpoint;
    attributePath.mClusterId  = mClusterId;
    attributePath.mFieldId    = 0xFFFD;
    attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid);
    return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback,
                                             BasicAttributeFilter<Int16uAttributeCallback>);
}

} // namespace Controller
} // namespace chip
